//============================================================
// Program:		CGFParticleSystem
// Description:	Simple Particle Engine
// Author:		Benjamin Gottemoller
// Website:		http://www.particlefield.com
// Date:		who knows
// Legal:		Licensed under the gnu GPL (see gpl.txt for details)
//============================================================

#ifndef _CGF_PARTICLE_SYSTEM_
#define _CGF_PARTICLE_SYSTEM_

#pragma warning(disable:4995)
#include <d3dx8.h>

class CGFCamera;
class GameFrame;
class CGFParticleSystem;

struct PARTICLE
{
	int 			IsActive;
	int				Identifier;
	int				Type;
	D3DXVECTOR3		Pos;
	D3DXVECTOR3		LastPos;
	D3DXVECTOR3		Velocity;
	float			Scale;
	float			ScaleDelta;
	D3DXCOLOR		Color;
	float			ColorDelta;	
	float			MaxLife;		//Seconds to live
	float			Age;			//Age in seconds
};

struct PARTICLE_TYPE
{
	int		ObjLibIndex;
	int		IsAlphaActive;
	int		IsColorActive;
	int		IsBillboardingActive;

	float	Yaw, Pitch, Roll;			//Added to camera's Y,P,R if billboarding is on
	float	Extra1, Extra2, Extra3;		//For use by any modifiers 

	void (* full_modifier)(PARTICLE_TYPE *type, GameFrame *gfparent);
	void (* single_modifier)(PARTICLE_TYPE *type, GameFrame *gfparent, PARTICLE *particle);
};

class CGFParticleSystem
{
public:

	CGFParticleSystem();
	~CGFParticleSystem();

	int Initialize(GameFrame *gfparent, int num_types, int num_particles);
	void SetCamera(CGFCamera *camera)	{ Camera = camera; }
	void Destroy(void);

	int AddParticleType(PARTICLE_TYPE *type);

	//Particle Identifiers 0 to 999 are not checked for collisions
	//Particle Identifiers greater than 999 represent weapons
	int	AddParticle(int identifier, int type, float x, float y, float z, float xv, float yv, float zv, 
					float scale, float scale_delta, D3DXCOLOR color, float color_delta, float max_life);

	void KillParticles(void);			//Kill all the sparks
	void KillParticle(int index);		//Kill a spark at a given index in the spark array

	void Update(void);					
	void Render(void);					

	inline int GetNumActive(void)		{ return NumParticlesActive; }
	inline int GetNumParticles(void)	{ return NumParticles; }

private:
	
	GameFrame			*GFParent;
	CGFCamera			*Camera;

	int					NumTypes;
	int					NumTypesUsed;
	PARTICLE_TYPE		*Types;

	int					NumParticles;
	int					NumParticlesActive;
	PARTICLE			*Particles;
};

/*****************Modifier Prototypes*****************************************/
void YawSpinModifier(PARTICLE_TYPE *type, GameFrame *gfparent);
void PitchSpinModifier(PARTICLE_TYPE *type, GameFrame *gfparent);
void RollSpinModifier(PARTICLE_TYPE *type, GameFrame *gfparent);
/*****************************************************************************/

#endif