#include "main.h"


float CONST_CAM_ALPHA_MOUSE_SENSITIVETY = 0.005f;
float CONST_CAM_PHI_MOUSE_SENSITIVETY = 0.005f;

float CONST_CAM_ZOOM_SENSITIVITY = 1.0f/120.0f;

cardinal CONST_CUBEMAP_UPDATE_INTERVAL = 5000;

void TMyApplication::DrawToCubemap()
{
	Renderer->PushShader("Directlight");

	Renderer->SwitchToCubemapBuffer("Skybox",0);
	Renderer->SetGlPosXView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlPosXView(true, true);
	GameMap.DrawVBO();
	Renderer->PopShader();
	//glClearColor()
	//glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	Renderer->SwitchToCubemapBuffer("Skybox",1);
	Renderer->SetGlNegXView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlNegXView(true, true);
	//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	GameMap.DrawVBO();
	Renderer->PopShader();

	Renderer->SwitchToCubemapBuffer("Skybox",2);
	Renderer->SetGlPosYView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlPosYView(true, true);
	GameMap.DrawVBO();
	//glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	Renderer->PopShader();
	Renderer->SwitchToCubemapBuffer("Skybox",3);
	Renderer->SetGlNegYView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlNegYView(true, true);
	//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	GameMap.DrawVBO();
	Renderer->PopShader();
	Renderer->SwitchToCubemapBuffer("Skybox",4);
	Renderer->SetGlPosZView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlPosZView(true, true);
	GameMap.DrawVBO();
	//glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	Renderer->PopShader();

	Renderer->SwitchToCubemapBuffer("Skybox",5);
	Renderer->SetGlNegZView(false, true);
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGlNegZView(true, true);
	//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	GameMap.DrawVBO();
	Renderer->PopShader();

	Renderer->SwitchToScreen();

	Renderer->PopShader();
}

void TMyApplication::DrawToShadowMap()
{
	
	Renderer->PushShader("Lightview");
	
		Renderer->BeginDrawToDepthBufferGlobal(std::string("ShadowBufferGlobal"));
		DrawSceneWithoutWater();
		Renderer->BeginDrawToDepthBufferLocal(std::string("ShadowBufferLocal"));
		DrawSceneWithoutWater();
		Renderer->EndDrawToDepthBuffer();
	
	Renderer->PopShader();
}

void TMyApplication::DrawSceneWithoutWater()
{
	Renderer->SetGLCamAngleView();
	DrawCubemap();
	if (day)
	{
		Renderer->PushShader("Directlight");
	}
	else
	{
		Renderer->PushShader("Directlight2");
	}
	Renderer->SetGLCamView();
	GameMap.DrawVBO();
	Renderer->PopShader();
}

void TMyApplication::DrawWaterSurface()
{
	
	Renderer->PushShader("Water");

	RenderUniform1f("WaterTimer", WaterTimer);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, ResourceManager->TexList["normalmap.bmp"]);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, ResourceManager->FrameManager.GetFrameTexture("Skybox"));
	RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m);
	RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v);

	EnableVertexAttribArray("vPosition");
	EnableVertexAttribArray("vTexCoord");

	//Renderer->DrawTriangleList(TriangleList);
	DrawVertexDataStruct(waterVertexDataStruct);

	DisableVertexAttribArray("vPosition");
	DisableVertexAttribArray("vTexCoord");


	Renderer->PopShader();
}

void TMyApplication::DrawCubemap()
{
	if (day)
	{
		DrawCubemapDay();
	}
	else
	{
		DrawCubemapNight();
	}
}

void TMyApplication::DrawCubemapFixed()
{
	Renderer->PushShader("Env");
	//Renderer->SetGLCamAngleView();
	Renderer->SetGLCamAngleView();
	//Renderer->LoadIdentity();
	RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m);
	RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v);

	glBindTexture(GL_TEXTURE_CUBE_MAP, ResourceManager->FrameManager.GetFrameTexture("Skybox"));
	//glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);

	EnableVertexAttribArray("vPosition");

	DrawVertexDataStruct(cubemapVertexDataStruct);

	DisableVertexAttribArray("vPosition");

	Renderer->PopShader();
}

void TMyApplication::DrawCubemapDay()
{
	Renderer->PushShader("EnvReverse");
	//Renderer->SetGLCamAngleView();
	//Renderer->SetGLCamAngleView();
	//Renderer->LoadIdentity();
	RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m);
	RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v);

	//glBindTexture(GL_TEXTURE_CUBE_MAP, ResourceManager->FrameManager.GetFrameTexture("Skybox"));
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTextureDay);

	EnableVertexAttribArray("vPosition");

	DrawVertexDataStruct(cubemapVertexDataStruct);

	DisableVertexAttribArray("vPosition");

	glClear(GL_DEPTH_BUFFER_BIT);

	Renderer->PopShader();
}


void TMyApplication::DrawCubemapNight()
{
	Renderer->PushShader("EnvReverseNight");
	//Renderer->SetGLCamAngleView();
	//Renderer->SetGLCamAngleView();
	//Renderer->LoadIdentity();
	RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m);
	RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v);

	//glBindTexture(GL_TEXTURE_CUBE_MAP, ResourceManager->FrameManager.GetFrameTexture("Skybox"));
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTextureNight);

	EnableVertexAttribArray("vPosition");

	DrawVertexDataStruct(cubemapVertexDataStruct);

	DisableVertexAttribArray("vPosition");

	glClear(GL_DEPTH_BUFFER_BIT);

	Renderer->PopShader();
}

void TMyApplication::DrawFrameFullScreen()
{

}

//What to do on init
void TMyApplication::InnerInit()
{
	ResourceManager->PathToResources = "C:\\Work\\OldProjects\\ho3\\resources\\";

	glDisable(GL_CULL_FACE);

	
	ResourceManager->ShaderManager.AddShader("GUI", "shaders/gui_transparent.vertex", "shaders/gui_transparent.fragment");
	ResourceManager->ShaderManager.AddShader("Parallax", "shaders/directlight_parallax_shadow.vertex", "shaders/directlight_parallax_shadow.fragment");
	ResourceManager->ShaderManager.AddShader("Directlight", "shaders/directlight.vertex", "shaders/directlight.fragment");
	ResourceManager->ShaderManager.AddShader("Directlight2", "shaders/directlight2.vertex", "shaders/directlight2.fragment");
	ResourceManager->ShaderManager.AddShader("Directlight3", "shaders/directlight3.vertex", "shaders/directlight3.fragment");
	ResourceManager->ShaderManager.AddShader("Env", "shaders/env.vertex", "shaders/env.fragment");
	ResourceManager->ShaderManager.AddShader("EnvReverse", "shaders/env_reverse.vertex", "shaders/env_reverse.fragment");
	ResourceManager->ShaderManager.AddShader("EnvReverseNight", "shaders/env_reverse_night.vertex", "shaders/env_reverse_night.fragment");
	ResourceManager->ShaderManager.AddShader("Water", "shaders/water.vertex", "shaders/water.fragment");
	ResourceManager->ShaderManager.AddShader("Frame", "shaders/frame.vertex", "shaders/frame.fragment");
	ResourceManager->ShaderManager.AddShader("Lightview", "shaders/lightview.vertex", "shaders/lightview.fragment");
	ResourceManager->ShaderManager.AddShader("Simple3D", "shaders/simple3d.vertex", "shaders/simple3d.fragment");

	Renderer->SetBackgroundShader("Env");

	Renderer->PushShader("Parallax");
	//Renderer->PushShader("GUI");


	ResourceManager->ModelManager.AddLiteModel("models/bt_box_yellow.lm1");
	ResourceManager->ModelManager.AddLiteModel("models/bt_box_red.lm1");
	ResourceManager->ModelManager.AddLiteModel("models/bt_box_blue.lm1");
	ResourceManager->ModelManager.AddLiteModel("models/bt_cone.lm1");

	ResourceManager->ModelManager.AddLiteModel("models/girl.lm1");
	ResourceManager->ModelAnimManager.AddAnimationToModel("girl.lm1","models/girl.bn2");
	ResourceManager->ModelAnimManager["girl.lm1"]->LoadAnimSequenceFromFileAn1("models/girl.an1");

	ResourceManager->ModelManager.AddLiteModel("models/bonemodel.lm1");
	ResourceManager->ModelAnimManager.AddAnimationToModel("bonemodel.lm1","models/bonemodel.bn2");
	ResourceManager->ModelAnimManager["bonemodel.lm1"]->LoadAnimSequenceFromFileAn1("models/bonemodel.an1");

	GameMap.LoadMap();
	
	Renderer->SetLandToCalcCollision(GameMap.GetLand());

	Renderer->MoveDist(15.0f);
	Renderer->MovePhi(pi/6);
	

	float len = 50.0f;

	//ResourceManager->LightManager.SetLightPos(0, vec4(-len * cos(pi/4), len * sin(pi/4), 0.0f, 0.0f));

	ResourceManager->FrameManager.AddCubemapBuffer("Skybox",512,512);

	Renderer->SetBackgroundCubemap(ResourceManager->FrameManager.GetFrameTexture("Skybox"));

	ResourceManager->TexList.AddTexture("../resources/normalmap.bmp");

	std::array<std::string, 6> cubemapTextureStr = {
		"../resources/sky/posx.bmp", "../resources/sky/negx.bmp", "../resources/sky/posy.bmp", "../resources/sky/negy.bmp", "../resources/sky/posz.bmp", "../resources/sky/negz.bmp" 
	};

	cubemapTexture = ResourceManager->TexList.AddCubemapTexture(cubemapTextureStr);
	 
	//!!!! for some reason up and down switched
	std::array<std::string, 6> cubemapTextureDayStr = {
	"../resources/sky/yavin_rt.bmp", "../resources/sky/yavin_lf.bmp", "../resources/sky/yavin_dn.bmp", "../resources/sky/yavin_up.bmp", "../resources/sky/yavin_bk.bmp", "../resources/sky/yavin_ft.bmp"
	};


	cubemapTextureDay = ResourceManager->TexList.AddCubemapTexture(cubemapTextureDayStr);

	std::array<std::string, 6> cubemapTextureNightStr = {
	"../resources/sky/space_rt.bmp", "../resources/sky/space_lf.bmp", "../resources/sky/space_up.bmp", "../resources/sky/space_dn.bmp", "../resources/sky/space_bk.bmp", "../resources/sky/space_ft.bmp"
	};

	cubemapTextureNight = ResourceManager->TexList.AddCubemapTexture(cubemapTextureNightStr);
	//."posx.bmp","negx.bmp","posy.bmp","negy.bmp","posz.bmp","negz.bmp"

	ResourceManager->FrameManager.AddFrameRenderBuffer("ScreenBlur", 512, 512);
	ResourceManager->FrameManager.AddDepthBuffer("ShadowBufferGlobal", 512, 512);

	ResourceManager->FrameManager.AddDepthBuffer("ShadowBufferLocal", 1024, 1024);


	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("ShadowBufferGlobal"));
	glActiveTexture(GL_TEXTURE3);
	glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("ShadowBufferLocal"));
	glActiveTexture(GL_TEXTURE0);

	glClearColor(0.2f, 0.5f, 1.0f, 1.0f);

	//Renderer->SetShadowClampValue(0.3f);
	//Renderer->SetShadowClampValue(0.0f);
	Renderer->SetFogBeginDistance(15.f);
	Renderer->SetFogEndDistance(30.f);


	// +x
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f });

	// -x
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f });


	// +y
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f });


	// -y
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f });


	// +z
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f });
	
	// -z
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f });

	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f });
	cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f });


	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });

	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });


	cubemapVertexDataStruct.RefreshVBO();


	/*
	glBegin(GL_POLYGON);
	glTexCoord2f(2, 2);
	glVertex3f(20, 0, 20);
	glTexCoord2f(2, 0);
	glVertex3f(20, 0, -20);
	glTexCoord2f(0, 0);
	glVertex3f(-20, 0, -20);
	glTexCoord2f(0, 2);
	glVertex3f(-20, 0, 20);
	glEnd();*/

	waterVertexDataStruct.PositionData.push_back({ -20, 0, -20 });
	waterVertexDataStruct.PositionData.push_back({ 20, 0, -20 });
	waterVertexDataStruct.PositionData.push_back({ 20, 0, 20 });

	waterVertexDataStruct.PositionData.push_back({ -20, 0, -20 });
	waterVertexDataStruct.PositionData.push_back({ 20, 0, 20 });
	waterVertexDataStruct.PositionData.push_back({ -20, 0, 20 });

	waterVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	waterVertexDataStruct.TexCoordData.push_back({ 2.0, 0.0 });
	waterVertexDataStruct.TexCoordData.push_back({ 2.0, 2.0 });

	waterVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	waterVertexDataStruct.TexCoordData.push_back({ 2.0, 2.0 });
	waterVertexDataStruct.TexCoordData.push_back({ 0.0, 2.0 });
	waterVertexDataStruct.RefreshVBO();

	frameVertexDataStruct.PositionData.push_back({ 0, 0, 0 });
	frameVertexDataStruct.PositionData.push_back({ 800, 0, 0});
	frameVertexDataStruct.PositionData.push_back({800, 600, 0 });

	frameVertexDataStruct.PositionData.push_back({ 0, 0, 0 });
	frameVertexDataStruct.PositionData.push_back({ 800, 600, 0 });
	frameVertexDataStruct.PositionData.push_back({ 0, 600, 0 });

	frameVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	frameVertexDataStruct.TexCoordData.push_back({ 1.0, 0.0 });
	frameVertexDataStruct.TexCoordData.push_back({ 1.0, 1.0 });

	frameVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 });
	frameVertexDataStruct.TexCoordData.push_back({ 1.0, 1.0 });
	frameVertexDataStruct.TexCoordData.push_back({ 0.0, 1.0 });
	frameVertexDataStruct.RefreshVBO();

	day = false;
	GameMap.day = day;

}


//What to do on deinit
void TMyApplication::InnerDeinit()
{
	GameMap.FreeMap();
	ResourceManager->FrameManager.DeleteFrameRenderBuffer("Skybox");
}

//What to do on draw
void TMyApplication::InnerDraw()
{	
	Renderer->SwitchToScreen();
	glClearColor(0.2f, 0.55f, 1.0f, 1.0f);
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	if (day)
	{

	}
	else
	{
		Renderer->SetLightPos(lightPos);
	}
	Renderer->PushShader("Directlight");
	//DrawCubemapDay();

	DrawToCubemap();

	Renderer->SwitchToFrameBuffer(std::string("ScreenBlur"));

	DrawSceneWithoutWater();

	Renderer->PopShader();

	DrawWaterSurface();
	
	
	Renderer->SwitchToScreen();
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	Renderer->PushShader("Frame");

	Renderer->PushProjectionMatrix(800, 600);
	Renderer->LoadIdentity();


	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("ScreenBlur"));
	RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m);
	RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v);

	EnableVertexAttribArray("vPosition");
	EnableVertexAttribArray("vTexCoord");

	DrawVertexDataStruct(frameVertexDataStruct);

	DisableVertexAttribArray("vPosition");
	DisableVertexAttribArray("vTexCoord");


	Renderer->PopProjectionMatrix();

	Renderer->PopShader();

	

	/*
	Renderer->PushShader("Directlight");
	DrawSceneWithoutWater();
	Renderer->PopShader();
	*/
	//DrawToCubemap();

	/*
	DrawToCubemap();

	DrawToShadowMap();
	
	Renderer->SwitchToFrameBuffer(std::string("ScreenBlur"));
	
	DrawSceneWithoutWater();
	DrawWaterSurface();
	

	Renderer->SwitchToScreen();

	Renderer->PushShader("Frame");
	Renderer->DrawFrameFullScreen(std::string("ScreenBlur"));
	Renderer->PopShader();*/



	/*
	Renderer->SwitchToFrameBuffer(std::string("ScreenBlur"));
	
	Renderer->PushShader("GUI");
	DrawSceneWithoutWater();
	Renderer->PopShader();

	Renderer->SwitchToScreen();

	Renderer->PushShader("Frame");
	Renderer->DrawFrameFullScreen(std::string("ScreenBlur"));
	Renderer->PopShader();*/
	

	
}

//What to do on update. timer means how many ms passed since last update
void TMyApplication::InnerUpdate(cardinal timer)
{
	WaterTimer += 0.001f * timer;

	lightPos = vec3(sin(WaterTimer) * 4.f-2, 5, 0);

	GameMap.Update(timer);

}

void TMyApplication::UpdateQuick()
{
	if (GetKeyState(VK_UP) >> 15)
	{
		Renderer->MoveForward();
	}

	if (GetKeyState(VK_DOWN) >> 15)
	{
		Renderer->MoveBackward();
	}

	if (GetKeyState(VK_LEFT) >> 15)
	{
		Renderer->MoveLeft();
	}

	if (GetKeyState(VK_RIGHT) >> 15)
	{
		Renderer->MoveRight();
	}
}

void TMyApplication::OnMouseMove(TMouseState& mouseState)
{
	if (MouseRightButtonPressed)
	{
		int dx = mouseState.X - MouseX0;
		int dy = mouseState.Y - MouseY0;
		
		MouseX0 = mouseState.X;
		MouseY0 = mouseState.Y;

		Renderer->MoveAlpha(dx * CONST_CAM_ALPHA_MOUSE_SENSITIVETY);
		Renderer->MovePhi(dy * CONST_CAM_PHI_MOUSE_SENSITIVETY);
	}
}

void TMyApplication::OnMouseDown(TMouseState& mouseState)
{
	if (mouseState.RightButtonPressed)
	{
		MouseRightButtonPressed = true;
		MouseX0 = mouseState.X;
		MouseY0 = mouseState.Y;
	}

	if (mouseState.LeftButtonPressed)
	{
		MouseLeftButtonPressed = true;
		view += 1;
		if (view == 7)
		{
			view = 0;
		}
	}
}

void TMyApplication::OnMouseUp(TMouseState& mouseState)
{

	
	MouseRightButtonPressed = false;
	if (MouseLeftButtonPressed)
	{
		MouseLeftButtonPressed = false;
		GameMap.PlayerClicked(mouseState.X, mouseState.Y);
	}
}

void TMyApplication::OnMouseWheel(short int delta)
{
	Renderer->MoveDist(-CONST_CAM_ZOOM_SENSITIVITY * delta);
}


int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
	LPSTR lpszCmdLine, int nCmdShow)
{
	//Create application
	TMyApplication Application;

	//Start application
	return MainLoop(Application);
}