static char ErsGui_id[] = "$Header: ErsGui.cc,v 1.8 97/10/03 09:30:10 oreilly Exp $";


/*
$Log:	ErsGui.cc,v $
Revision 1.8  97/10/03  09:30:10  09:30:10  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.7  97/09/10  08:50:39  08:50:39  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.6  97/05/30  15:52:08  15:52:08  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.5  97/05/12  20:37:10  20:37:10  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.4  97/03/20  12:29:21  12:29:21  oreilly (Thomas C. O'Reilly)
..

Revision 1.3  96/10/28  09:12:04  09:12:04  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.2  96/07/22  10:42:00  10:42:00  oreilly (Thomas C. O'Reilly)
First external release

*/
#include <stdlib.h>
#include <values.h>
#include <Xm/RowColumn.h>
#include <Xm/Form.h>
#include <Xm/Separator.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/Frame.h>
#include "ErsGui.h"
#include "TiburonApp.h"
#include "tiburon.h"
#include "AlarmedText.h"
#include "RovNav.h"
#include "TableForm.h"

#define dprintf if (debug) fprintf

const char *const ErsGui::latchDisarmedMnem = "Disarmed";
const char *const ErsGui::latchArmedMnem = "Armed";
const char *const ErsGui::latchArmedNoPwrMnem = "ArmedNoPwr";
const char *const ErsGui::latchRunningMnem = "Running";

const char *const ErsGui::latchedMnem = "Latched";
const char *const ErsGui::unlatchedMnem = "Unlatched";
const char *const ErsGui::connectedMnem = "Connected";
const char *const ErsGui::unconnectedMnem = "Unconnected";

ErsGui::ErsGui(const char *name, Widget parent, int period) :
  DmGuiObject(name, parent)
{
  _baseWidget = 
    XtVaCreateWidget(name, xmRowColumnWidgetClass, parent, 
		     XmNorientation, XmVERTICAL,
		     0);

  installDestroyHandler();

  _volts = 0;
  _life = 0;
  _mode = 0;
  
  char errorBuf[errorMsgSize];
  char voltAlarmName[MaxDmNameLen];
  char lifeAlarmName[MaxDmNameLen];
  
  strcpy(voltAlarmName, ERS_DCON_DM_PREFIX);
  strcat(voltAlarmName, BATTERY_VOLTAGE_ALARM_DM);
  strcpy(lifeAlarmName, ERS_DCON_DM_PREFIX);
  strcat(lifeAlarmName, BATTERY_LIFE_ALARM_DM);  

  SystemAlarms *alarms = ((TiburonApp *)theApplication)->systemAlarms;
  Alarm *voltAlarm;
  if ((voltAlarm = alarms->find(voltAlarmName)) == NULL)
  {
    sprintf(errorBuf,
	    "ErsGui::ErsGui() - Couldn't find \"%s\" in SystemAlarms",
	    voltAlarmName);

    setError(errorBuf);
    return;
  }    

  char itemName[MaxDmNameLen];
  strcpy(itemName, ERS_DCON_DM_PREFIX);
  char *namePtr = itemName + strlen(itemName);
 
  strcpy(namePtr, BATTERY_LIFE_DM);

  DmFlt32Object *dmLife = new DmFlt32Object(itemName);
  if (dmLife->error())
  {
    dmLife->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }

  Alarm *lifeAlarm;
  if ((lifeAlarm = alarms->find(lifeAlarmName)) == NULL)
  {
    sprintf(errorBuf,
	    "ErsGui::ErsGui() - Couldn't find \"%s\" in SystemAlarms",
	    lifeAlarmName);

    setError(errorBuf);
    return;
  }
  
  strcpy(namePtr, BATTERY_VOLTAGE_DM);

  DmNat16Object *dmVolts = new DmNat16Object(itemName);
  if (dmVolts->error())
  {
    dmVolts->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }


#ifdef ZILCH

  _mode = new ErsMode("mode", baseWidget());
  _mode->show();
  
  _depth = new DynamicLabel("depth", baseWidget());
  _depth->show();

  Widget mgr, mgr2;

  const int Columns = 2;

  mgr = XtVaCreateWidget("mgr", xmRowColumnWidgetClass, baseWidget(),
			 XmNpacking, XmPACK_COLUMN,
			 XmNnumColumns, Columns,
			 XmNorientation, XmVERTICAL,
			 NULL);

  // First column
  XtVaCreateManagedWidget("currentLabel", xmLabelWidgetClass, mgr, 0);

  Widget voltButton =
    XtVaCreateManagedWidget("voltButton", xmPushButtonWidgetClass, mgr, 0);

  XtAddCallback(voltButton, XmNactivateCallback,
		&ErsGui::voltButtonCallback, (XtPointer )this);

  XtVaCreateManagedWidget("lifeLabel", xmLabelWidgetClass, mgr, 0);

  // Second column
  _batCurr = XtVaCreateManagedWidget("current", xmLabelWidgetClass, mgr, 0);

  mgr2 = XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr,
			  XmNorientation, XmHORIZONTAL, 0);

  _volts = 
    new AlarmedNat16Text("volts", mgr2, "%.2f V", dmVolts, Aperiodic,
			 voltAlarm, True, 0.001);

  _volts->show();

  _readVoltTime = 
    XtVaCreateManagedWidget("readVoltTime", xmLabelWidgetClass, mgr2, 0);

  XtManageChild(mgr2);

  _life = 
    new AlarmedFlt32Text("life", mgr, "%.1f hrs", dmLife, period,
			 lifeAlarm);

  _life->show();
  
  XtManageChild(mgr);

#endif

  // ------------------------------------------------

  TableRowForm *mgr;
  Widget mgr2;

  mgr = new TableRowForm("mgr", baseWidget(), 4);

  mgr2 = XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr->baseWidget(),
			  XmNorientation, XmHORIZONTAL, 0);

  XtVaCreateManagedWidget("modeLabel", xmLabelWidgetClass, mgr2, 0);

  _mode = new ErsMode("mode", mgr2);

  XtManageChild(mgr2);

  mgr->append(mgr2);
  
  mgr2 = XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr->baseWidget(),
			  XmNorientation, XmHORIZONTAL, 0);

  XtVaCreateManagedWidget("depthLabel", xmLabelWidgetClass, mgr2, 0);

  _depth = new DynamicLabel("depth", mgr2);
  _depth->show();

  XtManageChild(mgr2);

  mgr->append(mgr2);
  
  mgr->show();

  mgr = new TableRowForm("mgr", baseWidget(), 4);

  mgr->append(XtVaCreateManagedWidget("currentLabel", xmLabelWidgetClass, 
				      mgr->baseWidget(), 0));

  _batCurr = XtVaCreateManagedWidget("current", xmLabelWidgetClass, 
				     mgr->baseWidget(), 0);

  mgr->append(_batCurr);
  mgr->show();

  mgr = new TableRowForm("mgr", baseWidget(), 4);

  Widget voltButton =
    XtVaCreateManagedWidget("voltButton", xmPushButtonWidgetClass, 
			    mgr->baseWidget(), 0);

  XtAddCallback(voltButton, XmNactivateCallback,
		&ErsGui::voltButtonCallback, (XtPointer )this);

  mgr->append(voltButton);

  mgr2 = XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr->baseWidget(),
			  XmNorientation, XmHORIZONTAL, 0);

  _volts = 
    new AlarmedNat16Text("volts", mgr2, "%.2f V", dmVolts, 
			 Aperiodic, voltAlarm, True, 0.001);

  _volts->show();

  _readVoltTime = 
    XtVaCreateManagedWidget("readVoltTime", xmLabelWidgetClass, 
			    mgr2, 0);

  XtManageChild(mgr2);

  mgr->append(mgr2);

  mgr->show();

  mgr = new TableRowForm("mgr", baseWidget(), 4);

  mgr->append(XtVaCreateManagedWidget("lifeLabel", xmLabelWidgetClass, 
				      mgr->baseWidget(), 0));

  _life = 
    new AlarmedFlt32Text("life", mgr->baseWidget(), "%.1f hrs", dmLife, period,
			 lifeAlarm);

  _life->show();

  mgr->append(_life);
  
  mgr->show();

  // ------------------------------------------------

  
  Widget frame = 
    XtVaCreateManagedWidget("frame", xmFrameWidgetClass, _baseWidget,
			    NULL);

  _rovNav = new RovNav("rovNav", frame);
  _rovNav->show();

  strcpy(itemName, ERS_DCON_DM_PREFIX);
  namePtr = itemName + strlen(itemName);
  
  strcpy(namePtr, ERS_DEPTH_METERS_DM);
  _dmDepth = new DmFlt64Object(itemName);
  if (_dmDepth->error())
  {
    _dmDepth->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmDepth, DmConsumeFlag) == -1)
    return;
  
  strcpy(namePtr, BATTERY_CURRENT_DM);
  _dmBatCurr = new DmNat16Object(itemName);
  if (_dmBatCurr->error())
  {
    _dmBatCurr->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmBatCurr, DmConsumeFlag) == -1)
    return;
  
  
  strcpy(namePtr, BATTERY_VOLTAGE_CMD_DM);
  _dmReadVoltCmd = new DmEmptyObject(itemName);
  if (_dmReadVoltCmd->error())
  {
    _dmReadVoltCmd->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmReadVoltCmd, DmProvideFlag) == -1)
    return;
  
  strcpy(itemName, TIBURON_DM_PREFIX);
  namePtr = itemName + strlen(itemName);
  
  if (setConsumePeriod(period) == -1)
    return;


  updateGui();
}


ErsGui::~ErsGui()
{
  delete _volts;
  delete _life;
  delete _mode;
  delete _rovNav;
}


void ErsGui::updateGui(DM_Item handle)
{
  char errorBuf[errorMsgSize];
  Errno errno;
  DM_Time t;
  XmString xmstr;
  MBool debug = FALSE;
  Pixel foreground, background;
  
  TiburonApp *app = (TiburonApp *)theApplication;

  char buf[512];
  
  Flt64 depth;
  
  if ((errno = _dmDepth->read(&depth, &t)) != SUCCESS)
  { 
    _dmDepth->errorMsg(errorBuf);
    setError(errorBuf);
  }

  static Flt64 prevDepth = -10000.;
  if (depth != prevDepth)
  {
    sprintf(buf, "%.1f m", depth);
    _depth->setText(buf);
  }
  prevDepth = depth;
  
  Nat16 current;
  if ((errno = _dmBatCurr->read(&current, &t)) != SUCCESS)
  {
    _dmBatCurr->errorMsg(errorBuf);
    setError(errorBuf);
  }
  
  static Nat16 prevCurrent = MAXSHORT;

  if (current != prevCurrent)
  {
    sprintf(buf, "%d mA", current);
    xmstr = XmStringCreateSimple(buf);
    XtVaSetValues(_batCurr, XmNlabelString, xmstr, NULL);
    XmStringFree(xmstr);    
  }
  prevCurrent = current;
}


void ErsGui::readVoltCmd()
{
  DM_Time t;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  Errno errno;
  if ((errno = _dmReadVoltCmd->write(&t)) != SUCCESS)
  {
    _dmReadVoltCmd->errorMsg(errorBuf);
    setError(errorBuf);
  }
  char buf[100];
  struct tm *timePtr = gmtime((const time_t *)&t.tv_sec);
  strftime(buf, sizeof(buf), "at %H:%M:%S UTC", timePtr); 
  XmString xmstr = XmStringCreateSimple(buf);
  XtVaSetValues(_readVoltTime, XmNlabelString, xmstr, NULL);
  XmStringFree(xmstr);
  
}


void ErsGui::voltButtonCallback(Widget w, XtPointer clientData,
				XtPointer callData)
{
  ErsGui *obj = (ErsGui *)clientData;
  obj->readVoltCmd();
}


void ErsGui::thresholdButtonCallback(Widget w, XtPointer clientData,
				     XtPointer callData)
{
  fprintf(stderr, "Popup alarm threshold window...\n");
}


void ErsGui::updateFromPeer(DmGuiObject *peer, void *clientData)
{
}
