#pragma once
#include "UnitData.h"
#include <BWAPI.h>

/**
 * @brief This class holds arbitrator-related data for each unit.
 */
class ArbitratorUnitData : public virtual UnitData
{
  //
  // Problem: Right now only the highest potential successor action is kept. If the issuing
  //          behavior gets terminated after having issued the action, it is possible that
  //          no action is available for arbitration (since other potential actions were discarded).
  //

public:
  ArbitratorUnitData(BWAPI::Unit* unit)
    : UnitData(unit)
  {}

  /**
   * @brief Describes the importance of an action.
   *        Right now the importance is a simple unsigned integer.
   */
  struct ActionImportance
  {
    //ActionImportance()
    //{
    //}

    template <class Behavior>
    ActionImportance(const Behavior& behavior)
      : m_priority(behavior.getCurrentPriority())
    {
    }
  
    ActionImportance& operator= (const ActionImportance& importance)
    {
      m_priority = importance.m_priority;
      return *this;
    }

	  ActionImportance& operator= (const int importance)
    {
      m_priority = importance;
      return *this;
    }

    unsigned int m_priority;

    friend bool operator< (const ActionImportance& importance1, const ActionImportance& importance2)
    {
      return importance1.m_priority < importance2.m_priority;
    }

    friend bool operator> (const ActionImportance& importance1, const ActionImportance& importance2)
    {
      return importance1.m_priority > importance2.m_priority;
    }
  };


  //~ArbitratorUnitData();

  ///**
  // * @brief Adds a new potential action for this unit.
  // * @param action the action to add.
  // * @param importance the importance of the action to add.
  // */
  //void addSubmittedAction(const Command &action, ActionImportance importance);

  ///**
  // * @brief Chooses the action that this unit will accomplish, given a history of commands.
  // * @return the chosen action, possibly NULL.
  // */
  //const Command* arbitrate();

protected:
  //class ActionData : public Component
  //{
  //public:
  //  ActionData()
  //    : m_action(NULL), m_eventHandler(*this)
  //  {
  //  }

  //  const Command* getAction() const
  //  {
  //    return m_action;
  //  }

  //  //ActionImportance getImportance() const
  //  //{
  //  //  return m_importance;
  //  //}

  //  bool propose(const Command& action, ActionImportance importance);

  //  bool propose(ActionData& data);

  //  void clear();

  //  friend bool operator> (const ActionData& data1, const ActionData& data2)
  //  {
  //    // It is possible that a previously issued action was cancelled by the
  //    // subsequent termination of the issuing behavior, hence checking for NULL.

  //    return (data1.m_action != NULL &&
  //            (data2.m_action == NULL || data1.m_importance > data2.m_importance));
  //  }

  //protected:
  //  void onActionTerminate(void* data);

  //  const Command* m_action;
  //  ActionImportance m_importance;
  //  Command::OnActionEnded::SubscriberID m_id;
  //  EVENT_HANDLER(ActionData, onActionTerminate) m_eventHandler;
  //};

  ///**
  // * @brief The highest importance action that began executing previously at some point in time.
  // * @remarks Points to an element of m_actions.
  // */
  //ActionData* m_highestImportanceAction;
  ///**
  // * @brief The highest importance successor action, which may begin executing 
  // *        when a call to arbitrate() takes place.
  // * @remarks Points to an element of m_actions.
  // */
  //ActionData* m_possibleSuccessorAction;

  ///**
  // * @brief Buffer for possible actions.
  // */
  //ActionData m_actions[2];
};