
#pragma once

#include "MW4.hpp"
#include "Subsystem.hpp"

namespace Adept
{
	class Effect;
	class Site;
}

namespace MechWarrior4
{
	class Vehicle;
	class LightEntity;
	class MWMover;

	typedef Subsystem__ClassData							SearchLight__ClassData;
	typedef Subsystem__Message								SearchLight__Message;
	typedef Subsystem__ExecutionStateEngine					SearchLight__ExecutionStateEngine;
	
	//##########################################################################
	//##################   SearchLight::CreateMessage    #######################
	//##########################################################################

	class SearchLight__CreateMessage:
		public Subsystem__CreateMessage
	{
	public:
	
		char
			siteName[128];

		SearchLight__CreateMessage(
			size_t length,
			int priority,
			int message_flags,
			Stuff::RegisteredClass::ClassID class_id,
			int replicator_flags,
			const ResourceID& instance_id,
			const Stuff::LinearMatrix4D &creation_matrix,
			Stuff::Scalar age,
			int execution_state,
			int name_id,
			int entity_alignment,
			int subsystem_index,
			BYTE location_id,
			int critical_hits,
			const char *site_name
		):
			Subsystem__CreateMessage(
				length, 
				priority, 
				message_flags, 
				class_id, 
				replicator_flags,
				instance_id,
				creation_matrix,
				age,
				execution_state,
				name_id,
				entity_alignment,
				subsystem_index,
				location_id,
				critical_hits
			)
			{
				Check_Pointer(site_name);
				Str_Copy(siteName, site_name, sizeof(siteName));
			}

		static void
			ConstructCreateMessage(Script *script);
	};

	//##########################################################################
	//###########################   SearchLight GameModel    ###################
	//##########################################################################

	class SearchLight__GameModel;

	typedef Subsystem__ClassData							Weapon__ClassData;
	typedef Subsystem__Message								Weapon__Message;
	typedef Subsystem__ExecutionStateEngine					Weapon__ExecutionStateEngine;
	
	class SearchLight__GameModel:
		public Subsystem::GameModel
	{
	public:

		Adept::ResourceID
			lightEntityResource,
			lightConeResource;

		enum {
			LightEntityResourceAttributeID = Subsystem__GameModel::NextAttributeID,
			LightConeResourceAttributeID,
			NextAttributeID
		};

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


		static void
			ConstructGameModel(Script *script);
	};

	//##########################################################################
	//###########################   SearchLight    #############################
	//##########################################################################

	class SearchLight:
		public Subsystem
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef SearchLight__ClassData						ClassData;
		typedef SearchLight__GameModel						GameModel;
		typedef SearchLight__Message						Message;
		typedef SearchLight__ExecutionStateEngine			ExecutionStateEngine;
		typedef SearchLight__CreateMessage					CreateMessage;


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

		void CommonCreation(CreateMessage *message);

		Adept::Replicator::CreateMessage*
			SaveMakeMessage(Stuff::MemoryStream *stream, Adept::ResourceFile *res_file);

		void SaveInstanceText(Stuff::Page *instance_page);

		static void
			CreateStream(
				Adept::ResourceID data_list,
				Stuff::MemoryStream *stream
			);

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

		~SearchLight();

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

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Simulation Support
	//
	public:
		void
			PostCollisionExecute(Stuff::Time till);
		bool
			TakeCriticalHit();
		void
			DestroySubsystem();
		bool
			ConnectSubsystem();
		void
			CreateSearchLight();
		void
			CreateLightCone();
		void
			ShowBeam();
		void
			HideBeam();

		Adept::Site *sitePointer;
		Stuff::SlotOf<LightEntity*> lightEntity;
		Stuff::SlotOf<Effect*> lightConeEntity;
		MString siteName;
		bool isLightOn;

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


