#define NO_SDL_GLEXT

#include <GL/glew.h>
#include <SDL/SDL_OpenGL.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <math.h>

#include "demo_script.h"
#include "demo_textures.h"
#include "demo_meshes.h"
#include "demo_shaders.h"
#include "demo_screen.h"

#include "math_vector3D.h"

#include "part_fire.h"

GLuint bufferTexture[2];
mesh3D_gen *object1;

bool fire_init = false;

int programm3 = PR_FIRE;

unsigned int frameselect = 0;

GLfloat LightAmbient1[]= { 0.0f, 1.0f, 0.5f, 1.0f };
GLfloat LightDiffuse1[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition1[]= { 0.0f, 0.0f, -32.0f, 1.0f };

GLfloat LightAmbient2[]= { 1.0f, 0.5f, 0.25f, 1.0f };
GLfloat LightDiffuse2[]= { 1.0f, 1.0f, 0.5f, 1.0f };
GLfloat LightPosition2[]= { 0.0f, 0.0f, 32.0f, 1.0f };

void fire_precalcs()
{
	glActiveTextureARB(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_1D);

	for (int i=0; i<2; i++)
	{
		bufferTexture[i] = GenTexture(ScreenWidth, ScreenHeight, GEN_EMPTY, 2);
		glBindTexture(GL_TEXTURE_2D, bufferTexture[i]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	}

	object1 = GenMesh(128, 128, GEN_FLOWER_MESH, 6.0f, 8.0f, 6.0f);

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    fire_init = true;
}

void DrawTest3()
{
	glEnable(GL_LIGHTING);

	quad2D *q = object1->quads;
	point3D *v = object1->points;
	vector3D *n = object1->vx_normals;

	int isize = object1->npls_x * object1->npls_y;


	glBegin(GL_QUADS);

	for (int i=0; i<isize; i++)
	{
		int p1 = q->p1; int p2 = q->p2; int p3 = q->p3;	int p4 = q->p4;
		glNormal3f(n[p1].x, n[p1].y, n[p1].z);	glVertex3f(v[p1].x, v[p1].y, v[p1].z);
		glNormal3f(n[p2].x, n[p2].y, n[p2].z);	glVertex3f(v[p2].x, v[p2].y, v[p2].z);
		glNormal3f(n[p3].x, n[p3].y, n[p3].z);	glVertex3f(v[p3].x, v[p3].y, v[p3].z);
		glNormal3f(n[p4].x, n[p4].y, n[p4].z);	glVertex3f(v[p4].x, v[p4].y, v[p4].z);
		q++;
	}

	glEnd();
}

void DrawQuad3(float l)
{
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f); glVertex2f(-l, -l);
		glTexCoord2f(1.0f, 0.0f); glVertex2f( l, -l);
		glTexCoord2f(1.0f, 1.0f); glVertex2f( l, l);
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-l, l);
	glEnd();
}

#define shite -2.415f

void DrawFire(int ptime, int bufnum)
{
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);

	glActiveTextureARB(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_1D);

	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse1);
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition1);
	glEnable(GL_LIGHT1);

	glLightfv(GL_LIGHT2, GL_AMBIENT, LightAmbient2);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDiffuse2);
	glLightfv(GL_LIGHT2, GL_POSITION,LightPosition2);
	glEnable(GL_LIGHT2);

	glShadeModel(GL_SMOOTH);

	glBindTexture(GL_TEXTURE_2D, bufferTexture[bufnum]);
	MyUseProgram(programm3);

	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, shite * 16.0f);
	DrawQuad3(16.0f);

	NotUseProgram();

	float px = sin((float)ptime / 768.0f) * 12.0f;
	float py = sin((float)ptime / 512.0f) * 10.0f;

	float rr = (float)(rand() / 32768.0f);
	float rg = (float)(rand() / 32768.0f);
	float rb = (float)(rand() / 32768.0f);

	glLoadIdentity();
	glTranslatef(px, py, shite * 16.0f);
	glRotatef(1.5f*px*py, 1.0f, 0.0f, 0.0f);
	glRotatef(1.0f*px*py, 0.0f, 1.0f, 0.0f);
	glRotatef(0.5f*px*py, 0.0f, 0.0f, 1.0f);

	glColor3f(rr, rg, rb);
	glDisable(GL_TEXTURE_2D);
	glColor3f(1.0f, 1.0f, 1.0f);
	DrawTest3();

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, bufferTexture[(bufnum+1) & 1]);
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, ScreenWidth, ScreenHeight, 0);
}

void fire_run(int ptime)
{
	if (!fire_init) fire_precalcs();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	DrawFire(ptime, frameselect);

	frameselect = (frameselect + 1) & 1;
}
