#define	STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<tchar.h>
#include	"kctrl.h"
#include	"controls.h"
#include	"resource.h"
#include	"appmain.h"
#include	"appsub.h"

BOOL	AboutDialogExec( HINSTANCE hInst, HWND hWnd, LPBOOL fDelete ) ;
extern	BOOL	g_bNarrow ;

/*-------------------------------------------------------------------------*
 * ListArea
 *-------------------------------------------------------------------------*/
/*
 * ウィンドウを作成する
 */
HWND
ListArea::Create( HINSTANCE hInst, HWND hWndParent, DWORD x, DWORD y, DWORD w, DWORD h, WORD id )
{
	m_hWnd = CreateWindowEx( 0,
					CTRL_BIGLIST,
					TEXT(""),
					WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
					x, y, w, h,
					hWndParent,
					(HMENU) id,
					hInst,
					0 ) ;
	return m_hWnd ;
}

/*
 * リストプロシージャを設定する
 */
void
ListArea::SetProc( int (*proc)( int ln, const BYTE **buf, int *len ) )
{
	SendMessage( m_hWnd, BLM_SETPROC, 0, (LPARAM) proc ) ;
}

/*
 * カーソル行を取得する
 */
DWORD
ListArea::GetCurSel() const
{
	return SendMessage( m_hWnd, BLM_GETCURSEL, 0, 0 ) ;
}

/*
 * カーソル行を設定する
 */
void
ListArea::SetCurSel( DWORD index )
{
	SendMessage( m_hWnd, BLM_SETCURSEL, (WPARAM) index, 0 ) ;
}

/*
 * キー入力
 */
void
ListArea::SendKey( DWORD nVirtKey ) const
{
	SendMessage( m_hWnd, WM_KEYDOWN, nVirtKey, 0 ) ;
}

/*
 * 内容のクリア
 */
void
ListArea::Clear()
{
	SendMessage( m_hWnd, BLM_SETPROC, 0, (LPARAM) NULL ) ;
	InvalidateRect( m_hWnd, NULL, TRUE ) ;
}

/*
 * キー入力マスクの設定
 */
void
ListArea::SetKeyMask( BOOL fTitle )
{
	DWORD	mask = fTitle ? 0 : BL_MASK_LEFT|BL_MASK_RIGHT ;
	SendMessage( m_hWnd, BLM_SETKEYMASK, 0, (LPARAM) ~mask ) ;
}

/*-------------------------------------------------------------------------*
 * HeaderArea
 *-------------------------------------------------------------------------*/
/*
 * ウィンドウを作成する
 */
DWORD
HeaderArea::Create( HINSTANCE hInst, HWND hWndParent, DWORD x, DWORD y, DWORD w, WORD id )
{
	DWORD	ch = GetFontH() + 4 ;

	/* 種別領域を作成する */
	m_hWnd = CreateWindowEx( 0,
					CTRL_LABEL,
					TEXT(""),
					WS_CHILD|WS_VISIBLE|WS_BORDER,
					x, y, w, ch,
					hWndParent,
					(HMENU) id,
					hInst,
					0 ) ;
	y += ch + 2 ;
	return y ;
}

/*
 * 表示文字列を作成する
 */
void
HeaderArea::SetText( LPCTSTR text )
{
	SetWindowText( m_hWnd, text ) ;
}

/*-------------------------------------------------------------------------*
 * DateArea
 *-------------------------------------------------------------------------*/
/*
 * DateAreaのコンストラクタ
 */
DateArea::DateArea()
{
	sjis2unicode( (LPBYTE) "日月火水木金土月日時分", m_sFix, sizeof m_sFix ) ;
}

/*
 * ウィンドウを作成する
 */
DWORD
DateArea::Create( HINSTANCE hInst, HWND hWndParent, DWORD x, DWORD y, DWORD w, WORD id )
{
	DWORD	ch = GetFontH() + 2 ;

	/* 種別領域を作成する */
	m_hWnd = CreateWindowEx( 0,
					CTRL_LABEL,
					TEXT(""),
					WS_CHILD|WS_VISIBLE,
					x, y, w, ch,
					hWndParent,
					(HMENU) id,
					hInst,
					0 ) ;
	Refresh() ;
	y += ch + 2 ;
	return y ;
}

/*
 * 画面表示を更新する
 */
void
DateArea::Refresh()
{
	SYSTEMTIME	st ;
	TCHAR		buf[ 100 ] ;

	GetLocalTime( &st ) ;
	wsprintf( buf, TEXT("%2d%c%2d%c(%c) %2d%c%2d%c"),
			  st.wMonth, m_sFix[ 7 ], st.wDay, m_sFix[ 8 ],
			  m_sFix[ st.wDayOfWeek ],
			  st.wHour, m_sFix[ 9 ], st.wMinute, m_sFix[ 10 ] ) ;
	SetWindowText( m_hWnd, buf ) ;
}

/*-------------------------------------------------------------------------*
 * MainWindow
 *-------------------------------------------------------------------------*/
MainWindow::MainWindow( DiaApp *pApp )
{
	m_pApp = pApp ;
	m_hIcon = 0 ;
	m_fDeleteReg = FALSE ;
}

MainWindow::~MainWindow()
{
	if ( m_hIcon ) {
		::DeleteObject( m_hIcon ) ;
	}
}

void
MainWindow::WMCreate( HWND hWnd )
{
	RECT		rect ;
	DWORD		height = 2, tw, rw, h, th, dw ;
	HINSTANCE	hInst = m_pApp->get_inst() ;

	m_hWnd = hWnd ;
	LONG	lStyle = GetWindowLong( hWnd, GWL_STYLE ) ;
#ifdef	_WIN32_WCE
	lStyle &= ~WS_CAPTION ;
#endif	/* _WIN32_WCE */
	SetWindowLong( hWnd, GWL_STYLE, lStyle ) ;
	/* コマンドバーを追加する */
	height += CreateCommandBar() ;
	/* アイコンを作成しタスクバーに登録する */
	m_hIcon = (HICON) LoadImage( m_pApp->get_inst(), MAKEINTRESOURCE(IDI_APPICON),
								 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ) ;
	if ( m_hIcon ) {
		SendMessage( hWnd, WM_SETICON, FALSE, (LPARAM)m_hIcon ) ;
	}
	/* 表示領域を求める */
	GetClientRect( m_hWnd, &rect ) ;
	tw = rect.right ;
	th = rect.bottom ;
	if ( tw < 480 ) {
		/* 画面幅が小さい場合 */
		g_bNarrow = TRUE ;
		h = height ;
		/* 日付領域を作成する */
		h = m_pApp->get_date()->Create( hInst, m_hWnd, 2, h, tw - 8,
										IDC_DATE ) ;
		h += 2 ;
		/* ヘッダー領域を作成する */
		h = m_pApp->get_header()->Create( hInst, m_hWnd, 2, h, tw - 8,
										  IDC_HEADER ) ;
		h += 2 ;
		/* 一覧表示領域を作成する */
		m_pApp->get_list()->Create( hInst, m_hWnd, 2, h, tw - 8, th - h - 4,
									IDC_LIST ) ;
	} else {
		/* 日付領域の幅を求める */
		dw = GetFontHW() * 20 + 8 ;
		rw = tw - dw - 8 ;
		/* ヘッダー領域を作成する */
		h = m_pApp->get_header()->Create( hInst, m_hWnd, 2, height, rw,
										  IDC_HEADER ) ;
		/* 日付領域を作成する */
		m_pApp->get_date()->Create( hInst, m_hWnd, 2 + rw + 2, height + 2, dw,
									IDC_DATE ) ;
		h += 2 ;
		/* 一覧表示領域を作成する */
		m_pApp->get_list()->Create( hInst, m_hWnd, 2, h, tw - 8, th - h - 4,
									IDC_LIST ) ;
	}
	/* タイマーの処理を開始する */
	m_pApp->SetTimer( m_hWnd, FALSE, TRUE ) ;
}

void
MainWindow::WMDestroy()
{
	/* タイマーの処理を停止する */
	m_pApp->SetTimer( m_hWnd, TRUE, FALSE ) ;
	PostQuitMessage( 0 ) ;
}

LRESULT
MainWindow::WMCommand( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	WORD	idCtrl = LOWORD(wParam) ;
	WORD	notifyCode = HIWORD(wParam) ;
	BOOL	fQuit = FALSE, fDelete = FALSE ;

	switch ( idCtrl ) {
	case IDM_ABOUT:
		if ( AboutDialogExec( m_pApp->get_inst(), hWnd, &fDelete ) ) {
			if ( fDelete ) {
				m_fDeleteReg = TRUE ;
				SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
			}
		}
		break ;
	case IDM_EXIT:
		SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		break ;
	case IDM_REREAD:
	case IDM_OPEN:
		if ( m_pApp->OpenTableFile( m_hWnd, idCtrl == IDM_REREAD, &fQuit ) ) {
			m_pApp->EnterTitle() ;
		} else if ( fQuit ) {
			SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		}
		break ;
	case IDC_LIST:
		if ( notifyCode == BLN_ENTER ) {
			if ( m_pApp->is_title() ) {
				m_pApp->EnterContent() ;
			} else {
				m_pApp->SetAlarm() ;
			}
		} else if ( notifyCode == BLN_ESC ) {
			if ( m_pApp->is_title() ) {
				m_pApp->EnterContent() ;
			} else {
				m_pApp->EnterTitle() ;
			}
		} else if ( (notifyCode & 0x0F00) == BLN_KEYDOWN ) {
			DWORD	nVirtKey = notifyCode & 0x00FF ;

			if ( nVirtKey == VK_LEFT ) {
				SendMessage( hWnd, WM_COMMAND, IDC_LEFT, 0 ) ;
			} else if ( nVirtKey == VK_RIGHT ) {
				SendMessage( hWnd, WM_COMMAND, IDC_RIGHT, 0 ) ;
			}
		}
		break ;
	case IDC_HEADER:
		if ( notifyCode == LAN_CLICK && !m_pApp->is_title() ) {
			m_pApp->EnterTitle() ;
		}
		break ;
	case IDC_HOME:
		if ( !m_pApp->is_title() ) {
			if ( m_pApp->Home() ) {
				m_pApp->SetupList() ;
			}
		}
		break ;
	case IDC_LEFT:
		if ( !m_pApp->is_title() ) {
			if ( m_pApp->Prev() ) {
				m_pApp->SetupList() ;
			}
		}
		break ;
	case IDC_RIGHT:
		if ( !m_pApp->is_title() ) {
			if ( m_pApp->Next() ) {
				m_pApp->SetupList() ;
			}
		}
		break ;
	case IDM_SETUP:
		/* セットアップを行う */
		m_pApp->Setup( hWnd ) ;
		break ;
	case IDM_EDIT_CONFIG:
		/* .CFGファイルを編集する */
		m_pApp->ExecuteEditor( FALSE ) ;
		break ;
	case IDM_EDIT_TABLE:
		/* .TBLファイルを編集する */
		m_pApp->ExecuteEditor( TRUE ) ;
		break ;
	}
	return 0 ;
}

void
MainWindow::WMTimer( int idCtrl )
{
	m_pApp->Refresh() ;
}

void
MainWindow::WMSetFocus()
{
	m_pApp->get_list()->SetFocus() ;
}

BOOL
MainWindow::WMClose()
{
	if ( m_fDeleteReg ) {
		m_pApp->DeleteReg() ;
	} else {
		m_pApp->SetReg() ;
	}
	return FALSE ;
}

BOOL
MainWindow::Create()
{
	HWND	hWnd = CreateWindowEx( 0,
						GetClassName(),
						szTitleName,
						WS_VISIBLE,
#ifdef	_WIN32_WCE
						0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
#else	/* _WIN32_WCE */
						0, 0, 240, 320, //480, 240,
#endif	/* _WIN32_WCE */
						NULL,
						NULL,
						m_pApp->get_inst(),
						this ) ;
	if ( hWnd == 0 ) {
		return FALSE ;
	}
    ShowWindow( hWnd, SW_SHOW ) ;
    UpdateWindow( hWnd ) ;
    return TRUE ;
}

DWORD
MainWindow::CreateCommandBar()
{
	HINSTANCE	hInst = m_pApp->get_inst() ;

#ifdef	_WIN32_WCE
	static TBBUTTON	tbButton[] = {
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{0,       IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{1,       IDC_LEFT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{3,       IDC_HOME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{0,              0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{2,      IDC_RIGHT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
	} ;

	m_hWndCB = CommandBar_Create( hInst, m_hWnd, 0 ) ;
	CommandBar_InsertMenubar( m_hWndCB, hInst, IDR_MAIN_MENU, 0 ) ;
    CommandBar_AddBitmap( m_hWndCB, hInst, IDR_TOOLBAR1, 8, 16, 16 ) ;
    CommandBar_AddButtons( m_hWndCB, sizeof(tbButton) / sizeof(*tbButton), tbButton ) ;
	CommandBar_AddAdornments( m_hWndCB, 0, 0 ) ;
	return CommandBar_Height( m_hWndCB ) ;
#else	/* _WIN32_WCE */
	return 0 ;
#endif	/* _WIN32_WCE */
}

BOOL
MainWindow::RegisterClass( HINSTANCE hInst )
{
	WNDCLASS	wc ;

	wc.style         = NULL ;
	wc.lpfnWndProc   = (WNDPROC) WndProc ;
	wc.cbClsExtra    = 0 ;
	wc.cbWndExtra    = 4 ;
	wc.hInstance     = hInst ;
	wc.hIcon         = NULL ;
	wc.hCursor       = NULL ;
	wc.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
#ifdef	_WIN32_WCE
	wc.lpszMenuName  = 0 ;
#else	/* _WIN32_WCE */
	wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU) ;
#endif	/* _WIN32_WCE */
	wc.lpszClassName = 	GetClassName() ;
	return ::RegisterClass( &wc ) ;
}
