// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "xkeymacs.h"
#include "Profile.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WM_USER_NTFYICON (WM_USER+100)

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(IDC_ABOUT, OnAbout)
	ON_COMMAND(IDC_QUIT, OnQuit)
	ON_COMMAND(IDC_DISABLE, OnDisable)
	ON_COMMAND(IDC_PROPERTIES, OnProperties)
	ON_COMMAND(IDC_OPTIONS, OnOptions)
	ON_COMMAND(IDC_KEYBOARD, OnKeyboard)
	ON_COMMAND(IDC_IMPORT, OnImport)
	ON_COMMAND(IDC_EXPORT, OnExport)
	ON_COMMAND(IDC_RESET, OnReset)
	ON_COMMAND(ID_HELP_FINDER, OnHelpFinder)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here

	m_pXkeymacsDll			= new CXkeymacsDll;
	m_pPropertiesDlg		= new CProperties;
	m_nResultPropertiesDlg	= -1;
	m_bPropertiesDlgExist	= FALSE;
	m_pAboutDlg				= new CAboutDlg;
	m_nResultAboutDlg		= -1;
	m_bAboutDlgExist		= FALSE;
	m_pOptionsDlg			= new COptionsDlg;
	m_nResultOptionsDlg		= -1;
	m_bOptionsDlgExist		= FALSE;
	m_p104KeyboardDlg		= new C104Keyboard;
	m_nResult104KeyboardDlg	= -1;
	m_b104KeyboardDlgExist	= FALSE;
	m_p109KeyboardDlg		= new C109Keyboard;
	m_nResult109KeyboardDlg	= -1;
	m_b109KeyboardDlgExist	= FALSE;

	// register window class
	WNDCLASS	stWndClass;
	CString szClassName(MAKEINTRESOURCE(AFX_IDS_APP_TITLE));

	stWndClass.style			= CS_BYTEALIGNWINDOW;
	stWndClass.lpfnWndProc		= &AfxWndProc;
	stWndClass.cbClsExtra		= 0;
	stWndClass.cbWndExtra		= 0;
	stWndClass.hInstance		= AfxGetInstanceHandle();
	stWndClass.hIcon			= NULL;
	stWndClass.hCursor			= NULL;
	stWndClass.hbrBackground	= (HBRUSH)COLOR_BACKGROUND;
	stWndClass.lpszMenuName		= NULL;
	stWndClass.lpszClassName	= szClassName;

	AfxRegisterClass(&stWndClass);

	// make window
	CRect	rect(0, 0, 100, 100);

	Create(szClassName, CString(MAKEINTRESOURCE(AFX_IDS_APP_TITLE)), WS_OVERLAPPEDWINDOW | WS_MINIMIZE, rect);
}

CMainFrame::~CMainFrame()
{
	delete m_pXkeymacsDll;
	m_pXkeymacsDll = NULL;

	delete m_pPropertiesDlg;
	m_pPropertiesDlg = NULL;

	delete m_pAboutDlg;
	m_pAboutDlg = NULL;

	delete m_pOptionsDlg;
	m_pOptionsDlg = NULL;

	delete m_p104KeyboardDlg;
	m_p104KeyboardDlg = NULL;

	delete m_p109KeyboardDlg;
	m_p109KeyboardDlg = NULL;
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1) {
		return -1;
	}

	CXkeymacsData::Set106Keyboard(CProfile::Is106Keyboard());

	// init notify icon data
	NOTIFYICONDATA notifyIconData[MAX_ICON_TYPE] = {
		{ sizeof(NOTIFYICONDATA), m_hWnd, MAIN_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED) },
		{ sizeof(NOTIFYICONDATA), m_hWnd, CX_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  AfxGetApp()->LoadIcon(IDI_CX_OFF) },
		{ sizeof(NOTIFYICONDATA), m_hWnd, META_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  AfxGetApp()->LoadIcon(IDI_META_OFF) },
		{ sizeof(NOTIFYICONDATA), m_hWnd, SHIFT_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  AfxGetApp()->LoadIcon(IDI_SHIFT_OFF) },
		{ sizeof(NOTIFYICONDATA), m_hWnd, CTRL_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  AfxGetApp()->LoadIcon(IDI_CTRL_OFF) },
		{ sizeof(NOTIFYICONDATA), m_hWnd, ALT_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,
		  AfxGetApp()->LoadIcon(IDI_ALT_OFF) },
	};
	LoadString(AfxGetInstanceHandle(), AFX_IDS_APP_TITLE, notifyIconData[MAIN_ICON].szTip,
			   sizeof(notifyIconData[MAIN_ICON].szTip));
	LoadString(AfxGetInstanceHandle(), IDS_TIP_CX, notifyIconData[CX_ICON].szTip,
			   sizeof(notifyIconData[CX_ICON].szTip));
	LoadString(AfxGetInstanceHandle(), IDS_TIP_META, notifyIconData[META_ICON].szTip,
			   sizeof(notifyIconData[META_ICON].szTip));
	LoadString(AfxGetInstanceHandle(), IDS_TIP_SHIFT, notifyIconData[SHIFT_ICON].szTip,
			   sizeof(notifyIconData[SHIFT_ICON].szTip));
	LoadString(AfxGetInstanceHandle(), IDS_TIP_CTRL, notifyIconData[CTRL_ICON].szTip,
			   sizeof(notifyIconData[CTRL_ICON].szTip));
	LoadString(AfxGetInstanceHandle(), IDS_TIP_ALT, notifyIconData[ALT_ICON].szTip,
			   sizeof(notifyIconData[ALT_ICON].szTip));

	// set notify icon data
	m_pXkeymacsDll->SetNotifyIconData(MAIN_ICON, notifyIconData[MAIN_ICON],
		(HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),
		(HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED),
		(HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED),		// disable without C-q
		(HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED),
		AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1));

	// set notify ^X icon data
	m_pXkeymacsDll->SetNotifyIconData(CX_ICON, notifyIconData[CX_ICON], AfxGetApp()->LoadIcon(IDI_CX_ON),
									  AfxGetApp()->LoadIcon(IDI_CX_OFF),
									  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0));

	// set notify Meta icon data
	m_pXkeymacsDll->SetNotifyIconData(META_ICON, notifyIconData[META_ICON], AfxGetApp()->LoadIcon(IDI_META_ON),
									  AfxGetApp()->LoadIcon(IDI_META_OFF),
									  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0));

	// set notify Shift icon data
	m_pXkeymacsDll->SetNotifyIconData(SHIFT_ICON, notifyIconData[SHIFT_ICON], AfxGetApp()->LoadIcon(IDI_SHIFT_ON),
									  AfxGetApp()->LoadIcon(IDI_SHIFT_OFF),
									  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0));

	// set notify Ctrl icon data
	m_pXkeymacsDll->SetNotifyIconData(CTRL_ICON, notifyIconData[CTRL_ICON], AfxGetApp()->LoadIcon(IDI_CTRL_ON),
									  AfxGetApp()->LoadIcon(IDI_CTRL_OFF),
									  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0));

	// set notify Alt icon data
	m_pXkeymacsDll->SetNotifyIconData(ALT_ICON, notifyIconData[ALT_ICON], AfxGetApp()->LoadIcon(IDI_ALT_ON),
									  AfxGetApp()->LoadIcon(IDI_ALT_OFF),
									  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0));

	m_pXkeymacsDll->SetKeyboardHook();

	return 0;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers

void CMainFrame::SetForegroundTheDialog(CDialog *pDialog)
{
	if (pDialog) {
		pDialog->SetForegroundWindow();
	}
}

void CMainFrame::SetForegroundSomeDialog()
{
	CDialog *pDialog = NULL;

	if (m_bPropertiesDlgExist) {
		pDialog = m_pPropertiesDlg;
	} else if (m_bOptionsDlgExist) {
		pDialog = m_pOptionsDlg;
	} else if (m_b104KeyboardDlgExist) {
		pDialog = m_p104KeyboardDlg;
	} else if (m_b109KeyboardDlgExist) {
		pDialog = m_p109KeyboardDlg;
	} else if (m_bAboutDlgExist) {
		pDialog = m_pAboutDlg;
	} else {
		EnableWindow(FALSE);
		return;
	}

	SetForegroundTheDialog(pDialog);
	return;
}

void CMainFrame::PopUpDialog(CDialog *pDialog, int *pnResultDialog, BOOL *pbDialogExist)
{
	if (pDialog			== NULL
	 || pnResultDialog	== NULL
	 || pbDialogExist	== NULL) {
		return;
	}

	if (!*pbDialogExist) {
		*pbDialogExist = TRUE;
		*pnResultDialog = pDialog->DoModal();
		*pbDialogExist = FALSE;
		*pnResultDialog = -1;

		SetForegroundSomeDialog();
	} else {
		SetForegroundTheDialog(pDialog);
	}
}

void CMainFrame::PopUpPropertiesDialog()
{
	PopUpDialog(m_pPropertiesDlg, &m_nResultPropertiesDlg, &m_bPropertiesDlgExist);
}

// show right menu on icon in system tray
void CMainFrame::ShowRightMenu(ICON_TYPE icon)
{
	CMenu rightMenu;
	rightMenu.LoadMenu(IDR_RIGHT_MENU);

	CMenu *popUp = rightMenu.GetSubMenu(0);

	if (icon == MAIN_ICON) {
		popUp->SetDefaultItem(IDC_PROPERTIES);

		CString szDisable(MAKEINTRESOURCE(IDS_ENABLE));
		if (m_pXkeymacsDll->IsKeyboardHook()) {
			szDisable.LoadString(IDS_DISABLE);
		}
		popUp->ModifyMenu(IDC_DISABLE, MF_STRING, IDC_DISABLE, szDisable);

		if (CProfile::Is9x()) {
			popUp->DeleteMenu(IDC_KEYBOARD, MF_BYCOMMAND);
		}
	} else {
		popUp->SetDefaultItem(IDC_OPTIONS);

		popUp->DeleteMenu(IDC_PROPERTIES, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_IMPORT, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_EXPORT, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_KEYBOARD, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_DISABLE, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_RESET, MF_BYCOMMAND);
		popUp->DeleteMenu(IDC_QUIT, MF_BYCOMMAND);
		popUp->DeleteMenu(0, MF_BYPOSITION);	// Delete separator
		popUp->DeleteMenu(1, MF_BYPOSITION);	// Delete separator
	}

	SetForegroundWindow();

	CPoint pt;
	GetCursorPos(&pt);
	popUp->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
}

// get message of icon on system tray
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	static UINT s_uTaskbarRestart;

	switch (message) {
	case WM_CREATE:
		s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
		break;
	case WM_USER_NTFYICON:
		switch (lParam) {
		case WM_LBUTTONUP:
			SetForegroundSomeDialog();
			break;
		case WM_LBUTTONDBLCLK:
			if (wParam == MAIN_ICON) {
				PopUpPropertiesDialog();
			} else {
				PopUpOptionsDialog();
			}
			break;
		case WM_RBUTTONUP:
			ShowRightMenu((ICON_TYPE)wParam);
			break;
		default:
			break;
		}
	default:
		if (message == s_uTaskbarRestart) {
			m_pXkeymacsDll->AddAllShell_NotifyIcon();
		}
		break;
	}
	
	return CFrameWnd::WindowProc(message, wParam, lParam);
}

void CMainFrame::OnProperties()
{
	PopUpPropertiesDialog();
}

void CMainFrame::PopUpOptionsDialog()
{
	PopUpDialog(m_pOptionsDlg, &m_nResultOptionsDlg, &m_bOptionsDlgExist);
}

void CMainFrame::OnOptions() 
{
	// TODO: Add your command handler code here
	PopUpOptionsDialog();
}

// stop/start keyboard hook
void CMainFrame::OnDisable() 
{
	// TODO: Add your command handler code here
	if (m_pXkeymacsDll->IsKeyboardHook()) {
		m_pXkeymacsDll->SetKeyboardHookFlag(FALSE);
	} else {
		m_pXkeymacsDll->SetKeyboardHookFlag(TRUE);
	}
}

// Close the Dialog if it is opened.
void CMainFrame::CloseDialog(CDialog *pDialog, int *pnResult)
{
	if (*pnResult != -1) {
		pDialog->EndDialog(*pnResult);
		*pnResult = -1;
	}
}

void CMainFrame::OnQuit() 
{
	// TODO: Add your command handler code here
	CloseDialog(m_pAboutDlg, &m_nResultAboutDlg);
	CloseDialog(m_pPropertiesDlg, &m_nResultPropertiesDlg);
	CloseDialog(m_pOptionsDlg, &m_nResultOptionsDlg);
	CloseDialog(m_p104KeyboardDlg, &m_nResult104KeyboardDlg);
	CloseDialog(m_p109KeyboardDlg, &m_nResult109KeyboardDlg);

	m_pXkeymacsDll->ReleaseKeyboardHook();
	m_pXkeymacsDll->DeleteAllShell_NotifyIcon();

	PostQuitMessage(0);
}

void CMainFrame::PopUpAboutDialog()
{
	PopUpDialog(m_pAboutDlg, &m_nResultAboutDlg, &m_bAboutDlgExist);
}

void CMainFrame::OnAbout() 
{
	// TODO: Add your command handler code here
	PopUpAboutDialog();
}

void CMainFrame::OnKeyboard() 
{
	// TODO: Add your command handler code here
	PopUpKeyboardDialog();
}

void CMainFrame::PopUpKeyboardDialog()
{
	if (CProfile::Is106Keyboard()) {
		PopUpDialog(m_p109KeyboardDlg, &m_nResult109KeyboardDlg, &m_b109KeyboardDlgExist);
	} else {
		PopUpDialog(m_p104KeyboardDlg, &m_nResult104KeyboardDlg, &m_b104KeyboardDlgExist);
	}
}

void CMainFrame::OnImport() 
{
	// TODO: Add your command handler code here
	CProfile::ImportProperties();
	CProfile::InitDllData();
}

void CMainFrame::OnExport() 
{
	// TODO: Add your command handler code here
	CProfile::ExportProperties();
}

void CMainFrame::OnReset() 
{
	// TODO: Add your command handler code here
	m_pXkeymacsDll->ReleaseKeyboardHook();
	m_pXkeymacsDll->SetKeyboardHook();
}

void CMainFrame::OnHelpFinder() 
{
	// TODO: Add your command handler code here
	char szPath[MAX_PATH] = {'\0'};
	const char szExt[_MAX_EXT] = {"txt"};
	_makepath(szPath, NULL, NULL, CString(MAKEINTRESOURCE(IDS_README)), szExt);

	char szModuleFileName[MAX_PATH] = {'\0'};
	if (GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName))) {
		char szDrive[_MAX_DRIVE] = {'\0'};
		char szDir[_MAX_DIR] = {'\0'};
		_splitpath(szModuleFileName, szDrive, szDir, NULL, NULL);
		_makepath(szPath, szDrive, szDir, CString(MAKEINTRESOURCE(IDS_README)), szExt);
	}

	ShellExecute(NULL, NULL, szPath, NULL, NULL, SW_SHOWNORMAL);
}

(C) 2001-2005 oishi@cam.hi-ho.ne.jp