#ifndef __AICOMMANDHPP__
#define __AICOMMANDHPP__

enum AICOMMAND { MOVE_CMD,SAY_CMD,STANCE_CMD,TURN_CMD,SEND_CMD,
		PLACEMENT_CMD,ATTACK_CMD,TRADE_CMD,SPECIAL_CMD,ADJUST_CMD,REMOVE_CMD};

typedef struct 
{
	double speed;		// speed to move there
	void *curpath;		// current path to follow, probably just a list of points
	UINT inpath;		// where in path list we are
	double sx,sy,sz;	// start location
	double dx,dy,dz;	// destination location
	UINT sPosture;		// starting posture
	UINT dPosture;		// destination posture
	double dFacing;		// destination facing
} MoveCommandData;

typedef struct 
{
	char *text;			// text to say
	UINT tone;			// tone of voice
	UINT intext;		// where in text we are
} SayCommandData;

typedef struct 
{
	UINT stance;		// stance to enter
	UINT curpos;		// phase of changing stance
} StanceCommandData;

typedef struct 
{
	bool absolute;		// true if using the facing variable
	double facing;		// facing to turn to
	double speed;		// speed to turn
	AI *turnto;	// object to face, instead of absolute facing
} TurnCommandData;

typedef struct 
{
	UINT type;			// type of information to send
	AI *dest;	// object to send the data to
	UINT method;		// how to send the data, means how much is sent at a time
	UINT where;			// where in data being sent we are
} SendCommandData;

typedef struct 
{
	double x,y,z;		// location to be in
	double facing;		// direction to face
	UINT pos;			// position of various parts in location
	UINT where;			// where in movement we are
} PlacementCommandData;

typedef struct 
{
	AI *who;		// object to attack
	UINT with;			// what to attack with
	UINT action;		// type of attack
	UINT where;			// where in sequence we are
} AttackCommandData;

typedef struct
{
	AI *who;		// object to trade with
	AI *what;	// object to trade
	UINT how;			// how we want to perform the trade (hand, magic, etc)
} TradeCommandData;

typedef struct 
{
	UINT action;		// special action to perform
	UINT where;			// where in sequence we are
} SpecialCommandData;

typedef struct
{
//· code for changing sort order or priority levels
//· new sort order
//· new priority level
//· priority set to remove
//· priority set to add
} AdjustCommandData;

typedef struct 
{
//· command area from which to remove command
//· command id of command to remove
//· other info to pick what command to remove
} RemoveCommandData;

union CommandUnion
{
	MoveCommandData moveData;
	SayCommandData sayData;
	StanceCommandData stanceData;
	TurnCommandData turnData;
	SendCommandData sendData;
	PlacementCommandData placementData;
	AttackCommandData attackData;
	TradeCommandData tradeData;
	SpecialCommandData specialData;
	AdjustCommandData adjustData;
	RemoveCommandData removeData;
};

struct CommandEntry{
	static FixedHeap<CommandEntry> m_EmptyCommand;

	AICOMMAND commandType;
	UINT validFor;
	UINT priority;
	AIAREA from;
	CommandUnion commandData;
	CommandEntry *next,*prev;
	CommandEntry *sort_next,*sort_prev;
	CommandEntry *chain_next,*chain_prev;

    static CommandEntry *GetBlankCommand (void) { return (CommandEntry *) m_EmptyCommand.Alloc (); }
    static void DoneCommand (CommandEntry *oldknow)  { m_EmptyCommand.Free (oldknow); }

	void *operator new (size_t size) {return GetBlankCommand (); } 
	void operator delete (void *value,size_t size) { DoneCommand ((CommandEntry *) value); }
};

#endif