//===========================================================================//
// File:	bridge.hpp													
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 01/12/2000  AHF  Inital base class 
//===========================================================================//

#pragma once

#include "MW4.hpp"
#include <adept\Entity.hpp>
#include <adept\EntityClassData.hpp>
#include <adept\NameTable.hpp>


namespace Adept
{
  class Entity;
  class Effect;
}

namespace MechWarrior4
{

	class Cultural;

	//##########################################################################
	//###########################   Cultural_GameModel    ######################
	//##########################################################################

	class Cultural__GameModel:
		public Adept::Entity__GameModel
    {
	  public:
		  typedef Entity__GameModel BaseClass;

		Adept::ResourceID
			deathEntityResource;
		Adept::ResourceID
			destroyedEffectResource;
		Adept::ResourceID
			rammingDestroyedEffectResource;

		enum {
			DeathEntityResourceAttributeID = Entity__GameModel::NextAttributeID,
			DestroyedEffectResourceAttributeID,
			RammingDestroyedEffectResourceAttributeID,
			NextAttributeID
		};

		static bool
			ReadAndVerify(
				Cultural__GameModel *model,
				Adept::ModelAttributeEntry *attribute_entry,
				const char *data,
				char **error,
				int error_buffer = 128
			);

		static void
			ConstructGameModel(Script *script);
    };


	//##########################################################################
	//###########################   Cultural_CreateMessage    ##################
	//##########################################################################

	class Cultural__CreateMessage : 
		public Adept::Entity__CreateMessage 
	{
		public:
			typedef Adept::Entity__CreateMessage BaseClass;
		
			bool 
				destroyableFlag;

			Cultural__CreateMessage(
				size_t length,
				int priority,
				int message_flags,
				Stuff::RegisteredClass::ClassID class_id,
				int replicator_flags,
				const ResourceID& data_list_id,
				const Stuff::LinearMatrix4D &local_to_parent,
				Stuff::Scalar age,
				int execution_state,
				ObjectID name_id,
				int entity_alignment,
				bool destroyable
			):
				Entity__CreateMessage(
					length, 
					priority, 
					message_flags, 
					class_id,
					replicator_flags,
					data_list_id,
					local_to_parent,
					age,
					execution_state,
					name_id,
					entity_alignment
  				),
				destroyableFlag(destroyable)
			{}

			static void
				ConstructCreateMessage(Script *script);
	};


	typedef Entity__Message								Cultural__Message;
	typedef Entity__ClassData							Cultural__ClassData;
	typedef Entity__ExecutionStateEngine				Cultural__ExecutionStateEngine;
	typedef Entity__TakeDamageMessage					Cultural__TakeDamageMessage;


	class Cultural:public Adept::Entity
	{
	public:

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Inheritance Support
		//

		typedef Cultural__CreateMessage					CreateMessage;
		typedef Cultural__GameModel						GameModel;
		typedef Cultural__ExecutionStateEngine			ExecutionStateEngine;
		typedef Cultural__Message						Message;
		typedef Cultural__TakeDamageMessage				TakeDamageMessage;

		typedef Entity									BaseClass;

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Run-time Construction and Destruction Support
		//
	
	public:
		static void 
			InitializeClass();
		static void	
			TerminateClass();
		static Cultural*
			Make(CreateMessage *message,ReplicatorID *base_id);
		void
			Respawn(Adept::Entity::CreateMessage *message);

	protected:
		Cultural(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element);

		~Cultural();

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

	protected:
		static const MessageEntry
			MessageEntries[];

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Damage/Destruction Support
	//
	public:

		bool destroyableFlag;

		bool IsDestroyable()
		{
			return destroyableFlag;
		}

		bool IsNeverExecuteState();

		void
			SaveInstanceText(Stuff::Page *page);

		void
			TakeDamageMessageHandler(const TakeDamageMessage *message);

		virtual void
			ReactToHit(const TakeDamageMessage *message,Adept::DamageObject *part_hit);
		virtual void
			ReactToInternalDamage(int damage_mode);
		virtual void
			ReactToDestruction(int damage_mode,int damage_type);
		virtual void
			RemoveFromExecution();

		Effect*
		  CreateEffect(const Adept::ResourceID& effect_id, const Point3D &location, const Normal3D &normal);

		Entity *
			CreateStaticHermitEntity(const Adept::ResourceID& entity_id);

		int
			GetTableArray()
				{Check_Object(this); return NameTable::CulturalArray;}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Game Model Support
	//
	public:
		const GameModel*
			GetGameModel()
				{
					Check_Object(this);
					return Cast_Pointer(const GameModel*,gameModelResource.GetPointer());
				}
	  //
	  // Need this for appropriate animation direction during destruction
	  //
	  Stuff::Normal3D 
		  last_hit_normal;
	  int 
		  lastHitType ;

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

}

