#pragma once

class CParticle;

enum tParticleType
{
	PARTICLE_SPARK = 0,
	PARTICLE_SPARK_SMALL,
	PARTICLE_WHEEL_DIRT,
	PARTICLE_WHEEL_WATER,
	PARTICLE_BLOOD,
	PARTICLE_BLOOD_SMALL,
	PARTICLE_BLOOD_SPURT,
	PARTICLE_DEBRIS,
	PARTICLE_DEBRIS2,
	PARTICLE_WATER,
	PARTICLE_FLAME,
	PARTICLE_FIREBALL,
	PARTICLE_GUNFLASH,
	PARTICLE_GUNFLASH_NOANIM,
	PARTICLE_GUNSMOKE,
	PARTICLE_GUNSMOKE2,
	PARTICLE_SMOKE,
	PARTICLE_SMOKE_SLOWMOTION,
	PARTICLE_GARAGEPAINT_SPRAY,
	PARTICLE_SHARD,
	PARTICLE_SPLASH,
	PARTICLE_CARFLAME,
	PARTICLE_STEAM,
	PARTICLE_STEAM2,
	PARTICLE_STEAM_NY,
	PARTICLE_STEAM_NY_SLOWMOTION,
	PARTICLE_ENGINE_STEAM,
	PARTICLE_RAINDROP,
	PARTICLE_RAINDROP_SMALL,
	PARTICLE_RAIN_SPLASH,
	PARTICLE_RAIN_SPLASH_BIGGROW,
	PARTICLE_RAIN_SPLASHUP,
	PARTICLE_WATERSPRAY,
	PARTICLE_EXPLOSION_MEDIUM,
	PARTICLE_EXPLOSION_LARGE,
	PARTICLE_EXPLOSION_MFAST,
	PARTICLE_EXPLOSION_LFAST,
	PARTICLE_CAR_SPLASH,
	PARTICLE_BOAT_SPLASH,
	PARTICLE_BOAT_THRUSTJET,
	PARTICLE_BOAT_WAKE,
	PARTICLE_WATER_HYDRANT,
	PARTICLE_WATER_CANNON,
	PARTICLE_EXTINGUISH_STEAM,
	PARTICLE_PED_SPLASH,
	PARTICLE_PEDFOOT_DUST,
	PARTICLE_HELI_DUST,
	PARTICLE_HELI_ATTACK,
	PARTICLE_ENGINE_SMOKE,
	PARTICLE_ENGINE_SMOKE2,
	PARTICLE_CARFLAME_SMOKE,
	PARTICLE_FIREBALL_SMOKE,
	PARTICLE_PAINT_SMOKE,
	PARTICLE_TREE_LEAVES,
	PARTICLE_CARCOLLISION_DUST,
	PARTICLE_CAR_DEBRIS,
	PARTICLE_HELI_DEBRIS,
	PARTICLE_EXHAUST_FUMES,
	PARTICLE_RUBBER_SMOKE,
	PARTICLE_BURNINGRUBBER_SMOKE,
	PARTICLE_BULLETHIT_SMOKE,
	PARTICLE_GUNSHELL_FIRST,
	PARTICLE_GUNSHELL,
	PARTICLE_GUNSHELL_BUMP1,
	PARTICLE_GUNSHELL_BUMP2,
	PARTICLE_TEST,
	PARTICLE_BIRD_FRONT,
	PARTICLE_RAINDROP_2D,
	
	MAX_PARTICLES,
	PARTICLE_FIRST = PARTICLE_SPARK,
	PARTICLE_LAST = PARTICLE_RAINDROP_2D
};

enum 
{
	ZCHECK_FIRST      = BIT(0),
	ZCHECK_STEP       = BIT(1),
	DRAW_OPAQUE       = BIT(2),
	SCREEN_TRAIL      = BIT(3),
	SPEED_TRAIL       = BIT(4),
	RAND_VERT_V       = BIT(5),
	CYCLE_ANIM        = BIT(6),
	DRAW_DARK         = BIT(7),
	VERT_TRAIL        = BIT(8),
	_FLAG9            = BIT(9),		// unused
	DRAWTOP2D         = BIT(10),
	CLIPOUT2D         = BIT(11),
	ZCHECK_BUMP       = BIT(12),
	ZCHECK_BUMP_FIRST = BIT(13)
};


struct tParticleSystemData
{
	tParticleType m_Type;
	Char          m_aName[20];
	Float         m_fCreateRange;
	Float         m_fDefaultInitialRadius;
	Float         m_fExpansionRate;
	UInt16        m_nZRotationInitialAngle;
	Int16         m_nZRotationAngleChangeAmount;
	UInt16        m_nZRotationChangeTime;
	UInt16        m_nZRadiusChangeTime;
	Float         m_fInitialZRadius;
	Float         m_fZRadiusChangeAmount;
	UInt16        m_nFadeToBlackTime;
	Int16         m_nFadeToBlackAmount;
	UInt8         m_nFadeToBlackInitialIntensity;
	UInt8         m_nFadeAlphaInitialIntensity;
	UInt16        m_nFadeAlphaTime;
	Int16         m_nFadeAlphaAmount;
	UInt16        m_nStartAnimationFrame;
	UInt16        m_nFinalAnimationFrame;
	UInt16        m_nAnimationSpeed;
	UInt16        m_nRotationSpeed;
	char _pad1[2];
	Float         m_fGravitationalAcceleration;
	Int32         m_nFrictionDecceleration;
	Int32         m_nLifeSpan;
	Float         m_fPositionRandomError;
	Float         m_fVelocityRandomError;
	Float         m_fExpansionRateError;
	Int32         m_nRotationRateError;
	UInt32        m_nLifeSpanErrorShape;
	Float         m_fTrailLengthMultiplier;
	UInt32        Flags;
	RwRGBA        m_RenderColouring;
	UInt8         m_InitialColorVariation;
	RwRGBA        m_FadeDestinationColor;
	char _pad2[3];
	UInt32        m_ColorFadeTime;
	
	RwRaster      **m_ppRaster;
	CParticle     *m_pParticles;
};
VALIDATE_SIZE(tParticleSystemData, 0x88);


class cParticleSystemMgr
{
	enum
	{
		CFG_PARAM_PARTICLE_TYPE_NAME = 0,
		CFG_PARAM_RENDER_COLOURING_R,
		CFG_PARAM_RENDER_COLOURING_G,
		CFG_PARAM_RENDER_COLOURING_B,
		CFG_PARAM_INITIAL_COLOR_VARIATION,
		CFG_PARAM_FADE_DESTINATION_COLOR_R,
		CFG_PARAM_FADE_DESTINATION_COLOR_G,
		CFG_PARAM_FADE_DESTINATION_COLOR_B,
		CFG_PARAM_COLOR_FADE_TIME,
		CFG_PARAM_DEFAULT_INITIAL_RADIUS,
		CFG_PARAM_EXPANSION_RATE,
		CFG_PARAM_INITIAL_INTENSITY,
		CFG_PARAM_FADE_TIME,
		CFG_PARAM_FADE_AMOUNT,
		CFG_PARAM_INITIAL_ALPHA_INTENSITY,
		CFG_PARAM_FADE_ALPHA_TIME,
		CFG_PARAM_FADE_ALPHA_AMOUNT,
		CFG_PARAM_INITIAL_ANGLE,
		CFG_PARAM_CHANGE_TIME,
		CFG_PARAM_ANGLE_CHANGE_AMOUNT,
		CFG_PARAM_INITIAL_Z_RADIUS,
		CFG_PARAM_Z_RADIUS_CHANGE_TIME,
		CFG_PARAM_Z_RADIUS_CHANGE_AMOUNT,
		CFG_PARAM_ANIMATION_SPEED,
		CFG_PARAM_START_ANIMATION_FRAME,
		CFG_PARAM_FINAL_ANIMATION_FRAME,
		CFG_PARAM_ROTATION_SPEED,
		CFG_PARAM_GRAVITATIONAL_ACCELERATION,
		CFG_PARAM_FRICTION_DECCELERATION,
		CFG_PARAM_LIFE_SPAN,
		CFG_PARAM_POSITION_RANDOM_ERROR,
		CFG_PARAM_VELOCITY_RANDOM_ERROR,
		CFG_PARAM_EXPANSION_RATE_ERROR,
		CFG_PARAM_ROTATION_RATE_ERROR,
		CFG_PARAM_LIFE_SPAN_ERROR_SHAPE,
		CFG_PARAM_TRAIL_LENGTH_MULTIPLIER,
		CFG_PARAM_PARTICLE_CREATE_RANGE,
		CFG_PARAM_FLAGS,

		MAX_CFG_PARAMS,
		CFG_PARAM_FIRST = CFG_PARAM_PARTICLE_TYPE_NAME,
		CFG_PARAM_LAST = CFG_PARAM_FLAGS
	};

public:
	tParticleSystemData m_aParticles[MAX_PARTICLES];

	cParticleSystemMgr() { ctor(); } void ctor();
	
	void Initialise();
	void LoadParticleData();
	//void RangeCheck(tParticleSystemData *pData);
};

VALIDATE_SIZE(cParticleSystemMgr, 0x2420);

extern cParticleSystemMgr mod_ParticleSystemManager;