//===========================================================================//
// File:	Engine.hpp													
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 09/09/98  JSE  Inital base class based off of Shadowrun/Adept       
// 09/24/98  BDB  Inital Engine subsystem based off of Subsystem.hpp       
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

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

namespace MechWarrior4
{
	class Vehicle;
	class Engine__GameModel;
	class HeatManager;


	typedef Subsystem__ClassData							Engine__ClassData;
	typedef Subsystem__Message								Engine__Message;
	typedef Subsystem__ExecutionStateEngine					Engine__ExecutionStateEngine;
	

	//##########################################################################
	//###########################   Engine::GameModel    #######################
	//##########################################################################

	class Engine__GameModel:
		public Subsystem::GameModel
	{
	public:
		typedef Subsystem__GameModel BaseClass;
		
		int
			m_numHeatSinks;

		Stuff::Scalar
			m_tonsPerUpgrade,
			m_mpsPerUpgrade,
			m_heatSinkEfficiency;

		enum {
			TonsPerUpgradeAttributeID = Subsystem__GameModel::NextAttributeID,
			MPSPerUpgradeAttributeID,
			NumHeatSinksAttributeID,
			HeatSinkEfficiencyAttributeID,
			NextAttributeID
		};

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

		static void
			ConstructGameModel(Script *script);
	};

	//##########################################################################
	//##################    Weapon::CreateMessage    ###########################
	//##########################################################################

	class Engine__CreateMessage:
		public Subsystem__CreateMessage
	{
	public:
		typedef Subsystem__CreateMessage BaseClass;
	
		int
			m_engineUpgrades;
		
		Engine__CreateMessage(
			size_t length,
			int priority,
			int message_flags,
			Stuff::RegisteredClass::ClassID class_id,
			int replicator_flags,
			const Adept::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,
			int engine_upgrades
		):
			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
			),
			m_engineUpgrades(engine_upgrades)	
			{}

		static void
			ConstructCreateMessage(Script *script);
	};


	//##########################################################################
	//###########################   Engine    ##################################
	//##########################################################################

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

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef Engine__ClassData									ClassData;
		typedef Engine__GameModel									GameModel;
		typedef Engine__Message										Message;
		typedef Engine__ExecutionStateEngine					ExecutionStateEngine;
		typedef Engine__CreateMessage								CreateMessage;


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static Engine* 
			Make(
				CreateMessage *message,
				Adept::ReplicatorID *base_id
			);
		Adept::Replicator::CreateMessage*
			SaveMakeMessage(MemoryStream *stream, Adept::ResourceFile *res_file);

		static void
			CreateStream(
				Adept::ResourceID data_list,
				Stuff::MemoryStream *stream
			);
		
	protected:
		Engine(
			ClassData *class_data,
			CreateMessage *message,
			Adept::ReplicatorID *base_id,
			ElementRenderer::Element *element
		);

		~Engine();

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

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Simulation Support
	//
	public:
		void
			ConnectHeatManager(HeatManager *heat_manager);
		void
			ConnectEngine(Vehicle *parent_mech);
		void
			Upgrade();
		void
			Degrade();
		void
			SetNewSpeed();

		Stuff::Scalar
			GetMaxSpeed()
				{Check_Object(this); return m_maxSpeed;}
		Stuff::Scalar
			GetMaxSpeedForDisplay()
				{Check_Object(this); return m_maxSpeed * 3.6f;}
		int
			GetUpgrades()
				{Check_Object(this); return m_upgrades;}
		int
			GetMPSPerUpgrade()
				{Check_Object(this); return m_mpsPerUpgrade;}
	protected:
		Stuff::Scalar
			m_mechMinMaxMPS,
			m_mechMaxMaxMPS;
		int
			m_upgrades;
		int
			m_mpsPerUpgrade;
		int
			m_maxUpgrades;
		Stuff::Scalar
			m_maxSpeed;

		Vehicle *m_parentMech;

		Stuff::Scalar
			m_engineTonnage;

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


