#pragma once
#include "../../DecisionMaking/Layer1Reactive/Layer1FSM/Behaviors/Protoss/EngageEnemies/GroupAttack/GroupAttackBehavior.h"
#include "../../PerceptualState/Locations/Static/Shape/CoordinatesLocation.h"
#include "../Scenario.h"

class CombatTroopVsZergScenario : public Scenario<CombatTroopVsZergScenario>
{
public:
  CombatTroopVsZergScenario()
    : m_group("Attack group")
    , m_groupAttack(*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)
  {
    const std::set<BWAPI::Unit*>& units = BWAPI::Broodwar->self()->getUnits();
    // FinitePatrolBehavior
    m_group.insert(units.begin(), units.end());
    const BWAPI::Position positionToAttack = BWAPI::Position(BWAPI::TilePosition(43, 3));
    m_groupAttack = new GroupAttackBehavior(this, 150, &m_group, new CoordinatesLocation(positionToAttack));
    m_groupAttack->start();
  }

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

  PersistentUnitGroup m_group;
  ProcessContainer<GroupAttackBehavior> m_groupAttack;
};