#include "stdafx.h"
#include "ShuttleControlBehavior.h"
#include "../../../Layer1FSM.h"

///////////////////////////////////////////////////
// Waiting state

ShuttleControlBehavior::Waiting::Waiting(ShuttleControlBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_moveCommand(*this)
  , m_timerEvent(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 2, 2)
  , m_transitionToPickUpStateDanger(
      *this,
      InDanger(behavior.m_reaver), 
      NoTransitionAction(), 
      behavior.m_pickUpState)
  , m_transitionToPickUpStateTarget(
      *this,
      NoTarget(behavior.m_reaver), 
      NoTransitionAction(), 
      behavior.m_pickUpState)
  , m_transitionToSelf(
      *this,
      IsDecelerating(behavior.m_unit,behavior.m_reaver), 
      NoTransitionAction(), 
      *this)
  , m_events(m_timerEvent)
  , m_transitions(m_transitionToPickUpStateDanger,m_transitionToPickUpStateTarget,m_transitionToSelf)
{
}

void ShuttleControlBehavior::Waiting::onEnter()
{  
  int x = m_context.m_unit->getPosition().x() - m_context.m_reaver->getPosition().x();
  int y = m_context.m_unit->getPosition().y() - m_context.m_reaver->getPosition().y();
  if(x > 0)
    x = m_context.m_reaver->getPosition().x()-200;
  else
    x = m_context.m_reaver->getPosition().x()+200;
  if(y > 0)
    y = m_context.m_reaver->getPosition().y()-200;
  else
    y = m_context.m_reaver->getPosition().y()+200;
  Layer1FSM::getInstance().getArbitrator().submitCommand(m_context.m_unit, MoveCommand(*this, BWAPI::Position(x,y)), Arbitration::ActionImportance(m_context));
}

///////////////////////////////////////////////////
// Drop state

ShuttleControlBehavior::Drop::Drop(ShuttleControlBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_unloadAllUnitsAtPosition(*this)
  , m_unitIsUnloaded(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 1, 1)
  , m_transitionToWaitingState(
      *this,
      UnitOnGround(behavior.m_reaver), 
      NoTransitionAction(), 
      behavior.m_getDistanceState)
  , m_events(m_unitIsUnloaded)
  , m_transitions(m_transitionToWaitingState)
{
}

void ShuttleControlBehavior::Drop::onEnter()
{
  const BWAPI::Position position = Spar->getPerceptualState()->getEnemyInfluenceBorder(m_context.m_unit->getPosition());
  Layer1FSM::getInstance().getArbitrator().submitCommand(m_context.m_unit, UnloadAllUnitsAtPositionCommand(*this, position), Arbitration::ActionImportance(m_context));
}

///////////////////////////////////////////////////
// PickUp state

ShuttleControlBehavior::PickUp::PickUp(ShuttleControlBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_loadUnitCommand(*this)
  , m_unitIsLoaded(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 1, 1)
  , m_transitionToDropState(
      *this,
      UnitLoaded(behavior.m_reaver), 
      NoTransitionAction(), 
      behavior.m_dropState)
  , m_events(m_unitIsLoaded)
  , m_transitions(m_transitionToDropState)
{
}

void ShuttleControlBehavior::PickUp::onEnter()
{
	Layer1FSM::getInstance().getArbitrator().submitCommand(m_context.m_unit, LoadUnitCommand(*this, m_context.m_reaver), Arbitration::ActionImportance(m_context));
}

///////////////////////////////////////////////////
// ShieldRecharge state

ShuttleControlBehavior::GetDistance::GetDistance(ShuttleControlBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_moveCommand(*this)
  , m_moveActionGiven(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 1, 1)
  , m_transitionToWaitingState(
      *this,
      NoCondition(), 
      NoTransitionAction(), 
      behavior.m_waitingState)
  , m_events(m_moveActionGiven)
  , m_transitions(m_transitionToWaitingState)
{
}

void ShuttleControlBehavior::GetDistance::onEnter()
{
  int x = m_context.m_reaver->getPosition().x() + 150;
  int y = m_context.m_reaver->getPosition().y() + 150;
  Layer1FSM::getInstance().getArbitrator().submitCommand(m_context.m_unit, MoveCommand(*this, BWAPI::Position(x,y)), Arbitration::ActionImportance(m_context));
}
