#pragma once
#include "ArbitratorUnitData.h"

// Keep in mind: spamming attack-move actions every frame will cause the unit to move without attacking
// (hence BWAPI lastOrderFrame?)

class Command;
class PersistentUnitGroup;

/**
 * @brief The arbitration is in charge of resolving actions conflicts.
 *        This class is named "Arbitration" instead of "Arbitrator" to avoid name conflicts with BWSAL.
 */
class Arbitration
{
public:
  typedef ArbitratorUnitData::ActionImportance ActionImportance;

  Arbitration() {}

  ~Arbitration() {}

  void onStart() {}

  void onFrame() {}

  //void onFrame()
  //{
  //  executeActions();
  //}

  void onEnd() {}

  /**
   * @brief Submits an action to the arbitration to be accomplished by the specified unit.
   * @param unit the unit which is to accomplish the action.
   * @param command the command to accomplish.
   * @param importance details about the importance of the action.
   */
  template <class Command>
  void submitCommand(BWAPI::Unit* unit, const Command &command, ActionImportance importance)
  {
    unused(importance);

    command.execute(unit);
  }

  /**
   * @brief Submits an action to the arbitration to be accomplished by the specified group of units.
   * @param group the group of units which is to accomplish the action.
   * @param command the command to accomplish.
   * @param importance details about the importance of the action.
   */
  template <class Command>
  void submitCommand(const PersistentUnitGroup* group, const Command &command, ActionImportance importance)
  {
    unused(importance);

    command.executeForGroup(group);
  }

protected:
  /**
   * @brief Executes all actions which were deemed important. Note that all submitted actions will
   *        be cleared after this method terminates. 
   */
  //void executeActions();

  /**
   * @brief The units for which at least one action was previously submitted.
   */
  // Use hash_set?
  //std::set<BWAPI::Unit*> m_unitsWithSubmittedActions;
};