/* 
 * This file is automaticaly generated, Please dont edit this file! 
 */
#include <shader.h> 











































void shader_checkShaderForErrors( shader * this, GLuint shader ) {

		GLint isCompiled = 0;

		glGetShaderiv( shader, GL_COMPILE_STATUS, &isCompiled );

		if(isCompiled == GL_FALSE)
		{
			GLint maxLength = 0;

			glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &maxLength );

			GLchar errorMessage[ maxLength ];


			glGetShaderInfoLog( shader, maxLength, &maxLength, errorMessage );

			printf("Error:		%s\n\n", errorMessage);


			glDeleteShader( shader ); 

			return;
		}

	}

void shader_createFromFile( shader * this, char * vertexShaderPath,  char * fragmentShaderPath ) {

		text * vertexShaderSource 	= fileSystem_readFile( filesystem,  vertexShaderPath, "utf8" );

		text * fragmentShaderSource = fileSystem_readFile( filesystem,  fragmentShaderPath, "utf8" );

		GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

		glShaderSource( vertexShader, 1, &vertexShaderSource->value, NULL );

		glCompileShader( vertexShader );

		shader_checkShaderForErrors( this,  vertexShader );



		GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );

		glShaderSource( fragmentShader, 1, &fragmentShaderSource->value, NULL );

		glCompileShader( fragmentShader );

		shader_checkShaderForErrors( this,  fragmentShader );


		GLint program	= glCreateProgram();

		glAttachShader( program, fragmentShader );

		glAttachShader( program, vertexShader );



		glLinkProgram( program );

		glUseProgram( program );




		int attributeCount = 0;

		GLsizei bufSize = 64;

		GLsizei length; 

		GLint size; 

		GLenum type; 

		

		glGetProgramiv( program, GL_ACTIVE_ATTRIBUTES, &attributeCount );

		printf("Active Attributes: %d\n", attributeCount );


		for (int i = 0; i < attributeCount; i++)
		{
			GLenum type;

			


			attribute attributeInstance 		= attribute_new();

			glGetActiveAttrib( program, ( GLuint ) i, bufSize, &length, &size, &type, attributeInstance.name);

			printf("Attribute #%d Type: %u Name: %s\n", i, type, attributeInstance.name);

			GLint attributeLocation = glGetAttribLocation( program, attributeInstance.name );

			glEnableVertexAttribArray( attributeLocation );


			attributeInstance.location 			= attributeLocation;

			

			attributeInstance.type				= type;

			array_add( this->attributes,  &attributeInstance );


		}

		printf("attributes count:		%i\n", array_length( this->attributes ));

		int uniformCount = 0;



		glGetProgramiv( program, GL_ACTIVE_UNIFORMS, &uniformCount );

		printf( "Active Uniforms: %d\n", uniformCount );



		
		for (int i = 0; i < uniformCount; i++)
		{

			uniform * uniformInstance 			= uniform_newPointer();

			GLenum type;

			GLchar name[bufSize];

			glGetActiveUniform( program, ( GLuint ) i, bufSize, &length, &size, &type, uniformInstance->name );

			printf( "Uniform #%d Type: %u Name: %s\n", i, type, uniformInstance->name );

			GLint uniformLocation = glGetUniformLocation( program, uniformInstance->name );

			uniformInstance->location 			= uniformLocation;

			uniformInstance->type				= type;

			array_add( this->uniforms,  uniformInstance );
			
		}

		printf("uniforms count:		%i\n", array_length( this->uniforms ));


	}

struct attribute * shader_getAttributeByName( shader * this, char * attributeName ) {

		int attributeCount 	= array_length( this->attributes );

		

		for ( int i = 0; i < attributeCount; ++i )
		{
			uniform * currentAttribute = array_get( this->attributes,  i );

			char * currentAttributeName	= ( char * ) currentAttribute->name;

			

			if( char_operator_compare( currentAttributeName ,  attributeName) ) {

				return currentAttribute;

			}

		}

	}

void shader_setUniform( shader * this, char * name,  void * value ) {

		int uniformCount 	= array_length( this->uniforms );

	

		for (int i = 0; i < uniformCount; ++i)
		{
			uniform * currentUniform = array_get( this->uniforms,  i );

			char * uniformName	= (char *)currentUniform->name;

		

			if( char_operator_compare( uniformName ,  name) ) {

				

				switch( currentUniform->type ) {


					case GL_FLOAT_VEC2:

						vector2 * vector2Value	= ( vector2 * ) value;

						

						glUniform2f( currentUniform->location, vector2Value->x, vector2Value->y );

					break;

					case GL_FLOAT_VEC3:

						vector3 * vector3Value	= ( vector3 * ) value;

						

						glUniform3f( currentUniform->location, vector3Value->x, vector3Value->y, vector3Value->z );

					break;

				}

			}


		}


	}

shader shader_new() {

	shader instance;

	instance.__classIndex = 8;

	instance.uniforms = array_newPointer();

	instance.attributes = array_newPointer();

	return instance;

}

shader * shader_newPointer() {

	struct shader * pointer = malloc( sizeof ( struct shader ) );

	pointer->__classIndex = 8;

	pointer->uniforms = array_newPointer();

	pointer->attributes = array_newPointer();

	return pointer;

}

uniform uniform_new() {

	uniform instance;

	instance.__classIndex = 9;

	return instance;

}

uniform * uniform_newPointer() {

	struct uniform * pointer = malloc( sizeof ( struct uniform ) );

	pointer->__classIndex = 9;

	return pointer;

}

attribute attribute_new() {

	attribute instance;

	instance.__classIndex = 10;

	return instance;

}

attribute * attribute_newPointer() {

	struct attribute * pointer = malloc( sizeof ( struct attribute ) );

	pointer->__classIndex = 10;

	return pointer;

}

