#pragma once
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/General/Move/UnitMove/ThreatAwareUnitMoveBehavior.h"
#include "../../PerceptualState/Locations/Static/Shape/CoordinatesLocation.h"
#include "../Scenario.h"
#include <limits>

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

    SPAR* module = sparFactory.instantiate<Layer1GameState, Layer2Cueing, Layer3TacticalRecognition, Layer4StrategicRecognition,
                                           Layer1FSM, Layer2Managers, InactiveLayer3, InactiveLayer4>(this);

    return module;
  }

protected:
  virtual void onSparStarted(void* data)
  {
    const std::set<BWAPI::Unit*>& units = BWAPI::Broodwar->self()->getUnits();

    //BWAPI::Broodwar->enableFlag(BWAPI::Flag::CompleteMapInformation);

    BWAPI::Unit* observer = NULL;
    BWAPI::Unit* flag = NULL;

    for (std::set<BWAPI::Unit*>::const_iterator it = units.begin(); it != units.end(); ++it)
    {
      BWAPI::Unit* unit = (*it);
      BWAPI::UnitType type = unit->getType();
      if (unit->getType() == BWAPI::UnitTypes::Powerup_Flag)
      {
        flag = unit;
      }
      else if (unit->getType() == BWAPI::UnitTypes::Protoss_Observer)
      {
        observer = unit;
      }
    }

    UnitMoveBehavior::MoveOptions options = ThreatAwareUnitMoveBehavior::getDefaultMoveOptions(
      pathfinding::GeneralThreatEvaluator(observer), 
      pathfinding::ConsiderThreatAsObstacle(observer), 
      128,           // lookahead
      1 * TILE_SIZE, // max distance
      2);            // refresh rate
    ThreatAwareUnitMoveBehavior* behavior = new ThreatAwareUnitMoveBehavior(
      this, 
      100, 
      observer, 
      flag->getPosition(), 
      options);
    behavior->zombifyOnTerminate();
    behavior->start();
  }

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