#include "DataLogWriter.h"
#include "BluefinBattLog.h"
#include "BluefinBatt.h"
#include "TimeP.h"
#include "Syslog.h"

BluefinBattLog::BluefinBattLog(BluefinBatt *driver, 
			       DataLog::FileFormat fileFormat,
			       int numbatts) 
   : _numBatts(numbatts), _driver(driver), _simDriver(0),
      DataLogWriter(BluefinBattLogName, fileFormat, AutoTimeStamp) 
{
   init();
}
BluefinBattLog::BluefinBattLog(Simulator *driver, 
			       DataLog::FileFormat fileFormat,
			       int numbatts) 
   : _numBatts(numbatts), _driver(0), _simDriver(driver),
      DataLogWriter(BluefinBattLogName, fileFormat, AutoTimeStamp) 
{
   init();
}

void BluefinBattLog::init()
{
  char buf[100];
  setMnemonic("bluefinBattLog");
  Boolean debug = False;

  // Create and initialize data structures for each battery in the array.
  // And setup units and longname fields for logging
  //
  _data = new struct battdata[_numBatts];

  for (int i = 0; i < _numBatts; i++)
  {
    sprintf(buf,      "voltage_%d", i);
    addField((_data[i].voltage = new DoubleData(buf)));
    _data[i].voltage->setUnits("Volts");
    sprintf(buf,      "Battery number %d nominal voltage", i);
    _data[i].voltage->setLongName(buf);

    sprintf(buf,      "current_%d", i);
    addField((_data[i].current = new DoubleData(buf)));
    _data[i].current->setUnits("Amps");
    sprintf(buf,      "Battery number %d nominal current", i);
    _data[i].current->setLongName(buf);

    sprintf(buf,      "temp_%d", i);
    addField((_data[i].temp = new DoubleData(buf)));
    _data[i].temp->setUnits("Celsius");
    sprintf(buf,      "Battery number %d internal temp", i);
    _data[i].temp->setLongName(buf);

    sprintf(buf,      "minvoltage_%d", i);
    addField((_data[i].minvoltage = new DoubleData(buf)));
    _data[i].minvoltage->setUnits("Volts");
    sprintf(buf,      "Battery number %d minimum cell brick voltage", i);
    _data[i].minvoltage->setLongName(buf);

    sprintf(buf,      "maxvoltage_%d", i);
    addField((_data[i].maxvoltage = new DoubleData(buf)));
    _data[i].maxvoltage->setUnits("Volts");
    sprintf(buf,      "Battery number %d maximum cell brick voltage", i);
    _data[i].maxvoltage->setLongName(buf);

    sprintf(buf,      "waterleak_%d", i);
    addField((_data[i].waterleak = new IntegerData(buf)));
    _data[i].waterleak->setUnits("Unitless");
    sprintf(buf,      "Battery number %d water leak code", i);
    _data[i].waterleak->setLongName(buf);

    sprintf(buf,      "capacity_%d", i);
    addField((_data[i].capacity = new DoubleData(buf)));
    _data[i].capacity->setUnits("Watt-hours");
    sprintf(buf,      "Battery number %d remaining capacity", i);
    _data[i].capacity->setLongName(buf);

    sprintf(buf,      "depth_%d", i);
    addField((_data[i].depth = new DoubleData(buf)));
    _data[i].depth->setUnits("Meters");
    sprintf(buf,      "Depth reading when battery data %d acquired", i);
    _data[i].depth->setLongName(buf);
  }

  for (int j = 0; j < _numBatts; j++)
  {
    dprintf("%s is %s with units %s\n",
      _data[j].voltage->name(), _data[j].voltage->longName(), _data[j].voltage->units());
    dprintf("%s is %s with units %s\n",
      _data[j].current->name(), _data[j].current->longName(), _data[j].current->units());
    dprintf("%s is %s with units %s\n",
      _data[j].temp->name(), _data[j].temp->longName(), _data[j].temp->units());
  }
}


BluefinBattLog::~BluefinBattLog()
{
  for (int i = 0; i < _numBatts; i++) {
    delete _data[i].voltage;
    delete _data[i].current;
    delete _data[i].temp;
    delete _data[i].minvoltage;
    delete _data[i].maxvoltage;
    delete _data[i].waterleak;
    delete _data[i].capacity;
    delete _data[i].depth;
  }

  delete _data;
}


void BluefinBattLog::setFields()
{

   // Set values
   if( _driver )
   {
      for (int i = 0; i < _numBatts; i++)
      {
	 _data[i].voltage->setValue(_driver->_output->data[i].voltage);
	 _data[i].current->setValue(_driver->_output->data[i].current);
	 _data[i].temp->setValue(_driver->_output->data[i].temp);
	 _data[i].minvoltage->setValue(_driver->_output->data[i].minvoltage);
	 _data[i].maxvoltage->setValue(_driver->_output->data[i].maxvoltage);
	 _data[i].waterleak->setValue(_driver->_output->data[i].waterleak);
	 _data[i].capacity->setValue(_driver->_output->data[i].capacity);
	 _data[i].depth->setValue(_driver->_depth); // Depth is not in output record
      }
   }
   else if( _simDriver )
   {
      for (int i = 0; i < _numBatts; i++)
      {
	 _data[i].voltage->setValue(_simDriver->_battData.voltage);
	 _data[i].current->setValue(_simDriver->_battData.current);
	 _data[i].temp->setValue(_simDriver->_battData.temp);
	 _data[i].minvoltage->setValue(_simDriver->_battData.minvoltage);
	 _data[i].maxvoltage->setValue(_simDriver->_battData.maxvoltage);
	 _data[i].waterleak->setValue(_simDriver->_battData.waterleak);
	 _data[i].capacity->setValue(_simDriver->_battData.capacity);
	 //_data[i].depth->setValue(_simDriver->_position[3]); // Depth is not in output record
      }
   }
}

