/*
/ BSTMKERNEL.H
/ ************
/ This is the main Win32 Kernel for the engine and
/ handles the application from creation to closure. 
/ Whilst running, the Kernel manages the tasks
/ and timing functions as well as providing some
/ UI functions to the game.
/
/ Will Beddow 2010 - http://343gs.com/brainstem
/
/ This software is currently under development
/ and is subject to change and improvement. Some
/ aspects of the system are incomplete and/or 
/ unstable due to ongoing implementation.
/
*/

#ifndef __BSTMKERNEL_H__
#define __BSTMKERNEL_H__

#include "Compile.h"
#include "Types.h"
#include "Kernel.h"
#include "Task.h"
#include "Params.h"
#include "Resource.h"

#include "BstmDevice.h"
#include "BstmDirector.h"

#include <string>
#include <sstream>
#include <algorithm>
#include <typeinfo>

extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace Brainstem 
{
	class Kernel : public IKernel
	{
	public:
		Kernel(const Kernel_Params& params);
		~Kernel();

		bool Init();
		bool Run();
		void Release();

		IDevice* GetDevice();
		IDirector* GetDirector();

		void SetEventManager(IEventManager* eventManager);

		const char* GetWorkingDirectory();
		void SetWindowTitle(const char* title);

		void SetMousePosition(Vector2<int> position);
		Vector2<int> GetMousePosition();

		void SetWindowPosition(Vector2<int> position);
		Vector2<int> GetWindowPosition();

		Dimension2<int> GetWindowSize();
		Dimension2<int> GetResolution();

		Vector2<int> GetWindowCenter();

		void CenterWindow (HWND hwndChild);

		void SetConsoleState(int state);
		void SetMouseVisible(bool visible);

		void SetPause(bool pause);
		bool IsPaused();

		float GetDeltaTime();
		float GetFPS();
		long GetFrameIndex();

	private:

		TaskManager* Tasks;

		static LRESULT CALLBACK StaticProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
		LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

		char GetKey(WPARAM wParam);
		void SetProcessorAffinity();

		Kernel_Params Parameters;

		IDevice* kDevice;
		IDirector* kDirector;

		std::string Directory;

		IEventManager* EventManager;

		WNDCLASSEX wClass;
		HANDLE CoreFont;

		bool isPaused;

		void ResetTimer();

		long TotalFrames;
		long TimeCurrent;
		long TimeLastUpdate;

		float TimeDelta;
		float TimeFPSElapsed;
		float TimeFPSLastTick;
		float TimeFPS;
	};
}

#endif