#pragma once
#include "../../../Utils/SafeMultiset.h"
#include "ActionResources.h"

// This class is only used to avoid circular references

class L2TacticalAction;

class Layer2ManagersBase
{
public:
  struct ResourcesRequest;
  struct SortByPriorityThenID
  {
    bool operator()(const ResourcesRequest* rr1, const ResourcesRequest* rr2) const;
  };
  typedef SafeMultiset<ResourcesRequest*, SortByPriorityThenID> ResourcesRequestsType;

  struct AvailableResourcesFunctor;
  struct UseResources;

  struct ResourcesRequest : public Component
  {
    ResourcesRequest(EventHandler1<BWAPI::Unit*>& p_eventHandler)
      : eventHandler(p_eventHandler)
      , isInContainer(false)
      , reserved(false)
    {}
    // Caller shouldn't set these values!
    unsigned int id;
    unsigned int priority;
    ActionResources actionResources;
    EventHandler1<BWAPI::Unit*>& eventHandler;
    bool isInContainer;
    bool reserved;
    ResourcesRequestsType::iterator posInContainer;
  protected:
    virtual void _output(std::ostream& out) const;
  private:
    ResourcesRequest(const ResourcesRequest& other);
    //reference member prevent the use of the assignment operator
    ResourcesRequest& operator=( const ResourcesRequest&);
  };
};

inline bool Layer2ManagersBase::SortByPriorityThenID::operator()(const Layer2ManagersBase::ResourcesRequest* rr1, 
                                                                 const Layer2ManagersBase::ResourcesRequest* rr2) const
{
  return rr1->priority > rr2->priority || (rr1->priority == rr2->priority && rr1->id < rr2->id);
}
