#pragma once
#include "../../../Utils/Process/Process.h"
#include "TransportUnitRecordType.h"

/**
 * @brief A bunker unit record keeps track of what units are stored inside a specific bunker, doing so by evaluating
 *        the range of fire of the units within.
 */
class BunkerUnitRecordType : public TransportUnitRecordType
{
public:
  BunkerUnitRecordType(UnitRecord* unitRecord, BWAPI::UnitType unitType);

  class SavedState : public TransportUnitRecordType::SavedState
  {
  public:
    SavedState(BunkerUnitRecordType* unitRecordType)
      : TransportUnitRecordType::SavedState(unitRecordType)
    {}
  };

  virtual SavedState* saveState() 
  {
    return new SavedState(this);
  }

protected:
  class BunkerTroopsEstimationProcess : public Process
  {
  public:
    BunkerTroopsEstimationProcess(const Process* parent, BunkerUnitRecordType* bunker)
      : Process(parent)
      , m_bunker(bunker)
      , m_bunkerDestroyEventHandler(*this)
    { 
    }

    virtual UnitRecordGroup _getUnitsInvolved() const
    {
      UnitRecord* unitRecord = m_bunker->getUnitRecord();
      return UnitRecordGroup(&unitRecord, &unitRecord + 1);
    }

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

    virtual void onStart();
    virtual void onEnd();

    void onBunkerDestroy(void*)
    {
      terminate(Success);
    }

    // No need to register to morph/renegade since bunkers can't do that
    EVENT_HANDLER(BunkerTroopsEstimationProcess, onBunkerDestroy) m_bunkerDestroyEventHandler;
    UnitRecord::OnIndividualUnitRecordDestroy::SubscriberID m_bunkerDestroyID;

    BunkerUnitRecordType* const m_bunker;
  };

  ProcessContainer<BunkerTroopsEstimationProcess> m_troopsEstimationProcess;
};