#pragma once
#include "../../../Utils/Process/ProcessContainer.h"
#include "../../../PerceptualState/Locations/Static/AutoPopulated/BaseLocation.h"
#include "../../Layer2Actions/Interface/Actions/Collect.h"
#include "../../Layer2Actions/Interface/Actions/Recruit.h"
#include "../../Layer2Actions/Interface/Actions/Build.h"
#include "L3Priority.h"

class L3BaseLocation : public BaseLocation
{
public:
  L3BaseLocation(const BWTA::BaseLocation* baseLocation, Region* parent)
    : BaseLocation(baseLocation, parent)
    , m_collectMineralsEndedEventHandler(*this)
    , m_collectGasEndedEventHandler(*this)
    , m_probeRecruitedEventHandler(*this)
    , m_collectMinerals(*this)
    , m_collectGas(*this)
    , m_recruitProbes(*this)
    , m_buildAssimilators(*this)
  {
  }

  ~L3BaseLocation()
  {
  }

  size_t getNbProbesOnMinerals() const
  {
    return m_collectMinerals->getGroup()->size();
  }
  CollectMinerals* getCollectMinerals()
  {
    return m_collectMinerals;
  }

  size_t getNbProbesOnGas() const
  {
    return m_collectGas->getGroup()->size();
  }
  CollectGas* getCollectGas()
  {
    return m_collectGas;
  }

  void buildAssimilator(const Process* parent);

  void instantiateCollectActions(const Process* parent);

  void executeCollectResources(const Process* parent);

  void executeRecruitProbes(const Process* parent);
  void cancelRecruitProbes();

protected:
  std::string probesName(const std::string suffix)
  {
    std::stringstream ss;
    ss << "Location#" << getID() << "-Probes" << suffix;
    return ss.str();
  }

  void onCollectMineralsEnded(void* data);
  void onCollectGasEnded(void* data);
  void onProbeRecruited(void* data, const Recruit* recruit, BWAPI::Unit* probe);

  EVENT_HANDLER(L3BaseLocation, onCollectMineralsEnded) m_collectMineralsEndedEventHandler;
  EVENT_HANDLER(L3BaseLocation, onCollectGasEnded) m_collectGasEndedEventHandler;
  EVENT_HANDLER2(L3BaseLocation, onProbeRecruited, const Recruit*, BWAPI::Unit*) m_probeRecruitedEventHandler;

  ProcessContainer<CollectMinerals> m_collectMinerals;
  ProcessContainer<CollectGas> m_collectGas;
  ProcessContainer<Recruit> m_recruitProbes;
  ProcessContainerList<Build> m_buildAssimilators;

private:
  L3BaseLocation(const L3BaseLocation& other);
};