#pragma once
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/Protoss/ReaverDrop/ReaverControlBehavior.h"
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/Protoss/ReaverDrop/ShuttleControlBehavior.h"
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/Protoss/ReaverDrop/ReaverShuttleGroupBehavior.h"
#include "../Scenario.h"

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

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

    return module;
  }

protected:
  virtual void onSparStarted(void* data)
  {
    const std::set<BWAPI::Unit*>& units = BWAPI::Broodwar->self()->getUnits();
    BWAPI::Unit* reaver[15];
    int k = 0;
    // Reaver
    for (std::set<BWAPI::Unit*>::const_iterator it = units.begin();
         it != units.end();
         ++it)
    {
      BWAPI::Unit* unit = (*it);
      if (unit->getType() == BWAPI::UnitTypes::Protoss_Reaver){
        Behavior* behavior = new ReaverControlBehavior(this, 100, unit);
        behavior->zombifyOnTerminate();
        behavior->start();
        reaver[k] = unit;
        k++;
      }
    }
    k=0;
    // Shuttle
    for (std::set<BWAPI::Unit*>::const_iterator it = units.begin();
         it != units.end();
         ++it)
    {
      BWAPI::Unit* unit = (*it);
      if (unit->getType() == BWAPI::UnitTypes::Protoss_Shuttle){
        Behavior* behavior = new ShuttleControlBehavior(this, 100, unit,reaver[k]);
        behavior->zombifyOnTerminate();
        behavior->start();
        k++;
      }
    }
  }

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