#include "SmokeParticleSystem.h"

SmokeParticleSystem::SmokeParticleSystem(dReal posx, dReal posy, dReal posz, int size, 
										 bool continuous, std::string filename)
: BaseParticleSystem(posx, posy, posz, size, filename)
{
	isContinuous = continuous;

	force[0] = 6;
	force[1] = -5;
	force[2] = 4;

	for (int loop=0;loop<maxParticles;loop++)			// Initials All The Textures
	{
		particleList[loop].active=true;				// Make All The Particles Active
		particleList[loop].life=1.0f;				// Give All The Particles Full Life
		//particleList[loop].fade=float(rand()%100)/1000.0f+0.003f;	// Random Fade Speed
		particleList[loop].fade=(FRAND/7)+0.7;	// Random Fade Speed
		particleList[loop].x=position.x;		// X Position
		particleList[loop].y=position.y;		// Y Position
		particleList[loop].z=position.z;		// Z Position
		//particleList[loop].xi=float((rand()%50)-26.0f);//*10.0f;		// Random Speed On X Axis
		//particleList[loop].yi=float((rand()%50)-25.0f);//*10.0f;		// Random Speed On Y Axis
		//particleList[loop].zi=float((rand()%50)-25.0f);//*10.0f;		// Random Speed On Z Axis
		particleList[loop].xi=FRAND*magnitude/2;	// Random Speed On X Axis
		particleList[loop].yi=(FRAND+2)*8;	// Random Speed On Y Axis
		particleList[loop].zi=FRAND*magnitude/2;	// Random Speed On Z Axis
//		particle[loop].xg=0.0f;					// Set Horizontal Pull To Zero
//		particle[loop].yg=-0.0f;					// Set Vertical Pull Downward
//		particle[loop].zg=0.0f;					// Set Pull On Z Axis To Zero
		particleList[loop].r = 1.0;
		particleList[loop].g = 1.0;
		particleList[loop].b = 1.0;
	}
}

void SmokeParticleSystem::Draw(void)
{
	for (int loop=0;loop<maxParticles;loop++)				// Loop Through All The Particles
	{
		if (particleList[loop].active)					// If The Particle Is Active
		{
			glPushMatrix();
			
			if (usingTexture)
			{	
				float matAmbientAndDiffuse[4] = {particleList[loop].r, particleList[loop].g, 
					particleList[loop].b, particleList[loop].life};
				glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matAmbientAndDiffuse);

				glTranslatef(particleList[loop].x,particleList[loop].y,particleList[loop].z);

				GLfloat viewMatrix[16];
				glGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);

				// undo all rotations
				// beware all scaling is lost as well 
				for(int i=0; i<3; i++) 
				{
					for(int j=0; j<3; j++) 
					{
						if (i==j)
						{
							viewMatrix[i*4+j] = 1.0;
						}
						else
						{
							viewMatrix[i*4+j] = 0.0;
						}
					}
				}

				//set the modelview with no rotations and scaling
				glLoadMatrixf(viewMatrix);

				dReal scalingFactor = (dReal)magnitude*5;
				glScalef((2-particleList[loop].life)*scalingFactor,
					(2-particleList[loop].life)*scalingFactor, (2-particleList[loop].life)*scalingFactor);

				if (particleList[loop].life < 0.9)
				{
#ifdef USING_VRJUGGLER //using Juggler's special context-specific data types
					glCallList(*displayListID);
#else //using normal data types
					glCallList(displayListID);
#endif
				}
			}
			else
			{
				glColor4f(particleList[loop].r,particleList[loop].g,particleList[loop].b,particleList[loop].life);
				glPointSize(particleList[loop].life*4);
				glTranslatef(particleList[loop].x,particleList[loop].y,particleList[loop].z);
				glBegin(GL_POINTS);	
					glVertex3f(0, 0, 0);
				glEnd();
			}

			glPopMatrix();
		}
	}
}

bool SmokeParticleSystem::Update(dReal deltaTime)
{			
	bool particlesStillActive = false;

	for (int loop=0;loop<maxParticles;loop++)				// Loop Through All The Particles
	{	
		particleList[loop].x+=particleList[loop].xi*deltaTime;// Move On The X Axis By X Speed
		particleList[loop].y+=particleList[loop].yi*deltaTime;// Move On The Y Axis By Y Speed
		particleList[loop].z+=particleList[loop].zi*deltaTime;// Move On The Z Axis By Z Speed

		particleList[loop].xi+=force[0]*deltaTime;		// Take Pull On X Axis Into Account
		particleList[loop].yi+=force[1]*deltaTime;		// Take Pull On Y Axis Into Account
		particleList[loop].zi+=force[2]*deltaTime;		// Take Pull On Z Axis Into Account

		particleList[loop].life-=particleList[loop].fade*deltaTime;		// Reduce Particles Life By 'Fade'

		//if (particleList[loop].life <= 1.0 && particleList[loop].life > 0.75)
		//{
		//	particleList[loop].b = 4*(particleList[loop].life - 0.75);
		//}
		//else if (particleList[loop].life <= 0.75 && particleList[loop].life > 0.5)
		//{
		//	particleList[loop].g = 4*(particleList[loop].life - 0.5);
		//}
		//else if (particleList[loop].life <= 0.5 && particleList[loop].life > 0.0)
		//{
		//	particleList[loop].r = 0.9;
		//	particleList[loop].g = 0.9;
		//	particleList[loop].b = 0.9;
		//}

		if (isContinuous)
		{
			if (particleList[loop].life<0.0f || particleList[loop].y <= 0)	// If Particle Is Burned Out
			{
					particleList[loop].life=1.0f;				// Give It New Life
					particleList[loop].fade=(FRAND/7)+0.7;	// Random Fade Speed
					particleList[loop].x=position.x;		// X Position
					particleList[loop].y=position.y;		// Y Position
					particleList[loop].z=position.z;		// Z Position
					particleList[loop].xi=FRAND*magnitude/2;	// Random Speed On X Axis
					particleList[loop].yi=(FRAND+2)*8;	// Random Speed On Y Axis
					particleList[loop].zi=FRAND*magnitude/2;	// Random Speed On Z Axis

					//particleList[loop].fade=float(rand()%100)/1000.0f+0.003f;	// Random Fade Value
					//particleList[loop].x=0.0f;					// Center On X Axis
					//particleList[loop].y=0.0f;					// Center On Y Axis
					//particleList[loop].z=0.0f;					// Center On Z Axis
					//particleList[loop].xi=float((rand()%60)-32.0f);	// X Axis Speed And Direction
					//particleList[loop].yi=float((rand()%60)-30.0f);	// Y Axis Speed And Direction
					//particleList[loop].zi=float((rand()%60)-30.0f);		// Z Axis Speed And Direction
			}
			else
			{
				particlesStillActive = true;
			}
		}
		else //not continuous
		{
			if (particleList[loop].life<0.0f || particleList[loop].y <= 0)
			{
				particleList[loop].active = false;
			}
			else
			{
				particlesStillActive = true;
			}
		}
	}

	//return particlesStillActive;
	return true; //hack for the demo
}