#include "stdafx.h"
#include "UnitAttackBehavior.h"

BWAPI::Unit* UnitAttackBehavior::selectTargetImpl(const std::set<BWAPI::Unit*>& enemies) const
{
  //int targetHealth = boost::numeric::bounds<int>::highest();
  //int targetDistance = boost::numeric::bounds<int>::highest();
  //bool targetIsThreat = false;
  //bool targetInRange = false;
  int targetValue = boost::numeric::bounds<int>::lowest();
  BWAPI::Unit* target = NULL;

  for(std::set<BWAPI::Unit*>::const_iterator i=enemies.begin(); i!=enemies.end(); ++i)
  {
    BWAPI::Unit* enemyUnit = *i;
    //Ignore invisible units, eggs and larvae
    if(!enemyUnit->isDetected() 
      || (m_unit->getType().airWeapon() == BWAPI::WeaponTypes::None && enemyUnit->getType().isFlyer())
      || enemyUnit->getType() == BWAPI::UnitTypes::Zerg_Larva 
      || enemyUnit->getType() == BWAPI::UnitTypes::Zerg_Egg)
      continue;

    const int health = enemyUnit->getHitPoints() + enemyUnit->getShields();
    const bool inRange = m_unit->isInWeaponRange(enemyUnit);
    const int distance = enemyUnit->getDistance(m_unit->getPosition());
    //not a threat if the enemyUnit is a worker or if the enemyUnit is a building that cannot attack
    const bool isThreat = !(enemyUnit->getType().isWorker() || (enemyUnit->getType().isBuilding() && !enemyUnit->getType().canAttack() && enemyUnit->getType() != BWAPI::UnitTypes::Terran_Bunker));

    // TODO: type of weapon vs enemy unit resistance
    const int value = static_cast<int>(
      - 10 * health 
      - (inRange? 0 : 40 * (double)distance) 
      + (isThreat? 5000 : 0) 
      + (enemyUnit->getType().isWorker() ? 100 : 0)
      - (enemyUnit->getType().isAddon() ? -10000 : 0)
    );
    if (value > targetValue)
    {
      targetValue = value;
      target = enemyUnit;
    }

    //if( (!targetIsThreat || isThreat)
    // && ((!targetIsThreat && isThreat) || distance < targetDistance || (inRange && health < targetHealth)))
    //{
    //  targetHealth = health;
    //  targetDistance = distance;
    //  target = enemyUnit;
    //  targetIsThreat = isThreat;
    //}
  }
  return target;
}