/** \file NMEA.cc 

  NMEA.cc - Implementation of NMEA and related classes.

  Implements NMEA, GPGGA, GPRMC and Field classes defined in NMEA.h
  Provides methods for synthesizing NMEA 0183 GPS strings.

  \author k. headley
  copyright MBARI 2008 
*/

/****************************************************************************/
/* Copyright (c) 2008 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : NMEA.cc                                                       */
/* Author   : K Headley                                                     */
/* Project  : Benthic Imaging AUV                                           */
/* Created  : 04/01/2008                                                    */
/****************************************************************************/
/* Modification History:                                                    */
/*  $Id: NMEA.cc,v 1.2 2009/02/11 00:44:11 headley Exp $   */
/*  $Name: FastSim $ */
/****************************************************************************/

#include "NMEA.h"

/** Default no argument constructor */
Field::Field(){}

/** Integer constructor 
    @param value - initial value
*/
Field::Field(int value){
  _intValue=value;
  _type=INT;
}
/** Unsigned integer constructor
    @param value - initial value
 */
Field::Field(unsigned int value){
  _uintValue=value;
  _type=UINT;
}
/** Double constructor
    @param value - initial value
 */
Field::Field(double value){
  _doubleValue=value;
  _type=DOUBLE;
}
/** Unsigned char constructor
    @param value - initial value
 */
Field::Field(unsigned char value){
  _ucharValue=value;
  _type=UCHAR;
}
/** Character constructor
    @param value - initial value
 */
Field::Field( char value){
  _charValue=value;
  _type=CHAR;
}
/** Character pointer constructor 
    @param value - initial value
*/
Field::Field( char *value){
  _pcharValue=value;
  _type=PCHAR;
}
/** time_t constructor
    @param value - initial value
 */
Field::Field(time_t value){
  _timeValue=value;
  _type=TIMET;
}
/** time_t constructor
    @param value - initial value
 */
Field::Field(struct timeval value){
  _tvalValue=value;
  _type=TVALT;
}
/** @return field type 
    @see FieldType
 */
Field::FieldType Field::getType(){
  return _type;
}

/** return _pcharValue member variable */
char *Field::pcharValue(){
  return _pcharValue;
}
/** return _charValue member variable */
char Field::charValue(){
  return _charValue;
}
/** return _intValue member variable */
int Field::intValue(){
  return _intValue;
}
/** @return _uintValue member variable */
unsigned int Field::uintValue(){
  return _uintValue;
}
/** @return _ucharValue member variable */
unsigned char Field::ucharValue(){
  return _ucharValue;
}
/** @return _doubleValue member variable */
double Field::doubleValue(){
  return _doubleValue;
}
/** @return _timeValue member variable */
time_t Field::timeValue(){
  return _timeValue;
}
/** @return _tvalValue member variable */
struct timeval Field::tvalValue(){
  return _tvalValue;
}
/** set _intValue member variable
    @param value new value
 */
void Field::setValue(int value){
  _intValue=value;
  _type=INT;
}
/** set _pcharValue member variable
    @param value new value
 */
void Field::setValue(char *value){
  _pcharValue=value;
  _type=PCHAR;
}
/** set _charValue member variable
    @param value new value
 */
void Field::setValue(char value){
  _charValue=value;
  _type=CHAR;
}
/** set _uintValue member variable
    @param value new value
 */
void Field::setValue(unsigned int value){
  _uintValue=value;
  _type=UINT;
}
/** set _ucharValue member variable
    @param value new value
 */
void Field::setValue(unsigned char value){
  _ucharValue=value;
  _type=UCHAR;
}
/** set _doubleValue member variable
    @param value new value
 */
void Field::setValue(double value){
  _doubleValue=value;
  _type=DOUBLE;
}
/** set _timeValue member variable
    @param value new value
 */
void Field::setValue(time_t value){
  _timeValue=value;
  _type=TIMET;
}
/** set _tvalValue member variable
    @param value new value
 */
void Field::setValue(struct timeval value){
  _tvalValue=value;
  _type=TVALT;
}

/** output stream operator.
    Formats object for output stream insertion
    @param output output stream handle
    @param n Field object pointer
 */
ostream& operator<<(ostream& output, const Field& n) {
  switch(n._type){
  case Field::PCHAR:
    output << n._pcharValue ;
    break;
  case Field::CHAR:
    output << n._charValue ;
    break;
  case Field::UINT:
    output << n._uintValue;
    break;
  case Field::INT:
    output << n._intValue;
    break;
  case Field::UCHAR:
    output << n._ucharValue;
    break;
  case Field::DOUBLE:
    output << n._doubleValue;
    break;
  case Field::TIMET:
    output << n._timeValue;
    break;
  case Field::TVALT:
    output<<setiosflags(ios::fixed)<< setw(5)<<setprecision(4)<< setfill('0')<< setiosflags(ios::showpoint)<<(double)n._tvalValue.tv_sec+((double)(n._tvalValue.tv_usec/1000000.0));
    break;
  case Field::DATET:
    output << n._timeValue;
    break;
  }
  return output;  // for multiple << operators.
}

/** Default no argument constructor */
NMEA::NMEA(){
  _type=t_UNKNOWN;
  _timestampRes=CENTISEC;
}

/** @return NMEA message type */
NMEA::MessageType NMEA::getType(){
  return _type;
}

/** @return specified field
    @param index field index
    @see NMEA::FIELDS
 */
Field *NMEA::getField(NMEA::FIELDS index){
  return &_fields[index];
}

/** Set integer field 
    @param field field index
    @param value new value
*/
void NMEA::setField(NMEA::FIELDS field,int value){
  getField(field)->setValue((int) value);
}
/** Set unsigned int field 
    @param field field index
    @param value new value
*/
void NMEA::setField(NMEA::FIELDS field,unsigned int value){
  getField(field)->setValue((unsigned int) value);
}
/** Set character pointer field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,char *value){
  getField(field)->setValue((char *) value);
}
/** set character field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,char value){
  getField(field)->setValue((char) value);
}
/** Set unsigned character field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,unsigned char value){
  getField(field)->setValue((unsigned char) value);
}
/** Set double field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,double value){
  getField(field)->setValue((double) value);
}
/** Set time_t field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,time_t value){
  getField(field)->setValue((time_t) value);
}
/** Set timeval field
    @param field field index
    @param value new value
 */
void NMEA::setField(NMEA::FIELDS field,struct timeval value){
  getField(field)->setValue((struct timeval) value);
}
/** set _timestampRes member variable.
    @see TIMESTAMP_RES
    @param value new value
 */
void NMEA::timestampResolution(TimestampResolution value){
  _timestampRes=value;
}

