#pragma once

#include "MW4.hpp"
#include "BeamWeapon.hpp"

namespace Adept
{
	class Effect;
}

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

	//##########################################################################
	//###############    BombastWeapon::ExecutionStateEngine    ################
	//##########################################################################

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

		typedef BeamWeapon::ExecutionStateEngine BaseClass;

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

		static BombastWeapon__ExecutionStateEngine*
			Make(
				BombastWeapon *weapon,
				FactoryRequest *request
			);

	protected:
		BombastWeapon__ExecutionStateEngine(
			ClassData *class_data,
			BombastWeapon *weapon,
			FactoryRequest *request
		);

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// State stuff
	//
	public:
		enum {
			ChargingState = BeamWeapon__ExecutionStateEngine::StateCount,
			StateCount
		};

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

	protected:
		static const StateEntry
			StateEntries[];

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

	class BombastWeapon__GameModel;

	typedef BeamWeapon__ClassData						BombastWeapon__ClassData;
	typedef BeamWeapon__Message							BombastWeapon__Message;
	typedef BeamWeapon__CreateMessage					BombastWeapon__CreateMessage;


	class BombastWeapon__GameModel:
		public BeamWeapon::GameModel
	{
	public:
		typedef BeamWeapon::GameModel BaseClass;
		
		Stuff::Scalar
			maxChargeTime;
		Stuff::Scalar
			timeForMaxCharge;
		Adept::ResourceID
			chargeEffectResource;
		Adept::ResourceID
			initialChargeBeamResource,
			halfChargeBeamResource,
			threeQuarterChargeBeamResource,
			fullChargeBeamResource;
		Adept::ResourceID
			initialChargeFlareResource,
			halfChargeFlareResource,
			threeQuarterChargeFlareResource,
			fullChargeFlareResource;

		enum {
			MaxChargeTimeAttributeID = BeamWeapon__GameModel::NextAttributeID,
			TimeForMaxChargeAttributeID,
			ChargeEffectResourceAttributeID,
			InitialChargeBeamResourceAttributeID,
			HalfChargeBeamResourceAttributeID,
			ThreeQuarterChargeBeamResourceAttributeID,
			FullChargeBeamResourceAttributeID,
			InitialChargeFlareResourceAttributeID,
			HalfChargeFlareResourceAttributeID,
			ThreeQuarterChargeFlareResourceAttributeID,
			FullChargeFlareResourceAttributeID,
			NextAttributeID
		};

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

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

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

		typedef BeamWeapon BaseClass;

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef BombastWeapon__ClassData						ClassData;
		typedef BombastWeapon__GameModel						GameModel;
		typedef BombastWeapon__Message							Message;
		typedef BombastWeapon__ExecutionStateEngine				ExecutionStateEngine;
		typedef BombastWeapon__CreateMessage					CreateMessage;


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static BombastWeapon* 
			Make(
				CreateMessage *message,
				ReplicatorID *base_id
			);

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

		~BombastWeapon();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 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 
			PreCollisionExecute(Stuff::Time till);
		void
			PostCollisionExecute(Stuff::Time till);
		void
			CleanUpCreatedBeam();
		void
			CreateBeam();
		void
			CreateChargeEffect();
		void
			CreateMuzzleFlash();
		void
			SetQuery(Adept::Entity::CollisionQuery *query);

		Stuff::SlotOf<Adept::Effect *>
			chargeEffect;
		Stuff::Time
			startChargeTime;
		Stuff::Scalar
			percentCharged;

		bool
			ReadyToFire();

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

	inline
		BombastWeapon__ExecutionStateEngine::BombastWeapon__ExecutionStateEngine(
			ClassData *class_data,
			BombastWeapon *mover,
			FactoryRequest *request
		):
			BeamWeapon__ExecutionStateEngine(class_data, mover, request)
	{
	}

}


