//
// DX9Crowd.h
//
// DX9Crowd Plugin
//
// Copyright (c) 2004 memon/moppi productions
//

#ifndef __DX9CrowdPLUGIN_H__
#define __DX9CrowdPLUGIN_H__


#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "EffectI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "ParamI.h"
#include "BBox2C.h"
#include "Matrix2C.h"
#include "DeviceContextC.h"
#include "DeviceInterfaceI.h"
#include "DemoInterfaceC.h"
#include "DX9ViewportC.h"
#include "DX9DeviceC.h"
#include "TimeContextC.h"
#include "AutoGizmoC.h"
#include "ImportableImageI.h"
#include "DX9MeshPlugin.h"
#include "SimpleVehicleC.h"
#include <list>

//////////////////////////////////////////////////////////////////////////
//
//  Class IDs
//

#define	CLASS_DX9CROWD_EFFECT_NAME	"Crowd (DX9)"
#define	CLASS_DX9CROWD_EFFECT_DESC	"Crowd (DX9)"

const PluginClass::ClassIdC	CLASS_DX9CROWD_EFFECT( 0x96E21A04, 0x94D74DA7 );


//////////////////////////////////////////////////////////////////////////
//
//  DX9Crowd effect class descriptor.
//

class DX9CrowdDescC : public PluginClass::ClassDescC
{
public:
	DX9CrowdDescC();
	virtual ~DX9CrowdDescC();
	virtual void*						create();
	virtual PajaTypes::int32			get_classtype() const;
	virtual PluginClass::SuperClassIdC	get_super_class_id() const;
	virtual PluginClass::ClassIdC		get_class_id() const;
	virtual const char*					get_name() const;
	virtual const char*					get_desc() const;
	virtual const char*					get_author_name() const;
	virtual const char*					get_copyright_message() const;
	virtual const char*					get_url() const;
	virtual const char*					get_help_filename() const;
	virtual PajaTypes::uint32			get_required_device_driver_count() const;
	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx );
	virtual PajaTypes::uint32			get_ext_count() const;
	virtual const char*					get_ext( PajaTypes::uint32 ui32Index ) const;
};

namespace DX9CrowdPlugin {

//////////////////////////////////////////////////////////////////////////
//
// DX9Crowd effect class.
//

	enum TransformGizmoParamsE {
		ID_TRANSFORM_POS = 0,
		ID_TRANSFORM_SCALE,
		TRANSFORM_COUNT,
	};


	enum AttributeGizmoParamsE {
		ID_ATTRIBUTE_FILE_OBSTACLES = 0,
		ID_ATTRIBUTE_LOOK_AT_OBJECT,
		ID_ATTRIBUTE_HERO_OBJECT,
		ID_ATTRIBUTE_HERO_ANIM,
		ID_ATTRIBUTE_HERO_ANIM_TIME,
		ID_ATTRIBUTE_FILE_HERO_MESH,
		ID_ATTRIBUTE_FILE_DUDE1_MESH,
		ID_ATTRIBUTE_FILE_DUDE2_MESH,
		ID_ATTRIBUTE_FILE_DUDE3_MESH,
		ID_ATTRIBUTE_FILE_DUDE4_MESH,
		ID_ATTRIBUTE_FILE_DUDE5_MESH,
		ID_ATTRIBUTE_DUDE_COUNT,
		ID_ATTRIBUTE_TEEN_COUNT,
		ID_ATTRIBUTE_ADULT_COUNT,
		ID_ATTRIBUTE_BASS_AFFECT,
		ATTRIBUTE_COUNT,
	};

	enum TimeGizmoParamsE {
		ID_TIME_FRAME = 0,
		TIME_COUNT,
	};

	enum AVIPlayerEffectGizmosE {
		ID_GIZMO_TRANS = 0,
		ID_GIZMO_ATTRIB,
		ID_GIZMO_TIME,
		GIZMO_COUNT,
	};

	class DX9CrowdEffectC : public Composition::EffectI
	{
	public:
		static DX9CrowdEffectC*				create_new();
		virtual Edit::DataBlockI*			create();
		virtual Edit::DataBlockI*			create( Edit::EditableI* pOriginal );
		virtual void									copy( Edit::EditableI* pEditable );
		virtual void									restore( Edit::EditableI* pEditable );

		virtual PajaTypes::int32			get_gizmo_count();
		virtual Composition::GizmoI*	get_gizmo( PajaTypes::int32 i32Index );

		virtual PluginClass::ClassIdC	get_class_id();
		virtual const char*						get_class_name();

		virtual void									set_default_file( PajaTypes::int32 i32Time, Import::FileHandleC* pHandle );
		virtual Composition::ParamI*	get_default_param( PajaTypes::int32 i32Param );

		virtual PajaTypes::uint32			update_notify( EditableI* pCaller );

		virtual void									initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

		virtual void									eval_state( PajaTypes::int32 i32Time );

		virtual PajaTypes::BBox2C			get_bbox();

		virtual const PajaTypes::Matrix2C&	get_transform_matrix() const;

		virtual bool									hit_test( const PajaTypes::Vector2C& rPoint );

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


	protected:
		DX9CrowdEffectC();
		DX9CrowdEffectC( Edit::EditableI* pOriginal );
		virtual ~DX9CrowdEffectC();

		void		init_effect();
		void		init_meshes();
		void		reset_meshes();

		void		reset_vehicles();
		void		update_vehicles( PajaTypes::int32 i32Time );
		void		save_vehicle_states( PajaTypes::int32 i32Time );
		void		restore_vehicle_states( PajaTypes::int32 i32Time );
		bool		check_birth_pos( const PajaTypes::Vector2C& Pos );
		void		init_obstacles( PajaTypes::int32 i32Time );

	private:
		Composition::AutoGizmoC*	m_pTraGizmo;
		Composition::AutoGizmoC*	m_pAttGizmo;
		Composition::AutoGizmoC*	m_pTimeGizmo;

		CD3DModelInstance*				m_pHeroInstance;
		LPD3DXEFFECT							m_pEffect;

		struct SavedStateS
		{
			bool							bActive;
			PajaTypes::int32	i32Time;
			std::vector<SimpleVehicleStateS>	vecStates;
		};
		std::vector<SavedStateS>	m_vecSavedStates;

		std::vector<ObstacleS>		m_vecObstacles;

		PajaTypes::int32					m_i32CurState;

		PajaTypes::int32					m_i32CurTime;
		PajaTypes::int32					m_i32NextSaveTime;

		PajaTypes::int32					m_i32HeroObj;
		PajaTypes::int32					m_i32LookAtObj;

		PajaTypes::int32					m_i32TeenCount;
		PajaTypes::int32					m_i32AdultCount;

		PajaTypes::Matrix2C				m_rTM;
		PajaTypes::BBox2C					m_rBBox;

		std::vector<SimpleVehicleC*>	m_vecVehicles;
		PajaTypes::float32						m_f32SubFrame;
		PajaTypes::int32							m_i32VehicleCount;
		PajaTypes::int32							m_i32SavedStateSize;
	};

};	// namespace


extern DX9CrowdDescC			g_rDX9CrowdDesc;


#endif	// __DX9Crowd_H__
