module gedo.video.particle;



public import gedo.math.vector;
public import gedo.video.ggl;
public import gedo.video.color;
public import gedo.video.texture;



public class ParticleEmitter
{
public:
	this(Texture t, float s, GGL_BlendMode blend, int life, int count, Vector force)
	{
		_texture = t;
		_size    = s;
		_force[] = force[];
		_life    = life;
		_blend   = blend;

		_particles.length = count;
		foreach(inout particle; _particles)
		{
			particle = new Particle();
		}

		_count = 0;
	}


	void add(Vector position, Vector velocity)
	{
		foreach(particle; _particles)
		{
			if(particle.isStoped)
			{
				particle.start(position, velocity, _life);

				++_count;
				return;
			}
		}
	}


	void update()
	{
		foreach(particle; _particles)
		{
			particle.update(_force);
		}
	}


	void draw()
	{
		GGL_setBlendMode(_blend);

		foreach(particle; _particles)
		{
			particle.draw(_texture, _size, _life);
		}
	}


	bool isRunning()
	{
		foreach(particle; _particles)
		{
			if(!particle.isStoped)
			{
				return true;
			}
		}

		return false;
	}


	int count()
	{
		return _count;
	}


private:
	GGL_BlendMode _blend;
	Particle[]    _particles;
	Texture       _texture;
	Vector        _force;
	float         _size;
	int           _life;
	int           _count;
}



private class Particle
{
public:
	bool isStoped()
	{
		return (_life == 0);
	}


	void start(Vector p, Vector v, int l)
	{
		_position[] = p[];
		_velocity[] = v[];
		_life       = l;
	}


	void update(Vector force)
	{
		if(_life > 0)
		{
			--_life;

			.gedo.math.vector.add(_velocity, force);
			.gedo.math.vector.add(_position, _velocity);
		}
	}


	void draw(Texture t, float size, int l)
	{
		if(_life > 0)
		{
			GGL_pushMatrix();
			scope(exit)
			{
				GGL_popMatrix();
			}

			translate(_position);

			GGL_enterBillBoardMode();

			auto k = cast(double)(l - _life) / l;
			t.draw(size, size, rgba(255, 255, 255, cast(int)(255.0*(1.0 - k*k))));
			//size *= 1.0 - k*k;
			//t.draw(size, size, WHITE);
		}
	}


private:
	Vector _position;
	Vector _velocity;
	int    _life;
}
