#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include "Uhs.h"
#include "DmErrno.h"
#include "westernFlyer.h"
#include "uhs.h"
#include "values.h"
#include "sensorsDm.h"
#include "controlDM.h"

Uhs::Uhs(const char *name, Widget parent)
  : DmGuiObject(name, parent)
{
  _pduGfAlarm = 0;
  _lineSpeed = 0;
  _lineOut = 0;
  _depthRate = 0;
  _delta = 0;

  _baseWidget = 
    XtVaCreateWidget(name, xmRowColumnWidgetClass, parent,
		     XmNorientation, XmVERTICAL,
		     NULL);

  installDestroyHandler();
  
  Widget label;
  
  label = 
    XtVaCreateManagedWidget("uhsLabel", xmLabelWidgetClass, _baseWidget, NULL);
  
  Widget mgr =
    XtVaCreateWidget("mgr", xmRowColumnWidgetClass, _baseWidget,
		     XmNpacking, XmPACK_COLUMN,
		     XmNnumColumns, 2,
		     XmNorientation, XmVERTICAL,
		     NULL);

  
  label = 
    XtVaCreateManagedWidget("deltaLabel", xmLabelWidgetClass, mgr, NULL);

  label = 
    XtVaCreateManagedWidget("lineOutLabel", xmLabelWidgetClass, mgr, NULL);

  label = 
    XtVaCreateManagedWidget("lineSpeedLabel", xmLabelWidgetClass, mgr, NULL);
  
  label = 
    XtVaCreateManagedWidget("depthRateLabel", xmLabelWidgetClass, mgr,
			    NULL);

  
  _delta = 
    new DynamicLabel("delta", mgr, XmALIGNMENT_BEGINNING);
  
  _delta->show();
  
  _lineOut =
    new DynamicLabel("lineOut", mgr, XmALIGNMENT_BEGINNING);

  _lineOut->show();

  _lineSpeed = 
    new DynamicLabel("lineSpeed", mgr, XmALIGNMENT_BEGINNING);
  
  _lineSpeed->show();

  _depthRate = 
    new DynamicLabel("depthRate", mgr, XmALIGNMENT_BEGINNING);

  _depthRate->show();
  

  XtManageChild(mgr);

  _pduGfAlarm = new PduGfAlarm("pduGfAlarm", _baseWidget);
  _pduGfAlarm->show();
  
  
  char errorBuf[errorMsgSize];
  char itemName[MaxDmNameLen];

  strcpy(itemName, VEHICLE_DEPTH_DM);

  _dmDepth = new DmFlt64Object(itemName);
  if (_dmDepth->error())
  {
    _dmDepth->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  strcpy(itemName, SENSOR_RATE_DEPTH_DM);
  
  _dmDepthRate = new DmFlt32Object(itemName);
  if (_dmDepthRate->error())
  {
    _dmDepthRate->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  strcpy(itemName, UHS_DM_PREFIX);
  char *namePtr = itemName + strlen(itemName);
  
  strcpy(namePtr, UHS_LINE_COUNT_DM);
  _dmLineOut = new DmNat16Object(itemName);
  if (_dmLineOut->error())
  {
    _dmLineOut->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  strcpy(namePtr, UHS_LINE_SPEED_DM);
  _dmLineSpeed = new DmNat16Object(itemName);
  if (_dmLineSpeed->error())
  {
    _dmLineSpeed->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }


  if (addDmObject(_dmDepth, DmConsumeFlag) == -1)
    return;

  if (addDmObject(_dmDepthRate, DmConsumeFlag) == -1)
    return;

  if (addDmObject(_dmLineOut, DmConsumeFlag) == -1)
    return;

  if (addDmObject(_dmLineSpeed, DmConsumeFlag) == -1)
    return;
  
  if (setConsumePeriod(1000) == -1)
    return;
  
  _prevLineSpeed = _prevLineOut = MAXSHORT;
  _prevDelta = MAXFLOAT;
  _prevDepthRate = MAXFLOAT;
  
  updateGui();
}


Uhs::~Uhs()
{
  delete _pduGfAlarm;
  delete _lineSpeed;
  delete _lineOut;
  delete _depthRate;
  delete _delta;
}


void Uhs::updateGui(DM_Item handle)
{
  Nat16 lineSpeed;
  Nat16 lineOut;
  char errorBuf[errorMsgSize];
  Errno errno;
  DM_Time t;
  char buf[100];
  float value;
  
  if ((errno = _dmLineSpeed->read(&lineSpeed, &t)) != SUCCESS)
  {
    sprintDmError(errno, "Uhs::updateGui(), reading lineSpeed - ", errorBuf);
    setError(errorBuf);
  }
  else if (lineSpeed != _prevLineSpeed)
  {
    value = lineSpeed;
    sprintf(buf, "%.1f m/min", value);
    _lineSpeed->setText(buf);
    
    _prevLineSpeed = lineSpeed;
  }

  Flt64 depth;
  
  if ((errno = _dmDepth->read(&depth, &t)) != SUCCESS)
  {
    sprintDmError(errno, "Uhs::updateGui(), reading depth - ", errorBuf);
    setError(errorBuf);
  }

  if ((errno = _dmLineOut->read(&lineOut, &t)) != SUCCESS)
  {
    sprintDmError(errno, "Uhs::updateGui(), reading lineOut - ", errorBuf);
    setError(errorBuf);
  }
  else if (lineOut != _prevLineOut)
  {
    value = lineOut;
    sprintf(buf, "%.1f m", value);
    _lineOut->setText(buf);
    
    _prevLineOut = lineOut;
  }

  Flt64 delta = depth - lineOut;
  
  if (delta != _prevDelta)
  {
    sprintf(buf, "%.1f m", delta);
    _delta->setText(buf);
    _prevDelta = delta;
  }

  Flt32 depthRate;
  
  if ((errno = _dmDepthRate->read(&depthRate, &t)) != SUCCESS)
  {
    sprintDmError(errno, "Uhs::updateGui(), reading depthRate - ", 
		  errorBuf);

    setError(errorBuf);
    return;
  }

  depthRate *= 60.;
  
  if (depthRate != _prevDepthRate)
  {
    sprintf(buf, "%.1f m/min", depthRate);
    _depthRate->setText(buf);
    
    _prevDepthRate = depthRate;
  }

}

