#ifdef _DEBUG
	#include <stdlib.h>
	#include "../mmgr.h"
#endif

#include <math.h>

#include "jakautuminen.hpp"
#include "../mathematics.hpp"
#include "../primitives.hpp"


// --------------------------------------------------
// Global shitee to hack things up faster
float SplitEffectTime;

// --------------------------------------------------
// Particles
void SplitMother::draw(float time)
{
	if(time>=0.99999f) return;

	glColor4f(1,1,1, 1-Mathematics::calcPosFloat(time, 0.9f, 1.0f));
	Vector p = pos + spd*time;
	p.x += 0.2f* sinf(SplitEffectTime*6.0f*this->randomFactor);
	Primitives::drawBillboard(p, 0.3f);

}

void SplitParticle::draw(float time)
{
	Vector p = pos + spd*time*(0.5f+randomFactor);
	p.z += 0.2f*sinf(SplitEffectTime*6.0f*this->randomFactor);
	p.y += 0.2f*cosf(SplitEffectTime*6.0f*this->randomFactor);
	p.x += 0.2f*cosf(SplitEffectTime*6.0f*(1-this->randomFactor));
	Primitives::drawBillboard(p, 0.13f);
}

// --------------------------------------------------
// Effect
void Jakautuminen::draw()
{
	const float pos = (time - startTime) / (endTime - startTime);
	float alpha = 1.0f;

	const float fadeinstart = 0.0f;
	const float fadeinstop = 0.1f;
	const float fadeoutstart = 0.90f;
	const float fadeoutstop = 1.0f;

	if (pos >= fadeinstart && pos <= fadeinstop)
		alpha *= (pos-fadeinstart) / (fadeinstop-fadeinstart);
	if (pos >= fadeoutstart && pos <= fadeoutstop)
		alpha *= 1-(pos-fadeoutstart) / (fadeoutstop-fadeoutstart);

	renderScene(pos, alpha);
}

void Jakautuminen::renderScene(float pos, float alpha)
{
    Vector3 cam = Vector3(0, 0, -7);
    Vector3 tgt = Vector3(0, 0, 0);
    Vector3 upw = Vector3(0, 1, 0);

    glLoadIdentity();
    gluLookAt(cam.x, cam.y, cam.z, tgt.x, tgt.y, tgt.z, upw.x, upw.y, upw.z);

	SplitEffectTime = pos;

	glEnable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glDisable(GL_DEPTH_TEST);
    glBindTexture(GL_TEXTURE_2D, dmsGetTexture("purpleparticle.jpg")->getID());
    glColor4f(1,1,1, alpha);

	int i;
	for(i=0; i<motherCount; i++)
	{
		mothers[i].draw(Mathematics::calcPosFloat(pos, 0, 0.4f));
	}
	

	glBindTexture(GL_TEXTURE_2D, dmsGetTexture("fireparticle.jpg")->getID());

	if(pos > 0.4f)
	{
		for(i=0; i<particleCount; i++)
		{
			particles[i].draw(Mathematics::calcPosFloat(pos, 0.4f, 1.0f));
		}
	}

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, dmsGetTexture("flash.png")->getID());

	if(pos>0.4f)
		{
		const float fade = powf( (1-Mathematics::calcPosFloat(pos, 0.40f, 0.436f)), 5);
		glColor4f(104/255.0f, 79/255.0f, 148/255.0f, fade);
		glRotatef(pos*3500, 1,1,1);
		glDisable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);
		glDepthMask(0);

		dmsPerspective2D(1,1);
		glLoadIdentity();

		float x0 = 0+fade*0.25f;
		float x1 = 1-fade*0.25f;
		float y0 = 1-fade*0.25f;
		float y1 = 0+fade*0.25f;

		glBegin(GL_QUADS);

		glTexCoord2f(x0, y0);
		glVertex2f(0, 0);
		glTexCoord2f(x1, y0);
		glVertex2f(1, 0);
		glTexCoord2f(x1, y1);
		glVertex2f(1, 1);
		glTexCoord2f(x0, y1);
		glVertex2f(0, 1);

		glEnd();

		glDepthMask(1);
		dmsPerspective3D();
		glLoadIdentity();
	}
}


Jakautuminen::Jakautuminen()
{	
}

Jakautuminen::~Jakautuminen()
{
	delete [] mothers;
	delete [] particles;
}


bool Jakautuminen::init(unsigned long s, unsigned long e)
{
	int i;

	motherCount = 3;
	mothers = new SplitMother[motherCount];

	for(i=0; i<motherCount; i++)
	{
		mothers[i].pos = Mathematics::randVectSphere()*4;
		mothers[i].spd = mothers[i].pos *  -1;
		mothers[i].randomFactor = Mathematics::randFloat();
	}


	particleCount = motherCount*250;
	particles = new SplitParticle[particleCount];


	for(i=0; i<particleCount; i++)
	{
		particles[i].pos = Vector();
		particles[i].spd = Mathematics::randVectSphere()*25.0f;
		particles[i].randomFactor = Mathematics::randFloat();
	}



	startTime = s;
	endTime = e;
	return true;
}

