/*
   Copyright (C) 2004 by James Gregory
   Part of the GalaxyHack project
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.
 
   See the COPYING file for more details.
*/

#ifndef GUARD_AIInterpreter
#define GUARD_AIInterpreter

#include "GlobalConstants.h"
#include "RTSStructs.h"

#include <vector>
#include <string>

using std::vector;
using std::string;

class Group_Base;

class AIInterpreter {
public:
	void Init(Group_Base* iThisGroup, const vector<ustring>* iTheText, AICommands* iTheCommands);
	void GetCommands();

	//don't want people decrementing them to negative values
	unsigned int scriptVars[nAIVars];
	CoordsInt saveGroups[nAIVars];
	unsigned int scriptTimers[nAIVars];

private:
	void CallFunction();

	void SkipBlock(int tabLevel);

	bool InterpretIf();
	bool InterpretIfPartTwo();
	bool TrueOrFalse();

	bool CompareValues(int firstValue, const unsigned char operatorType, int secondValue);
	
	void InterpretSetVar();
	void InterpretSetSaveGroup();
	void InterpretStartTimer();

	void InterpretMove();
	void InterpretFire();
	void InterpretPatrol();

	//overloaded...
	int TokenToInt();
	int TokenToInt(int& giveSide, int& giveGroup);
	int StatToInt(const unsigned char theToken, int nSide, int nGroup);

	void GetGroupIndices(int& side, int& group);
	bool AreGroupsTheSame();

	void FindNearestWith(CoordsInt& giveIndices, int& giveDist);
	void FindNearestWithPartTwo(CoordsInt& giveIndices, vector<bool>& possibleSides, int& giveDist);
	void SearchThroughGroups(vector<bool>& possibleSides, vector<vector <bool> >& possibleGroups);

	bool DoAnyHave();
	int HowManyHave();
	void WhichSidesValid(vector<bool>& possibleSides);
	bool IsNearestLikeThis();
	bool IsGroupLikeThis(int nSide, int nGroup, bool discountDead, bool discountOur);
	bool IsEdgeLikeThis(int nSide, int nGroup);
	
	void NearestEnemy(int& giveSide, int& giveGroup);
	void NearestFriend(int& giveGroup);
	void NearestAlly(int& giveSide, int& giveGroup);
	void WhichSavedGroup(int& giveSide, int& giveGroup);
	
	void ShortCircuitSkip();

	CompassDirection TokenToEdge(int& giveDist);
	CompassDirection NearestEdge(int& distance);
	int DistToXEdge(CompassDirection which);
	int DistToLeftEdge() const;
	int DistToRightEdge() const;
	int DistToTopEdge() const;
	int DistToBottomEdge() const;

	Group_Base* thisGroup;
	const vector<ustring>* theText;
	AICommands* theCommands;
	int mySide;
	int myGroup;

	int currentLine;
	int insCounter;
	ustring::const_iterator lIter;
	ustring::const_iterator lEnd;
};

#endif
