/*
 * Interface code to COMBOBOX widget
 *
 * Copyright  Martin Ayotte, 1993
 *
 */

/*
#define DEBUG_COMBO
*/

static char Copyright[] = "Copyright Martin Ayotte, 1993";

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "windows.h"
#include "combo.h"
#include "heap.h"
#include "win.h"
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

HBITMAP hComboBit = 0;

LPHEADCOMBO ComboGetStorageHeader(HWND hwnd);
int CreateComboStruct(HWND hwnd);


/***********************************************************************
 *           ComboWndProc
 */
LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
{    
    WORD	wRet;
    RECT	rect;
    int		y, count;
    int		width, height;
    int		AltState;
    WND  	*wndPtr;
    LPHEADCOMBO lphc;
    LPDRAWITEMSTRUCT lpdis;
    HDC		hMemDC;
    BITMAP	bm;
    char	str[128];
    PAINTSTRUCT paintstruct;
    static RECT rectsel;
    switch(message)
    {
    case WM_CREATE:
	ShowScrollBar(hwnd, SB_BOTH, FALSE);
	GetClientRect(hwnd, &rect);
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;
/*	SetWindowPos(hwnd, 0, 0, 0, width, 16, 
		SWP_NOMOVE | SWP_NOZORDER); */
	CreateComboStruct(hwnd);
	wndPtr = WIN_FindWndPtr(hwnd);
	lphc = ComboGetStorageHeader(hwnd);
	if (lphc == NULL) return 0;
#ifdef DEBUG_COMBO
        printf("Combo WM_CREATE %lX !\n", lphc);
#endif
	if (hComboBit == (HBITMAP)NULL) 
	    hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO));
	lphc->hWndDrop = CreateWindow("BUTTON", "", 
        	WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_OWNERDRAW,
        	width - 16, 0, 16, 16, hwnd, 1, wndPtr->hInstance, 0L);
        if (wndPtr->dwStyle & CBS_SIMPLE)
/*	    lphc->hWndEdit = CreateWindow("EDIT", "", */
	    lphc->hWndEdit = CreateWindow("STATIC", "", 
		WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
		0, 0, width - 16, 16, hwnd, 1, wndPtr->hInstance, 0L);
	else
	    lphc->hWndEdit = CreateWindow("STATIC", "", 
		WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
		0, 0, width - 16, 16, hwnd, 1, wndPtr->hInstance, 0L);
	lphc->hWndLBox = CreateWindow("LISTBOX", "", 
        	WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY,
        	wndPtr->rectClient.left, wndPtr->rectClient.top + 16, width, height, 
        	wndPtr->hwndParent, 1, wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd));
        ShowWindow(lphc->hWndLBox, SW_HIDE);
#ifdef DEBUG_COMBO
        printf("Combo Creation Drop=%X LBox=%X!\n", lphc->hWndDrop, lphc->hWndLBox);
#endif
	return 0;
    case WM_DESTROY:
	lphc = ComboGetStorageHeader(hwnd);
	if (lphc == 0) return 0;
/*
	DestroyWindow(lphc->hWndDrop);
	DestroyWindow(lphc->hWndEdit);
*/
	DestroyWindow(lphc->hWndLBox);
	free(lphc);
/*
	*((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; 
        printf("Combo WM_DESTROY after clearing wExtra !\n");
*/
#ifdef DEBUG_COMBO
        printf("Combo WM_DESTROY %lX !\n", lphc);
#endif
	return DefWindowProc( hwnd, message, wParam, lParam );
	
    case WM_COMMAND:
	wndPtr = WIN_FindWndPtr(hwnd);
	lphc = ComboGetStorageHeader(hwnd);
	if (lphc == NULL) return 0;
        if (LOWORD(lParam) == lphc->hWndDrop) {
	    if (HIWORD(lParam) != BN_CLICKED) return 0;
#ifdef DEBUG_COMBO
	    printf("CB_SHOWDROPDOWN !\n");
#endif
	    lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
	    if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
		ShowWindow(lphc->hWndLBox, SW_SHOW);
/*
		SetFocus(lphc->hWndLBox);
*/
		}
	    else {
/*
		SetFocus(lphc->hWndEdit);
*/
		ShowWindow(lphc->hWndLBox, SW_HIDE);
		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
		if (y != LB_ERR) {
		    SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
		    SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
		    }
		}
            }
        if (LOWORD(lParam) == lphc->hWndLBox) {
            switch(HIWORD(lParam))
        	{
        	case LBN_SELCHANGE:
		    lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
		    ShowWindow(lphc->hWndLBox, SW_HIDE);
		    y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
		    if (y != LB_ERR) {
		    	SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
		    	SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
		    	}
		    SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
			        	MAKELONG(hwnd, CBN_SELCHANGE));
        	    break;
        	case LBN_DBLCLK:
		    SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
			        	MAKELONG(hwnd, CBN_DBLCLK));
        	    break;
        	}
            }
	break;
    case WM_LBUTTONDOWN:
        printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam);
	wndPtr = WIN_FindWndPtr(hwnd);
	lphc = ComboGetStorageHeader(hwnd);
	lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
	if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN)
	    ShowWindow(lphc->hWndLBox, SW_SHOW);
	break;
    case WM_KEYDOWN:
	wndPtr = WIN_FindWndPtr(hwnd);
	lphc = ComboGetStorageHeader(hwnd);
	y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
	count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
	printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
	if (GetKeyState(VK_MENU) < 0) {
	    lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
	    if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
		ShowWindow(lphc->hWndLBox, SW_SHOW);
		}
	    else {
		ShowWindow(lphc->hWndLBox, SW_HIDE);
		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
		if (y != LB_ERR) {
		    SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
		    SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
		    }
		}
	    }
	else
	    {
	    switch(wParam) {
		case VK_HOME:
		    y = 0;
			break;
		case VK_END:
		    y = count - 1;
		    break;
		case VK_UP:
		    y--;
		    break;
		case VK_DOWN:
		    y++;
		    break;
		}
	    if (y < 0) y = 0;
	    if (y >= count) y = count - 1;
	    SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
	    SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
	    SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
	    SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
				    MAKELONG(hwnd, CBN_SELCHANGE));
	    }
	break;
    case WM_CTLCOLOR:
    	return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
    case WM_DRAWITEM:
#ifdef DEBUG_SCROLL
	    printf("ComboBox WM_DRAWITEM w=%04X l=%08X\n", wParam, lParam);
#endif
        lpdis = (LPDRAWITEMSTRUCT)lParam;
	if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_DRAWENTIRE) {
	    hMemDC = CreateCompatibleDC(lpdis->hDC);
	    GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
	    SelectObject(hMemDC, hComboBit);
	    BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
	    DeleteDC(hMemDC);
	    }
	if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_SELECT) {
	    CopyRect(&rect, &lpdis->rcItem);
	    InflateRect(&rect, -1, -1);
	    DrawReliefRect(lpdis->hDC, rect, 1, 1);
	    }
	break;
    case WM_PAINT:
	BeginPaint( hwnd, &paintstruct );
	EndPaint( hwnd, &paintstruct );
	lphc = ComboGetStorageHeader(hwnd);
        InvalidateRect(lphc->hWndEdit, NULL, TRUE);
        UpdateWindow(lphc->hWndEdit);
        InvalidateRect(lphc->hWndDrop, NULL, TRUE);
        UpdateWindow(lphc->hWndDrop);
        if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
	    InvalidateRect(lphc->hWndLBox, NULL, TRUE);
	    UpdateWindow(lphc->hWndLBox);
	    }
	break;
    case CB_ADDSTRING:
#ifdef DEBUG_COMBO
        printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
#endif
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
    case CB_GETLBTEXT:
        printf("CB_GETLBTEXT #%u !\n", wParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
    case CB_GETLBTEXTLEN:
        printf("CB_GETLBTEXTLEN !\n");
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
    case CB_INSERTSTRING:
        printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
    case CB_DELETESTRING:
        printf("CB_DELETESTRING #%u !\n", wParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
    case CB_RESETCONTENT:
        printf("CB_RESETCONTENT !\n");
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
    case CB_DIR:
        printf("ComboBox CB_DIR !\n");
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
    case CB_FINDSTRING:
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
    case CB_GETCOUNT:
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
    case CB_GETCURSEL:
        printf("ComboBox CB_GETCURSEL !\n");
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
    case CB_SETCURSEL:
        printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
    case CB_GETEDITSEL:
        printf("ComboBox CB_GETEDITSEL !\n");
	lphc = ComboGetStorageHeader(hwnd);
/*        return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
        break;
     case CB_SETEDITSEL:
        printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam);
	lphc = ComboGetStorageHeader(hwnd);
/*        return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
	break;
    case CB_SELECTSTRING:
        printf("ComboBox CB_SELECTSTRING !\n");
	lphc = ComboGetStorageHeader(hwnd);
        break;
    case CB_SHOWDROPDOWN:
        printf("ComboBox CB_SHOWDROPDOWN !\n");
	lphc = ComboGetStorageHeader(hwnd);
	lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
	if (wParam != 0) {
	    ShowWindow(lphc->hWndLBox, SW_SHOW);
	    }
	else {
	    lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
	    ShowWindow(lphc->hWndLBox, SW_HIDE);
	    SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
			        	MAKELONG(hwnd, CBN_DROPDOWN));
	    }
        break;
    case CB_GETITEMDATA:
        printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
        break;
    case CB_SETITEMDATA:
        printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam);
	lphc = ComboGetStorageHeader(hwnd);
        return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
        break;
    case CB_LIMITTEXT:
        printf("ComboBox CB_LIMITTEXT !\n");
	lphc = ComboGetStorageHeader(hwnd);
/*        return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
        break;
	
    default:
	return DefWindowProc( hwnd, message, wParam, lParam );
    }
return 0;
}



LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADCOMBO lphc;
    wndPtr = WIN_FindWndPtr(hwnd);
    if (wndPtr == 0) {
    	printf("Bad Window handle on ComboBox !\n");
    	return 0;
    	}
    lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]);
    return lphc;
}



int CreateComboStruct(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADCOMBO lphc;
    wndPtr = WIN_FindWndPtr(hwnd);
    if (wndPtr == 0) {
    	printf("Bad Window handle on ComboBox !\n");
    	return 0;
    	}
    lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
    *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc;
    lphc->dwState = 0;
    return TRUE;
}



