//////////////////////////////////////////
// CalenderProc.h
// Copyright (c) 04/24/2020 by BCCSkelton
//////////////////////////////////////////
#define		BSIZE 256

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//ウィンドウメッセージ関数
/////////////////////////////////
bool CMyWnd::OnCreate(WPARAM wParam, LPARAM lParam) {

	//コモンコントロールの初期化
	INITCOMMONCONTROLSEX ic;
	ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
	ic.dwICC = ICC_BAR_CLASSES | ICC_DATE_CLASSES;	//StatusBarとMonthCalenderコントロール
	InitCommonControlsEx(&ic);						//必要なものだけをロード

	//MCコントロールの作成
	hMC = CreateWindowEx(0, MONTHCAL_CLASS, "",
		WS_VISIBLE | WS_CHILD | WS_BORDER | MCS_DAYSTATE,
		0, 0, 0, 0, m_hWnd, NULL, m_hInstance, NULL);

	//ステータスバー登録−Init(hWnd, hIinstance, ID, (以下省略可）Style)
	SBar.Init(m_hWnd, m_hInstance, STATUSBAR);
	//ステータスバー文字列設定
	MonthCal_GetCurSel(hMC, &st);	//MCCからシステムタイムを取得
	SBarInfo(FALSE);				//システムタイムの日付表示（ユーザー関数）

	//MCCの最小サイズを求め、MCCと主ウィンドウのサイズを設定
	SetMCC(hMC);

	//メニューハンドルの取得
	hMenu = GetMenu(m_hWnd);

	return TRUE;
}

bool CMyWnd::OnNotify(WPARAM wParam, LPARAM lParam) {

	LPNMSELCHANGE lpSChange = (LPNMSELCHANGE)lParam;
	if (lpSChange->nmhdr.hwndFrom != hMC || lpSChange->nmhdr.code != MCN_SELCHANGE)
		//MCコントロールではないか、選択変更がなければウインドウズにコントロールを戻す。
		return FALSE;
	else {								//MCCから変更通知が入った場合
		MonthCal_GetCurSel(hMC, &st);	//システムタイムを取得し、
		SBarInfo(TRUE);					//指定日時をステータスバーに表示
		InvalidateRect(m_hWnd, NULL, TRUE);
		return TRUE;
	}
}

bool CMyWnd::OnSize(WPARAM wParam, LPARAM lParam) {

	//ステータスバーの自動調整
	SBar.AutoSize();
	//MCCのサイズ調整
	int wd, ht, margin = 10;		//ウィンドウクライアントエリアの余白
	RECT rc;						//ウィンドウサイズ取得のための変数
	//ウィンドウに合わせてMCCサイズを調整
	GetClientRect(m_hWnd, &rc);		//ウィンドウクライアント領域のサイズ
	wd = rc.right - rc.left - margin * 2;
	ht = rc.bottom - rc.top - margin * 2;
	GetWindowRect(SBar.m_hWnd, &rc);	//ステータスバーのサイズ
	ht -= rc.bottom - rc.top;			//ステータスバーの高さを除算
	MoveWindow(hMC, margin, margin, wd, ht, TRUE);	//x, y, 幅, 高さ, 再描画

	return TRUE;
}

bool CMyWnd::OnClose(WPARAM wParam, LPARAM lParam) {

	if(MessageBox(m_hWnd, "終了しますか？", "終了確認",
					MB_YESNO | MB_ICONQUESTION) == IDYES)
		//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		return TRUE;
	else
		//そうでなければウィンドウではDefWindowProc関数をreturn、ダイアログではreturn FALSEとなる。
		return FALSE;
}

bool CMyWnd::OnDestroy(WPARAM, LPARAM) {

	return TRUE;
}

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//メニュー項目、コントロール関数
/////////////////////////////////
bool CMyWnd::OnExplanation() {

	MessageBox(m_hWnd,
				"西暦はローマ歴から始まり、シーザーがエジプト歴による修正を命じた後、何度かの修正を経て、現在のグレゴリオ歴に至りました。\n1752年9月に修正を行った英国では過去の誤差修正（閏年調整）の為に9月2日の後が14日となりました。\n残念ながら、MCコントロールは1753年から9998年までしか表示できません。",
				"西暦解説", MB_OK | MB_ICONINFORMATION);
	return TRUE;
}

bool CMyWnd::OnVersion() {

	MessageBox(m_hWnd, "Calender Ver. 1.0", "バージョン情報",
				MB_OK | MB_ICONINFORMATION);
	return TRUE;
}

bool CMyWnd::OnExit() {

	SendMessage(m_hWnd, WM_CLOSE, 0, 0);
	return TRUE;
}

bool CMyWnd::OnSpecym() {

	specdlg.DoModal(m_hWnd, "IDD_SPEC", specdlgProc);
	SBarInfo(FALSE);
	return TRUE;
}

bool CMyWnd::OnWeekno() {

	LONG lStyle;			//MCコントロールのスタイル変更用変数
	lStyle = GetWindowLong(hMC, GWL_STYLE);
	lStyle |= MCS_WEEKNUMBERS;
	SetWindowLong(hMC, GWL_STYLE, lStyle);
	ModifyMenu(hMenu, IDM_WEEKNO, IDM_NOWEEKNO, "週数を表示しない(&W)");
	SetMCC(hMC);
	InvalidateRect(m_hWnd, NULL, TRUE);

	return TRUE;
}

bool CMyWnd::OnNotoday() {

	LONG lStyle;			//MCコントロールのスタイル変更用変数
	lStyle = GetWindowLong(hMC, GWL_STYLE);
	lStyle |= MCS_NOTODAY;
	SetWindowLong(hMC, GWL_STYLE, lStyle);
	ModifyMenu(hMenu, IDM_NOTODAY, IDM_TODAY, "今日を表示する(&T)");
	SetMCC(hMC);
	InvalidateRect(m_hWnd, NULL, TRUE);
	return TRUE;
}

bool CMyWnd::OnNoWeekno() {

	LONG lStyle;			//MCコントロールのスタイル変更用変数
	lStyle = GetWindowLong(hMC, GWL_STYLE);
	lStyle &= ~MCS_WEEKNUMBERS;
	SetWindowLong(hMC, GWL_STYLE, lStyle);
	ModifyMenu(hMenu, IDM_NOWEEKNO, IDM_WEEKNO, "週数を表示する(&W)");
	SetMCC(hMC);
	InvalidateRect(m_hWnd, NULL, TRUE);
	return TRUE;
}

bool CMyWnd::OnToday() {

	LONG lStyle;			//MCコントロールのスタイル変更用変数
	lStyle = GetWindowLong(hMC, GWL_STYLE);
	lStyle &= ~MCS_NOTODAY;
	SetWindowLong(hMC, GWL_STYLE, lStyle);
	ModifyMenu(hMenu, IDM_TODAY, IDM_NOTODAY, "今日を表示しない(&T)");
	SetMCC(hMC);
	InvalidateRect(m_hWnd, NULL, TRUE);
	return TRUE;
}

///////////////////////////////
//ユーザー定義関数
///////////////////////////////
bool CMyWnd::SetMCC(HWND hMC) {

	int wd, ht, margin = 10;				//ウィンドウクライアントエリアの余白
	RECT rw, rc;							//サイズ取得のための変数
	//MCコントロールの表示サイズ取得と表示
	SendMessage(hMC, MCM_GETMINREQRECT, NULL, (LPARAM)&rw);	//最小限のサイズ取得
	wd = rw.right - rw.left;				//MCコントロールの最小幅
	ht = rw.bottom - rw.top;				//MCコントロールの最小高さ
	MoveWindow(hMC, margin, margin, wd, ht, TRUE);	//x, y, 幅, 高さ, 再描画
	//MCコントロールに合わせてウィンドウサイズを調整
	GetWindowRect(m_hWnd, &rw);				//ウィンドウのサイズ
	GetClientRect(m_hWnd, &rc);				//ウィンドウクライアント領域のサイズ
	wd += rw.right - rw.left - rc.right + rc.left + margin * 2;
	ht += rw.bottom - rw.top - rc.bottom + rc.top + margin * 2;
	GetWindowRect(SBar.m_hWnd, &rw);		//ステータスバーのサイズ
	ht += rw.bottom - rw.top;				//ステータスバーの高さを追加
	SetWindowPos(m_hWnd, HWND_TOP, 0, 0, wd, ht, SWP_NOMOVE | SWP_NOZORDER);
	return TRUE;
}

bool CMyWnd::SBarInfo(bool notified) {

	char buff[BSIZE];	//最大256文字
	if(notified)
		wsprintf(buff, "%d年%d月%d日を選択しました", st.wYear, st.wMonth, st.wDay);
	else
		wsprintf(buff, "%d年%d月を表示", st.wYear, st.wMonth);
	SBar.SetText(0, buff);
	return TRUE;
}

bool CMyWnd::ModifyMenu(HMENU hMenu, int oldid, int newid, char* item) {

	MENUITEMINFO mi;
	ZeroMemory(&mi, sizeof(MENUITEMINFO));
	mi.cbSize = sizeof(MENUITEMINFO);
	mi.fMask = MIIM_TYPE | MIIM_ID;
	mi.fType = MFT_STRING;
	mi.fState = MFS_ENABLED;
	mi.wID = newid;
	mi.dwTypeData = (LPTSTR)item;
	mi.cch = strlen(item);
	if (!SetMenuItemInfo(hMenu, oldid, FALSE, &mi))
		MessageBox(m_hWnd, "メニューの変更に失敗しました", "エラー", MB_OK | MB_ICONERROR);
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool SPECDLG::OnButton() {

	char buff[BSIZE];
	int i;
	MonthCal_GetCurSel(hMC, &st);	//現在MCCで指定された年月日を取得
	if(!GetDlgItemText(m_hWnd, IDC_EDIT1, buff, BSIZE - 1)) {
		MessageBox(m_hWnd, "年を読み取れませんでした", "エラー", MB_OK | MB_ICONERROR);
		specdlg.EndModal(TRUE);
		return FALSE;
	}
	else {
		i = atoi(buff);
		if(i < 1753 || i > 9998) {	//仕様外データエラー
			MessageBox(m_hWnd, "この年は表示できません", "エラー", MB_OK | MB_ICONERROR);
			specdlg.EndModal(TRUE);
			return FALSE;
		}
		else
			st.wYear = i;
	}
	if(!GetDlgItemText(m_hWnd, IDC_EDIT2, buff, BSIZE - 1)) {
		MessageBox(m_hWnd, "月を読み取れませんでした", "エラー", MB_OK | MB_ICONERROR);
		specdlg.EndModal(TRUE);
		return FALSE;
	}
	else {
		i = atoi(buff);
		if(i < 1 || i > 12) {		//仕様外データエラー
			MessageBox(m_hWnd, "この月は表示できません", "エラー", MB_OK | MB_ICONERROR);
			specdlg.EndModal(TRUE);
			return FALSE;
		}
		else
			st.wMonth = i;
	}
	MonthCal_SetCurSel(hMC, &st);	//指定年月での表示
	specdlg.EndModal(TRUE);
	return TRUE;
}
