///////////////////////////
// OpenGL Sampler Program
///////////////////////////
//インクルードファイル
#define		STRICT
#include	<windows.h>
#include	"ResGLSampler.h"
#include	"OpenGL.h"				//OpenGL用初期化、表示、終了関数等
#include	"DrawFunctions.h"	//OpenGLによる描画関数を記述したファイル
#include	"GLSamplerProc.h"		//ウィンドウ割り込み処理関数

#pragma comment(lib, "freeglut")	//若しくはコンパイラーの-Lオプションを使う

//外部変数
char szClassName[] = "GL_Sampler";
char szTitleName[] = "GL Sampler";

///////////////////////////////////////
//バージョンダイアログコールバック関数
///////////////////////////////////////
BOOL CALLBACK VerDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	bool Done = FALSE;
	switch(msg){
	case WM_COMMAND:
		if(LOWORD(wParam) == IDOK) {
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			Done == TRUE;
		}
		break;
	case WM_SYSCOMMAND:
		if(wParam == SC_CLOSE) {
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			Done == TRUE;
		}
		break;
	case WM_CLOSE:
		EndDialog(hWnd, 0);
		Done == TRUE;
		break;
	}
	return Done;
}

/////////////////////////////
//ウィンドウコールバック関数
/////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	bool Done = FALSE;
	switch(msg){
		case WM_COMMAND:				//メニュー処理
			switch(LOWORD(wParam)) {
			case IDM_2D01:
			case IDM_2D02:
			case IDM_2D03:
			case IDM_2D04:
			case IDM_2D05:
			case IDM_3D01:
			case IDM_3D02:
			case IDM_3D03:
			case IDM_3D04:
			case IDM_3D05:
				Done = DrawMenu(LOWORD(wParam));
				break;
			case IDM_VERSION:			//ダイアログ処理
				DialogBox((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), "IDD_VERSION", hWnd, VerDlgProc);
				Done = TRUE;
				break;
			case IDM_EXIT:				//終了処理
				SendMessage(hWnd, WM_CLOSE, NULL, NULL);
				Done = TRUE;
				break;
			}
			break;
		case WM_CREATE:					//ウィンドウ生成時処理
			Done = OnCreate(hWnd);
			break;
		case WM_LBUTTONDOWN:			//マウス左ボタン押下時処理
			Done = OnLButtonDown(hWnd);
			break;
		case WM_SIZE:					//ウィンドウサイズ変更時処理
			Done = OnSize(lParam);
			break;
		case WM_CLOSE:					//ウィンドウ終了時処理
			Done = OnClose(hWnd);
			if(Done) {
				DestroyWindow(hWnd);
				return TRUE;
			}
			else
				return FALSE;
			break;
		case WM_DESTROY:				//ウィンドウ消滅時処理
			Done = OnDestroy();
			PostQuitMessage(0);
			break;
		default:
			break;
	}
	if(Done)
		return 0L;
	else
		return(DefWindowProc(hWnd, msg, wParam, lParam));
}

///////////////////////////
//ウィンドウ・クラスの登録
///////////////////////////
BOOL InitApp(HINSTANCE hInstance) {

	WNDCLASSEX wc;
	wc.cbSize			= sizeof(WNDCLASSEX);				//この構造体のサイズ
	wc.style			= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc		= WndProc;		//プロシージャ名
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;	//インスタンス
	wc.hIcon			= (HICON)LoadImage(hInstance, "IDI_ICON", IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);	//LoadIcon関数は旧いので。
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName		= "IDM_MENU";	//メニュー名
	wc.lpszClassName	= (LPCSTR)szClassName;
	wc.hIconSm			= (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);	//"IDI_ICON"で指定すると読み込めない
	return (RegisterClassEx(&wc));
}

///////////////////
//ウィンドウの生成
///////////////////
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {

	HWND hWnd = CreateWindowEx(
			NULL,					//dwExStyle
			szClassName,			//ウィンドウクラス名
			szTitleName,			//タイトルバーにこの名前が表示されます
			WS_OVERLAPPEDWINDOW,	//ウィンドウスタイル
			CW_USEDEFAULT,			//Ｘ座標
			CW_USEDEFAULT,			//Ｙ座標
			640,					//幅
			640,					//高さ
			NULL,					//親ウィンドウのハンドル、親を作るときはNULL
			NULL,					//メニューハンドル、クラスメニューを使うときはNULL
			hInstance,				//インスタンスハンドル
			NULL);
	if(!hWnd)
		return FALSE;
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	return TRUE;
}

///////////////////
//ウィンドウループ
///////////////////
WPARAM Loop() {

	MSG msg;
	//ウィンドウメッセージループ
	while(GetMessage(&msg, NULL, 0, 0) > 0) {	//エラーの場合-1が返る
		TranslateMessage(&msg);
		DispatchMessage(&msg);
		if(IsGL()) {	//IsGLが真になると次のメッセージ処理からOpenGLのループ処理になる
			//アイドル時に描画させるメッセージループ
			while(msg.message != WM_QUIT) {	//WM_QUIR == 0x0012
				if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				//処理メッセージが無ければ描画する
				else {
					if(!g_Stop)	//一時停止フラグ
						DrawObjects(g_DrawMenuNo);
				}
			}
			break;		//GLLoopが終了するとこのループも抜ける
		}
	}
	return msg.wParam;
}

////////////////////////
//ウィンドウズメイン関数
////////////////////////
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) {

	if(!hPrevInst) {
		if(!InitApp(hCurInst))					//ウィンドウ・クラスの登録
			return FALSE;
	}
	if(!InitInstance(hCurInst, nCmdShow)) {		//ウィンドウの生成
		return FALSE;
	}
	return Loop();
}
