#pragma once
#include <BWAPI.h>
#include "BWTA.h"
#include "GlobalConstants.h"


using namespace std;
using namespace BWAPI;

class MicroBehaviour;
class NudgeModule;
class UnitManager;
class BaseModel;
class Army;


class UnitModel {
public:
	UnitModel(BWAPI::Unit* target, UnitManager* u);
	~UnitModel();
	bool isAlive();
	bool isOwnedByPlayer();
	BWAPI::Unit* getUnit();
	void setLastKnownPosition(BWAPI::Position pos);
	void setLastKnownTilePosition(BWAPI::TilePosition pos);
	void setLastKnownHitPointsAndShields(int hp, int shields);
	void setLastKnownUnitType(BWAPI::UnitType t);
	void setLastKnownRegion(BWTA::Region* r);
	bool isBeingTargetted();
	bool isUnderThreat();
	bool checkUnderThreat();
	void setUnderThreat(bool s);
		bool isUnderThreatRange(int r);
	Position getThreatLoc();
		bool isUnderThreatMin(int num);
	void drawDebuggingInformation();
	void attack(UnitModel* tar);
	void attack(Unit* tar);
	void clearArmyOwner();
	BWAPI::Position getPosition();
	BWAPI::TilePosition getTilePosition();
	int getHP();
	int getMaxHP();
	int getQualitativeHP();
		int getQualitativeShields();
	int getShields();
	MicroBehaviour* getMicroBehaviour();
	BWTA::Region* getRegion();
	BWAPI::UnitType getType();
	void executeMicroBehaviour();
	void clearMicroBehaviour();
	BWAPI::Position findClosestPoint(std::vector<BWAPI::Position> points, BWAPI::Position clamp, int dist);
	BWAPI::Position findClosestPointTowardsBase(std::vector<BWAPI::Position> points, BWAPI::Position clamp, int dist);
	BWAPI::Position findFurthestPoint(std::vector<BWAPI::Position> points, BWAPI::Position clamp, int dist);
	UnitModel* findClosestUnit(std::vector<UnitModel*> points);

	void setBaseOwner(BaseModel* b);
	BaseModel* getBaseOwner();
	std::vector<TilePosition> getPath();
	void setMicroBehaviour(MicroBehaviour* beh);
	void setMicroBehaviour(int BEHAVIOUR_IDENTIFIER);
	bool compileBehaviour(int BEHAVIOUR_IDENTIFIER);
	void setCurrentTaskType(int TASK_TYPE);
	void setCurrentTaskType(int TASK_TYPE, int duration);
	void setCurrentTaskType(int TASK_TYPE, Position posTrigger);
		void setCurrentTaskType(int TASK_TYPE, BWTA::Region* reg);
	int getCurrentTaskType();

	void pathMove(TilePosition p, int PATHFINDING_TYPE);
	void pathMove(std::vector<TilePosition> incPath);
	void pathStop();
	void promptPathReplan(TilePosition t);
	bool isFollowingPath();
	bool isOnSmallChokePoint();
	bool microBehaviourInControl();
	bool isStasised();
	void setLastKnownStasisStatus(bool s);
	void setTaskTimer(int t);
	void nudgeOffTile(TilePosition t);
	void setAlive(bool a);
	void setArmyOwner(Army* a);
	TilePosition getNextPathWaypoint();
	Army* getArmyOwner();
	bool isReservedForTraining();
	void setReservedStatus(bool trainingReservationStatus);
	NudgeModule* getNudgeModule();
private:
	// memory stuff
	BWAPI::Unit* subject;
	NudgeModule* nm;
	BWAPI::Position lastKnownPosition;
	BWAPI::TilePosition lastKnownTilePosition;
	BWAPI::UnitType lastKnownType;
	BWTA::Region* lastKnownRegion;
	int lastKnownHitPoints;
	int lastKnownShields;
	int maxHPForType;
	int curBehaviourID;
	bool ownedByPlayer;
	bool lastKnownStasisStatus;
	UnitManager* unitmanager;
	// behaviour stuff
	MicroBehaviour* behaviour;
	std::vector<TilePosition> path;
	TilePosition nextWayPoint;
	int PATHFINDING_CHOICE;
	bool stoppedPathing;
	bool microInControl;
	bool alive;
	bool underThreat;
	Position taskSwitchPosTrigger;
	BWTA::Region* taskSwitchPosTriggerRegion;
	int ACTIVE_TASK_TYPE;
	int taskTimer;
	BaseModel* owner;
	Army* armyOwner;
	bool reservedForTraining;
	Position threatLoc;
	TilePosition moveLoc;
protected:


	
};
