#include "ParticleDrawer.h"
#include <math.h>


#include "MemoryManager/DebugNew.h"


using namespace ParticleSystem;

ParticleDrawer::ParticleDrawer(void)
{
	engine = new std::list<Engine>;
}

ParticleDrawer::~ParticleDrawer(void)
{
	delete engine;
}

void ParticleDrawer::addManager(ParticleManager * manager)
{
	for (manager->startIteration();!manager->iterationFinished(); manager->next())
	{
		addEngine(&manager->current());
	}
}

void ParticleDrawer::addEngine(ParticleEngine * e)
{
	Engine en;
	en.engine = e;
	// calcule de la distance a la camera
	const float * cPos = ParticleEngine::getCameraPos();
	const float * ePos = e->getGenerator()->pos;
	// optimisation du calcule de la distance...
	// pour plus de detail sur cette optimisation, voir le commentaire dans ParticleEngine::draw()
	/*en.distance = sqrt(	(ePos[0] - cPos[0])*(ePos[0] - cPos[0]) + 
							(ePos[1] - cPos[1])*(ePos[1] - cPos[1]) + 
							(ePos[2] - cPos[2])*(ePos[2] - cPos[2]));*/
	static float vect[3];
	vect[0] = (ePos[0]-cPos[0]);
	vect[1] = (ePos[1]-cPos[1]);
	vect[2] = (ePos[2]-cPos[2]);
	en.distance = vect[0]*vect[0] + vect[1]*vect[1] * vect[2]*vect[2];
	// puis on l'insert dans la liste.
	// recherche sequentielle car on utilise une liste...
	// TODO faire un benchmarking avec un vector pour voir si on perd ou gagne de la vitesse.
	std::list<Engine>::iterator it;
	for (it = engine->begin();it != engine->end();it++)
	{
		if (it->distance < en.distance)
		{
			break;
		}
	}
	engine->insert(it,en);
	startIteration();
}

void ParticleDrawer::clear()
{
	engine->clear();
}

void ParticleDrawer::draw()
{
	for (std::list<Engine>::iterator it = engine->begin(); it != engine->end(); it++)
	{
		it->engine->draw();
	}
}

void ParticleDrawer::startIteration()
{
	iterator = engine->begin();
}

bool ParticleDrawer::iterationFinished()
{
	return (iterator == engine->end());
}

ParticleEngine & ParticleDrawer::current()
{
	return *(iterator->engine);
}

void ParticleDrawer::next()
{
	if (!iterationFinished())
	{
		iterator++;
	}
}

