// -----------------------------------------------
// partmang.cpp
// -----------------------------------------------
// Particle manager, to control particles in the game
// Also, implementation of base particle
// ----------------------------------------------- 
// Developed By Kronoman - Copyright (c) 2004
// In loving memory of my father
// -----------------------------------------------

#include "partmang.h"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
// The base particle, a dot
// This particle must be used as base 
// for making other types of particles, using
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
CBaseParticle::CBaseParticle()
{
	x = 0.0;
	y = 0.0;
	dx = 0.0;
	dy = 0.0;
	color = 0;
	life = 0;
}

CBaseParticle::CBaseParticle(float x1, float y1, float dx1, float dy1, int color1, int life1)
{
	x = x1;
	y = y1;
	dx = dx1;
	dy = dy1;
	color = color1;
	life = life1;
}

CBaseParticle::~CBaseParticle()
{
	// nothing to be done here
}
// -----------------------------------------------
// updates particle's logic, 
// must return TRUE if particle is dead 
// (particle WILL be _deleted_ from memory 
// by manager if dead)
// -----------------------------------------------
bool CBaseParticle::update_logic(CParticleManager &particle_manager)
{
	// nothing to be done here, all that this particle needs is taken into account by manager :^D
	return false; // I'm not dead (the manager will take care of disccount my life)
}

// -----------------------------------------------
// renders particle on bmp, displaced by x,y
// -----------------------------------------------
void CBaseParticle::render_particle(BITMAP *bmp, int xd, int yd)
{
	putpixel(bmp, (int)x - xd, (int)y - yd, color);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
// The particle manager
// This handles a bunch of particles
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   
CParticleManager::CParticleManager()
{
	add_x = add_y = 0.0;
	add_dx = add_dy = 0.0;
}

CParticleManager::~CParticleManager()
{
	nuke_particle_list(); // our precious RAM needs freedom! Viva la revolucion de la RAM!
}

// -----------------------------------------------
// this will free all memory used by particles, 
// and particles itself.
// -----------------------------------------------
void CParticleManager::nuke_particle_list()
{
	list<CBaseParticle *>::iterator i = particle_list.begin(); // iterator for our linked list of particle pointers
	
	for (i = particle_list.begin(); i != particle_list.end(); i++)
		delete (*i); // delete object
	
	// clear the list
	particle_list.clear();
}

// -----------------------------------------------
// adds a particle to manager (the particle 
// WILL be nuked automatically when 
// the manager object gets deleted)
// -----------------------------------------------
void CParticleManager::add_particle(CBaseParticle *node)
{
	particle_list.push_back(node); 
}

// -----------------------------------------------
// updates logic of all particles
// -----------------------------------------------
void CParticleManager::update_logic()
{
	list<CBaseParticle *>::iterator i = particle_list.begin(); // iterator for our linked list of particle pointers
	
	while (i != particle_list.end())
	{	
		// apply wind, and gravity, and own movement of particle
		(*i)->dx += add_dx;
		(*i)->dy += add_dy;
		(*i)->x += add_x + (*i)->dx;
		(*i)->y += add_y + (*i)->dy;
		
		// decrease life of particle
		(*i)->life--;
		
		if ((*i)->update_logic(*this) || ((*i)->life < 0))
		{
			list<CBaseParticle *>::iterator i2 = i; 
			// particle is dead, erase it
			i++;
			delete (*i2);
			particle_list.erase(i2);
		}
		else
		{
			i++; // next
		}
	}

}

// -----------------------------------------------
// renders particles on bmp, displaced by x,y
// -----------------------------------------------
void CParticleManager::render(BITMAP *bmp, int x, int y)
{
	list<CBaseParticle *>::iterator i = particle_list.begin(); // iterator for our linked list of particle pointers
	
	for (i = particle_list.begin(); i != particle_list.end(); i++)
		(*i)->render_particle(bmp, x, y); // renders particle on bmp, displaced by x,y		
}

