#include "stdafx.h"
#include "ReaverShuttleGroupBehavior.h"
#include "../../General/Move/GroupMoveBehavior.h"
#include "../../../Layer1FSM.h"

///////////////////////////////////////////////////
// SetPairs state
///////////////////////////////////////////////////

ReaverShuttleGroupBehavior::SetPairs::SetPairs(ReaverShuttleGroupBehavior& behavior)
  : BehaviorStateT(behavior)
  , m_event(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 1, 1)
  , m_transitionToPickUpState(*this,
                              NoCondition(), 
                              NoTransitionAction(),
                              behavior.m_pickUpState)
  , m_events(m_event)
  , m_transitions(m_transitionToPickUpState)
{
}

void ReaverShuttleGroupBehavior::SetPairs::onEnter()
{
  std::set<BWAPI::Unit*>::const_iterator it_shuttles = m_context.m_shuttles->begin();
  for(std::set<BWAPI::Unit*>::const_iterator it_reavers = m_context.m_reavers->begin();
    it_reavers != m_context.m_reavers->end();
    ++it_reavers)
  {
    if(it_shuttles != m_context.m_shuttles->end()){
      m_context.m_pairs.insert(std::pair<BWAPI::Unit*,BWAPI::Unit*>((*it_shuttles),(*it_reavers)));
      it_shuttles++;
    }
  }
}

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

ReaverShuttleGroupBehavior::PickUp::PickUp(ReaverShuttleGroupBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_loadUnitCommand(*this)
  , m_event(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 5, 5)
  , m_transitionToSendToTargetState(*this,
                                    AllPickedUp<std::set<BWAPI::Unit*>>(*behavior.m_reavers), 
                                    NoTransitionAction(),
                                    behavior.m_sendToTargetState)
  , m_events(m_event)
  , m_transitions(m_transitionToSendToTargetState)
{
}


void ReaverShuttleGroupBehavior::PickUp::onEnter()
{
  //send them to pick reaver
  for(std::map<BWAPI::Unit*,BWAPI::Unit*>::const_iterator it = m_context.m_pairs.begin();it != m_context.m_pairs.end();it++)
  {
    Layer1FSM::getInstance().getArbitrator().
      submitCommand((*it).first, LoadUnitCommand(*this, it->second), Arbitration::ActionImportance(m_context));
  }
}

///////////////////////////////////////////////////
// SendToTarget state
///////////////////////////////////////////////////

ReaverShuttleGroupBehavior::SendToTarget::SendToTarget(ReaverShuttleGroupBehavior& behavior)
  : BehaviorStateT(behavior)
  //, m_moveCommand(*this)
  , m_event(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 5, 5)
  , m_transitionToAttackPhaseState(*this,
                                   GroupReachedPosition<std::set<BWAPI::Unit*>>(*behavior.m_shuttles,behavior.m_enemyBase, DEFAULT_GROUP_MAX_DISTANCE), 
                                   NoTransitionAction(),
                                   behavior.m_attackPhaseState)
  , m_events(m_event)
  , m_transitions(m_transitionToAttackPhaseState)
{
}

void ReaverShuttleGroupBehavior::SendToTarget::onEnter()
{
  for(std::map<BWAPI::Unit*,BWAPI::Unit*>::const_iterator it = m_context.m_pairs.begin();it != m_context.m_pairs.end();it++)
  {
    Layer1FSM::getInstance().getArbitrator().
      submitCommand((*it).first, MoveCommand(*this, m_context.m_enemyBase), Arbitration::ActionImportance(m_context));
  }
}

///////////////////////////////////////////////////
// AttackPhase state
///////////////////////////////////////////////////

ReaverShuttleGroupBehavior::AttackPhase::AttackPhase(ReaverShuttleGroupBehavior& behavior)
  : BehaviorStateT(behavior)
  , m_event(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 5, 5)
  , m_transitionToRemoveUnitState(*this,
                                  PairBroken<std::set<BWAPI::Unit*>>(*behavior.m_reavers), 
                                  NoTransitionAction(),
                                  behavior.m_removeUnitState)
  , m_events(m_event)
  , m_transitions(m_transitionToRemoveUnitState)
{
}

void ReaverShuttleGroupBehavior::AttackPhase::onEnter()
{
  //spawn ATTACK!~
}

///////////////////////////////////////////////////
// RemoveUnit state
///////////////////////////////////////////////////

ReaverShuttleGroupBehavior::RemoveUnit::RemoveUnit(ReaverShuttleGroupBehavior& behavior)
  : BehaviorStateT(behavior)
  , m_event(*this, Scheduler::FSM_SCHEDULING_PRIORITY, 5, 5)
  , m_transitionToSelf(*this,
                       PairBroken<std::set<BWAPI::Unit*>>(*behavior.m_reavers), 
                       NoTransitionAction(),
                       *this)
 , m_events(m_event)
 , m_transitions(m_transitionToSelf)
{
}

void ReaverShuttleGroupBehavior::RemoveUnit::onEnter()
{
  //Remove pair
}