#include "stdafx.h"
#include "../../../../PerceptualState/Resources/ResourceManager.h"
#include "../Layer3Script.h"
#include "../L3BaseLocation.h"
#include "BuildExpansionsProcess.h"
#include "../../../../PerceptualState/PerceptualState.h"
#include "../../../../PerceptualState/Locations/Static/Autopopulated/BaseLocation.h"

const static double SATURATION_RATIO_TO_TRIGGER_EXPAND = 0.85;

void BuildExpansionsProcess::run()
{
  // Expansions
  if (m_expand == NULL && 
      Spar->getPerceptualState()->getResourceManager()->calculateProbesSaturationRatio().getMineralsSaturationRatio() >= SATURATION_RATIO_TO_TRIGGER_EXPAND)
  {
    BaseLocation* expandLocation = getNextExpandLocation();
    if (expandLocation != NULL)
    {
      m_expand = Layer3Script::getInstance().getLayer2().instantiateExpand(
        this,
        PRIORITY_EXPAND,
        expandLocation);
      m_expand->start();
    }
  }
}

BaseLocation* BuildExpansionsProcess::getNextExpandLocation() const
{
  BaseLocation* bestLocation = NULL;
  double minDistance = boost::numeric::bounds<double>::highest();

  const Map* map = Spar->getPerceptualState()->getMap();
  std::pair<Map::base_location_const_iterator, Map::base_location_const_iterator> baseLocations = map->getBaseLocations();
  for (Map::base_location_const_iterator it = baseLocations.first; it != baseLocations.second; ++it)
  {
    BaseLocation* candidate = *it;
    if (candidate->getNbOwnUnits(BWAPI::UnitTypes::Protoss_Nexus) == 0 &&
        !candidate->hasEnemyResourceDepot() &&
        !candidate->hasEnemyArmyUnits())
    {
      BWAPI::TilePosition mainBasePos(Layer3Script::getInstance().getMainBase()->getCurrentCenter());
      BWAPI::TilePosition candiatePos(candidate->getCurrentCenter());
      if(BWTA::isConnected(mainBasePos, candiatePos))
      {
        double distance = BWTA::getGroundDistance(mainBasePos, candiatePos);
          //= m_layer3Script.getMainBase()->getCurrentCenter().getDistance(candidate->getCurrentCenter());
        if (distance < minDistance && distance > 0)
        {
          minDistance = distance;
          bestLocation = candidate;
        }
      }
    }
  }
  return bestLocation;
}