#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_image.h>

#include "include/blur.h"
#include "include/main.h"
#include "include/object.h"

static struct BlurLocal
{
	GLuint texture;
	unsigned int *pixels;
	GLfloat counter;
	GLfloat alpha;
}local;


GLuint blr_getTexture()
{
	return local.texture;
}

/**
 * cleanup blur
 */
void blr_cleanup()
{

}

/**
 * initialize blur
 */
int blr_init()
{
	memset(&local, 0, sizeof(struct BlurLocal));
		
	if(!(local.pixels = malloc(m_getScreenWidth()*m_getScreenHeight()*4*sizeof(unsigned int))))
	{
		return -1;
	}
	
	glGenTextures(1, &(local.texture));
	glBindTexture(GL_TEXTURE_2D, local.texture);
	glTexImage2D(GL_TEXTURE_2D,0,4,
					(GLfloat) m_getScreenWidth(), (GLfloat) m_getScreenHeight(),
					0, GL_RGB,GL_UNSIGNED_INT, local.pixels);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	free(local.pixels);
	local.pixels = NULL;
	
	if(glGetError() != GL_NO_ERROR)
		return -1;
	
	return 0;
}

void blr_do()
{
	local.counter = 0.01;
	local.alpha = 0.6;
	
	if(!m_getMoveExplosion())
	{
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, local.texture);
		GL_CHECKERROR;
		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 
				(GLfloat) m_getScreenWidth(), (GLfloat) m_getScreenHeight(), 0);
	}
}

/**
 * get copy of viewport-buffer
 */
void blr_process()
{
	
	
	if(local.counter > 0)
	{

		if(m_getMoveExplosion())
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, local.texture);
			GL_CHECKERROR;
			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 
					(GLfloat) m_getScreenWidth(), (GLfloat) m_getScreenHeight(), 0);
		}
		
	
		/* for alpha-blending */
		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
		GL_CHECKERROR;
		glEnable(GL_BLEND);
		GL_CHECKERROR;
		
		/* change projection */
		glMatrixMode(GL_PROJECTION);			// Select Projection
		glPushMatrix();							// Push The Matrix
		glLoadIdentity();						// Reset The Matrix
		glOrtho(0, 1, 1, 0, -1, 1);
		glMatrixMode(GL_MODELVIEW);				// Select Modelview Matrix
		glPushMatrix();							// Push The Matrix
		glLoadIdentity();						// Reset The Matrix
		

		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, local.texture);
		glDisable(GL_LIGHTING);
	
		glBegin(GL_QUADS);
			
			glColor4f(1,1,1,local.alpha);
			
			glTexCoord2f(0,0);
			glVertex3f(-local.counter,-local.counter,-1);
		
			glTexCoord2f(1,0);
			glVertex3f(1+local.counter, -local.counter,-1);
		
			glTexCoord2f(1,-1);
			glVertex3f(1+local.counter,1+local.counter,-1);
		
			glTexCoord2f(0,-1);
			glVertex3f(-local.counter,1+local.counter,-1);
			
		
		glEnd();
		GL_CHECKERROR;
		
		
		glDisable(GL_BLEND);
		GL_CHECKERROR;
		
		/* reset projection */
		glMatrixMode( GL_PROJECTION );			// Select Projection
		glPopMatrix();							// Pop The Matrix
		glMatrixMode( GL_MODELVIEW );			// Select Modelview
		glPopMatrix();	
		
		/* adjust counter */
		local.counter += 0.002;
		local.alpha -= 0.01;
		
		if(local.counter >= 0.15)
		{
			local.counter = -1;
			local.alpha = 0;
		}
	}
}
