#pragma once
#include "../../../../PerceptualState/Processes/MonitoringProcess/UpgradeMonitoringProcess.h"
#include "../../../../PerceptualState/Processes/MonitoringProcess/TechMonitoringProcess.h"
#include "../../Interface/Actions/Research.h"
#include "L2TacticalAction.h"

class L2Research : public virtual Research, public L2TacticalAction
{
public:
  L2Research(const Process* parent, unsigned int priority)
    : Research(parent, priority)
    , L2TacticalAction(parent, priority)
    , TacticalAction(parent, priority)
    , Process(parent)
    , m_researchTerminateEventHandler(*this)
    , m_resourceAllocatedEventHandler(*this)
    , m_resourcesRequest(m_resourceAllocatedEventHandler)
    , m_researchProcess(NULL)
    , m_building(NULL)
  {
  }

  virtual UnitRecordGroup _getUnitsInvolved() const;

protected:
  virtual void onStartImplementation();
  virtual void onCancelImplementation();
  virtual void onEndImplementation();
  virtual void onResourcesAllocated(void*, BWAPI::Unit* building) = 0;

  void onResearchProcessTerminate(void*);  
  
  BWAPI::Unit* m_building;
  Layer2ManagersBase::ResourcesRequest m_resourcesRequest;
  MonitoringProcess* m_researchProcess;

  EVENT_HANDLER1(L2Research, onResourcesAllocated, BWAPI::Unit*) m_resourceAllocatedEventHandler;

  MonitoringProcess::OnTerminate::SubscriberID m_researchTerminateSubscriberID;
  EVENT_HANDLER(L2Research, onResearchProcessTerminate) m_researchTerminateEventHandler;
};

class L2UpgradeResearch : public virtual UpgradeResearch, public L2Research
{
public:
  L2UpgradeResearch(const Process* parent, unsigned int priority, UpgradeTypeObject* upgrade)
    : UpgradeResearch(parent, priority, upgrade)
    , L2Research(parent, priority)
    , Research(parent, priority)
    , TacticalAction(parent, priority)
    , Process(parent)
    , m_upgrade(upgrade)
  {    
  }

protected:
  UpgradeTypeObject* m_upgrade;

  virtual void onStartImplementation();
  virtual void onResourcesAllocated(void* data, BWAPI::Unit* b);
};

class L2TechResearch : public virtual TechResearch, public L2Research
{
public:
  L2TechResearch(const Process* parent, unsigned int priority, TechTypeObject* tech)
    : TechResearch(parent, priority, tech)
    , L2Research(parent, priority)
    , Research(parent, priority)
    , TacticalAction(parent, priority)
    , Process(parent)
    , m_tech(tech)
  {
  }

protected:
  TechTypeObject* m_tech;

  virtual void onStartImplementation();
  virtual void onResourcesAllocated(void* data, BWAPI::Unit* b);
};
