/****************************************************************************/
/* Copyright (c) 2006 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : smac.h                                                        */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 03/17/2006                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#ifndef _SMAC_H
#define _SMAC_H

/*
CLASS
smac

DESCRIPTION
Seafloor Mapping Acoustic Comms

AUTHOR
Rich Henthorn

*/

// Record Format
//  _____________________________________________________
//  | Data Record Header | Record Data Frame | Checksum |
//  -----------------------------------------------------
//
typedef struct tagSMAC_RECORD_HEADER
{ 
  unsigned int    version;   //	version of the frame protocol, 1, 2, 3, or 4
  unsigned int    rec_size;  // size of record data frame (portion after header)
  unsigned long   ts_sec;    // system time in milliseconds
  unsigned long   ts_msec;   // millisecond fraction of the current second
  unsigned int    record_type;
  long            parameter;
  unsigned int    checksum;  // header checksum
} SMAC_RECORD_HEADER;

// Seafloor Mapping Surface Aided Nav Record Format
typedef struct tagSMAC_SAN_RECORD
{
  // Data from WinFrog
  float wfTime;    // Timestamp
  float wfLat;     // Latitude
  float wfLong;    // Longitude
  float wfSlant;   // Slant range
} SMAC_SAN_RECORD;

// Seafloor Mapping Vehicle Status Record Format
typedef struct tagSMAC_STAT_RECORD
{
  // Data from AUV
  float auvLat;
  float auvLong;
  float auvHeading;
  float auvDepth;
  float auvAlt;
  float auvVolt;
  float auvHumid;
  unsigned int auvBehavior;
  unsigned int auvAbort;
} SMAC_STAT_RECORD;

// Seafloor Mapping Vehicle Command Record Format
typedef struct tagSMAC_CMD_RECORD
{
  // TBD
} SMAC_CMD_RECORD;


class smac 
{
  
public:

  smac();
  virtual ~smac();

  static const char* _behaviorNames[];

  enum RecordType {
    SAN = 0,     // Surface-aided nav record
    STAT,        // Vehicle Status record
	CMD,         // A simple command
    INVALID
  };

  enum CmdType {
    REQ_STAT,      // Surface request for status from vehicle
	REQ_SAN_ON,    // Vehicle requests surface to begin sending SAN messages
	REQ_SAN_OFF,   // Vehicle requests surface to stop sending SAN messages
	ABORT_MISSION, // Surface commanding vehicle to abort mission
	START_SURVEY,  // Surface commanding vehicle to start survey
    INVALID_CMD
  };

  enum BhavrType {
    ABORT_BHAVR = 0,
	DIVE_BHAVR,
	SURVEY_BHAVR,
	ASCEND_BHAVR,
	INVALID_BHAVR // Should always be the last one
  };

  // Serialize header and record into packet for transmission. Function inserts
  // version, timestamp, size, record type and checksum into the header.
  //
  // Returns 0 if successful, non-zero on error
  //
  // Parameters:
  // IN/OUT header - pointer to the header
  // IN san | st | cmd - pointer to record
  // IN/OUT packet - pointer to target packet area
  // OUT packet_size - size of target packet area
  //
  // Error conditions: (1) invalid pointers (2) packet too small
  //
  static int encodePacket(SMAC_RECORD_HEADER *header, SMAC_SAN_RECORD *san,
                   const char *packet, unsigned long *packet_size);
  
  static int encodePacket(SMAC_RECORD_HEADER *header, SMAC_STAT_RECORD *st,
                   const char *packet, unsigned long *packet_size);
  
  static int encodePacket(SMAC_RECORD_HEADER *header, SMAC_CMD_RECORD *cmd,
                   const char *packet, unsigned long *packet_size);

  // Decode serialized packet into SMAC header
  // Returns 0 if successful, -1 if checksum is invalid,
  // 1 if there's another problem
  //
  // Parameters:
  // IN packet
  // IN packet_size
  // IN/OUT header
  //
  static int decodeHeader(const char *packet, unsigned long packet_size,
                   SMAC_RECORD_HEADER *header);
                          
  // Decode serialized packet into SMAC record
  // Returns 0 if successful, -1 if checksum is invalid,
  // 1 if this isn't the correct record type
  //
  // Parameters:
  // IN packet
  // IN packet_size
  // IN/OUT san | st | cmd
  //
  static int decodeSanRecord(const char *packet, unsigned long packet_size,
                      SMAC_SAN_RECORD *san);

  static int decodeStatRecord(const char *packet, unsigned long packet_size,
                       SMAC_STAT_RECORD *st);

  static int decodeCmdRecord(const char *packet, unsigned long packet_size,
                      SMAC_CMD_RECORD *cmd);

  static unsigned int calcChecksum(const char *packet, unsigned long packet_size);

  static unsigned int calcChecksum(SMAC_RECORD_HEADER* hdr);

  static void setHeader(SMAC_RECORD_HEADER *header);

  static void printPacket(const char *packet, unsigned long packet_size);
  
protected:

  static const unsigned int _headerSize, _sanSize, _statSize, _cmdSize;
  
};

#endif
