/****************************************************************************/
/* Copyright (c) 2007 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : AmcAgent.h                                                    */
/* Author   :                                                               */
/* Project  : Onboard Deliberative Autonomy                                 */
/* Version  : 1.0                                                           */
/* Created  : 02/14/2007                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#ifndef _AmcAgent_H
#define _AmcAgent_H

#include <sys/select.h>
#include "Attributes.h"
#include "MessageQueue.h"
#include "Task.h"

#define DEFAULT_PORT 8004
#define DEFAULT_HUP  10    // AMC timeout (seconds) after which assume AMC died

#define DEFAULT_CONFIG "amcAgent.cfg"
#define AmcMessageQueueName "amcMessages"

/*
CLASS 
AmcAgent

DESCRIPTION
Gather data representing the state of the vehicle, and broadcast data
over socket. We'll implement the publisher as a device driver in order
to use common idioms and framework components we're all familiar with.

*/

class LayeredControlIF;
class AmcMessage;

class AmcAgent {

public:
  
  /////////////////////////////////////////////////////////
  // overloaded Constructor
  AmcAgent(Boolean sim = False, 
           Boolean verbose = False, char* configfile = DEFAULT_CONFIG);

  ///////////////////////////////////////////////////////
  //destructor
  virtual  ~AmcAgent();
  int init();
  void run();
  LayeredControlIF* getLC() { return _layeredControlIF; }

protected:

  FILE *_log;
  Boolean _verbose;
  Boolean _missionStarted;
  int     _socket;
  int     _client;
  int     _insertNum, _appendNum;
  long    _port;
  long    _hupTime;
  long    _msgTime;
  long    _period;
  long    _sdelta;
  fd_set  _fdset;
  LayeredControlIF* _layeredControlIF;

  char*  _config;
  char*  _sim;
  struct sockaddr_in _servaddr, _cliaddr;
  Attributes _attributes;
  AmcMessage *_msgs;

  //////////////////////////////////////////////////////////////// 
  // initialization function - create interfaces to the servers
  // we're going to need, create the socket, etc.
  //
  int openLC();  // Open interface to LayeredControl
  int  setupSocket();
  int  acceptClient();
  void createCfgAttributes();
  void loadConfigFile(const char* file);
  void reportCfgAttributes();
  void handleAmcRequest(const char *msg);
  void handleLCMessages();
  void ackAmc (long id, const char *msg);
  void nackAmc(long id, const char *msg);
  int writeAndVerify(const char *behaviors, const char *file);
  
  int initMission(const char* initialStack);
  int appendBehaviors(const char *behaviors);
  int insertBehaviors(const char *behaviors);
  int deleteBehavior(const char *id);
  
  void log(const char *format, ...);
};

#endif
