#pragma once
#include "../Scenario.h"
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/General/Move/UnitMove/ThreatAwareUnitMoveBehavior.h"
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/Protoss/CorsairHarassmentBehavior.h"
#include "../../PerceptualState/Locations/Static/AutoPopulated/Map.h"

class TestRetreatScenario : public Scenario<TestRetreatScenario>
{
public:
  TestRetreatScenario()
    : m_moveAction(*this)
  {}

  template <class SparAIFactory>
  SparAIContainer* instantiateSparAIImpl(SparAIFactory& sparFactory)
  {
    typedef SparAIModule<Layer1GameState, Layer2Cueing, Layer3TacticalRecognition, Layer4StrategicRecognition,
                         Layer1FSM, InactiveLayer2, InactiveLayer3, InactiveLayer4> SPAR;

    return sparFactory.instantiate<Layer1GameState, Layer2Cueing, Layer3TacticalRecognition, Layer4StrategicRecognition,
                                   Layer1FSM, InactiveLayer2, InactiveLayer3, InactiveLayer4>(this);
  }

protected:
  virtual void onSparStarted(void* data)
  {
    BWAPI::Unit* corsair = NULL;
    const std::set<BWAPI::Unit*>& units = BWAPI::Broodwar->self()->getUnits();
    for (std::set<BWAPI::Unit*>::const_iterator it = units.begin(); it != units.end(); ++it)
    {
      BWAPI::Unit* unit = (*it);
      if (unit->getType() == BWAPI::UnitTypes::Protoss_Corsair)
      {
        corsair = unit;
        break;
      }
    }

    UnitMoveBehavior::MoveOptions options = ThreatAwareUnitMoveBehavior::getDefaultMoveOptions(
      pathfinding::GeneralThreatEvaluator(corsair), 
      pathfinding::ConsiderThreatAsObstacle(corsair), 
      0,                                          // lookahead
      corsair->getType().airWeapon().maxRange(),  // max distance
      2,                                          // refresh rate
      boost::numeric::bounds<size_t>::highest()); // giving up delay

    m_moveAction = new ThreatAwareUnitMoveBehavior(
      this,
      100,
      corsair,
      BWAPI::getCenter(BWAPI::TilePosition(43,3)),
      options);
    m_moveAction->start();
  }

  void _output(std::ostream &out) const
  {
    out << "TestRetreat Scenario";
  }

  ProcessContainer<ThreatAwareUnitMoveBehavior> m_moveAction;
};