#pragma once
#include "UnitModel.h"
#include "BWAPI.h"
#include "BWTA.h"
#include "ParticleGenerator.h"
#include <vector>
#include <map>
using namespace std;
using namespace BWAPI;
using namespace BWTA;

class Overseer;

class Army {
public:
	Army(Overseer* ov);	
	void initialize();
	void monitor();
	void setTarget(BWTA::Region* r);
	void addToArmy(UnitModel* u);
	void addToArmyDirect(UnitModel* u);
	vector<UnitModel*> getMembers();
	void attackTargetRegion();
	void formUp();
	void reform();
	void calculateArmyStructure();
	void calculatePath();
	void nextWayPoint();
	void transformPath();
	bool isArmyUnderAttack();
	void rallyIdleMembers();
	bool isAlive();
	bool checkAlive();
	void defendSelf();
	void assaultRegion();
	void disband();
	BWTA::Region* getCurrentTarget();
	Position getCentrePoint();
	void manageAirReplacementRequests();
	void manageGroundReplacementRequests();
	UnitModel* getLastAttacker();
	void removeFromArmy(UnitType t);
	void removeFromArmy(UnitModel* u);
	bool positionIsInTargetRegion(Position p);
	bool unitIsInTargetRegion(UnitModel* p);
	void clearChokePointObstructions();

	// monitor function sub-functions
	void manageArmySpacialStructure();
	void manageIdleMap();

	int countNumTypeInArmy(UnitType t);
	bool isSupportSquad();

	bool isContainingForce();
	
	void setSupportSquad();
	int getInitialForceSize();
	BWTA::Region* findNewTarget();
	TilePosition origin;

private:
	vector<UnitModel*> members;
	BWTA::Region* target;
	BWTA::Region* originalTarget;
	bool formed;
	bool movingToTargetRegion;
	bool attackingTargetRegion;
	bool armyIsReforming;
	bool armyUnderAttack;
	bool combat_just_switched;
	bool next_waypoint_is_choke;
	bool zealots_ahead;
	bool isContain;
	bool alive;
	bool supportSquad;
	int reformFrameLimit;
	int REFORM_WAIT_PERIOD;
	int initialForceSize;
	float DEATH_THRESHOLD;
	std::map<BWAPI::TilePosition, std::vector<BWAPI::TilePosition>> localPathMap;

	UnitModel* lastAttacker;
	Position lastInterestingPosition;
	Position effectiveTarget;
	Position combatAnchor;
	Overseer* overseer;
	std::vector<Position> armyFront;
	std::vector<Position> armyBack;
	int furthestDistance;
	Position centrePoint;
		Position lastCentrePoint;
	BWAPI::Position currentWayPoint;
	std::vector<BWAPI::TilePosition> path;
	std::vector<BWAPI::TilePosition> badPath;
	std::map<UnitType, int> initialStateMap;
	BWTA::Region* curRegion;
	BWTA::Region* curRegTar;
	std::map<UnitModel*, int> idleMap;
	int tickCount;
	int armyIdleCounter;
	bool armyInTargetRegion;
	int PATH_CALCULATION_LIMIT;
	int failedPathAttempts;
protected:

};