/* 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_BehaviorPacketEncoder_h
#define INCLUDED_BehaviorPacketEncoder_h

#include "../headers/SPOutEncoder.h"

/*------------------------------------------------------------------
CLASS
  BehaviorEncodeNames

DESCRIPTION
  Encodes behavior names.
------------------------------------------------------------------*/
class BehaviorEncodeNames : public SPOutEncoder {
public:
  template<class FSM,class State>
  static uchar *encodeAllNames(uchar *buf,int beh_id, const char *beh_name,int num_states,char const * const *state_names,FSM *fsm);
  
private:
};

template<class FSM,class State>
uchar *BehaviorEncodeNames::encodeAllNames(uchar *buf,int beh_id, const char *beh_name,int num_states,char const * const *state_names,FSM *fsm)
{
  uchar *bufp;

  bufp = buf;
  // behavior id
  encodeAs<uchar>(&bufp,beh_id);

  // behavior name
  encodeString<uchar>(&bufp,beh_name);

  // states
  encodeAs<uchar>(&bufp,num_states);
  for(int state_idx=0; state_idx<num_states; state_idx++){
    // state name
    const char *state_name=state_names[state_idx];
    encodeString<uchar>(&bufp,state_name);

    // transitions
    int num_transitions;
    num_transitions = fsm->countStateTransitions((State)state_idx);
    encodeAs<uchar>(&bufp,num_transitions);
    for(int trans_idx=0; trans_idx<fsm->maxTransitions(); trans_idx++){
      typedef const typename FSM::TransitionInfo ConstTransInfo;
      ConstTransInfo *trans_info;
      trans_info = fsm->lookupTransitionInfo((State)state_idx,trans_idx);
      if(trans_info!=NULL){
        encodeAs<uchar>(&bufp,trans_info->trans_id);
        encodeString<uchar>(&bufp,trans_info->trans_name);
      }
    }
  }

  return bufp;
}

/*------------------------------------------------------------------
CLASS
  BehaviorEncodeTrace

DESCRIPTION
  Encodes behavior traces.
------------------------------------------------------------------*/
class BehaviorEncodeTrace : public SPOutEncoder {
public:
  template<class FSM,class State>
  static uchar *encodeTrace(uchar *buf,int beh_id,FSM *fsm);
};
  
template<class FSM,class State>
uchar *BehaviorEncodeTrace::encodeTrace(uchar *buf,int beh_id,FSM *fsm)
{
  uchar *bufp;

  bufp = buf;

  encodeAs<uchar>(&bufp,beh_id);
  encodeAs<uchar>(&bufp,fsm->asleep());
  
  const typename FSM::TransitionEvent *event;
  int num_events;
  num_events = fsm->numEvents();
  encodeAs<uchar>(&bufp,num_events);
  for(int event_idx=0; event_idx<num_events; event_idx++){
    event = fsm->lookupEvent(event_idx);
    encodeAs<uchar>(&bufp,event->old_state);
    encodeAs<uchar>(&bufp,event->trans_id);
  }
  fsm->clearEvents();
  encodeAs<uchar>(&bufp,fsm->lookupState());

  return bufp;
}

#endif
