#ifndef OGLSHADER_ED561HDF4G614764R64Z
#define OGLSHADER_ED561HDF4G614764R64Z

#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <GL/glew.h>
#include <flexilog.h>
#include "3dmath.h"
#include "glgetproc.h"

//#include <glm/glm.hpp>
//#include <glm/gtc/matrix_transform.hpp>

using namespace std;

#include "OglTex.h"

#define uint unsigned int

struct UniformNameType {
	UniformNameType( string name, char type ) :name( name ), type( type ) {}
	string name;
	char type;
};
struct UniformTypeID {
	UniformTypeID( ) { type = 0; id = 0; }
	UniformTypeID( char type, GLuint id ) :type( type ), id( id ) {}
	char type;
	GLuint id;
};

class OglShader {
public:
	virtual void compile_( const char * file_path, GLenum type );
	OglShader( );
	virtual ~OglShader( );
	void notDelete( );
	GLuint ShaderID;
	vector<UniformNameType> uniformtypes;
private:
	bool del;
};
class OglVertexShader : public OglShader {
public:
	void compile( const char * file_path );
};
class OglFragmentShader : public OglShader {
public:
	void compile( const char * file_path );
};
class OglGeometryShader : public OglShader {
public:
	void compile(const char * file_path);
};
class OglComputeShader : public OglShader {
public:
	void compile(const char * file_path);
};

class OglShaderProg {
public:
	OglShaderProg();
	void link( OglShader& vsh, OglShader& fsh );
	void linkG(OglShader& vsh, OglShader& gSh, OglShader& fsh);
	void linkC(OglShader& csh);
	void enable( );
	void setColor( float r, float g, float b );
	void regTexture( OglTex *tex );
	void regTexture2DArray(OglTex *tex);

	void importValue( string name, float data );
	void importValue( string name, int data );
	void importValue( string name, unsigned int data);
	void importValue( string name, Matrix data );
	void importValue( string name, Vector3 data );
	void importValue( string name, Vector2 data );
	void importValue( string name, OglTex *data );
	void importValueTex2DArray(string name, OglTex *data);

	GLuint ProgramID;
private:
	void processUniform( UniformNameType unf );
	map<string, UniformTypeID> uniforms;
	map<OglTex*, uint> textureMap;
	uint textures;
};

#endif