#ifndef PARTICLESYSTEMC_H
#define PARTICLESYSTEMC_H

#include "PajaTypes.h"
#include "ColorC.h"
#include "ImportableI.h"
#include "FileIO.h"
#include "ScenegraphItemI.h"
#include "QuatC.h"
#include "Vector2C.h"
#include "Vector3C.h"
#include "ContVector3C.h"
#include "ContQuatC.h"
#include "ContBoolC.h"
#include "ContFloatC.h"
#include "ControllerC.h"
#include "MaterialC.h"
#include "WSMObjectC.h"

const PajaTypes::int32	CGITEM_PARTICLESYSTEM = 0x4000;


enum ParticleSystemTypeE {
	PARTICLE_RAIN,
	PARTICLE_SNOW,
	PARTICLE_FIRE,
};


class ParticleSystemC : public ScenegraphItemI
{
public:
	ParticleSystemC();
	virtual ~ParticleSystemC();

	virtual PajaTypes::int32			get_type();

	virtual void						set_position( const PajaTypes::Vector3C& rPos );
	virtual const PajaTypes::Vector3C&	get_position();

	virtual void						set_rotation( const PajaTypes::QuatC& rRot );
	virtual const PajaTypes::QuatC&		get_rotation();

	virtual void						eval_state( PajaTypes::int32 i32Time );
	virtual void						eval_geom( PajaTypes::int32 i32Time );

	virtual void						set_position_controller( ContVector3C* pCont );
	virtual ContVector3C*				get_position_controller();

	virtual void						set_rotation_controller( ContQuatC* pCont );
	virtual ContQuatC*					get_rotation_controller();

	virtual void						set_vis_controller( ContBoolC* pCont );
	virtual ContBoolC*					get_vis_controller();

	virtual bool						get_visible() const;

	virtual PajaTypes::float32			get_width() const;
	virtual void						set_width( PajaTypes::float32 f32Width );

	virtual PajaTypes::float32			get_height() const;
	virtual void						set_height( PajaTypes::float32 f32Height );

	virtual PajaTypes::uint32			get_particle_type() const;
	virtual void						set_particle_type( PajaTypes::uint32 ui32Type );

	virtual PajaTypes::uint32			get_particle_count();
	virtual PajaTypes::float32*			get_particle_position_ptr();
	virtual PajaTypes::float32*			get_particle_velocity_ptr();
	virtual PajaTypes::int32*			get_particle_age_ptr();

	virtual void						update_dependencies( std::vector<ScenegraphItemI*> rScenegraph );

	virtual void						set_step_size( PajaTypes::int32 i32Step );
	virtual PajaTypes::int32			get_step_size() const;

	virtual void						set_max_particle_count( PajaTypes::int32 i32Max );
	virtual PajaTypes::int32			get_max_particle_count() const;

	virtual void						set_drop_size( PajaTypes::float32 f32Size );
	virtual PajaTypes::float32			get_drop_size() const;

	virtual void						set_speed( PajaTypes::float32 f32Speed );
	virtual PajaTypes::float32			get_speed() const;

	virtual void						set_start_time( PajaTypes::int32 i32Time );
	virtual PajaTypes::int32			get_start_time() const;

	virtual void						set_life_time( PajaTypes::int32 i32Life );
	virtual PajaTypes::int32			get_life_time() const;

	virtual void						set_birth_rate( PajaTypes::float32 f32Rate );
	virtual PajaTypes::float32			get_birth_rate() const;

	virtual void						set_constant_birth_rate( bool bState );
	virtual bool						get_constant_birth_rate() const;

	virtual void						set_tumble_scale( PajaTypes::float32 f32Scale );
	virtual PajaTypes::float32			get_tumble_scale() const;

	virtual void						set_tumble( PajaTypes::float32 f32Val );
	virtual PajaTypes::float32			get_tumble() const;

	virtual void						set_variation( PajaTypes::float32 f32Val );
	virtual PajaTypes::float32			get_variation() const;

	virtual void						set_drop_size_cont( ContFloatC* pCont );
	virtual void						set_speed_cont( ContFloatC* pCont );
	virtual void						set_start_time_cont( ContFloatC* pCont );
	virtual void						set_life_time_cont( ContFloatC* pCont );
	virtual void						set_tumble_scale_cont( ContFloatC* pCont );
	virtual void						set_tumble_cont( ContFloatC* pCont );
	virtual void						set_variation_cont( ContFloatC* pCont );
	virtual void						set_birthrate_cont( ContFloatC* pCont );
	virtual void						set_width_cont( ContFloatC* pCont );
	virtual void						set_height_cont( ContFloatC* pCont );

	virtual	void						birth_particle( PajaTypes::int32 i32BT, PajaTypes::int32 index );
	virtual void						compute_particle_start( PajaTypes::int32 i32T0 );
	virtual PajaTypes::int32			count_live();

	virtual void						update_particles( PajaTypes::int32 i32T );
	virtual PajaTypes::int32			get_particle_life( PajaTypes::int32 i32T, PajaTypes::int32 i32Index );
	virtual PajaTypes::Vector3C			get_particle_position( PajaTypes::int32 i32T, PajaTypes::int32 i32Index );
	virtual PajaTypes::Vector3C			get_particle_velocity( PajaTypes::int32 i32T, PajaTypes::int32 i32Index );

	virtual void						add_ws_modifier( const char* szName );

	// material
	virtual void						set_texture( Import::FileHandleC* pHandle );
	virtual Import::FileHandleC*		get_texture() const;

	virtual void						set_color( const PajaTypes::ColorC &rDiffuse );
	virtual void						set_transparency( const PajaTypes::float32 f32Trans );
	virtual void						set_selfillum( const PajaTypes::float32 f32SelfIllum );
	virtual void						set_transparency_type( PajaTypes::uint32 ui32Type );

	virtual const PajaTypes::ColorC&	get_color() const;
	virtual PajaTypes::float32			get_transparency() const;
	virtual PajaTypes::float32			get_selfillum() const;
	virtual PajaTypes::uint32			get_transparency_type() const;


	virtual PajaTypes::uint32			save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32			load( FileIO::LoadC* pLoad );

private:

	void								kill_all_particles();


	struct WSModifierS {
		WSModifierS() : m_pObject( 0 ) {};
		std::string	m_sName;
		WSMObjectC*	m_pObject;
	};

	std::vector<WSModifierS>		m_rModifiers;
	std::vector<ForceFieldI*>		m_rForceFields;
	std::vector<CollisionObjectI*>	m_rCollisionObjs;

	std::vector<PajaTypes::float32>	m_rPartPositions;
	std::vector<PajaTypes::float32>	m_rPartVelocities;
	std::vector<PajaTypes::int32>	m_rPartAges;

	PajaTypes::int32	m_i32ValidTime;
	PajaTypes::int32	m_i32LastBirthTime;


	PajaTypes::uint32	m_ui32ParticleType;
	PajaTypes::Vector3C	m_rPosition;
	PajaTypes::QuatC	m_rRotation;
	bool				m_bVis;
	PajaTypes::int32	m_i32StepSize;
	PajaTypes::int32	m_i32MaxParticleCount;
	PajaTypes::float32	m_f32DropSize;
	PajaTypes::float32	m_f32Speed;
	PajaTypes::int32	m_i32StartTime;
	PajaTypes::int32	m_i32LifeTime;
	bool				m_bConstantBirth;
	PajaTypes::float32	m_f32TumbleScale;
	PajaTypes::float32	m_f32Tumble;
	PajaTypes::float32	m_f32Variation;
	PajaTypes::float32	m_f32BirthRate;
	PajaTypes::float32	m_f32Width;
	PajaTypes::float32	m_f32Height;

	ContVector3C*		m_pPosCont;
	ContQuatC*			m_pRotCont;
	ContBoolC*			m_pVisCont;
	ContFloatC*			m_pDropSizeCont;
	ContFloatC*			m_pSpeedCont;
	ContFloatC*			m_pStartTimeCont;
	ContFloatC*			m_pLifeTimeCont;
	ContFloatC*			m_pTumbleScaleCont;
	ContFloatC*			m_pTumbleCont;
	ContFloatC*			m_pVariationCont;
	ContFloatC*			m_pBirthRateCont;
	ContFloatC*			m_pWidthCont;
	ContFloatC*			m_pHeightCont;

	// material
	PajaTypes::ColorC		m_rColor;
	PajaTypes::float32		m_f32Transparency;
	PajaTypes::float32		m_f32SelfIllum;
	Import::FileHandleC*	m_pTextureHandle;
	PajaTypes::uint32		m_ui32TransparencyType;
};


#endif // PARTICLESYSTEMC_H