#include "GameWindow.h"

#define WS_MYSTYLE (WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU)
#define WINDOWCLASSNAME L"Dodge"

bool m_keyDown[256];

GameWindow::GameWindow(void)
{
	m_hInstance = GetModuleHandle(NULL);

	WNDCLASS wndClass = {0,};
	wndClass.hInstance = m_hInstance;
	wndClass.lpszClassName = WINDOWCLASSNAME;
	wndClass.lpfnWndProc = WndProc;

	RegisterClass(&wndClass);

	RECT adjust = {0, 0, 400, 400};
	AdjustWindowRect(&adjust, WS_MYSTYLE, FALSE);
	int x = GetSystemMetrics(SM_CXSCREEN) / 2, y = GetSystemMetrics(SM_CYSCREEN) / 2, w, h;
	w = adjust.right - adjust.left; h = adjust.bottom - adjust.top;
	x -= w / 2; y -= h / 2;
	m_hWnd = CreateWindowEx(NULL, WINDOWCLASSNAME, L"Dodge", WS_MYSTYLE, x, y, w, h, NULL, NULL, m_hInstance, NULL);

	m_gameGraphics.Create(m_hWnd);
}

GameWindow::~GameWindow(void)
{
	m_gameGraphics.Destroy();
	DestroyWindow(m_hWnd);
	UnregisterClass(WINDOWCLASSNAME, m_hInstance);
}

void GameWindow::RunningOn()
{
	ShowWindow(m_hWnd, SW_SHOW);
	UpdateWindow(m_hWnd);

	MSG msg;
	DWORD lastTickCount = GetTickCount(), nowTickCount = lastTickCount;
	float dt;
	while(true)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL, 0, 0))
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			nowTickCount = GetTickCount();
			dt = (nowTickCount - lastTickCount) / 10.0f;
			lastTickCount = nowTickCount;
			m_gameStateManager.Update(dt);
			m_gameGraphics.Clear();
			m_gameGraphics.Begin();
			m_gameStateManager.Draw(dt);
			m_gameGraphics.End();
			m_gameGraphics.Present();
			Sleep(1);
		}
	}
}

GameGraphics& GameWindow::GetGraphics()
{
	return m_gameGraphics;
}

GameStateManager& GameWindow::GetStateManager()
{
	return m_gameStateManager;
}

bool GameWindow::IsKeyDown(DWORD vkey)
{
	return m_keyDown[vkey];
}

void GameWindow::Close()
{
	CloseWindow(m_hWnd);
	DestroyWindow(m_hWnd);
}

LRESULT CALLBACK GameWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_KEYDOWN:
		m_keyDown[wParam] = true;
		break;
	case WM_KEYUP:
		m_keyDown[wParam] = false;
		break;
	case WM_CLOSE:
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}

	return 0;
}