#include <algorithm>
#include <stdlib.h>
#include <string>
#include <GL/freeglut.h>
#include "LevelState.h"
#include "ShaderManager.h"
#include "InputManager.h"
#include "ModelManager.h"
#include "TextureManager.h"
#include "RenderState.h"
using namespace std;

int currentTime = 0;
int vsync = 0;
int sizeX = 0;
int sizeY = 0;
int counter = 0;

void init() {
	GameState::GAMESTATE = new LevelState();

	ShaderManager::getInstance()->initialize();
	ModelManager::getInstance()->initialize();
	TextureManager::getInstance()->initialize();

	glutSetCursor(GLUT_CURSOR_NONE);
	//glutFullScreen();
}

void resize(int w, int h) {
	sizeX = w;
	sizeY = h;
	GameState::GAMESTATE->resize(w, h);
}

void render(void) {
	int lastTime = currentTime;
	currentTime = glutGet( GLUT_ELAPSED_TIME );
	int timePassed = currentTime - lastTime;
	vsync += timePassed;
	
	if (vsync > (1000/60)){
		float fps = 1000.0f/timePassed;
		if (fps > 60)
			fps=60;
		vsync = 0;

		char buffer[5];
		_itoa((int)fps, buffer, 10);
		string title = string("LD26 - FPS: ") + string(buffer);
		glutSetWindowTitle(title.c_str());
		
		GameState::GAMESTATE->tick((int)fps);
		
		counter++;
	}
	
}

void keyDown(unsigned char key, int xx, int yy) {
	if (key == 27) 
	{ 
		exit(0);
	}
	InputManager::getInstance()->registerKeyDown((int)key);
	if (key >= '0' && key <= '4') 
	{
		//RenderStateManager::RENDERSTATE = (RenderState)((int)key-(int)'0');
	}
}

void keyUp(unsigned char key, int xx, int yy) {
	InputManager::getInstance()->registerKeyUp((int)key);
}

void mousePress(int button, int state, int x, int y) {
	if (state == GLUT_DOWN)
	{
		InputManager::getInstance()->registerMouseButtonDown(button);
		GameState::GAMESTATE->onclick();
	}
	else
	{
		InputManager::getInstance()->registerMouseButtonUp(button);
	}
}

void mousePressedMove(int x, int y) {
	InputManager::getInstance()->setMousePosition(x,y);
}

void mouseReleasedMove(int x, int y) {
	InputManager::getInstance()->setMousePosition(x,y);
}

void specialKeyDown(int key, int xx, int yy)
{
}

void mouseWheel(int button, int dir, int x, int y)
{
}

int main(int argc, char **argv) {
	// init GLUT and create window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(50,50);
	glutInitWindowSize(1280,720);
	glutCreateWindow("LD26");

	// register callbacks
	glutDisplayFunc(render);
	glutReshapeFunc(resize);
	glutIdleFunc(render);
	glutKeyboardFunc(keyDown);
	glutKeyboardUpFunc(keyUp);
	glutSpecialFunc(specialKeyDown);
	glutMouseFunc(mousePress);
	glutMotionFunc(mousePressedMove);
	glutPassiveMotionFunc(mouseReleasedMove);

	FreeConsole();

	// enter GLUT event processing cycle
	init();
	glutMainLoop();

	return 1;
}
