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

#define DEBUG_COMBO
/*
#define DEBUG_COMBO
*/

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

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "windows.h"
#include "combo.h"
#include "heap.h"
#include "win.h"
#include "prototypes.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;
    HDC		hDC, hMemDC;
    BITMAP	bm;
    char	str[128];
    PAINTSTRUCT paintstruct;
    static RECT rectsel;
    switch(message)
    {
    case WM_CREATE:
		wndPtr = WIN_FindWndPtr(hwnd);
		if (wndPtr == 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));
		GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
		wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL);
		GetWindowRect(hwnd, &rect);
		width = rect.right - rect.left;
		height = rect.bottom - rect.top;
		SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, 
										SWP_NOMOVE | SWP_NOZORDER); 
		CreateComboStruct(hwnd);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		if (wndPtr->dwStyle & CBS_SIMPLE)
/*			lphc->hWndEdit = CreateWindow("EDIT", "", */
			lphc->hWndEdit = CreateWindow("STATIC", "", 
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
				0, 0, width - bm.bmHeight, bm.bmHeight, 
				hwnd, 1, wndPtr->hInstance, 0L);
		else
			lphc->hWndEdit = CreateWindow("STATIC", "", 
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
				0, 0, width - bm.bmHeight, bm.bmHeight, 
				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 + bm.bmHeight, 
			width, height, wndPtr->hwndParent, 1, 
			wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd));
		ShowWindow(lphc->hWndLBox, SW_HIDE);
#ifdef DEBUG_COMBO
		printf("Combo Creation LBox=%X!\n", lphc->hWndLBox);
#endif
		return 0;
    case WM_DESTROY:
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == 0) return 0;
/*
		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->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);
		GetClientRect(hwnd, &rect);
		rect.left = rect.right - (rect.bottom - rect.top); 
		hDC = GetDC(hwnd);
		InflateRect(&rect, -1, -1);
		DrawReliefRect(hDC, rect, 1, 1);
		ReleaseDC(hwnd, hDC);
		wndPtr = WIN_FindWndPtr(hwnd);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
		    ShowWindow(lphc->hWndLBox, SW_SHOW);
		    SetFocus(lphc->hWndLBox);
			}
		else {
			printf("before Combo Restore Focus !\n");
			SetFocus(lphc->hWndEdit);
			printf("before Combo List Hide !\n");
			ShowWindow(lphc->hWndLBox, SW_HIDE);
			printf("before Combo List GetCurSel !\n");
			y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
			if (y != LB_ERR) {
				printf("before Combo List GetText !\n");
				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
				}
			printf("End of Combo List Hide !\n");
			}
		break;
    case WM_LBUTTONUP:
		printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
		GetClientRect(hwnd, &rect);
		rect.left = rect.right - (rect.bottom - rect.top); 
		hDC = GetDC(hwnd);
		InflateRect(&rect, -1, -1);
		DrawReliefRect(hDC, rect, 1, 0);
		ReleaseDC(hwnd, hDC);
		break;
   case WM_KEYDOWN:
		wndPtr = WIN_FindWndPtr(hwnd);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		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);
			    SetFocus(lphc->hWndLBox);
				}
			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_MEASUREITEM:
		printf("ComboBoxWndProc WM_MEASUREITEM !\n");
    	return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam));
    case WM_CTLCOLOR:
    	return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
    case WM_PAINT:
		GetClientRect(hwnd, &rect);
		hDC = BeginPaint(hwnd, &paintstruct);
		hMemDC = CreateCompatibleDC(hDC);
		if (hMemDC != 0 && hComboBit != 0) {
			GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
			SelectObject(hMemDC, hComboBit);
			BitBlt(hDC, rect.right - bm.bmWidth, 0, 
			bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
			}
		DeleteDC(hMemDC);
		EndPaint(hwnd, &paintstruct);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		InvalidateRect(lphc->hWndEdit, NULL, TRUE);
		UpdateWindow(lphc->hWndEdit);
		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
			InvalidateRect(lphc->hWndLBox, NULL, TRUE);
			UpdateWindow(lphc->hWndLBox);
			}
		break;
	case WM_SETFOCUS:
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		SetFocus(lphc->hWndEdit);
		break;
	case WM_KILLFOCUS:
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		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);
			}
		break;
	case CB_ADDSTRING:
#ifdef DEBUG_COMBO
		printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
#endif
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
    case CB_GETLBTEXT:
		printf("CB_GETLBTEXT #%u !\n", wParam);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
    case CB_GETLBTEXTLEN:
		printf("CB_GETLBTEXTLEN !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
    case CB_INSERTSTRING:
		printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
	case CB_DELETESTRING:
		printf("CB_DELETESTRING #%u !\n", wParam);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
	case CB_RESETCONTENT:
		printf("CB_RESETCONTENT !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
    case CB_DIR:
		printf("ComboBox CB_DIR !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		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);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
	case CB_GETCURSEL:
		printf("ComboBox CB_GETCURSEL !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
    case CB_SETCURSEL:
		printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
	case CB_GETEDITSEL:
		printf("ComboBox CB_GETEDITSEL !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
/*        return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
		break;
	case CB_SETEDITSEL:
		printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam);
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
/*        return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
		break;
	case CB_SELECTSTRING:
		printf("ComboBox CB_SELECTSTRING !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		break;
	case CB_SHOWDROPDOWN:
		printf("ComboBox CB_SHOWDROPDOWN !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
		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);
		if (lphc == NULL) return 0;
		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);
		if (lphc == NULL) return 0;
		return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
        break;
    case CB_LIMITTEXT:
		printf("ComboBox CB_LIMITTEXT !\n");
		lphc = ComboGetStorageHeader(hwnd);
		if (lphc == NULL) return 0;
/*        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;
}



/************************************************************************
 * 					DlgDirSelectComboBox	[USER.194]
 */
BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
{
	printf("DlgDirSelectComboBox(%04X, '%s', %d) \n",	hDlg, lpStr, nIDLBox);
}


/************************************************************************
 * 					DlgDirListComboBox		[USER.195]
 */
int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec, 
	int nIDLBox, int nIDStat, WORD wType)
{
	HWND		hWnd;
    LPHEADCOMBO lphc;
	printf("DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
	hWnd = GetDlgItem(hDlg, nIDLBox);
	lphc = ComboGetStorageHeader(hWnd);
	if (lphc == NULL) return 0;
	SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
	return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);
}



