#include "AerialScoutBehaviour.h"
#include "BaseModel.h"

AerialScoutBehaviour::AerialScoutBehaviour( UnitModel* sub , UnitManager* u )
{
	unitManager = u;
	subject = sub;
	targetPosition = BWAPI::Positions::None;
	targetCell = NULL;
	//pickNewTarget();
	currentTarget = NULL;
	id = PROTOSS_SCOUTING_OBSERVER;
}

bool AerialScoutBehaviour::execute()
{
	if(!subject->getUnit()->isCompleted() || !subject->isAlive()) {
		return true;
	}
	if(Broodwar->getFrameCount()%24 == 0) {
		reportEnemyBaseLoc();
	}

	if(subject->isBeingTargetted()){
		if(targetCell != NULL) {
			relinquishExploreTarget();
			subject->pathStop();
		}
		BaseModel* bm = unitManager->getClosestFriendlyBaseModel(subject->getPosition());
		if(bm != NULL) {
			subject->getUnit()->move(bm->getPosition());
		}
		return true;
	}
	if(targetCell != NULL) {
		//Broodwar->drawLineMap(subject->getPosition().x(), subject->getPosition().y(), targetPosition.x(), targetPosition.y(), BWAPI::Colors::Yellow);

		if(subject->getPosition().getDistance(targetPosition) <= 200) {
				relinquishExploreTarget();
				//Broodwar->drawEllipseMap(subject->getPosition().x(), subject->getPosition().y(), 8, 8, BWAPI::Colors::Yellow, true);
				subject->pathStop();
		} else {
				if(subject->getUnit()->isMoving()) {
				} else {
					if(unitManager->getEnemyBaseModelInRegion(BWTA::getRegion(targetPosition)) == NULL) {
						subject->getUnit()->move(targetPosition);
					} else {
						subject->pathMove((TilePosition)targetPosition, PATHFINDING_THREATAWARE_ASTAR_AIR);
					}
				}
		}
		
		} else {
			pickNewTarget();
			
		}
	return false;
}

void AerialScoutBehaviour::nudge()
{

}

void AerialScoutBehaviour::pickNewTarget()
{
	// pick new target
	std::vector<InformationCell*> mapCells = unitManager->getMapInformationSystem()->getMapCells();
	float bestRatio = -1000000;
	InformationCell* bestCell = NULL;
	for (vector<InformationCell*>::iterator i = mapCells.begin(); i != mapCells.end(); ++i)
	{
		InformationCell* cur = *i;
		if(cur->getInformationValue() == 0.00) {
			continue;
		}

		if(bestCell == NULL) {
			bestCell = cur;
		} else {
			int distance = cur->getPosition().getDistance(subject->getPosition());
			float qualityValue = cur->getInformationValue();
			if(cur->isBeingExplored()) {
				qualityValue*=0.5;
			}
			if(qualityValue > bestRatio) {
				bestCell = cur;
				bestRatio = qualityValue;
			}
		}
	}
	targetCell = bestCell;
	if(targetCell == NULL) {
		targetPosition = BWAPI::Positions::None;
		return;
	}
	targetPosition = bestCell->getPosition();
	targetCell->setBeingExplored(true);
}

void AerialScoutBehaviour::relinquishExploreTarget()
{
	if(targetCell != NULL) {
		targetCell->setBeingExplored(false);
		targetCell = NULL;
	}
}

void AerialScoutBehaviour::reportEnemyBaseLoc()
{
	if(unitManager->getSuspectedEnemyBaseLoc() != Positions::None) {
		return;
	}
	std::vector<UnitModel*> enms = unitManager->getAllEnemyUnitsInRange(subject->getPosition(), 300);
	std::vector<UnitModel*> fenms;
	// wait, lets also filter for scouting probes
	for(std::vector<UnitModel*>::iterator i = enms.begin(); i != enms.end(); i++) {
		if((*i)->getType().isWorker()) {

		} else {
			fenms.push_back((*i));
		}
		if((*i)->getType().isBuilding()) {
			// then we've probably got it
			break;
		}
	}


	if(fenms.empty()) {

	} else {
		std::set<BWTA::BaseLocation*> blocs = BWTA::getBaseLocations();

		BaseLocation* best = NULL;
		UnitModel* target = enms.at(0);
		for(std::set<BWTA::BaseLocation*>::const_iterator i = blocs.begin(); i != blocs.end(); i++) {
			BaseLocation* cur = *i;
			if(!cur->isStartLocation()) {
				continue;
			}
			if(best == NULL) {
				best = cur;
			} else {
				int bdist = best->getPosition().getDistance(target->getPosition());
				int cdist = cur->getPosition().getDistance(target->getPosition());
				if(cdist < bdist) {
					best = cur;
				}
			}

		}
		unitManager->registerSuspectedEnemyBaseLoc(best->getPosition());
	}
}
