#pragma once
#include "../../../Scheduler/SchedulerTaskHelper.h"
#include "../../../Utils/Process/Process.h"
#include <BWAPI.h>

class PerceptualState;

/**
 * @brief Process used to monitor the completion of something.
 */
class MonitoringProcess : public Process
{
public:
  MonitoringProcess(const Process* parent)
    : Process(parent)
  {}
  virtual void cancel() = 0;
  static const TerminationMode Cancelled;
protected:
  friend class PerceptualState;
  stdext::hash_map<BWAPI::Unit*, MonitoringProcess*>::iterator m_posInContainer;
};

template <class DerivedMonitoringProcess>
class MonitoringProcessT : public virtual MonitoringProcess
{
public:
  MonitoringProcessT(const Process* parent)
    : MonitoringProcess(parent)
    , m_timeoutEvent(*this, Scheduler::SCHEDULING_MEDIUM_PRIORITY,0,0)
  {
  }
protected:
  virtual void onStart()
  {
    if (!static_cast<DerivedMonitoringProcess*>(this)->testCompletion())
    {
      static_cast<DerivedMonitoringProcess*>(this)->setNewTimeout(false);
      m_timeoutEvent.activate();
    }
  }
  virtual void onEnd()
  {
    m_timeoutEvent.deactivate();
  }
  void onTimeout()
  {
    static_cast<DerivedMonitoringProcess*>(this)->onTimeoutImpl();
  }

  SCHEDULER_EVENT_HANDLER(MonitoringProcessT, onTimeout) m_timeoutEvent;
};
