//===========================================================================//
// File:	mechai.hpp																	     //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
//	07/13/99  AHF	Created File                  //
//---------------------------------------------------------------------------//
// Copyright (C) 1999, Microsoft										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "ai.hpp"
#include "aiutils.hpp"

namespace MechWarrior4
{
	
	class NonCom;
	typedef MechWarrior4::AI__CreateMessage			NonComAI__CreateMessage;

	//##########################################################################
	//###########################   NoncomAI   #################################
	//##########################################################################


	const int TYPE_INDEX = 0;
	const int RADIUS_INDEX = 1;			// for fidget
	const int CLOCKWISE_INDEX = 2;		// for trace
	const int MULTX_INDEX = 3;			// for fidget and trace
	const int MULTZ_INDEX = 4;			// for fidget and trace
	const int SPEED_INDEX = 5;			// for all

	const int HEIGHT_INDEX	= 7;
	const int BITMAP_LAYOUT_TYPE = 8;		// use '0' for people, '1' for animals

	const int TEXTURE_ID = 9;				// hold the type of noncom this is.  used for which one to use on the texture page

	const int FIDGET_TYPE = 0;
	const int TRACE_TYPE = 1;
	const int FLOCK_TYPE = 2;

	const Stuff::Scalar Trace_Distance 	= 10.0f;			// in meters
	const Stuff::Scalar Trace_Fudge			= 2.5f;				// creates donut around object

	class NonComAI : public MechWarrior4::AI
	{
		typedef AI inherited;

	public:
		static void InitializeClass();
		static void TerminateClass();

		static ClassData *DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Inheritance Support
	//
	public:
		typedef NonComAI__CreateMessage					CreateMessage;


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		virtual void Save (MemoryStream *stream) {AI::Save(stream);}
		virtual void Load (MemoryStream *stream) {AI::Load(stream);}
		static NonComAI* Make(CreateMessage *message,ReplicatorID *base_id);

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

		virtual ~NonComAI();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Message Support
	//
	public:

		enum {
			DebugTextMessageID = MechWarrior4::AI::NextMessageID,
			NextMessageID
		};

		void DebugTextMessageHandler(Adept::ReceiverDataMessageOf<int> *message);

		protected:
			static const MessageEntry MessageEntries[];

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution Support
	//
//	protected:
	public:
		NonCom *m_NonCom;
		Scalar m_MultX,m_MultZ;
		int m_LastObject;
		int m_LastType;
		Point3D m_CenterPoint;				// center of square for fidget
		Scalar m_SpeedX,m_SpeedZ;
		Scalar m_FakeSpeedX,m_FakeSpeedZ;			// used for actual movement, so can either walk or run
		Entity *m_FlockUnit;
		Scalar m_DistX,m_DistZ;				// max distance from center for unit
		Scalar m_PlayerAvoidLen;
		Point3D m_FlockAimDelta;

		ExtentBox m_TraceBox;

		stlport::vector<Entity *> m_FlockList;			// list of other entities in the flock list

		Scalar m_FidgetDestX, m_FidgetDestZ;
		Scalar m_LastHeadingChangeTime;
		Scalar m_LastTimeNearPlayer;
		Scalar m_NextFlockUpdateTime;

		enum MoveType
		{
			RUN,
			WALK,
			ANIMAL
		};

		MoveType m_MoveType;

		void CreateFakeSpeed (void);
		void DoFidget (Time till);
		void DoTrace (Time till);
		void DoFlock (Time till);

		void AddFlockUnit (Entity *newunit);

	public:
		void UpdatePos (Stuff::Time till);
		virtual void PreCollisionExecute(Stuff::Time till);
		virtual void PostCollisionExecute(Time till);
		virtual void Info (void (*printCallback)(char* s));
		virtual void Die (void);

	protected:
		bool IsAnimal();

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

