#pragma once

#include "MW4.hpp"
#include "helicopter.hpp"

namespace Adept
{
	class Effect;
}

namespace MechWarrior4
{
	class Dropship;
	class Subsystem;


	//##########################################################################
	//###############    Dropship::ExecutionStateEngine    #####################
	//##########################################################################

	class Dropship__ExecutionStateEngine:
		public Helicopter__ExecutionStateEngine
	{
	public:
		static void InitializeClass();
		static void TerminateClass();

		typedef Helicopter__ExecutionStateEngine BaseClass;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		typedef Dropship__ExecutionStateEngine*
			(*Factory)(
				Dropship *entity,
				FactoryRequest *request
			);

		static Dropship__ExecutionStateEngine* Make(Dropship *mover,FactoryRequest *request);

	protected:
		Dropship__ExecutionStateEngine(ClassData *class_data,Dropship *mover,FactoryRequest *request);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data support
	//
	public:
		static ClassData *DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// State stuff
	//
	public:
		enum {
			DoorOpenMotionState = Helicopter::ExecutionStateEngine::StateCount,
			DoorCloseMotionState,
			StateCount
		};

	int
		RequestState(int new_state,void* data = NULL);

	protected:
		static const StateEntry StateEntries[];

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:
		void TestInstance() const;
	};

	//##########################################################################
	//############################    Helicopter   #############################
	//##########################################################################

	//-------------------------------------------------------------------------
	// The following helper classes must always be typedef'd or overriden by an
	// inheritor
	//
	typedef Helicopter__ClassData							Dropship__ClassData;
	typedef Helicopter__Message								Dropship__Message;
	typedef Helicopter__CreateMessage					Dropship__CreateMessage;
	typedef Helicopter__GameModel							Dropship__GameModel;
	
	//-----------------------  End of inheritance stuff ------------------------

	class Dropship : public Helicopter
	{
		friend class MovementClass;

	public:
		static void InitializeClass();
		static void	TerminateClass();

		typedef Helicopter BaseClass;

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef Dropship__ClassData							ClassData;
		typedef Dropship__GameModel							GameModel;
		typedef Dropship__Message								Message;
		typedef Dropship__ExecutionStateEngine	ExecutionStateEngine;
		typedef Dropship__CreateMessage					CreateMessage;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static Dropship* Make(CreateMessage *message,ReplicatorID *base_id);
	
	protected:
		Dropship(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element);
		
		~Dropship();

		void Reuse(const CreateMessage *message,ReplicatorID *base_id);

		void Respawn(Adept::Entity::CreateMessage *message);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data support
	//
	public:
		static ClassData *DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution Support
	//
	public:
		Stuff::Point3D landTargetPosition;
		int m_NumEngines;
		Stuff::Time m_TakeOffStart;						// when to start moving up
	
		void TakeOff(Stuff::Scalar runway_distance);
		
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	protected:
		Stuff::Scalar m_DoorAmount;
		MWMover *m_DoorAR,*m_DoorFR,*m_DoorAL,*m_DoorFL;
		bool m_FirstFrame,m_HasDoors;
		Stuff::Scalar m_BaseYDoorAR,m_BaseYDoorFR,m_BaseYDoorAL,m_BaseYDoorFL;
		Stuff::Time m_DeathStart;
		bool m_CanDie;			// 2 seconds if on ground to play secondary

	public:

		void Land(void);
		void LandingMovementSimulation(Stuff::Time till);
		void TakeOffThrusterSimulation(Stuff::Time till,const Stuff::Vector3D& new_velocity,const Stuff::Vector3D& instantanious_angular_velocity,bool canswitch);
		virtual void EngineDead (void);
		void PreCollisionExecute(Time till);
		void DoorOpenAnim (Stuff::Time slice);
		void DoorCloseAnim (Stuff::Time slice);
		bool orderDoorOpen (void);
		bool orderDoorClose (void);
		void ReactToDestruction(int damage_mode, int damage_type);
		void InitializeArmorArray();

// MSL 5.04 Dropship
		//should this dropship be scored?
		bool m_scoreThisDropship;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:
		void TestInstance() const;

	};
	
	inline Dropship__ExecutionStateEngine::Dropship__ExecutionStateEngine(
		ClassData *class_data,
		Dropship *mover,
		FactoryRequest *request
	):
		BaseClass(class_data, mover, request)
			{}

}
