#pragma once

#include "MW4.hpp"
#include "MFB.hpp"


namespace MechWarrior4
{	
	class FieldBase;
	class MoverAI;

	

	//##########################################################################
	//############################    MFB    ###################################
	//##########################################################################

	//-------------------------------------------------------------------------
	// The following helper classes must always be typedef'd or overriden by an
	// inheritor
	//
	typedef MFB__Message						FieldBase__Message;
	typedef MFB__UpdateMessage			FieldBase__UpdateMessage;
	typedef MFB__CreateMessage			FieldBase__CreateMessage;
	typedef MFB__ClassData					FieldBase__ClassData;

	extern DWORD Executed_MFB_Count;


	//##########################################################################
	//#############		FieldBase::ExecutionStateEngine    #######################
	//##########################################################################

	class FieldBase__ExecutionStateEngine:
		public MFB::ExecutionStateEngine
	{
	public:
		static void InitializeClass();
		static void TerminateClass();

		typedef MFB::ExecutionStateEngine BaseClass;

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

		static FieldBase__ExecutionStateEngine*
			Make(FieldBase *mover,FactoryRequest *request);

	protected:
		FieldBase__ExecutionStateEngine(ClassData *class_data,FieldBase *mover,FactoryRequest *request);

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// State stuff
	//
	public:
		enum {
			OpenDoorState = MFB::ExecutionStateEngine::StateCount,
			CloseDoorState,
			StateCount
		};

	protected:
		static const StateEntry StateEntries[];

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

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

	//-----------------------  End of inheritance stuff ------------------------

	class FieldBase:
		public MFB
	{
	public:
		static void InitializeClass();
		static void TerminateClass();

		typedef MFB BaseClass;

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef FieldBase__ClassData					ClassData;
		typedef FieldBase__Message					Message;
		typedef FieldBase__ExecutionStateEngine		ExecutionStateEngine;
		typedef FieldBase__CreateMessage				CreateMessage;
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static FieldBase*
			Make( CreateMessage *message,ReplicatorID *base_id);


	protected:
		FieldBase(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element);
		
		void Respawn(Adept::Entity::CreateMessage *message);
		void CommonCreation(CreateMessage *message);

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

		~FieldBase();
		void ReactToDestruction(int damage_mode, int damage_type);

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Game Model Support
	//
	public:
		const GameModel* GetGameModel()
				{
					Check_Object(this);
					return Cast_Pointer(const GameModel*,gameModelResource.GetPointer());
				}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution Support
	//
	public:
		void TurnOn();
		void PreCollisionExecute(Stuff::Time till);
		bool CollisionHandler(Stuff::LinearMatrix4D *new_position,Stuff::DynamicArrayOf<CollisionData> *collisions);
		
	protected:
		Stuff::Scalar m_DoorAmount,m_LiftAmount;
		MWMover *m_DoorAR,*m_DoorFR,*m_DoorAL,*m_DoorFL,*m_Lift;
		bool m_HasDoors,m_FirstFrame;
		Stuff::Scalar m_BaseYDoorAR,m_BaseYDoorFR,m_BaseYDoorAL,m_BaseYDoorFL,m_BaseYLift;
		void DoorOpenAnim (Stuff::Time slice);
		void DoorCloseAnim (Stuff::Time slice);


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

	inline
		FieldBase__ExecutionStateEngine::FieldBase__ExecutionStateEngine(
			ClassData *class_data,
			FieldBase *mover,
			FactoryRequest *request
		):
			BaseClass(class_data, mover, request)
	{
	}

}
