#include <Xm/Label.h>
#include <Vk/VkErrorDialog.h>
#include "ToolsledRelease.h"
#include "TableForm.h"
#include "TiburonApp.h"
#include "DmErrno.h"
#include "tiburon.h"
#include "ers.h"

const char *const ToolsledRelease::latchedMnem = "Latched";
const char *const ToolsledRelease::unlatchedMnem = "Unlatched";
const char *const ToolsledRelease::connectedMnem = "Connected";
const char *const ToolsledRelease::unconnectedMnem = "Unconnected";


ToolsledRelease::ToolsledRelease(const char *name, Widget parent)
  : ReleaseControl(name, parent, "TIBURON.TOOLSLED")
{
  _latched = 0;
  _connected = 0;
  
  XtAddCallback(_releaseButton, XmNarmCallback,
		&ToolsledRelease::releaseCallback,
		(XtPointer )this);

  TableRowForm *row;
  Widget label;
  
  row = new TableRowForm("row", _statusMgr, 2);
  
  label = 
    XtVaCreateManagedWidget("latchLabel", xmLabelWidgetClass, 
			    row->baseWidget(), NULL);

  
  row->append(label);
  
  _latched = new DynamicLabel("latched", row->baseWidget());
  _latched->show();

  row->append(_latched);
  row->show();
  
  row = new TableRowForm("row", _statusMgr, 2);
  
  label = 
    XtVaCreateManagedWidget("connectorLabel", xmLabelWidgetClass, 
			    row->baseWidget(), NULL);

  row->append(label);
  
  _connected = new DynamicLabel("connected", row->baseWidget());
  _connected->show();
  row->append(_connected);
  
  row->show();

  XtManageChild(_statusMgr);
  
  char itemName[MaxDmNameLen];
  char errorBuf[errorMsgSize];
  
  strcpy(itemName, TIBURON_DM_PREFIX);
  char *namePtr = itemName + strlen(itemName);

  strcpy(namePtr, TOOLSLED_LATCH_RELEASE_DM);
  _dmReleaseCmd = new DmBooleanObject(itemName);
  if (_dmReleaseCmd->error())
  {
    _dmReleaseCmd->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmReleaseCmd, DmProvideFlag) == -1)
    return;
  
  strcpy(namePtr, TOOLSLED_LATCHED_DM);
  _dmLatched = new DmBooleanObject(itemName);
  if (_dmLatched->error())
  {
    _dmLatched->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmLatched, DmConsumeFlag) == -1)
    return;
  
  strcpy(namePtr, TOOLSLED_CONNECTED_DM);
  _dmConnected = new DmBooleanObject(itemName);
  if (_dmConnected->error())
  {
    _dmConnected->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  if (addDmObject(_dmConnected, DmConsumeFlag) == -1)
    return;
  
  if (setConsumePeriod(Aperiodic) == -1)
    return;

  _armCode = TOOLSLED_LATCH_ARM_CODE;

  updateGui();
}


ToolsledRelease::~ToolsledRelease()
{
  delete _latched;
  delete _connected;
}



void ToolsledRelease::updateGui(DM_Item handle)
{
  char errorBuf[errorMsgSize];
  Errno errno;
  DM_Time t;
  Pixel foreground, background;

  ReleaseControl::updateGui();
  
  TiburonApp *app = (TiburonApp *)theApplication;

  MBool latched;
  if ((errno = _dmLatched->read(&latched, &t)) != SUCCESS)
  {
    _dmLatched->errorMsg(errorBuf);
    setError(errorBuf);
  }

  char *ptr;
  
  if (latched)
  {
    ptr = (char *)latchedMnem;
    app->powerOnColors(&foreground, &background);
  }
  else
  {
    ptr = (char *)unlatchedMnem;
    app->powerOffColors(&foreground, &background);
  }

  _latched->setText(ptr);
  _latched->setColors(foreground, background);
  
  MBool connected;
  if ((errno = _dmConnected->read(&connected, &t)) != SUCCESS)
  {
    _dmConnected->errorMsg(errorBuf);
    setError(errorBuf);
  }

  if (connected)
  {
    ptr = (char *)connectedMnem;
    app->powerOnColors(&foreground, &background);
  }
  else
  {
    ptr = (char *)unconnectedMnem;
    app->priority1Colors(&foreground, &background);
    app->powerOffColors(&foreground, &background);
  }

  _connected->setText(ptr);
  _connected->setColors(foreground, background);
}


void ToolsledRelease::releaseCallback(Widget w,
				      XtPointer clientData,
				      XtPointer callData)
{
  ToolsledRelease *obj = (ToolsledRelease *)clientData;
  
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];

  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  
  if ((errno = obj->_dmReleaseCmd->write(TRUE, &t)) != SUCCESS)
  {
    sprintDmError(errno, "ToolsledRelease::releaseCallback()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
  }
}
