#pragma once
#include "../../../../Scheduler/SchedulerTaskHelper.h"
#include "../../../../PerceptualState/Locations/Static/AutoPopulated/AutoPopulatedLocation.h"
#include "TacticalAction.h"
#include <vector>

class Recruit : public virtual TacticalAction
{
public:
  Recruit(const Process* parent, unsigned int priority, AutoPopulatedLocation* location, const std::map<BWAPI::UnitType, size_t>& unitTypes, bool isInfinite = false)
    : TacticalAction(parent, priority)
    , Process(parent)
    , m_unitRecruitedEvent(*this)
    , m_location(*this, location)
    , m_units(unitTypes)
    , m_isInfinite(isInfinite)
  {}

  Recruit(const Process* parent, unsigned int priority, AutoPopulatedLocation* location, BWAPI::UnitType unitType, bool isInfinite = false)
    : TacticalAction(parent, priority)
    , Process(parent)
    , m_unitRecruitedEvent(*this)
    , m_location(*this, location)
    , m_units(getUnitTypes(unitType, 1))
    , m_isInfinite(isInfinite)
  {}

  const AutoPopulatedLocation* getLocation() const { return m_location; }
  AutoPopulatedLocation* getLocation() { return m_location; }

  const std::map<BWAPI::UnitType, size_t>& getUnitsToRecruit() const { return m_units; }

  DECLARE_EVENT2(OnUnitRecruited, const Recruit*, BWAPI::Unit*);
  OnUnitRecruited& getUnitRecruitedEvent() const { return m_unitRecruitedEvent; }

protected:
  virtual void _output(std::ostream& out) const;

  static std::map<BWAPI::UnitType, size_t> getUnitTypes(BWAPI::UnitType unitType, size_t nb)
  {
    std::map<BWAPI::UnitType, size_t> unitTypes;
    unitTypes.insert(std::make_pair(unitType, nb));
    return unitTypes;
  }

  const AutoPtr<AutoPopulatedLocation> m_location;
  const std::map<BWAPI::UnitType, size_t> m_units;
  const bool m_isInfinite;

  EVENT(OnUnitRecruited) m_unitRecruitedEvent;
};