#ifndef FLAMETHROWERSYSTEM
#define FLAMETHROWERPARTICLESYSTEM
#include "particlesystem.h"
#include "util_vector.h"
#include "velocityparticle.h"
#include "cl_util.h"
#include "const.h"
#include "pm_shared.h"
#include "pmtrace.h"
#include "pm_defs.h"
#include "event_api.h"
#include "../common/particletypes.h"
#define NUMBER_OF_FLAME_PARTICLES 800

template <class TParticle> class TFlameThrowerParticleSystem:public TParticleSystem<TParticle>
{
public:	
	TFlameThrowerParticleSystem(int ent, int type, int radius, HSPRITE sprite):TParticleSystem<TParticle>(ent,type)
	{	m_iRadius = radius;
		m_fRemove = false;

		vec3_t vecStart,vecForward,vecRight,vecUp;
		cl_entity_t *pClient;
		pClient = gEngfuncs.GetEntityByIndex(m_iId);
		vecStart = pClient->origin;
		vec3_t vecAngles = pClient->curstate.angles;
		AngleVectors(vecAngles,vecForward,vecRight,vecUp);		
		
		m_hsprSprite = sprite;
		for (int i=0;i<NUMBER_OF_FLAME_PARTICLES;i++)
		{	TParticle p(m_hsprSprite);
			SetupParticle(p,vecStart,vecForward,vecRight,vecUp);
			particles.push_back(p);
		}
	}

	/**
	 * Updates the physics for all particles in the system
	 * @param timeDiff time difference since last draw
	 */	 
	virtual void think(float time)
	{
		vec3_t vecStart,vecForward,vecRight,vecUp;
		cl_entity_t *pClient;
		pClient = gEngfuncs.GetEntityByIndex(m_iId);
		vecStart = pClient->origin;
		vec3_t vecAngles = pClient->curstate.angles;
		vecAngles.x = vecAngles.x+180;
		vecAngles.y = vecAngles.y+180;
		AngleVectors(vecAngles,vecForward,vecRight,vecUp);
		
		vector<TParticle>::iterator b = particles.begin();
 		while (b != particles.end())
 		{
  			/*
			float flDist = (b->position - b->startPosition).Length();
			if( flDist>m_iRadius)
			{	SetupParticle(*b,vecStart,vecForward,vecRight,vecUp);
			}
			*/
			if((time-b->m_flStartTime)>b->duration)
			{	SetupParticle(*b,vecStart,vecForward,vecRight,vecUp);
			}			
			float flRatio = (time-b->m_flStartTime)/b->duration;
			b->m_flSize = flRatio*10+5; 
			
			b->color.x = b->startColor.x - b->startColor.x*flRatio;
			b->color.y = b->startColor.y - b->startColor.y*flRatio;
			b->color.z = b->startColor.z - b->startColor.z*flRatio;
			
			b->doThink(time);			
   			b++;			
   		}		
 	}
	
	void setRadius(int radius)
	{	m_iRadius = radius;
	}
private:
	void SetupParticle(TParticle &p,vec3_t vecStart,vec3_t vecForward,vec3_t vecRight,vec3_t vecUp)
	{	/*
		vec3_t vecDir = vecForward;
		
		vec3_t vecSide = gEngfuncs.pfnRandomFloat(-1,1)*vecRight;
		vecSide =vecSide + gEngfuncs.pfnRandomFloat(-1,1) *vecUp;
        VectorNormalize(vecSide);        
		float width = gEngfuncs.pfnRandomFloat(0,atan(FLAMETHROWER_ANGLE));
		vecDir = vecDir + vecSide * width;

		VectorNormalize(vecDir);
		//vecStart = vecStart + gEngfuncs.pfnRandomFloat( 0, m_iRadius ) * vecDir;
		
		p.color.x = p.startColor.x = 1.0-0.2*width/atan(FLAMETHROWER_ANGLE);
		p.color.y = p.startColor.y = 1.0-0.2*width/atan(FLAMETHROWER_ANGLE);
		p.color.z = p.startColor.z = 1.0- pow(width/atan(FLAMETHROWER_ANGLE),0.4);
		
		vec3_t vecStartPos = vecStart;//+vecDir*gEngfuncs.pfnRandomFloat(0, m_iRadius);
		p.position = vecStartPos;
		p.startPosition = vecStartPos;
		float flSpeed = gEngfuncs.pfnRandomFloat(100, 200);
		p.velocity = vecDir * flSpeed;		
		p.m_flSize = 5;
		*/
		
		//TEST
		p.position = vecStart;
		p.startPosition = vecStart;
		float flSpeed = gEngfuncs.pfnRandomFloat(100, 200);
		p.m_flSize = 5;

		float flStartAngle = gEngfuncs.pfnRandomFloat(0,FLAMETHROWER_ANGLE);
		p.color.x = p.startColor.x = 1.0;
		p.color.y = p.startColor.y = 1.0;
		p.color.z = p.startColor.z = 1.0 - pow(flStartAngle/FLAMETHROWER_ANGLE,1);

		float flSideSpeed = sin(flStartAngle)*flSpeed;	
		float flForwardSpeed = cos(flStartAngle)*flSpeed;	
		p.sideVelocity = vecRight*gEngfuncs.pfnRandomFloat(-1,1)+vecUp*gEngfuncs.pfnRandomFloat(-1,1);
		p.sideVelocity = p.sideVelocity.Normalize() * flSideSpeed;

		//calculate acceleration
		float flHalfDuration = ((float)m_iRadius*0.7)/flForwardSpeed;
		p.acceleration = p.sideVelocity/flHalfDuration;

		p.forwardVelocity = vecForward*flForwardSpeed;
		p.velocity = p.forwardVelocity + p.sideVelocity;			

		p.duration = flHalfDuration/0.7;

		p.m_flStartTime = gEngfuncs.GetClientTime();
	}

	int m_iRadius;
	HSPRITE m_hsprSprite;
};
#endif