/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#ifndef INCLUDED_Behavior_h
#define INCLUDED_Behavior_h

namespace Motion {
  class MotionCommand;
}

extern double MaxDX;
extern double MaxDY;
extern double MaxDA;

extern char* model;

#define MAX_DX MaxDX
#define MAX_DY MaxDY
#define MAX_DA MaxDA

#include "../Main/Events.h"
#include "FeatureSet.h"

//! A behavior that is capable of running independently (i.e. no arguments)
class IndependentBehavior : public EventProcessor {
private:
public:
  //! Gets the motion command that this behavior would like to execute
  /*! \param time the time at which a motion command is requested
      \return the desired motion command
  */
  virtual const Motion::MotionCommand *get(ulong time) = 0;

  //Similar to InitConnections() but does not do any Listen commands.
  //This should be used when one IndependentBehavior wants to call another
  //one and and instead of get() the parantheses operator - operator() -
  //is used.  This call should be executed after initializing the lower
  //level behavior.   
  virtual bool setupEventMgr() = 0;
};

//! A behavior that is called from the behavior tree.  Also capable of running 
//independently (i.e. no arguments) for testing purposes
class BehaviorSequence : public IndependentBehavior {
private:
public:
  BehaviorSequence()
  {
    numFailures  = 0;
    numSuccesses = 0;
  }

  //! Gets the motion command that this behavior would like to execute
  /*! \param time the time at which a motion command is requested
      \return the desired motion command
  */
  virtual const Motion::MotionCommand *get(ulong time) = 0;

  //Similar to InitConnections() but does not do any Listen commands.
  //This should be used when one IndependentBehavior wants to call another
  //one and and instead of get() the parantheses operator - operator() -
  //is used.  This call should be executed after initializing the lower
  //level behavior.   
  virtual bool setupEventMgr() = 0;

  //Return the execution status of the behavior sequence.
  // 1.0 = successful termination
  // 0.0 = active behavior, continue running
  //-1.0 = failure termination
  virtual double status(FeatureSet *features) = 0;

  //Resets the behavior (important for execution timeouts, etc).
  virtual void reset(ulong time) = 0;

  //! Records number of failures
  int numFailures;
  //! Records number of successes
  int numSuccesses;
};

#endif
