#include <Xm/RowColumn.h>
#include <Xm/ToggleB.h>
#include <Vk/VkErrorDialog.h>
#include "Alarm.h"
#include "GfSelfTest.h"
#include "TableForm.h"
#include "TiburonApp.h"

GfSelfTest::GfSelfTest(const char *name, Widget parent, 
		       const char *cmdItemName,
		       const char *statusItemName)
  : DmGuiObject(name, parent)
{
  _cmd = 0;
  _status = 0;
  
  _cmdItemName = NULL;
  
  _baseWidget = XtVaCreateWidget(name, xmRowColumnWidgetClass, parent, NULL);

  installDestroyHandler();

  char errorBuf[errorMsgSize];
 
  /* Find alarm items */
  SystemAlarms *alarms = ((TiburonApp *)theApplication)->systemAlarms;

 Alarm *selfTestAlarm;
  if ((selfTestAlarm = alarms->find(statusItemName)) == NULL)
  {
    sprintf(errorBuf,
	    "GfSelfTest::GfSelfTest() - couldn't find alarm \"%s\"",
	    statusItemName);

    theErrorDialog->postAndWait(errorBuf);
  }

  _cmdItemName = strdup(cmdItemName);
  
  TableRowForm *mgr = new TableRowForm(name, _baseWidget, 2);
  
  _cmdButton = 
    XtVaCreateManagedWidget("selfTestCmd", xmToggleButtonWidgetClass, 
			    mgr->baseWidget(), NULL);

  XtAddCallback(_cmdButton, XmNvalueChangedCallback,
		&GfSelfTest::cmdCallback, (XtPointer )this);
  
  mgr->append(_cmdButton);
  
  _status = new AlarmText("selfTestStatus", 
			  mgr->baseWidget(), 
			  selfTestAlarm, 
			  "Test result: %s");

  mgr->append(_status);
  mgr->show();


  _cmd = new DmBooleanObject(_cmdItemName);

  if (addDmObject(_cmd, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  if (setConsumePeriod(Aperiodic) == -1)
    return;
  
  updateGui();
}


GfSelfTest::~GfSelfTest()
{
  free((void *)_cmdItemName);
  delete _cmd;
  delete _status;
}


void GfSelfTest::updateGui(DM_Item handle)
{
  DM_Time t;
  Errno errno;
  MBool test;
  
  if ((errno = _cmd->read(&test, &t)) != SUCCESS)
  {
    char errorBuf[errorMsgSize];
    sprintDmError(errno, "GfSelfTest::updateGui()", errorBuf);
    setError(errorBuf);
    return;
  }

  if (test)
    XtVaSetValues(_cmdButton, XmNset, True, NULL);
  else
    XtVaSetValues(_cmdButton, XmNset, False, NULL);
}


int GfSelfTest::sendCmd(MBool test)
{
  char errorBuf[errorMsgSize];

  DM_Time t;
  static struct timezone tz = 
  {
    0, 0
  };
  
  gettimeofday(&t, &tz);
  
  if ((errno = _cmd->write(test, &t)) != SUCCESS)
  {
    sprintDmError(errno, "GfSelfTest::sendCmd()",  errorBuf);
    setError(errorBuf);
    theErrorDialog->postAndWait(errorBuf);
    return -1;
  }

  return 0;
}


void GfSelfTest::cmdCallback(Widget w,
			     XtPointer clientData,
			     XtPointer callData)
{
  GfSelfTest *obj = (GfSelfTest *)clientData;

  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;

  MBool test;
  if (cb->set)
    test = ~FALSE;
  else
    test = FALSE;
  
  obj->sendCmd(test);
}

