#define _CRT_SECURE_NO_WARNINGS
#ifndef _DEBUG
	#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#endif // DEBUG

#include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp>

#include "setup.h"
#include "callback.h"

int main(int argc, char** argv)
{
	oglVariables scene;

	// init everything
	setupGLFW();
	scene.window = createWindow();
	setupGLEW();
	initVariables(scene);
	glBindVertexArray(scene.vertexArrayID);

	// Set callback functions
	glfwSetMouseButtonCallback(scene.window, mouseButton);
	glfwSetCursorPosCallback(scene.window, mouseMove);
	glfwSetWindowSizeCallback(scene.window, windowResize);
	glfwSetScrollCallback(scene.window, mouseWheel);
	glfwSetKeyCallback(scene.window, keyPress);

	// set background color 0,5 0,8 1,0
	glClearColor(0.0000f, 0.0000f, 0.4000f, 0.0000f);

	// enable z-order
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);
	glEnable(GL_CULL_FACE);

	// load object to OGL
	glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
	glBufferData(
		GL_ARRAY_BUFFER,
		sizeof(scene.object.data) * scene.object.data.size(),
		scene.object.data.data(),
		GL_STATIC_DRAW
	);

	/*/ load color to OGL
	glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
	glBufferData(
		GL_ARRAY_BUFFER,
		sizeof(scene.object.color) * scene.object.color.size(),
		scene.object.color.data(),
		GL_STATIC_DRAW
	);*/

	// load UV to OGL
	glBindBuffer(GL_ARRAY_BUFFER, scene.uvBufferID);
	glBufferData(
		GL_ARRAY_BUFFER,
		sizeof(scene.object.uv) * scene.object.uv.size(),
		scene.object.uv.data(),
		GL_STATIC_DRAW
		);

	// Main loop
	do {
		//processInteraction(scene.window);
		calcMatrices(scene);

		// clear the scene
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// use shader prgram
		glUseProgram(scene.shaderPrgmID);

		// tell shader transformation
		glUniformMatrix4fv(scene.matrix.id, 1, GL_FALSE, &scene.matrix.mvp[0][0]);

		// bind texture in texture unit 0
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, scene.object.textureID);
		// tell sampler to use texture unit 0
		glUniform1i(scene.samplerID, 0);

		// open attribute position
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

		/*/ open attribute color
		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);*/

		// open attribute uv
		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER, scene.uvBufferID);
		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

		// draw object
		glDrawArrays(GL_TRIANGLES, 0, 3*12);

		// close attributes
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);

		glfwSwapBuffers(scene.window);
		glfwPollEvents();
	}
	while (!glfwWindowShouldClose(scene.window));

	cleanUp(scene);

	return 0;
}
