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




























event * globalEvent; 

resourceManager	* resources; 



















char * quads_textFromNumber( quads * this, int i ) {

		char * fileName = malloc( sizeof( char ) * 100 );

		sprintf( fileName, "%d", i );

		return fileName;

	}

void quads_prepare( quads * this ) {

		printf("\n\n\n		Prepare renderPass Quad\n\n\n\n\n");








		this->samplerArray			= sampler2D_newPointer();


		for (int i = 1; i < 10; ++i )
		{

			char * fileName  	= quads_textFromNumber( this,  i );

			char_operator_add( fileName	,  ".png");

			printf("load png:	%s\n", fileName);

			

		}

		printf("\n\n");

		this->samplerArray->target				= GL_TEXTURE_2D_ARRAY;


		shader * vertexShader = shader_newPointer( GL_VERTEX_SHADER );

		shader_loadFromFile( vertexShader,  "assets/shaders/multiQuad.vertex" );


		shader * fragmentShader = shader_newPointer( GL_FRAGMENT_SHADER );

		shader_loadFromFile( fragmentShader,  "assets/shaders/multiQuad.fragment" );


		this->program 	= program_newPointer();

		program_addShader( this->program,  vertexShader );

		program_addShader( this->program,  fragmentShader );

		program_create( this->program );



		

		block * orientationBlock		= program_getBlock( this->program,  "orientation" );

		block * meshesBlock				= program_getBlock( this->program,  "meshes" );


		this->mesh = mesh_newPointer();

		mesh_setProgram( this->mesh,  this->program );

		mesh_createBuffers( this->mesh );

	
		

		


























		quads_createMeshes( this );

		


		sampler2D_addTexture( this->samplerArray,  resourceManager_loadPngImage( resources,  "1.png" ) );


		block_upload( meshesBlock );

	}

void quads_sortOpacity( quads * this, vector_quadMesh * meshes ) {


		int count = vector_quadMesh_length( meshes );

		int i, j;

		struct quadMesh temp;

		for (i = 0; i < (count - 1); ++i)
		{
			for (j = 0; j < count - 1 - i; ++j )
			{

				struct quadMesh quadA	= vector_quadMesh_get( meshes,  j );

				struct quadMesh quadB	= vector_quadMesh_get( meshes,  j + 1 );

				float a = ( intptr_t ) quadA.zIndex;

				float b = ( intptr_t ) quadB.zIndex;

				if ( a > b )
				{

					temp 						= meshes->items[j+1];

					meshes->items[ j + 1 ] 		= meshes->items[j];

					meshes->items[ j ] 			= temp;

				}
			}
		}

	}

void quads_createMeshes( quads * this ) {


		vector_quadMesh * meshes	= this->meshes;

		vector_quadMesh_resize( meshes,  100 );






















		vector_element * elements	= this->elements;


		{

			element instance 		= element_new();

			element_setter_position( &instance, vector3_new( 200, 200, 1100 ) );

			element_setter_size( &instance, vector2_new( 200., 200. ) );

			

			instance.opacity		= 1;

			element_setter_background( &instance, 1, (int[1]){ -2 }, "9.png" );

			

			vector_element_add( elements,  instance );




		}	


		{

			element instance 		= element_new();

			element_setter_position( &instance, vector3_new( 100, 100, 500 ) );

			element_setter_size( &instance, vector2_new( 400., 400. ) );

			element_setter_background( &instance, 1, (int[1]){ -2 }, "3.png" );

			

			

			instance.opacity			= .9;


			











			

			

			

		

			

		vector_element_add( elements,  instance );



		{

			element instance 		= element_new();

			element_setter_position( &instance, vector3_new( 20, 0, 1300 ) );

			element_setter_size( &instance, vector2_new( 40., 40. ) );

			element_setter_background( &instance, 1, (int[1]){ -2 }, "7.png" );

			instance.opacity		= 1;

			vector_element_add( elements,  instance );


		}	



		


			int count = vector_element_length( elements );

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

				element currentElement =  vector_element_get( elements,  i );

				quadMesh meshInstance 	= quadMesh_new();


				meshInstance.elementIndex = i;
				
				meshInstance.position	= vector2_new( currentElement.position.x, currentElement.position.y );

				meshInstance.zIndex		= currentElement.position.z;

				meshInstance.size		= currentElement.size;


				printf("zIndex:		%f\n", currentElement.position.z);

				int features		= 0;

				if( currentElement.useBackgroundImage ) {


					


					meshInstance.textureIndex		= sampler2D_getTextureIndex( this->samplerArray );

					printf("use background image.		%s \n", currentElement.backgroundImagePath  );

					sampler2D_addTexture( this->samplerArray,  resourceManager_loadPngImage( resources,  currentElement.backgroundImagePath ) );

				} else {

					printf("dont use background color.  %f  %f  %f \n", currentElement.backgroundColor.x, currentElement.backgroundColor.y, currentElement.backgroundColor.z);

					meshInstance.color		= currentElement.backgroundColor;

				}
				

				meshInstance.features		= element_updateFeature( &currentElement );

				meshInstance.opacity		= currentElement.opacity;

					


				element_setOriginal( &currentElement );

				vector_element_set( elements,  i, currentElement );


				vector_quadMesh_add( meshes,  meshInstance );

			}



			quads_sortOpacity( this,  meshes );



		}

















































		block * meshesBlock				= program_getBlock( this->program,  "meshes" );

		block_setData( meshesBlock,  ( float * ) meshes->items );

	}


quadMesh quads_updateMesh( quads * this, quadMesh currentMesh,  element currentElement ) {

		vector2 position 		= vector2_new( currentElement.position.x, currentElement.position.y );

		currentMesh.position	= position;

		currentMesh.zIndex		= currentElement.position.z;

		currentMesh.size		= currentElement.size;

		currentMesh.color		= currentElement.backgroundColor;

		return currentMesh;

	}

void quads_callElementEvents( quads * this, event * currentEvent,  element * currentElement,  int elementIndex ) {

		vector_char_pointer * mouseEvents	 = currentEvent->mouse->eventTypes;

		int mouseEventCount			 = vector_char_pointer_length( mouseEvents );

		for (int k = 0; k < mouseEventCount; ++k)
		{
			char * mouseEventCode = vector_char_pointer_get( mouseEvents,  k );

			printf("			mouse event:	%s\n", mouseEventCode);


			if( char_operator_compare( mouseEventCode ,  "click") ) {

				element_click( currentElement );

				

			}

			if( char_operator_compare( mouseEventCode ,  "mousedown") ) {

				element_mousedown( currentElement );

				

			}


			if( char_operator_compare( mouseEventCode ,  "mouseup") ) {

				element_mouseup( currentElement );

				

			}

			if( char_operator_compare( mouseEventCode ,  "mousemove") ) {

				if( !quads_integerContains( this,  this->mouseOverElements, elementIndex ) ) {

					element_mouseover( currentElement );

					vector_int_add( this->mouseOverElements,  elementIndex );

				}

			}

		}

	}

bool quads_integerContains( quads * this, vector_int * numbers,  int a ) {

		int count = vector_int_length( numbers );

		for (int j = 0; j < count; ++j)
		{

			int b = vector_int_get( numbers,  j );

			if( a == b ) {

				return true;

			}

		}

		return false;

	}

void quads_render( quads * this ) {

		program * currentProgram 			= this->program;

		event * currentEvent 				= globalEvent;


		block * eventsBlock 				= program_getBlock( currentProgram,  "events" );

		


		block * meshesBlock 				= program_getBlock( currentProgram,  "meshes" );


		eventsBlock->autoUpload 			= true;

		block_setMember( eventsBlock,  "window", &currentEvent->screen->size );


		meshesBlock->autoUpload 		= true;

		vector2 mousePosition			= globalEvent->mouse->position;


		int mouseX						= ( int ) mousePosition.x;

		int mouseY						= ( int ) mousePosition.y;


		vector_element * elements		= this->elements;

		vector_quadMesh * meshes		= this->meshes;


		vector_int * 	mouseOverElements = this->mouseOverElements;

		int count = vector_quadMesh_length( meshes );

		for (int i = 0; i < count; ++i)
		{
			quadMesh currentMesh	= vector_quadMesh_get( meshes,  i );

			int left	= currentMesh.position.x;

			int top		= currentMesh.position.y;

			int right	= currentMesh.position.x + currentMesh.size.x;

			int bottom	= currentMesh.position.y + currentMesh.size.y;

			int elementIndex 		= currentMesh.elementIndex;


			if( mouseX > left && mouseX < right && mouseY > top && mouseY < bottom ) {

				element currentElement	= vector_element_get( elements,  elementIndex );
		
				quads_callElementEvents( this,  currentEvent, &currentElement, elementIndex );

				currentMesh				= quads_updateMesh( this,  currentMesh, currentElement );

				vector_element_set( elements,  elementIndex, currentElement );

				block_setMemberArrayRow( meshesBlock,  "meshArray[0].color", i, ( float * ) & currentMesh );
				
			} else {

				if( quads_integerContains( this,  this->mouseOverElements, elementIndex ) ) {

					printf("mouseout\n\n");

					vector_int_delete( this->mouseOverElements,  elementIndex );

					element currentElement	= vector_element_get( elements,  elementIndex );


					element_mouseleave( &currentElement );



					currentMesh				= quads_updateMesh( this,  currentMesh, currentElement );

					vector_element_set( elements,  elementIndex, currentElement );

					block_setMemberArrayRow( meshesBlock,  "meshArray[0].color", i, ( float * ) & currentMesh );
				
				}


			}

		}


		


		

		

	


		vector2 * position2	= vector2_newPointer( 0.4, 0 );

		



		program_setUniform( this->program,  "samplerArray", this->samplerArray );

		glUseProgram( currentProgram->glProgram );

		int numItems	= 200;



		
		

		
		

		
		glDisable(GL_DEPTH_TEST);



		
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		


		glDepthRange(0.0, 1.0);

		glDepthFunc(GL_ALWAYS);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_CULL_FACE);





		glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );



		glBindVertexArray( this->mesh->vertexArrayObject );

		glDrawElements( GL_TRIANGLES, numItems, GL_UNSIGNED_INT, ( void * ) 0 ); 

	}

quads quads_new() {

	quads instance;

	instance.font = fontRenderer_newPointer();

	instance.meshes = vector_quadMesh_newPointer();

	instance.elements = vector_element_newPointer();

	instance.mouseOverElements = vector_int_newPointer();

	return instance;

}

quads * quads_newPointer() {

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

	pointer->font = fontRenderer_newPointer();

	pointer->meshes = vector_quadMesh_newPointer();

	pointer->elements = vector_element_newPointer();

	pointer->mouseOverElements = vector_int_newPointer();

	return pointer;

}

