/*
	WinSTon

	Keyboard Property Page
*/

#include "..\includes\winston.h"
#include "..\includes\dialog.h"
#include "..\includes\file.h"
#include "..\includes\keymap.h"
#include "..\includes\shortcut.h"

int nKeyTestItems;								// Number of items in Key Test list box
unsigned int KeyTimerID;						// Timer used in key test dialog to check keyboard state

//-----------------------------------------------------------------------
/*
	Set defaults for Keyboard
*/
void Dialog_Keyboard_SetDefaults(void)
{
	// Set defaults for Keyboard
	ConfigureParams.Keyboard.bDisableKeyRepeat = TRUE;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_KEY] = SHORTCUT_FULLSCREEN;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_SHIFT] = SHORTCUT_NOTASSIGNED;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_CTRL] = SHORTCUT_NOTASSIGNED;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_KEY] = SHORTCUT_MOUSEMODE;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_SHIFT] = SHORTCUT_NOTASSIGNED;
	ConfigureParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_CTRL] = SHORTCUT_NOTASSIGNED;
	strcpy(ConfigureParams.Keyboard.szMappingFileName,"");
}

//-----------------------------------------------------------------------
/*
	Write settings into dialog page
*/
void Dialog_Keyboard_WritePopulate(HWND hDlg)
{
	// Set items
	Dialog_SetButton(hDlg,IDC_RADIO_DISABLEKEYREPEAT,DialogParams.Keyboard.bDisableKeyRepeat);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_F11,pszShortCutF11TextString,0);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_SHIFT_F11,pszShortCutTextStrings,DialogParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_SHIFT]);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_CTRL_F11,pszShortCutTextStrings,DialogParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_CTRL]);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_F12,pszShortCutF12TextString,0);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_SHIFT_F12,pszShortCutTextStrings,DialogParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_SHIFT]);
	Dialog_SetComboBoxItems(hDlg,IDC_COMBO_CTRL_F12,pszShortCutTextStrings,DialogParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_CTRL]);
	Dialog_SetText(hDlg,IDC_EDIT_KEYMAP,DialogParams.Keyboard.szMappingFileName);

	bOKDialog = TRUE;
}

//-----------------------------------------------------------------------
/*
	Read settings back from dialog page
*/
void Dialog_Keyboard_ReadPopulate(HWND hDlg)
{
	// Read items
	DialogParams.Keyboard.bDisableKeyRepeat = Dialog_ReadButton(hDlg,IDC_RADIO_DISABLEKEYREPEAT);
	DialogParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_SHIFT] = Dialog_GetSelectedComboBoxItem(hDlg,IDC_COMBO_SHIFT_F11);
	DialogParams.Keyboard.ShortCuts[SHORT_CUT_F11][SHORT_CUT_CTRL] = Dialog_GetSelectedComboBoxItem(hDlg,IDC_COMBO_CTRL_F11);
	DialogParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_SHIFT] = Dialog_GetSelectedComboBoxItem(hDlg,IDC_COMBO_SHIFT_F12);
	DialogParams.Keyboard.ShortCuts[SHORT_CUT_F12][SHORT_CUT_CTRL] = Dialog_GetSelectedComboBoxItem(hDlg,IDC_COMBO_CTRL_F12);
	Dialog_ReadText(hDlg,IDC_EDIT_KEYMAP,DialogParams.Keyboard.szMappingFileName);
}

//-----------------------------------------------------------------------
/*
	Browse for key mapping file (.map)
*/
void Dialog_Keyboard_BrowseMappingFile(HWND hDlg)
{
	// Browse for file and change edit box if OK
	if (File_OpenSelectDlg(hWnd,DialogParams.Keyboard.szMappingFileName,FILEFILTER_MAPFILE,TRUE,FALSE))
		Dialog_SetText(hDlg,IDC_EDIT_KEYMAP,DialogParams.Keyboard.szMappingFileName);
}

//-----------------------------------------------------------------------
/*
	Keyboard Property page handler
*/
BOOL FAR PASCAL Dialog_Keyboard_DlgProc(HWND hDlg, UINT Message, UINT wParam, LONG lParam)
{
	switch(Message) {
		case WM_INITDIALOG:
			Dialog_Keyboard_WritePopulate(hDlg);
			nLastOpenPage = DIALOG_PAGE_KEYBOARD;
			return(TRUE);

		case WM_NOTIFY:
			switch(((NMHDR *)lParam)->code) {
				case PSN_APPLY:
					Dialog_Keyboard_ReadPopulate(hDlg);
					return(TRUE);
				case PSN_HELP:
					WinSTon_GoWeb("help\\options\\keyboard.html",FALSE);
					return(TRUE);
			}
			break;

		case WM_HELP:
			// Open help
			WinSTon_GoWeb("help\\options\\keyboard.html",FALSE);
			return(TRUE);

		case WM_COMMAND:
			switch(LOWORD(wParam)) {
				case IDC_BUTTON_KEYMAP_TESTKEY:
					Dialog_Keyboard_CreateKeyTestDialog(hDlg);
					return(TRUE);
				case IDC_BUTTON_KEYMAP_BROWSE:
					Dialog_Keyboard_BrowseMappingFile(hDlg);
					return(TRUE);
			}
			break;
	}

	return(FALSE);	// Not Processed!
}

//-----------------------------------------------------------------------
/*
	Write settings into dialog page
*/
void Dialog_Keyboard_WriteKeyTestPopulate(HWND hDlg)
{
	// Reset list box contents
	SendDlgItemMessage(hDlg,IDC_KEYTEST_LIST,LB_RESETCONTENT,0,(LONG)0);
	nKeyTestItems = 0;
	// As dialog does not receive WM_KEYDOWN messages we create a timer to check keyboard directly!
	KeyTimerID = SetTimer(hDlg,2,50,NULL);
}

//-----------------------------------------------------------------------
/*
	Add pressed key into key test list box, with details of currently assigned key
*/
void Dialog_Keyboard_PressedKey(HWND hDlg, unsigned int Key)
{
	char szString[1024];
	char STKey;

	// Find key
	STKey = Keymap_RemapWindowsKeyToSTScanCode(Key);
	// Create string
	if (STKey==-1)
		sprintf(szString,"PC key scan code: %d($%2.2X), Assigned ST scan code: (none)",Key,Key);
	else
		sprintf(szString,"PC key scan code: %d($%2.2X), Assigned ST scan code: %d($%2.2X)",Key,Key, STKey,STKey);
	// Add string into list box
	SendDlgItemMessage(hDlg,IDC_KEYTEST_LIST,LB_ADDSTRING,0,(LONG)szString);
	nKeyTestItems++;

	// Have filled list box?
	if (nKeyTestItems>=MAX_KEYTEST_ITEMS) {
		// Delete first item in list box
		SendDlgItemMessage(hDlg,IDC_KEYTEST_LIST,LB_DELETESTRING,0,(LONG)0);
		nKeyTestItems--;
	}
}

//-----------------------------------------------------------------------
/*
	Scan every key on keyboard and if any have been pressed, output to listbox view
*/
void Dialog_Keyboard_ScanAllKeys(HWND hDlg)
{
	unsigned int ScanCode;
	int i;

	// Scan every VK key
	for(i=0; i<256; i++) {
		// If key held down and pressed since last check?
		if ((GetAsyncKeyState(i)&0x8001)==0x8001) {
			// Display key assigned, map to 'scan code'
			ScanCode = MapVirtualKey(i,0);
			if (ScanCode)
				Dialog_Keyboard_PressedKey(hDlg,ScanCode);
		}
	}
}

//-----------------------------------------------------------------------
/*
	Key Test dialog
*/
BOOL PASCAL KeyTestDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message) {
		case WM_INITDIALOG:
			Dialog_Keyboard_WriteKeyTestPopulate(hWnd);
			return(FALSE);

		case WM_TIMER:
			// Scan keyboard for any pressed key, display assigned ST key in listbox
			Dialog_Keyboard_ScanAllKeys(hWnd);
			return(TRUE);

		case WM_HELP:
			// Open help
			WinSTon_GoWeb("help\\options\\keymap.html",FALSE);
			return(TRUE);

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					KillTimer(hWnd,KeyTimerID);
					EndDialog(hWnd,0);
					return(TRUE);

				case IDHELP:
					WinSTon_GoWeb("help\\options\\keymap.html",FALSE);
					return(TRUE);
			}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Create dialog for Key Test
*/
void Dialog_Keyboard_CreateKeyTestDialog(HWND hWnd)
{
	PROC lpfnDlgProc;

	// Open dialog
	lpfnDlgProc = MakeProcInstance((PROC)KeyTestDlgProc,hInst);
	DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_KEYTEST),hWnd,(DLGPROC)lpfnDlgProc,NULL);
}
