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

#pragma once

#include "MW4.hpp"
#include "Weapon.hpp"

namespace MechWarrior4
{
	class Vehicle;
	class CollisionGroup;
	class BeamWeapon;
	class BeamEntity;

	//##########################################################################
	//###############    BeamWeapon::ExecutionStateEngine    ###################
	//##########################################################################

	class BeamWeapon__ExecutionStateEngine:
		public Weapon::ExecutionStateEngine
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		typedef Weapon::ExecutionStateEngine BaseClass;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		typedef BeamWeapon__ExecutionStateEngine*
			(*Factory)(
				BeamWeapon *weapon,
				FactoryRequest *request
			);

		static BeamWeapon__ExecutionStateEngine*
			Make(
				BeamWeapon *weapon,
				FactoryRequest *request
			);

	protected:
		BeamWeapon__ExecutionStateEngine(
			ClassData *class_data,
			BeamWeapon *weapon,
			FactoryRequest *request
		);

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// State stuff
	//
	public:
		enum {
			FiringState = Weapon::ExecutionStateEngine::StateCount,
			RechargingState,
			StateCount
		};

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

	protected:
		static const StateEntry
			StateEntries[];

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

	class BeamWeapon__GameModel;

	typedef Weapon__ClassData									BeamWeapon__ClassData;
	typedef Weapon__Message										BeamWeapon__Message;
	typedef Weapon__CreateMessage								BeamWeapon__CreateMessage;


	class BeamWeapon__GameModel:
		public Weapon::GameModel
	{
	public:
		typedef Weapon::GameModel BaseClass;
		
		Stuff::Scalar
			fireDuration;

		Adept::ResourceID
			beamModelResource;

		enum {
			FireDurationAttributeID = Weapon__GameModel::NextAttributeID,
			BeamModelResourceAttributeID,
			NextAttributeID
		};

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

		static void
			ConstructGameModel(Script *script);
	};
	
	//##########################################################################
	//###########################   BeamWeapon    ##############################
	//##########################################################################

	class BeamWeapon:
		public Weapon
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		typedef Weapon BaseClass;

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef BeamWeapon__ClassData									ClassData;
		typedef BeamWeapon__GameModel									GameModel;
		typedef BeamWeapon__Message									Message;
		typedef BeamWeapon__ExecutionStateEngine					ExecutionStateEngine;
		typedef BeamWeapon__CreateMessage							CreateMessage;


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

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

		~BeamWeapon();

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

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Attribute Support
	//
	public:
		enum {
			BeamDistanceAttributeID = Weapon::NextAttributeID,
			BeamStartSFXAttributeID,
			NextAttributeID
		};

	public:
		//
		// Attributes
		//
		int beamStartSFX;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Simulation Support
	//
	public:
		void
			PreCollisionExecute(Stuff::Time till);
		void
			PostCollisionExecute(Stuff::Time till);
		void
			DestroySubsystem();
		virtual void
			CleanUpCreatedBeam();
		bool
			ReadyToFire(void);
		virtual void
			CreateBeam();

// MSL 5.06 Armor Mode
		int
			m_ArmorMode;

		bool
			fireRequest;

		Stuff::Scalar
			beamRechargeTime;

		Stuff::Scalar
			beamDistance;

		Stuff::Scalar
			accumlatedRechargeTime;

		Stuff::Scalar
			accumlatedDuration;

		Adept::Entity::CollisionQuery
			targetQuery;

		Stuff::Line3D collisionLine;
		Stuff::Normal3D collisionNormal;

		Stuff::SlotOf<BeamEntity*>
			beamEntity;


	protected:
		void
			Fire(Adept::Entity::CollisionQuery *query,
				Stuff::Time time_locked,
				const Stuff::Point3D& lockedTargetEntityPartOffset);
			virtual void QuickFire (Adept::Entity *target);

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

	inline BeamWeapon__ExecutionStateEngine::BeamWeapon__ExecutionStateEngine(
		ClassData *class_data,
		BeamWeapon *weapon,
		FactoryRequest *request
	):
		BaseClass(class_data, weapon, request)
			{}

}


