#pragma once
#include <string>
#include <gl\glew.h>
#include <gl\glfw3.h>
#include <glm\glm.hpp>
#include <vector>

class OpenGLController
{
////////////////////////////////////////////////////////////////////////////////////////////
// constructor/destructor
public:
	static OpenGLController* getInstance(int oglMajor = 4, int oglMinor = 5);
	~OpenGLController();

private:
	OpenGLController() {};
	OpenGLController(int oglMajor, int oglMinor);

////////////////////////////////////////////////////////////////////////////////////////////
// member
private:
	// window
	GLFWwindow* pWindow;
	std::string sWindowName;
	int iWidth;
	int iHeight;

	// init glfw
	int iOglMajorVersion;
	int iOglMinorVersion;
	int iAntiAliasingLevel;

// IDs ==========================
	//object data
	GLuint gluiVertexArrayID;
	GLuint gluiVertexBufferID;

	//obj color
	GLuint gluiUVBufferID;
	GLuint gluiTextureID;
	GLuint gluiShaderPrgmID;
	GLuint gluiSamplerID;

	//obj transformation
	GLuint gluiMatrixID;
// ==============================

	// data
	std::vector<GLfloat> vfVertices;
	std::vector<GLfloat> vfUV;

// transformation ===============
	//values
	float fRotationX;
	float fRotationY;
	float fRotationZ;
	double dTranslationX;
	double dTranslationY;
	double dTranslationZ;

	//matrices
	glm::mat4 m4x4Model;
	glm::mat4 m4x4View;
	glm::mat4 m4x4Projection;
// ==============================

	// camera
	float fFOV;
	float fMinView;
	float fMaxView;


////////////////////////////////////////////////////////////////////////////////////////////
// private functions
private:
	void processInit();

	void initDefault();
	void startGLFW();
	void createWindow();
	void startGLEW();
	void setCallbackFunctions();

	glm::mat4 getMVPMatrix();


////////////////////////////////////////////////////////////////////////////////////////////
// public functions
public:

	// callback
	void resize(int width, int height);
	void addRotX(float value);
	void addRotY(float value);
	void addTransX(double value);
	void addTransY(double value);
	void addTransZ(double value);

	// main routine
	GLFWwindow* getWindow() const;
	void updateScene();
	void loadMsh(const char* path);

};

