   ew/****************************************************************************/
/* Copyright (c) 2015 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  : Power Buoy Data Logger log file writer class                  */
/* Filename : fileSource.cpp                                                */
/* Author   : Henthorn                                                      */
/* Project  : Power Buoy                                                    */
/* Version  : 1.0                                                           */
/* Created  : 04/21/2015                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
/*                                                                          */
/* This class is meant to be used with data source objects to write source  */
/* to a log file.                                                           */
/*                                                                          */
/****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>

#include "LogWriter.hpp"


// LogWriter constructor opens a log file for writing.
//
LogWriter::LogWriter(const char *filename)
   : _name(NULL), _file(NULL)
{
   _name = strdup(filename);
   _file = fopen(_name, "w+");
   write_header();
   memset(&_xb, 0, sizeof(_xb));
   memset(&_bc, 0, sizeof(_bc));
}

LogWriter::~LogWriter()
{
   if (_name) delete _name;
   if (_file) fclose(_file);
}

// Write a header to the CSV file
//
int LogWriter::write_header()
{
   if (_file)
   {
      // Write the Timestamp and Crossbow column names
      //
      const char* header = "Timestamp, Roll Angle (deg), Pitch Angle (deg), Yaw Angle (deg), " \
                           "X Rate, Y Rate, Z Rate, X Accel, Y Accel, Z Accel, " \
                           "North Vel, East Vel, Down Vel, Lat, Long, Alt, Temp, "
                           "BC Time, Voltage, P1DC, PMeas, MinDBar, Lag, "
                           "iTemp1, iTemp2, iTemp3, iTemp4, Target Voltage, Target Current, "
                           "IBridge, ILoad, BridgeDC, LoadDC, RPMs, Torque\n";
      if (fputs(header, _file) < 0)
         printf("Didn't write header\n");

      // Boost Controller columns
      //

      // Spring controller columns
      //

      fflush(_file);
   }
   return 0;
}

// Write a complete record to the CSV file
//
int LogWriter::write_record()
{
   if (_file)
   {
      struct timeval time;
      gettimeofday( &time, 0 );
      double sec = time.tv_sec + time.tv_usec / 1000000.0;

      char logbuf[32];
      sprintf(logbuf, "%.3f, ", sec);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write timestamp\n");

      write_xb();
      write_bc();
      write_sc();

      if (fputs("\n", _file) < 0)
         printf("Didn't write newline\n");

      fflush(_file);
   }
   return 0;
}

// Write the Crossbow record
//
int LogWriter::write_xb()
{
   if (_file)
   {
      char logbuf[320];
      sprintf(logbuf, "%.3f, %.3f, %.3f,",
         _xb.rollAngle, _xb.pitchAngle, _xb.yawAngleTrue);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, ",
         _xb.xRateCorrected, _xb.yRateCorrected, _xb.zRateCorrected, 
         _xb.xAccel, _xb.yAccel, _xb.zAccel, 
         _xb.nVelocity, _xb.eVelocity, _xb.dVelocity);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f, %.3f, %.3f, ",
         _xb.latitude, _xb.longitude, _xb.altitude, _xb.xRateTemp);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

   }
   return 0;
}

// Write the Boost controller record
//
int LogWriter::write_bc()
{
   if (_file)
   {
      char logbuf[320];
      sprintf(logbuf, "%.3f, %.3f, ",
         _bc.time, _bc.voltage);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%d, %d, %d, %d, ",
         _bc.p1dc, _bc.pmeas, _bc.mindbar, _bc.lag);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%d, %d, %d, %d, ",
         _bc.itemp1, _bc.itemp2, _bc.itemp3, _bc.itemp4);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f, ",
         _bc.vtarget, _bc.ctarget);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f, ",
         _bc.ibridge, _bc.iload);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f, ",
         _bc.bridgedc, _bc.loaddc);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

      sprintf(logbuf, "%.3f, %.3f ",
         _bc.rpms, _bc.torque);
      if (fputs(logbuf, _file) < 0)
         printf("Didn't write record\n");

   }
   return 0;
}

// Write the Spring Controller record
//
int LogWriter::write_sc()
{
   if (_file)
   {
   }
   return 0;
}

int LogWriter::update_xbow_record(Crossbow::XB_Record *xb_rec)
{
   memcpy(&_xb, xb_rec, sizeof(_xb));
   printf("Updating XB...%.3f\n", _xb.xRateTemp);
   return write_record();
}

int LogWriter::update_boost_record(CanBus::BC_Record *bc_rec)
{
   memcpy(&_bc, bc_rec, sizeof(_bc));
   printf("Updating BC...\n");
   return write_record();
}

int LogWriter::update_spring_record(void *sc_rec)
{
   return write_record();
}
