//
//  Wumbo-SpriteBatch.cpp
//  fjords_ios
//
//  Created by Wade McGillis on 4/19/14.
//  Copyright (c) 2014 Wade McGillis. All rights reserved.
//

#include "Wumbo-SpriteBatch.h"
#include "Wumbo-Renderer.h"
#include "Wumbo-Quicky.h"
#include "Wumbo-Shader.h"

extern Wumbo::Shader *circleShader;

namespace Wumbo
{
	GLuint matrixUniformID;
	float uniformMatrix[16];
	
	SpriteBatch::SpriteBatch()
	{
		matrixUniformID = circleShader->getUniformIDFromName("supermatrix");
		uniformMatrix[0] = 0;//Sprite::STATICXOFFSET;//[0][0]
		uniformMatrix[1] = 0;//Sprite::STATICYOFFSET;//[0][1]

		wvertexcount = 0;
		glGenVertexArrays(1, &vertexarray);
		GL::BindVertexArray(vertexarray);
		glGenBuffers(1, &vertexbuffer);
		GL::BindVertexArray(0);
		//glMapBufferOES(vertexbuffer, GL_WRITE_ONLY_OES);
	}
	void SpriteBatch::pushvertex(float x, float y, float z, unsigned int color, float u, float v)
	{
		wvertices[wvertexcount] = MakeWVertex(x,y,z,(color >> 16) & 0xFF,(color >> 8) & 0xFF,(color >> 0) & 0xFF,(color >> 24) & 0xFF,u,-v);
		wvertexcount++;
	}
	void SpriteBatch::pushvertex(float x, float y, float z, unsigned char r, unsigned char g, unsigned char b, unsigned char a, float u, float v)
	{
		wvertices[wvertexcount] = MakeWVertex(x,y,z,r,g,b,a,u,-v);
		wvertexcount++;
	}
	void SpriteBatch::clear()
	{
		wvertexcount = 0;
		/*GL::BindVertexArray(vertexarray);
		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		char potato = 'L';
		glBufferData(GL_ARRAY_BUFFER, 1, &potato, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		GL::BindVertexArray(0);*/
	}
	void SpriteBatch::compile()
	{
		//printf("generate vertex buffer and array #%i\n",i);
		GL::BindVertexArray(vertexarray);
		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		
		glBufferData(GL_ARRAY_BUFFER, sizeof(WVertex)*wvertexcount, wvertices, GL_STREAM_DRAW);
		
		glEnableVertexAttribArray(WumboVertexAttribPosition);
		glVertexAttribPointer(WumboVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(WVertex), (char*)(0));
		
		glEnableVertexAttribArray(WumboVertexAttribColor);
		glVertexAttribPointer(WumboVertexAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(WVertex), (char*)(12));
		
		glEnableVertexAttribArray(WumboVertexAttribTexCoord0);
		glVertexAttribPointer(WumboVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(WVertex), (char*)(16));
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		GL::BindVertexArray(0);
	}
	WVertex *SpriteBatch::openGet()
	{
		WVertex *ret = NULL;
		/*glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		ret = (WVertex*)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
		glBindBuffer(GL_ARRAY_BUFFER, 0);*/
		return ret;
	}
	void SpriteBatch::closeGet()
	{
		/*glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		glUnmapBufferOES(GL_ARRAY_BUFFER);
		glBindBuffer(GL_ARRAY_BUFFER, 0);*/
	}
	void SpriteBatch::replaceColor(int vertex, unsigned int color)
	{
		//glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		//printf("glError BEFOR = %s\n",glGetString(glGetError()));
		glBufferSubData(GL_ARRAY_BUFFER, vertex * sizeof(WVertex) + 12, 4, &color);
		//printf("glError AFTER = %s\n",glGetString(glGetError()));
		//glBindBuffer(GL_ARRAY_BUFFER, 0);
	}
	void SpriteBatch::beginModify()
	{
		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	}
	void SpriteBatch::endModify()
	{
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}
	void SpriteBatch::replaceUV(int vertex, float u, float v)
	{
		v *= -1;
		//printf("glError BEFOR = %s\n",glGetString(glGetError()));
		glBufferSubData(GL_ARRAY_BUFFER, vertex * sizeof(WVertex) + 16, 4, &u);
		glBufferSubData(GL_ARRAY_BUFFER, vertex * sizeof(WVertex) + 20, 4, &v);
		//printf("glError AFTER = %s\n",glGetString(glGetError()));
		//glBindBuffer(GL_ARRAY_BUFFER, 0);
	}
	void SpriteBatch::render()
	{
		/*uniformMatrix[2] = Wumbo::__quickyRenderer->getVirtualRenderTarget().internalwidth;//[2][0]
		uniformMatrix[3] = Wumbo::__quickyRenderer->getVirtualRenderTarget().internalheight;//[2][1]
		glUniformMatrix4fv(matrixUniformID, 1, GL_FALSE, &uniformMatrix[0]);*/
		GL::BindVertexArray(vertexarray);
		glDrawArrays(GL_TRIANGLES, 0, wvertexcount);
	}
};