#include "ProbeMicroBehaviour.h"
#include "BaseModel.h"

ProbeMicroBehaviour::ProbeMicroBehaviour( UnitModel* sub , UnitManager* u )
{
	subject = sub;
	unitManager = u;
	attacking = false;
	moving = false;
	targettingSystem = new TargetEvaluator(sub);
	currentTarget = NULL;
	id = PROTOSS_PROBE;
	blockTimer = 0;
}

//************************************
// Method:    execute
// FullName:  ProbeMicroBehaviour::execute
// Access:    virtual public 
// Returns:   void
// Comments:  none
//************************************
bool ProbeMicroBehaviour::execute()
{
	
	if(Broodwar->getFrameCount()%64 == 0) {
		if(subject->getCurrentTaskType() == NO_TASK) {
		BWTA::Chokepoint* cp = BWTA::getNearestChokepoint(subject->getPosition());
		Position centre = cp->getCenter();

		int dist = centre.getDistance(subject->getPosition());
		
		if(dist < 128) {
			if(rand()%100 >= 25) {
			subject->getUnit()->move(unitManager->getClosestFriendlyBaseModel(subject->getPosition())->getSubject()->getPosition());
			return true;
			}
		}
		}
	}

	if(subject->getCurrentTaskType() != SCOUTING && subject->getCurrentTaskType() != EXPAND) {
		if(subject->isUnderThreat()) {
	if(subject->isUnderThreatRange(96)) {
			subject->getUnit()->move(subject->findClosestPoint(findSafestNearbyPoints(), BWAPI::Positions::None, -1));
			return true;
	}
	if(subject->getUnit()->isUnderStorm()) {
		subject->getUnit()->move(subject->findFurthestPoint(findSafestNearbyPoints(), BWAPI::Positions::None, -1));
		return true;
	}
		}
	}

	return false;
}

void ProbeMicroBehaviour::nudge()
{

}

std::vector<Position> ProbeMicroBehaviour::findSafestNearbyPoints()
{
	ParticleGenerator* p = new ParticleGenerator(64, 345, subject->getPosition());
	std::vector<Position> v = p->generate();
	std::vector<Position> filteredPoints;
	std::vector<UnitModel*> enemies = unitManager->getAllEnemyUnitsInRange(subject->getPosition(), 256);
	Position closestEnemyPos = Positions::None;
	for (vector<UnitModel*>::iterator i = enemies.begin(); i != enemies.end(); ++i)
	{
		UnitModel* cur = *i;
		if(closestEnemyPos == Positions::None) {
			closestEnemyPos = cur->getPosition();
		} else {
			if(subject->getPosition().getDistance(cur->getPosition()) < subject->getPosition().getDistance(closestEnemyPos)) {
				closestEnemyPos = cur->getPosition();
			}
		}


	}


	for(std::vector<Position>::const_iterator i = v.begin(); i != v.end(); i++) {
		Position cur = *i;
		if(closestEnemyPos != Positions::None) {
			if(cur.getDistance(closestEnemyPos) < subject->getPosition().getDistance(closestEnemyPos)) {
				continue;
			}
		}
		if(cur.getDistance(subject->getPosition()) < 128 || !Broodwar->isWalkable(cur.x()/8, cur.y()/8) || !subject->getUnit()->hasPath(cur) || BWTA::getRegion(cur) != subject->getRegion()) {
			continue;
		}
		if(!Broodwar->isBuildable((TilePosition)cur)) {
			continue;
		}

		bool dangerousPoint = false;
		for(std::vector<UnitModel*>::const_iterator it = enemies.begin(); it != enemies.end(); it++) {
			UnitModel* curEnemy = *it;
			if(cur.getDistance(curEnemy->getPosition()) <= 168) {
				dangerousPoint = true;
				break;
			}

		}
		if(!dangerousPoint) {
			filteredPoints.push_back(cur);
		}

	}

	return filteredPoints;

}