#include "stdafx.h"
#include "MeleeEngageBehavior.h"
#include "../../Layer1FSM.h"
#include "../../../../../PerceptualState/PerceptualState.h"
#include <BWAPI.h>

///////////////////////////////////////////////////
// Engaging state
///////////////////////////////////////////////////

MeleeEngageBehavior::Engaging::Engaging(MeleeEngageBehavior& behavior)
  : BehaviorStateT(behavior)
  , m_unitDestroyedEventHandler(*this)
  //, m_attackMoveCommand(*this)
  , m_timerEvent(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 10, 10)
  /*, m_transitionToSelf(
      *this,
      m_enemyUnitsInLocationEvent,
      NoCondition(), 
      NoTransitionAction(),
      *this)*/
  , m_events(m_timerEvent)
  , m_transitions(/*m_transitionToSelf*/)
{
}

MeleeEngageBehavior::Engaging::~Engaging()
{
}

void MeleeEngageBehavior::Engaging::prepare()
{
  m_context.m_enemyUnits = Spar->getPerceptualState()->getEnemyUnits(GroupRectangularLocation(m_context.getGroup()));
}

void MeleeEngageBehavior::Engaging::onEnter()
{
  if (m_context.m_enemyUnits.size() == 0)
    m_context.terminate(BehaviorT::Success);
  else
    findTargetAndFire();
}

void MeleeEngageBehavior::Engaging::onTimer()
{
  m_context.m_enemyUnits = Spar->getPerceptualState()->getEnemyUnits(GroupRectangularLocation(m_context.getGroup()));

  if (m_context.m_enemyUnits.size() == 0)
    m_context.terminate(BehaviorT::Success);
  else
    findTargetAndFire();
}

void MeleeEngageBehavior::Engaging::onUnitDestroyed(void*)
{
  if (m_context.m_enemyUnits.size() == 0)
    m_context.terminate(BehaviorT::Success);
  else
    findTargetAndFire();
}

void MeleeEngageBehavior::Engaging::findTargetAndFire()
{
	BWAPI::Position center = m_context.getGroup()->getCenter();
  BWAPI::Unit* nearestEnemyUnit = GroupHelper::getNearest(m_context.m_enemyUnits, center);
	
	BWAPI::getIndividualUnitDestroyEvent(nearestEnemyUnit).subscribe(&m_unitDestroyedEventHandler,0);

  Layer1FSM::getInstance().getArbitrator().
      submitCommand(m_context.getGroup(), AttackMoveCommand(*this, nearestEnemyUnit->getPosition()), Arbitration::ActionImportance(m_context));
}

void MeleeEngageBehavior::Engaging::onExit()
{
}