
#include <iostream>
#include <Spectre/Game/GameTime.h>
#include <Spectre/Game/FPSCounter.h>
#include <Spectre/Input/InputModule.h>
#include <Spectre/System/MessageHandler.h>

#include <Platform/PlatformMisc.h>
#include <Platform/Win32/Win32Application.h>
#include <Spectre/Game.h>

Game::Game()
{
	m_platform = new Win32Application();

	m_running = false;
	m_graphics = new Graphics(m_platform);
	m_input = new InputModule(&m_platform->getInput());

	m_messageHandler = new MessageHandler();
}

Game::~Game()
{
	delete m_input;
	delete m_graphics;
	delete m_platform;
	delete m_messageHandler;
}

void Game::setup()
{
	m_graphics->init();

	m_graphics->setClearColor(0.0f, 0.0f, 0.0f);

	init();
}

void Game::run()
{
	setup();

	gameLoop();
}

void Game::gameLoop()
{
	GameTime time;

	time.setTimeStep(120);
	m_running = true;
	while(m_running) {

		processEvents();

		if (time.beginFrame()) {

			while(time.tick()) {
				update(time.getTimeStep());
			}

			render();
			m_fpsCounter.addFrame();
		}
	}
}   

void Game::processEvents()
{
	MessageQueue& queue = m_platform->getMessageQueue();
	SysEvent event;

	m_platform->update();

	while(queue.pollEvent(event)) {

		if (event.type == SysEvent::Quit) {
			exit();
			break;
		}

		// Call message handler.

		if (event.type == SysEvent::Size) {
			m_messageHandler->onSizeChanged(event.size.display, event.size.width, event.size.height);
		}
	}
}

void Game::exit()
{
	m_running = false;
}

Graphics* Game::getGraphics() const
{
	return m_graphics;
}

InputModule* Game::getInput() const
{
	return m_input;
}

FPSCounter& Game::getFpsCounter()
{
	return m_fpsCounter;
}
