//////////////////////////////////////////
// GraphMakerProc.h
// Copyright (c) 12/14/2022 by ECCSkelton
//////////////////////////////////////////

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

	//PICTUREBOXの初期化
	m_PicBox.Init(m_hWnd, IDC_GRAPH);	//ダイアログコントロールIDC_GRAPHにラップ
	RECT rec;							//m_PicBoxのクライアントエリアサイズを取得
	GetClientRect(m_PicBox.m_hWnd, &rec);
	m_GraphW = rec.right - rec.left;	//m_PicBoxクライアントエリアの幅（523）
	m_GraphH = rec.bottom - rec.top;	//m_PicBoxクライアントエリアの高さ（334）
	ClearGraph();						//背景を黒、軸を反対色（白）で初期化する
	m_PicBox.Color(12);					//描画色を初期的に明るい緑色にする
	m_FrCol = GetCol();					//初期描画色を記録
	//コンボボックスの初期化
	WCHAR expStr1[11] = {0x0079, 0x0020, 0x003D, 0x0020, 0x0061, 0x0078, 0x0020, 0x002B, 0x0020, 0x0062, 0x0000};
	WCHAR expStr2[21] = {0x0079, 0x0020, 0x003D, 0x0020, 0x0061, 0x0078, 0x00B2, 0x0020, 0x002B, 0x0020, 0x0062, 0x0078, 0x0020, 0x002B, 0x0020, 0x0063, 0x0000};
	WCHAR expStr3[23] = {0x0079, 0x0020, 0x003D, 0x0020, 0x0061, 0x0078, 0x00B3, 0x0020, 0x002B, 0x0020, 0x0062, 0x0078, 0x00B2, 0x0020, 0x002B, 0x0020, 0x0063, 0x0078, 0x0020, 0x002B, 0x0020, 0x0064, 0x0000};
	WCHAR expStr4[17] = {0x0079, 0x0020, 0x003D, 0x0020, 0x002B, 0x002D, 0x221A, 0x0028, 0x0061, 0x0078, 0x00B2, 0x0020, 0x002D, 0x0020, 0x0062, 0x0029, 0x0000};
	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)L"");	//未選択用
	//一次方程式（linear equation）
	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)expStr1);
//	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)L"y = ax + b");
	//二次方程式（quadratic equation）
	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)expStr2);
//	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)L"y = ax^2 + bx + c");
	//三次方程式（cubic equation）
	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)expStr3);
//	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)L"y = ax^3 + bx^2 + cx + d");
	//円の方程式（equation of a circle）
	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)expStr4);
//	SendItemMsg(IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)L"y = +-√(ax^2 - b)");
	SendItemMsg(IDC_COMBOBOX, CB_SETCURSEL, 0, (LPARAM)0);
	//a-dの項入力エディットボックスをdisabledにする
	SendItemMsg(IDC_EDITA, EM_SETLIMITTEXT, 5, 0);
	EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), FALSE);
	SendItemMsg(IDC_EDITB, EM_SETLIMITTEXT, 5, 0);
	EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), FALSE);
	SendItemMsg(IDC_EDITC, EM_SETLIMITTEXT, 5, 0);
	EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), FALSE);
	SendItemMsg(IDC_EDITD, EM_SETLIMITTEXT, 5, 0);
	EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), FALSE);
	return TRUE;
}

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

	if(((NMHDR*)lParam)->code == WM_RBUTTONDOWN) {
		//ポップアップメニューを読みこむ
		HMENU hMenu = LoadMenuW(m_hInstance, L"IDM_POPUP");
		HMENU hPopupMenu = GetSubMenu(hMenu, 0);
		//ポップアップメニューの表示
		POINT pt;
		GetCursorPos(&pt);
		TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
					  pt.x, pt.y, 0, m_hWnd, NULL);
		//メニューリソースの開放
		DestroyMenu(hMenu);
	}
	return TRUE;
}

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

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

//ダイアログベースの場合はこれが必要
bool CMyWnd::OnDestroy(WPARAM wPram, LPARAM lParam) {

	PostQuitMessage(0);
	return TRUE;
}

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

	SetCol(m_BkCol);		//前景色から背景色へ変更
	ClearGraph();			//背景を背景色で塗りつぶす
	SetCol(m_FrCol);		//前景色へ再変更
	return TRUE;
}

bool CMyWnd::OnBackCol() {

	m_PicBox.Color(-1);		//カラーダイアログを使って色選択を行う（キャンセルの場合は0 == 黒）
	m_BkCol = GetCol();		//新設定色を記録
	OnClear();				//消去して再描画
	if(m_Selection)			//式（グラフ）が選択されていれば再描画
		OnShowgraph();
	return TRUE;
}

bool CMyWnd::OnFrontCol() {

	m_PicBox.Color(-1);		//カラーダイアログを使って色選択を行う（キャンセルの場合は0 == 黒）
	m_FrCol = GetCol();		//新設定色を記録
	if(m_Selection)			//式（グラフ）が選択されていれば再描画
		OnShowgraph();
	return TRUE;
}

bool CMyWnd::OnCombobox(WPARAM wParam) {

	if(HIWORD(wParam) == CBN_SELCHANGE) {
		m_Selection = SendItemMsg(IDC_COMBOBOX, CB_GETCURSEL, 0, 0);
		switch(m_Selection) {
		case 0:	//未選択状態（全ての項入力ボックスを不能にする）
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), FALSE);
			SendItemMsg(IDC_EDITA, WM_SETTEXT, 0, (LPARAM)L"");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), FALSE);
			SendItemMsg(IDC_EDITB, WM_SETTEXT, 0, (LPARAM)L"");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), FALSE);
			SendItemMsg(IDC_EDITC, WM_SETTEXT, 0, (LPARAM)L"");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), FALSE);
			SendItemMsg(IDC_EDITD, WM_SETTEXT, 0, (LPARAM)L"");
			break;
		case 1:	//一次方程式
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), TRUE);
			SendItemMsg(IDC_EDITA, WM_SETTEXT, 0, (LPARAM)L"1");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), TRUE);
			SendItemMsg(IDC_EDITB, WM_SETTEXT, 0, (LPARAM)L"0");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), FALSE);
			SendItemMsg(IDC_EDITC, WM_SETTEXT, 0, (LPARAM)L"");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), FALSE);
			SendItemMsg(IDC_EDITD, WM_SETTEXT, 0, (LPARAM)L"");
			break;
		case 2:	//二次方程式
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), TRUE);
			SendItemMsg(IDC_EDITA, WM_SETTEXT, 0, (LPARAM)L"0.01");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), TRUE);
			SendItemMsg(IDC_EDITB, WM_SETTEXT, 0, (LPARAM)L"0");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), TRUE);
			SendItemMsg(IDC_EDITC, WM_SETTEXT, 0, (LPARAM)L"-144");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), FALSE);
			SendItemMsg(IDC_EDITD, WM_SETTEXT, 0, (LPARAM)L"");
			break;
		case 3:
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), TRUE);
			SendItemMsg(IDC_EDITA, WM_SETTEXT, 0, (LPARAM)L"0.001");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), TRUE);
			SendItemMsg(IDC_EDITB, WM_SETTEXT, 0, (LPARAM)L"0");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), TRUE);
			SendItemMsg(IDC_EDITC, WM_SETTEXT, 0, (LPARAM)L"0");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), TRUE);
			SendItemMsg(IDC_EDITD, WM_SETTEXT, 0, (LPARAM)L"0");
			break;
		case 4:
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITA), TRUE);
			SendItemMsg(IDC_EDITA, WM_SETTEXT, 0, (LPARAM)L"1");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITB), TRUE);
			SendItemMsg(IDC_EDITB, WM_SETTEXT, 0, (LPARAM)L"6400");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITC), FALSE);
			SendItemMsg(IDC_EDITC, WM_SETTEXT, 0, (LPARAM)L"0");
			EnableWindow(GetDlgItem(m_hWnd, IDC_EDITD), FALSE);
			SendItemMsg(IDC_EDITD, WM_SETTEXT, 0, (LPARAM)L"0");
			break;
		}
		return TRUE;
	}
	return FALSE;
}

bool CMyWnd::OnShowgraph() {

	//変数宣言
	WCHAR str[6];
	double a, b, c, d;				//項の値（倍精度）
	static int sx, sy, ex, ey;		//始点と終点
	//aとbの項目データを読み取る
	SendItemMsg(IDC_EDITA, WM_GETTEXT, 6, (LPARAM)str);
	if(!*str) {
		MessageBoxW(m_hWnd, L"項aが未入力です", L"エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	a = stod(str);
	if(a == 0) {
		MessageBoxW(m_hWnd, L"項aがゼロです", L"エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	SendItemMsg(IDC_EDITB, WM_GETTEXT, 6, (LPARAM)str);
	if(!*str) {
		MessageBoxW(m_hWnd, L"項bが未入力です", L"エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	b = stod(str);
	//m_PicBoxクライアントエリアを左から右へ描画
	for(int i = 0, sx = ex = 0; i < m_GraphW; i++) {
		double x = (double)(ex - m_GraphW / 2);
		double y;
		ex = i;
		switch(m_Selection) {
		case 0:
			MessageBoxW(m_hWnd, L"式が選択されていません", L"エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		case 1:
			//一次方程式グラフ描画
			y = a * x + b;						//方程式計算
			ey = (int)-y + m_GraphH / 2;		//上下反転
			if(!sx)
				sy = ey;
			m_PicBox.Line(sx, sy, ex, ey);		//始点−終点線の描画
			break;
		case 2:
			//二次方程式グラフ描画
			SendItemMsg(IDC_EDITC, WM_GETTEXT, 6, (LPARAM)str);
			if(!*str) {
				MessageBoxW(m_hWnd, L"項cが未入力です", L"エラー", MB_OK | MB_ICONERROR);
				return FALSE;
			}
			c = stod(str);
			y = a * pow(x, 2.0) + b * x + c;	//方程式計算
			ey = (int)-y + m_GraphH / 2;		//上下反転
			if(!i)
				sy = ey;
			m_PicBox.Line(sx, sy, ex, ey);		//始点−終点線の描画
			break;
		case 3:
			//三次方程式グラフ描画
			SendItemMsg(IDC_EDITC, WM_GETTEXT, 6, (LPARAM)str);
			if(!*str) {
				MessageBoxW(m_hWnd, L"項cが未入力です", L"エラー", MB_OK | MB_ICONERROR);
				return FALSE;
			}
			c = stod(str);
			SendItemMsg(IDC_EDITD, WM_GETTEXT, 6, (LPARAM)str);
			if(!*str) {
				MessageBoxW(m_hWnd, L"項dが未入力です", L"エラー", MB_OK | MB_ICONERROR);
				return FALSE;
			}
			d = stod(str);
			y = a * pow(x, 3.0) + b * pow(x, 2.0) + c * x + d;	//方程式計算
			ey = (int)-y + m_GraphH / 2;		//上下反転
			if(!ex)
				sy = ey;
			m_PicBox.Line(sx, sy, ex, ey);		//始点−終点線の描画
			break;
		case 4:
			//円の方程式グラフ描画（＋と−の解を一緒に描画）
			double rad = sqrt(b);
			if(x >= -rad && x <= rad) {
				y = sqrt(abs(a * pow(x, 2.0) - b));	//方程式計算
				ey = -(int)y + m_GraphH / 2;		//上下反転（y）
				if(x == -rad)
					sy = ey;
				m_PicBox.Line(sx, sy, ex, ey);		//上限の描画
				m_PicBox.Line(sx, sy - sy * 2 + m_GraphH,
					ex, ey - ey * 2 + m_GraphH);	//下弦の描画
			}
			break;
		}
		sx = ex;	//一つ進む
		sy = ey;	//一つ進む
	}
	return TRUE;
}

bool CMyWnd::OnIdok() {

	SendMsg(WM_CLOSE, 0, 0);
	return TRUE;
}

//ユーザー定義関数
COLORREF CMyWnd::GetCol() {

	return m_PicBox.m_Color;
}

void CMyWnd::SetCol(COLORREF col) {

	m_PicBox.m_Color = col;
}

void CMyWnd::ClearGraph() {

	m_PicBox.BrSelection(1);
	m_PicBox.Clear();
	COLORREF ContraCol = m_BkCol ^ 0x00FFFFFF;
	SetCol(ContraCol);
	m_PicBox.Line(m_GraphW / 2, 0, m_GraphW / 2, m_GraphH);
	m_PicBox.Line(0, m_GraphH / 2, m_GraphW, m_GraphH / 2);
	SetCol(m_FrCol);
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
