// Author : Chris Tolley
// Date   : 8/10/2004
// ParticleSystem.cpp contains the class definition for a particle system to
// use with the Survival game

#include <windows.h>
#include <gl/gl.h>
#include <vector>
#include <stack>

using namespace std;

#include "ParticleSystem.h"

// Some constants to help us out
// The basic unit of time
const double		TIME_UNIT	= .09;

// Constructor
ParticleSystem::ParticleSystem()
{}


// Destructor
ParticleSystem::~ParticleSystem()
{}


// Updates all the particles stored in this system
void ParticleSystem::Update( float elapsedSec )
{
	// Create a place to store particles that have to die
	stack< int > dltList;

	// For each particle
	for( int n = 0; n < m_vParticles.size(); ++n )
	{
		// Add the elapsedSec to the particles age
		m_vParticles[n].Age_ += elapsedSec;

		// If it is time for this particle to die
		if( m_vParticles[n].Age_ >= m_vParticles[n].MaxAge_ )
		{
			// Add that particle to the delete list
			dltList.push( n );
		}// End if
		else
		{
			// Other wise move the particle through space
			m_vParticles[n].Position_[0] += 
				( elapsedSec * m_vParticles[n].Direction_[0] ) / TIME_UNIT;

			m_vParticles[n].Position_[1] += 
				( elapsedSec * m_vParticles[n].Direction_[1] ) / TIME_UNIT;

			m_vParticles[n].Position_[2] += 
				( elapsedSec * m_vParticles[n].Direction_[2] ) / TIME_UNIT;;
		}// End else
	}// End for n

	// While dltList is not empty
	while( ! dltList.empty() )
	{
		// Remove the particle indicated by the dltList
		m_vParticles.erase( m_vParticles.begin() + dltList.top() );

		// Pop the stack
		dltList.pop();
	}// End while
}// End ParticleSystem::Update


// Renders all the particles in this system
void ParticleSystem::Render()
{
	// Set the point size to 2
	glPointSize( 2 );

	// Enable point antialiasing
	glEnable( GL_POINT_SMOOTH );

	// Enable vertex arrays
	glEnableClientState( GL_COLOR_ARRAY );
	glEnableClientState( GL_VERTEX_ARRAY );

	// Set up the two arrays
	glColorPointer( 3, GL_FLOAT, sizeof( Particle ), &m_vParticles[0] );

	// Use arrayPointer to get the 12th byte of the first particle
	char* arrayPointer = reinterpret_cast< char* >( &m_vParticles[0] );
	glVertexPointer( 3, GL_FLOAT, sizeof( Particle ), &arrayPointer[12] );

	// Draw all the Particles
	glDrawArrays( GL_POINTS, 0, m_vParticles.size() );

	// Disable vertex arrays
	glDisableClientState( GL_COLOR_ARRAY );
	glDisableClientState( GL_VERTEX_ARRAY );

	// Disable point antialiasing
	glDisable( GL_POINT_SMOOTH );

	// Reset the color
	glColor3f( 1, 1, 1 );
	// Reset the point size to 1
	glPointSize( 1 );
}// End ParticleSystem::Render