#pragma once

#include "MW4.hpp"
#include "Airplane.hpp"

namespace Adept
{
	class Effect;
}

namespace MechWarrior4
{
	class Helicopter;
	class Subsystem;

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

	//-------------------------------------------------------------------------
	// The following helper classes must always be typedef'd or overriden by an
	// inheritor
	//
	typedef Airplane__ClassData							Helicopter__ClassData;
	typedef Airplane__Message							Helicopter__Message;
	typedef Airplane__CreateMessage						Helicopter__CreateMessage;
	typedef Airplane__GameModel							Helicopter__GameModel;
	typedef Airplane__ExecutionStateEngine				Helicopter__ExecutionStateEngine;
	
	//-----------------------  End of inheritance stuff ------------------------

	class Helicopter:
		public Airplane
	{
		friend class MovementClass;

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

		typedef Airplane BaseClass;

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef Helicopter__ClassData					ClassData;
		typedef Helicopter__GameModel					GameModel;
		typedef Helicopter__Message						Message;
		typedef Helicopter__ExecutionStateEngine		ExecutionStateEngine;
		typedef Helicopter__CreateMessage				CreateMessage;

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

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

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

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution Support
	//
	public:
		Stuff::Point3D landTargetPosition;
	
		void
			TakeOff(Stuff::Scalar runway_distance);
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//Effect support
	//
	public:
		void
			CreateTakeOffEffect();
		void
			CreateTakeOffGroundEffect(Stuff::Point3D ground_position);
		void
			CreateLandingEffect();
		void
			CreateLandingGroundEffect(Stuff::Point3D ground_position);

		Stuff::SlotOf<Adept::Effect *>
			m_takeOffEffect;
		Stuff::SlotOf<Adept::Effect *>
			m_takeOffGroundEffect;
		Stuff::SlotOf<Adept::Effect *>
			m_landingEffect;
		Stuff::SlotOf<Adept::Effect *>
			m_landingGroundEffect;

		bool m_StartTakeoffEffect;
		bool m_StartLandingEffect;
		Stuff::Point3D m_EffectGroundPosition;
		void PostCollisionExecute(Time till);


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	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);

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

	};

}
