#pragma once
#include "../../../Conditions/ReachedDestination.h"
#include "../../Utils/WrapperState.h"
#include "../Move/UnitMove/UnitMoveBehavior.h"
#include "ScoutBehavior.h"

/**
 * @brief The MotionScoutBehavior instructs a scouting unit to move using a threat-aware UnitMove behavior.
 */
class MotionScoutBehavior : public ScoutBehaviorT<MotionScoutBehavior>
{
protected:
  class GoToLocation;
  friend class GoToLocation;

  //State where the scout goes to the requested location
  class GoToLocation : public WrapperState<MotionScoutBehavior, GoToLocation, NoTransitionAction, GoToLocation>
  {
  public:
    GoToLocation(MotionScoutBehavior& behavior)
      : WrapperState(behavior, NoTransitionAction(), behavior.m_goToLocationState)
      , m_frameEvent(*this, Scheduler::SCHEDULING_MEDIUM_PRIORITY, 5, 0)
      , m_success(true)
    {}
    
	  Behavior* createSubBehavior();

    void onEnter();
    void onExit();

    void onSubBehaviorTerminated();
    void onFrame();

  protected:
    BWAPI::Position getNextPositionToScout() const;

    SCHEDULER_EVENT_HANDLER(GoToLocation, onFrame) m_frameEvent;
    bool m_success;
  };

public:
  MotionScoutBehavior(const Process* parent, unsigned int initialPriority, StaticLocation* location, BWAPI::Unit* scoutingUnit, lookahead_t lookahead = 0);

  typedef boost::tuple<
      GoToLocation&
    > States;
	const States m_states;

protected:
  virtual void _output(std::ostream& out) const
  {
    out << "MotionScoutBehavior(" << *m_unit << ")";
  }

  virtual void onStart()
  {
    UnitBehaviorT::onStart();
    m_goToLocationState.enter();
  }

  // States
  GoToLocation m_goToLocationState;
  bool m_scoutArrivedEventRaised;
  const lookahead_t m_lookahead;
};