#include "Wumbo-Sprite.h"
#include "Wumbo-Types.h"
#include "Wumbo-Functions.h"
#include "Wumbo-Header.h"
#if PLATFORM_IOS
#include <OpenGLES/ES2/gl.h>
#include <GLKit/GLKit.h>
#endif
#include "Wumbo-Program.h"
#include "Wumbo-Scene.h"
#include "Wumbo-Shader.h"

extern Wumbo::Shader *megaShader;
extern bool magicSuperMode;
namespace Wumbo
{
	Sprite::Sprite(Renderer *renderR)
	{
		/*displaySizeUniformID = megaShader->getUniformIDFromName("displaySize");//,renderer->getVirtualRenderTarget().internalwidth,renderer->getVirtualRenderTarget().internalheight);
		objectPositionUniformID = megaShader->getUniformIDFromName("objectPosition");//,x,y);
		objectScaleUniformID = megaShader->getUniformIDFromName("objectScale");//,xscale,yscale);
		displayOffsetUniformID = megaShader->getUniformIDFromName("displayOffset");*/
		
		matrixUniformID = megaShader->getUniformIDFromName("supermatrix");
		
		texCoordRotation = 0;

		//printf("HELP\n");
		renderer = renderR;
		x = 0.f;
		y = 0.f;
		xscale = 1.f;
		yscale = 1.f;
		width = 0.f;
		height = 0.f;
		texture = NULL;
		memset(texU, 0, MAX_SUBIMAGES);
		memset(texV, 0, MAX_SUBIMAGES);
		memset(texW, 0, MAX_SUBIMAGES);
		memset(texH, 0, MAX_SUBIMAGES);
		flipX = false;
		flipY = false;
		
		subimage = 0;

		vertexDirty = false;
		textureDirty = false;
		colorDirty = false;

		rotation = 0;
#if USE_VBOS
		
#if !TRU_VBO
#if PLATFORM_IOS
		glGenVertexArraysOES(1, &vertexArray);
		glBindVertexArrayOES(vertexArray);
#elif PLATFORM_OSX
		glGenVertexArraysAPPLE(1, &vertexArray);
		glBindVertexArrayAPPLE(vertexArray);
#else
		glGenVertexArrays(1, &vertexArray);
		glBindVertexArray(vertexArray);
#endif
#endif
		
		glGenBuffers(1, &vertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
#if TRU_VBO
		indices[0] = 0;
		indices[1] = 1;
		indices[2] = 2;
		indices[3] = 3;//{0,1,2,3};
		glGenBuffers(1, &indexBuffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
#endif
		
		glEnableVertexAttribArray(WumboVertexAttribPosition);
		glVertexAttribPointer(WumboVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 9*sizeof(float), (char*)(0*sizeof(float)));
		glEnableVertexAttribArray(WumboVertexAttribColor);
		glVertexAttribPointer(WumboVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 9*sizeof(float), (char*)(3*sizeof(float)));
		glEnableVertexAttribArray(WumboVertexAttribTexCoord0);
		glVertexAttribPointer(WumboVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 9*sizeof(float), (char*)(7*sizeof(float)));
#if TRU_VBO
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#else
#if PLATFORM_IOS
		glBindVertexArrayOES(0);
#elif PLATFORM_OSX
		glBindVertexArrayAPPLE(0);
#else
		glBindVertexArray(0);
#endif
#endif
		//printf("vertexBuffer = %i\nvertexArray = %i\n",vertexBuffer,vertexArray);
		
#endif//#else
		color = new GLfloat[16];
		GLfloat bob[] = {1.f,1.f,1.f,1.f,
						1.f,1.f,1.f,1.f,
						1.f,1.f,1.f,1.f,
						1.f,1.f,1.f,1.f};
		memcpy(color,bob,16*sizeof(GLfloat));
//#endif
	}
	Sprite::~Sprite()
	{
	}
	
	void Sprite::setActiveSubimage(int sub)
	{
		subimage = sub;
	}
	int Sprite::getActiveSubimage()
	{
		return subimage;
	}

	void Sprite::setColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a)
	{
		if (abs(r/255.f - color[0]) < 1.f/255.f && abs(g/255.f - color[1]) < 1.f/255.f && abs(b/255.f - color[2]) < 1.f/255.f && abs(a/255.f - color[3]) < 1.f/255.f)
			return;
		colorDirty = true;
		color[0] = color[4] = color[8] = color[12] = r / 255.f;
		color[1] = color[5] = color[9] = color[13] = g / 255.f;
		color[2] = color[6] = color[10] = color[14] = b / 255.f;
		color[3] = color[7] = color[11] = color[15] = a / 255.f;
	}

	void Sprite::setColor(unsigned int colour)
	{
		if (colour == getColor())
			return;
		colorDirty = true;
		color[0] = color[4] = color[8] = color[12] = ((colour & 0xFF000000) >> 24) / 255.f;
		color[1] = color[5] = color[9] = color[13] = ((colour & 0xFF0000) >> 16) / 255.f;
		color[2] = color[6] = color[10] = color[14] = ((colour & 0xFF00) >> 8) / 255.f;
		color[3] = color[7] = color[11] = color[15] = ((colour & 0xFF)) / 255.f;
	}

	unsigned int Sprite::getColor()
	{
		return ((int)(color[0]*255) << 24 | (int)(color[1]*255) << 16 | (int)(color[2]*255) << 8 | (int)(color[3]*255));
	}

	void Sprite::setScaleX(float xx)
	{
		xscale = xx;
	}
	float Sprite::getScaleX()
	{
		return xscale;
	}
	void Sprite::setScaleY(float yy)
	{
		yscale = yy;
	}
	float Sprite::getScaleY()
	{
		return yscale;
	}
	void Sprite::setScale(float xx, float yy)
	{
		xscale = xx;
		yscale = yy;
	}

	void Sprite::setTexCoordRotation(unsigned short angle)
	{
		if (angle != texCoordRotation)
		{
			texCoordRotation = angle;
			textureDirty = true;
		}
	}
	unsigned short Sprite::getTexCoordRotation()
	{
		return texCoordRotation;
	}

	void Sprite::recalculateTextureCoords()
	{
		GLuint texWidth = texture->getWidth();
		GLuint texHeight = texture->getHeight();
	    
		GLfloat left, top, right, bottom;
		if (!flipX)
		{
			left = texU[subimage];// - .5f/texWidth;
			right = (texU[subimage]+texW[subimage]);// + .5f/texWidth;
		}
		else
		{
			left = (texU[subimage]+texW[subimage]);// - .5f/texWidth;
			right = texU[subimage];// + .5f/texWidth;
		}
		if (!flipY)
		{
			top = 1-texV[subimage];// - .5f/texHeight;
			bottom = 1-(texV[subimage]+texH[subimage]);// + .5f/texHeight;
		}
		else
		{
			top = 1-(texV[subimage]+texH[subimage]);// - .5f/texHeight;
			bottom = 1-texV[subimage];// + .5f/texHeight;
		}
	    
	    if (texCoordRotation == 0)
		{
			GLfloat txc[] = {
				left, top,
				right, top,
				left, bottom,
				right, bottom
			};
			memcpy(texcoords,txc,8*sizeof(GLfloat));
		}
	    else if (texCoordRotation == 90)
		{
			GLfloat txc[] = {
				right, top,
				left, bottom,
				right, bottom,
				left, top
			};
			memcpy(texcoords,txc,8*sizeof(GLfloat));
		}
	    else if (texCoordRotation == 180)
		{
			GLfloat txc[] = {
				left, bottom,
				right, bottom,
				left, top,
				right, top
			};
			memcpy(texcoords,txc,8*sizeof(GLfloat));
		}
	    else if (texCoordRotation == 270)
		{
			GLfloat txc[] = {
				right, bottom,
				left, top,
				right, top,
				left, bottom
			};
			memcpy(texcoords,txc,8*sizeof(GLfloat));
		}
	}
	
	void Sprite::recalculateVerticesWithRotation()
	{
		float tempx = x;
		float tempy = y;
		const GLfloat xpx = 1.f/(renderer->getVirtualRenderTarget().internalwidth/2);
		const GLfloat ypx = 1.f/(renderer->getVirtualRenderTarget().internalheight/2);
		//printf("x %f\ty %f\n",xpx,ypx);
		//tempx -= view_xview;//gameEngine->GetViewX();
		//tempy -= gameEngine->GetViewY();
		GLfloat xxx1 = 0.f, xxx2 = 0.f, xxx3 = 0.f, xxx4 = 0.f, yyy1 = 0.f, yyy2 = 0.f, yyy3 = 0.f, yyy4 = 0.f;
		if (renderer->getRotation() == ScreenRotation_DOWN)
		{
			vec2df topleft = rotatePointDEG(tempx-xoffset,tempy-yoffset,tempx,tempy,rotation);
			vec2df topright = rotatePointDEG(tempx-xoffset+width,tempy-yoffset,tempx,tempy,rotation);
			vec2df bottomright = rotatePointDEG(tempx-xoffset+width,tempy-yoffset+height,tempx,tempy,rotation);
			vec2df bottomleft = rotatePointDEG(tempx-xoffset,tempy-yoffset+height,tempx,tempy,rotation);

			xxx1 = -1+topleft.x*xpx;
			yyy1 = 1-topleft.y*ypx;
			xxx2 = -1+topright.x*xpx;
			yyy2 = 1-topright.y*ypx;
			xxx3 = -1+bottomleft.x*xpx;
			yyy3 = 1-bottomleft.y*ypx;
			xxx4 = -1+bottomright.x*xpx;
			yyy4 = 1-bottomright.y*ypx;
		}
		else if (renderer->getRotation() == ScreenRotation_RIGHT)
		{
			xxx1 = 1-tempy*ypx;
			yyy1 = 1-tempx*xpx;
			xxx2 = 1-tempy*ypx;
			yyy2 = 1-tempx*xpx-width*xscale*xpx;
			xxx3 = 1-tempy*ypx-height*yscale*ypx;
			yyy3 = 1-tempx*xpx;
			xxx4 = 1-tempy*ypx-height*yscale*ypx;
			yyy4 = 1-tempx*xpx-width*xscale*xpx;
		}
		else if (renderer->getRotation() == ScreenRotation_LEFT)
		{
			xxx1 = -1+tempy*ypx;
			yyy1 = -1+tempx*xpx;
			xxx2 = -1+tempy*ypx;
			yyy2 = -1+tempx*xpx+width*xscale*xpx,
			xxx3 = -1+tempy*ypx+height*yscale*ypx;
			yyy3 = -1+tempx*xpx;
			xxx4 = -1+tempy*ypx+height*yscale*ypx;
			yyy4 = -1+tempx*xpx+width*xscale*xpx;
		}
		else if (renderer->getRotation() == ScreenRotation_UP)
		{
			xxx1 = 1-tempx*xpx;
			yyy1 = -1+tempy*ypx;
			xxx2 = 1-tempx*xpx-width*xscale*xpx;
			yyy2 = -1+tempy*ypx;
			xxx3 = 1-tempx*xpx;
			yyy3 = -1+tempy*ypx+height*yscale*ypx;
			xxx4 = 1-tempx*xpx-width*xscale*xpx;
			yyy4 = -1+tempy*ypx+height*yscale*ypx;
		}
	    
		float verts[] = {
			xxx1, yyy1,
			xxx2, yyy2,
			xxx3, yyy3,
			xxx4, yyy4
		};

		//printf("SPRITE POSITION1: %f, %f\n",xxx1,yyy1);
		//printf("SPRITE POSITION2: %f, %f\n",xxx2,yyy2);
		//printf("SPRITE POSITION3: %f, %f\n",xxx3,yyy3);
		//printf("SPRITE POSITION4: %f, %f\n",xxx4,yyy4);
	    
		memcpy(vertices,verts,8*sizeof(float));
	}
	void Sprite::recalculateVertices()
	{
		if (rotation < -.001 || rotation > .001)
		{
			recalculateVerticesWithRotation();
			return;
		}
		float tempx = x;
		float tempy = y;
		const GLfloat xpx = 1.f/(renderer->getVirtualRenderTarget().internalwidth/2);
		const GLfloat ypx = 1.f/(renderer->getVirtualRenderTarget().internalheight/2);
		//printf("x %f\ty %f\n",xpx,ypx);
		//tempx -= view_xview;//gameEngine->GetViewX();
		//tempy -= gameEngine->GetViewY();
		GLfloat xxx1 = 0.f, xxx2 = width, xxx3 = 0.f, xxx4 = width, yyy1 = 0.f, yyy2 = 0.f, yyy3 = height, yyy4 = height;
#if !USE_VBOS
		if (renderer->getRotation() == ScreenRotation_DOWN)
		{
			xxx1 = -1+tempx*xpx;
			yyy1 = 1-tempy*ypx;
		 
			xxx2 = -1+tempx*xpx+width*xscale*xpx;
			yyy2 = 1-tempy*ypx;
		 
			xxx3 = -1+tempx*xpx;
			yyy3 = 1-tempy*ypx-height*yscale*ypx;
		 
			xxx4 = -1+tempx*xpx+width*xscale*xpx;
			yyy4 = 1-tempy*ypx-height*yscale*ypx;
		}
		else if (renderer->getRotation() == ScreenRotation_RIGHT)
		{
			xxx1 = 1-tempy*ypx;
			yyy1 = 1-tempx*xpx;
			xxx2 = 1-tempy*ypx;
			yyy2 = 1-tempx*xpx-width*xscale*xpx;
			xxx3 = 1-tempy*ypx-height*yscale*ypx;
			yyy3 = 1-tempx*xpx;
			xxx4 = 1-tempy*ypx-height*yscale*ypx;
			yyy4 = 1-tempx*xpx-width*xscale*xpx;
		}
		else if (renderer->getRotation() == ScreenRotation_LEFT)
		{
			xxx1 = -1+tempy*ypx;
			yyy1 = -1+tempx*xpx;
			xxx2 = -1+tempy*ypx;
			yyy2 = -1+tempx*xpx+width*xscale*xpx,
			xxx3 = -1+tempy*ypx+height*yscale*ypx;
			yyy3 = -1+tempx*xpx;
			xxx4 = -1+tempy*ypx+height*yscale*ypx;
			yyy4 = -1+tempx*xpx+width*xscale*xpx;
		}
		else if (renderer->getRotation() == ScreenRotation_UP)
		{
			xxx1 = 1-tempx*xpx;
			yyy1 = -1+tempy*ypx;
			xxx2 = 1-tempx*xpx-width*xscale*xpx;
			yyy2 = -1+tempy*ypx;
			xxx3 = 1-tempx*xpx;
			yyy3 = -1+tempy*ypx+height*yscale*ypx;
			xxx4 = 1-tempx*xpx-width*xscale*xpx;
			yyy4 = -1+tempy*ypx+height*yscale*ypx;
		}
#endif
		float verts[] = {
			xxx1, yyy1, 0,
			xxx2, yyy2, 0,
			xxx3, yyy3, 0,
			xxx4, yyy4, 0
		};

		//printf("SPRITE POSITION1: %f, %f\n",xxx1,yyy1);
		//printf("SPRITE POSITION2: %f, %f\n",xxx2,yyy2);
		//printf("SPRITE POSITION3: %f, %f\n",xxx3,yyy3);
		//printf("SPRITE POSITION4: %f, %f\n",xxx4,yyy4);
	    
		memcpy(vertices,verts,12*sizeof(float));
	}
	void Sprite::recalculateVBO()
	{
		//NSLog(@"recalculate VBO");
#if USE_VBOS
		int i = -1;
		int j = -1;
	
#if TRU_VBO
		i = 0;
		j = 0;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 1;
		j = 1;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 2;
		j = 2;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 3;
		j = 3;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
#else
		i = 0;
		j = 0;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 1;
		j = 1;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 2;
		j = 2;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 3;
		j = 1;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 4;
		j = 2;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		i = 5;
		j = 3;
		memcpy(&vertexData[0 + 9*i], &vertices[0 + 3 * j], 3*sizeof(float)); // X Y Z
		memcpy(&vertexData[3 + 9*i], &color[0 + 4 * j], 4*sizeof(float)); // R G B A
		memcpy(&vertexData[7 + 9*i], &texcoords[0 + 2 * j], 2*sizeof(float)); // U V
#endif
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		
		//NSLog(@"POS %f,%f,%f COL %f,%f,%f,%f TEX %f,%f",vertexData[0 + 9*i],vertexData[1 + 9*i],vertexData[2 + 9*i],vertexData[3 + 9*i],vertexData[4 + 9*i],vertexData[5 + 9*i],vertexData[6 + 9*i],vertexData[7 + 9*i],vertexData[8 + 9*i]);
		
		//glGenVertexArraysOES(1, &vertexArray);
#if !TRU_VBO
#if PLATFORM_IOS
		glBindVertexArrayOES(vertexArray);
#elif PLATFORM_OSX
		glBindVertexArrayAPPLE(vertexArray);
#else
		glBindVertexArray(vertexArray);
#endif
#endif
		//glGenBuffers(1, &vertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		/*glEnableVertexAttribArray(GLKVertexAttribPosition);
		glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, 0);
		glEnableVertexAttribArray(GLKVertexAttribColor);
		glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 24, (char*)3);
		glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
		glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 24, (char*)7);*/
		
#if !TRU_VBO
#if PLATFORM_IOS
		glBindVertexArrayOES(vertexArray);
#elif PLATFORM_OSX
		glBindVertexArrayAPPLE(vertexArray);
#elif PLATFORM_OSX
		glBindVertexArrayAPPLE(vertexArray);
#else
		glBindVertexArray(vertexArray);
#endif
#endif
#endif
	}

	void Sprite::setVertices(GLfloat xxx1, GLfloat yyy1, GLfloat xxx2, GLfloat yyy2, GLfloat xxx3, GLfloat yyy3, GLfloat xxx4, GLfloat yyy4)
	{
		vertices[0] = xxx1;
		vertices[1] = yyy1;
		vertices[3] = xxx2;
		vertices[4] = yyy2;
		vertices[6] = xxx3;
		vertices[7] = yyy3;
		vertices[9] = xxx4;
		vertices[10] = yyy4;
	}
#if PLATFORM_IOS
#include <QuartzCore/QuartzCore.h>
#endif
//#include "Wumbo-iOSRoot.h"
	/*
	uniform vec2 displaySize;
	uniform vec2 objectPosition;
	uniform vec2 displayOffset;
	 */
	
	
	
	void Sprite::draw(int dispOffX, int dispOffY)
	{
#if PLATFORM_IOS
		double before = CACurrentMediaTime();
#endif
		if (vertexDirty)
		{
			//printf("vertex data was dirty!\n");
			recalculateVertices();
		}
		if (textureDirty)
		{
			//printf("texture data was dirty!\n");
			recalculateTextureCoords();
		}
		if (colorDirty)
		{
			//printf("color data was dirty!\n");
		}
		if (textureDirty || vertexDirty || colorDirty)
		{
			//printf("vbo recalculated!\n");
			recalculateVBO();
		}
		colorDirty = false;
		textureDirty = false;
		vertexDirty = false;
#if USE_VBOS
		uniformMatrix[0] = x;//[0][0]
		uniformMatrix[1] = y;//[0][1]
		uniformMatrix[2] = xscale;//[0][2]
		uniformMatrix[3] = yscale;//[1][0]
		uniformMatrix[4] = renderer->getVirtualRenderTarget().internalwidth;//[1][1]
		uniformMatrix[5] = renderer->getVirtualRenderTarget().internalheight;//[1][2]
		uniformMatrix[6] = dispOffX;//[2][0]
		uniformMatrix[7] = dispOffY;//[2][1]
#if PLATFORM_IOS
		if (false)//magicSuperMode)
			uniformMatrix[8] = 4*CACurrentMediaTime();
		else
			uniformMatrix[8] = 0;
#else
		uniformMatrix[8] = 0;
#endif
		glUniformMatrix3fv(matrixUniformID, 1, GL_FALSE, uniformMatrix);
		/*glUniform2f(displaySizeUniformID,renderer->getVirtualRenderTarget().internalwidth,renderer->getVirtualRenderTarget().internalheight);
		glUniform2f(objectPositionUniformID,x,y);
		glUniform2f(objectScaleUniformID,xscale,yscale);*/
#if TRU_VBO
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
		glDrawElements(GL_TRIANGLE_STRIP, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, (void*)0);
#else
#if PLATFORM_IOS
		glBindVertexArrayOES(vertexArray);
#elif PLATFORM_OSX
		glBindVertexArrayAPPLE(vertexArray);
#else
		glBindVertexArray(vertexArray);
#endif
		//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
		glDrawArrays(GL_TRIANGLES, 0, 6);
#endif
		//glUniform2f(displayOffsetUniformID,0,0);
#else
		glVertexPointer(3, GL_FLOAT, 0, vertices);
		glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
		glColorPointer(4, GL_FLOAT, 0, color);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
#endif
#if PLATFORM_IOS
		double after = CACurrentMediaTime();
#endif
		
		//NSLog(@"Time: %f",(after-before)*1000000);
	}

	void Sprite::setXOffset(float xx)
	{
		vertexDirty = true;
		xoffset = xx;
	}
	float Sprite::getXOffset()
	{
		return xoffset;
	}
	void Sprite::setYOffset(float yy)
	{
		vertexDirty = true;
		yoffset = yy;
	}
	float Sprite::getYOffset()
	{
		return yoffset;
	}
	void Sprite::setOffset(float xx, float yy)
	{
		vertexDirty = true;
		xoffset = xx;
		yoffset = yy;
	}

	void Sprite::setRotation(float r)
	{
		vertexDirty = true;
		rotation = r;
	}
	float Sprite::getRotation()
	{
		return rotation;
	}

	void Sprite::setFlipX(bool xx)
	{
		textureDirty = true;
		flipX = xx;
	}
	bool Sprite::getFlipX()
	{
		return flipX;
	}
	void Sprite::setFlipY(bool yy)
	{
		textureDirty = true;
		flipY = yy;
	}
	bool Sprite::getFlipY()
	{
		return flipY;
	}
	void Sprite::setX(float xx)
	{
#if !USE_VBOS
		vertexDirty = true;
#endif
		x = xx;
	}
	float Sprite::getX()
	{
		return x;
	}
	void Sprite::setY(float yy)
	{
#if !USE_VBOS
		vertexDirty = true;
#endif
		y = yy;
	}
	float Sprite::getY()
	{
		return y;
	}
	void Sprite::setPosition(float xx, float yy)
	{
#if !USE_VBOS
		vertexDirty = true;
#endif
		x = xx;
		y = yy;
	}
	void Sprite::setSize(float ww, float hh)
	{
		vertexDirty = true;
		width = ww;
		height = hh;
	}
	void Sprite::setWidth(float ww)
	{
		vertexDirty = true;
		width = ww;
	}
	float Sprite::getWidth()
	{
		return width;
	}

	void Sprite::setHeight(float hh)
	{
		vertexDirty = true;
		height = hh;
	}
	float Sprite::getHeight()
	{
		return height;
	}

	void Sprite::setSubrectPixels(int subimg, Rectanglei rect)
	{
		textureDirty = true;
		texU[subimg] = (float)rect.x/texture->getWidth();
		texV[subimg] = (float)rect.y/texture->getHeight();
		texW[subimg] = (float)rect.width/texture->getWidth();
		texH[subimg] = (float)rect.height/texture->getHeight();
	}
	
	Rectanglei Sprite::getSubrectPixels(int subimg)
	{
		Rectanglei rect;
		rect.x = texU[subimg] * texture->getWidth();
		rect.y = texV[subimg] * texture->getHeight();
		rect.width = texW[subimg] * texture->getWidth();
		rect.height = texH[subimg] * texture->getHeight();
		return rect;
	}

	void Sprite::setSubrectPixels(int subimg, int xx, int yy, int ww, int hh)
	{
		textureDirty = true;
		texU[subimg] = (float)xx/texture->getWidth();
		texV[subimg] = (float)yy/texture->getHeight();
		texW[subimg] = (float)ww/texture->getWidth();
		texH[subimg] = (float)hh/texture->getHeight();
	}

	void Sprite::setSubrect(int subimg, float xx, float yy, float ww, float hh)
	{
		textureDirty = true;
		texU[subimg] = xx;
		texV[subimg] = yy;
		texW[subimg] = ww;
		texH[subimg] = hh;
	}

	void Sprite::setTexU(int subimg, float uu)
	{
		textureDirty = true;
		texU[subimg] = uu;
	}
	float Sprite::getTexU(int subimg)
	{
		return texU[subimg];
	}
	void Sprite::setTexV(int subimg, float vv)
	{
		textureDirty = true;
		texV[subimg] = vv;
	}
	float Sprite::getTexV(int subimg)
	{
		return texV[subimg];
	}
	void Sprite::setTexW(int subimg, float ww)
	{
		textureDirty = true;
		texW[subimg] = ww;
	}
	float Sprite::getTexW(int subimg)
	{
		return texW[subimg];
	}
	void Sprite::setTexH(int subimg, float hh)
	{
		textureDirty = true;
		texH[subimg] = hh;
	}
	float Sprite::getTexH(int subimg)
	{
		return texH[subimg];
	}
	void Sprite::setTexture(Texture *tex)
	{
		texture = tex;
	}
	Texture *Sprite::getTexture()
	{
		return texture;
	}
};