
#pragma once
#ifndef AI_LANCEMATECOMMANDS_HPP
#define AI_LANCEMATECOMMANDS_HPP

#include "AI_LancemateAudio.hpp"
#include <Adept\Entity.hpp>
#include <Stuff\Auto_Ptr.hpp>
#pragma warning(push)
#include <stlport\vector>
#pragma warning(pop)
#include "AI_FindObject.hpp"



namespace MW4AI
{
	namespace LancemateCommands
	{
		enum ID
		{
			LANCEMATE_FIRST						= 4999, 		// NOTE: change the constants in MWCONST.ABI if you change these

			LANCEMATE_DEFAULT					= 5000,
			LANCEMATE_ATTACKPLAYERSTARGET		= 5001,
			LANCEMATE_DEFENDPLAYERSTARGET		= 5002,
			LANCEMATE_FORMONME					= 5003,
			LANCEMATE_HOLDFIRE					= 5004,
			LANCEMATE_GOTOMYNAVPOINT			= 5005,
			LANCEMATE_STOP						= 5006,
			LANCEMATE_SHUTDOWN					= 5007,
			LANCEMATE_ATTACKNEARESTTHREAT		= 5008,
			LANCEMATE_REPAIRATNEARESTREPAIRBAY	= 5009,
            //LANCEMATE_CAPTUREPLAYERSFLAG?
			LANCEMATE_LAST						= 5011
		};

		typedef std::vector<Adept::ObjectID> lancemate_list;

		void Execute(ID command, const lancemate_list& lancemates);
        void ExecuteForAllLancemates2(Mech* paMechs[], int nMechs, LancemateCommands::ID command_id, MWObject* pLeader, MWObject* pTarget);

		#define INTERFACE_LancemateCommand(post)	\
		  public:									\
			virtual void Init() ##post				\
			virtual bool Finished() const ##post	\
			virtual void Update() ##post

		#define PURE_LancemateCommand			INTERFACE_LancemateCommand(=0;)
		#define DERIVED_LancemateCommand(classname)		\
			INTERFACE_LancemateCommand(;)				\
			classname(MechWarrior4::CombatAI& combat_ai, MechWarrior4::MWObject& leader, LancemateAudio::AudioManager& audio_manager, Adept::Entity* pTarget2 = NULL)	\
            : LancemateCommand(combat_ai,leader,audio_manager,pTarget2) { Init(); }

		class LancemateCommand
		{
		  public:
			PURE_LancemateCommand;

			LancemateCommand(MechWarrior4::CombatAI& combat_ai,
							 MechWarrior4::MWObject& leader,
							 LancemateAudio::AudioManager& audio_manager,
                             Adept::Entity* pTarget2 = NULL); // jcem

			virtual ~LancemateCommand();

			virtual bool OnLeash() const;
			virtual Stuff::Point3D GetLeashPoint() const;
			virtual Stuff::Scalar GetLeashRadius() const;
			virtual bool CanDistract() const;
			virtual bool CanDeviateFromPath() const;
			virtual void NotifyNoPath();
			virtual bool CanInterrupt() const { return (true); }

			MechWarrior4::MWObject* FindSomeoneToAttack(const Adept::ObjectID* except_who,
														FindObject::Criteria = FindObject::FC_BEST_TARGET,
														Stuff::Scalar radius = MW4AI::FindObject::DISTANCE_LIMIT) const;

		  protected:
			MechWarrior4::CombatAI& m_CombatAI;
			SlotOf<MechWarrior4::MWObject*> m_Leader;
			LancemateAudio::AudioManager& m_AudioManager;
            SlotOf<Adept::Entity*> m_pTarget2;
		};

		Stuff::Auto_Ptr<LancemateCommand> CreateLancemateCommand(ID command,
																 MechWarrior4::CombatAI& combat_ai,
																 MechWarrior4::MWObject& leader,
																 LancemateAudio::AudioManager& audio_manager,
                                                                 Adept::Entity* pTarget2 = NULL);

		class Default
		  : public LancemateCommand
		{
			DERIVED_LancemateCommand(Default);

			virtual bool CanDistract() const;
			virtual bool CanDeviateFromPath() const;
			virtual void NotifyNoPath();

		  private:
			void GoIntoFormation();

		  private:
			SlotOf<Adept::Entity*> m_LastTarget;
			Stuff::Scalar m_LastTimeNotWaiting;
		};
	};
};



#endif // AI_LANCEMATECOMMANDS_HPP
