#include "common_header.h"
#include "win_OpenGLApp.h"

COpenGLWinApp::COpenGLWinApp()
{
}

COpenGLWinApp::~COpenGLWinApp()
{
}

bool COpenGLWinApp::createWindow(HINSTANCE hInstance, char *Title, int Width, int Height)
{
	this->Title = Title;

	WNDCLASSEX wcex;

	memset(&wcex, 0, sizeof(WNDCLASSEX));

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_OWNDC;
	wcex.lpfnWndProc = WndProc;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.lpszClassName = "OpenGL33Win32App";

	if(RegisterClassEx(&wcex) == 0)
	{
		MessageBox(NULL, "RegisterClassEx failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	DWORD Style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

	hWnd = CreateWindowEx(0, wcex.lpszClassName, Title, Style, 0, 0, Width, Height, NULL, NULL, hInstance, NULL);

	if(hWnd == NULL)
	{
		MessageBox(NULL, "CreateWindowEx failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(oglControl.initOpenGL(hWnd, initScene, renderScene, resizeScene, releaseScene) == false)
	{
		return false;
	}

	ShowWindow(hWnd, SW_SHOWMAXIMIZED);

	return true;
}

void COpenGLWinApp::appBody()
{
	MSG Msg;

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
}

void COpenGLWinApp::shutdown()
{
	oglControl.releaseOpenGLControl();
	DestroyWindow(hWnd);
}

void COpenGLWinApp::resetTimer()
{
	LastFrameTime = LastFPSTime = GetTickCount();
	FrameTime = 0.0f;
}

void COpenGLWinApp::updateTimer()
{
	DWORD Time = GetTickCount();

	FrameTime = float(Time - LastFrameTime) * 0.001f;
	LastFrameTime = Time;

	if(Time - LastFPSTime > 1000)
	{
		char *Text = new char[256];
		sprintf(Text, "%s - FPS: %d", Title, FPS);
		SetWindowText(hWnd, Text);
		delete [] Text;

		LastFPSTime = Time;
		FPS = 0;
	}
	else
	{
		FPS++;
	}
}

float COpenGLWinApp::sof(float fVal)
{
	return fVal * FrameTime;
}

COpenGLWinApp appMain;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;

	switch(uiMsg)
	{
		case WM_CLOSE:
			PostQuitMessage(0);
			break;

		case WM_KEYDOWN:
			if(wParam == VK_ESCAPE) PostQuitMessage(0);
			break;

		case WM_PAINT:
			BeginPaint(hWnd, &ps);
			appMain.updateTimer();
			appMain.oglControl.render();
			EndPaint(hWnd, &ps);
			InvalidateRect(hWnd, NULL, FALSE);
			break;

		case WM_SIZE:
			appMain.oglControl.resize(LOWORD(lParam), HIWORD(lParam));
			break;

		default:
			return DefWindowProc(hWnd, uiMsg, wParam, lParam);
	}

	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR sCmdLine, int iShow)
{
	if(appMain.createWindow(hInstance, "OpenGL 3.3 Win32 application - Skybox", 800, 600) == true)
	{
		appMain.resetTimer();
		appMain.appBody();
	}

	appMain.shutdown();

	return 0;
}
