#include "stdafx.h"
#include "GroupTacticalAction.h"
#include "../../../../BWAPI_Addon.h"
#include "../Layer2UnitData.h"

bool GroupTacticalAction::addActionToUnit(BWAPI::Unit* unit, bool force)
{
  return dynamic_cast<Layer2UnitData&>(BWAPI::getUnitData(unit)).proposeAction(this, force);
}

void GroupTacticalAction::removeActionFromUnit(BWAPI::Unit* unit)
{
  dynamic_cast<Layer2UnitData&>(BWAPI::getUnitData(unit)).removeAction(this);
}

void GroupTacticalAction::onStart()
{
  // Don't call GroupProcess::onStart() as it will be called in onStartInterface()
  TacticalAction::onStart();
}

void GroupTacticalAction::onStartInterface()
{
  TacticalAction::onStartInterface();

  if (m_initialGroup != NULL)
  {
    m_initialGroup->getUnitAddedEvent().unsubscribe(m_initialUnitAddedID);
    m_initialGroup->getUnitRemovedEvent().unsubscribe(m_initialUnitRemovedID);
    m_initialGroup->getGroupDestroyedEvent().unsubscribe(m_initialGroupDestroyedID);
  }
  for (PersistentUnitGroup::iterator it = m_group.begin(); it != m_group.end(); /**/)
  {
    BWAPI::Unit* initialUnit = *it;
    PersistentUnitGroup::iterator next = ++PersistentUnitGroup::iterator(it);
    if (!addActionToUnit(initialUnit, false))
    {
      m_group.remove(it);
    }
    it = next;
  }

  GroupProcess::onStart();
  // At this point the reference to initialGroup could be released

#ifdef _DEBUG
  for (PersistentUnitGroup::const_iterator it = getGroup()->begin(); it != getGroup()->end(); ++it)
  {
    assert(dynamic_cast<Layer2UnitData&>(BWAPI::getUnitData(*it)).getCurrentAction() == this);
  }
#endif
}

void GroupTacticalAction::_output(std::ostream& out) const
{
  TacticalAction::_output(out);
}

void GroupTacticalAction::onEnd()
{
  // Don't call GroupProcess::onEnd() as it will be called in onEndInterface()
  TacticalAction::onEnd();
}

void GroupTacticalAction::onEndInterface()
{
  TacticalAction::onEndInterface();

  GroupProcess::onEnd();

  for (PersistentUnitGroup::iterator it = m_group.begin(); it != m_group.end(); /**/)
  {
    PersistentUnitGroup::iterator next = ++PersistentUnitGroup::iterator(it);
    removeActionFromUnit(*it);
    // At the moment, units are NOT removed from the group during termination
    //m_group.remove(it);
    it = next;
  }
}