//Copyright (C) 2007 SiegeLord
//See ReadMe.txt and License.txt for copying information

#include "explosion.h"
#include "objectex.h"
#include "particles.h"
#include "sounds.h"

extern SObjectEx* g_obRootObject;

struct SExplosion : SParticleHolder
{
	SExplosion()
	{
		type = explosionparticle_type;
		active = false;
	}

	SExplosion(int num_parts) :
	SParticleHolder(num_parts)
	{
		type = explosionparticle_type;
		active = false;
	}

	zColor color;
	bool active;
	float dampening;
	float max_speed;
	float max_life;

	virtual int Handle()
	{
		if(active)
		{
			FOR1(num_particles)
			{
				SParticle* part = &(particles[ii]);
				if(part->life > 0)
				{
					part->life -= g_fDelta;

					part->velocity *= powf(dampening, g_fDelta);

					part->position = part->position + part->velocity * g_fDelta;
				}

				float factor = part->life / max_life;
				if(factor < 0)
					factor = 0;

				factor = 1 - factor;

				part->color = BlendColors(color, 0x00000000, factor);
			}
			UpdateBuffers();
			if(num_alive_particles == 0)
				active = false;
		}
		return 0;
	}
	virtual void Draw()
	{
		if(num_alive_particles > 0)
		{
			DrawModeAdd();

			DrawQuadBuffer(bmp, num_alive_particles, vertices, tcoords, colors);

			DrawModeSolid();
		}
	}

	void Pulse(float strength)
	{
		active = true;
		const int num_to_activate = (unsigned int)(num_particles * strength);
		FOR1(num_to_activate)
		{
			SParticle* part = &(particles[ii]);
			part->life = max_life * strength;
			part->position = position;
			float rand_dir = Rand(0, 2 * AL_PI);
			float rand_speed = Rand() * max_speed;
			part->velocity.x = rand_speed * cosf(rand_dir);
			part->velocity.y = rand_speed * sinf(rand_dir);
		}
	}
};

unsigned int g_nMaxNumExplosions = 40;

list<SExplosion*> g_lstExplosions;

void InitExplosionBuffers()
{
	SBitmap* bmp = FindBitmap("part.tga");
	const int size = g_nMaxNumExplosions;
	FOR1(size)
	{
		SExplosion* expl = new SExplosion(150);
		InitParticleHolder(expl, g_obRootObject);
		expl->color = 0xff05afff;
		expl->dampening = 0.75;
		expl->CreateBuffers();
		expl->max_speed = 100.0f;
		expl->max_life = 1.0f;
		expl->bmp = bmp;
		expl->num_alive_particles = 0;
		g_lstExplosions.push_back(expl);
	}
}

void CreateExplosion(const vector2d& pos, float power, zColor color)
{
	float strength = power;
	SnapVar(strength, 0.0f, 1.0f);
	for(list<SExplosion*>::iterator it = g_lstExplosions.begin(); it != g_lstExplosions.end(); it++)
	{
		if(!(*it)->active)
		{
			(*it)->color = color;
			(*it)->SetPosition(pos.x, pos.y);
			(*it)->Pulse(strength);
			CreateExplosionSound(g_obRootObject, (*it));
			break;
		}
	}
}
