#include <Xm/PushB.h>
#include <Xm/Form.h>
#include "DmBooleanButton.h"
#include "DmErrno.h"

DmBooleanButton::DmBooleanButton(const char *name, Widget parent,
				 DmBooleanObject *dmObject,
				 int period)
  : DmGuiObject(name, parent)
{
  _baseWidget = XtVaCreateWidget(name, xmFormWidgetClass, parent, 0);

  installDestroyHandler();

  unsigned flags;

  _button = 
    XtVaCreateManagedWidget("button", xmPushButtonWidgetClass, 
			    baseWidget(),
			    XmNtopAttachment, XmATTACH_FORM,
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNrightAttachment, XmATTACH_FORM,
			    NULL);

  _armed = False;

  XtAddCallback(_button, XmNarmCallback,
		&DmBooleanButton::buttonCallback,
		(XtPointer )this);

  XtAddCallback(_button, XmNdisarmCallback,
		&DmBooleanButton::buttonCallback,
		(XtPointer )this);

  // Get colors to use in re-drawing buttons
  XtVaGetValues(_button,
		XmNarmColor, &_armColor,
		XmNbackground, &_background,
		XmNtopShadowColor, &_lightEdgeColor, 
		XmNbottomShadowColor, &_darkEdgeColor,
		NULL);

  flags = DmConsumeFlag | DmProvideFlag;

  _dmObject = dmObject;

  if (addDmObject(_dmObject, flags) == -1)
    return;

  setConsumePeriod(period);

  updateGui();
}



DmBooleanButton::~DmBooleanButton()
{
}


void DmBooleanButton::updateGui(DM_Item handle)
{
  Boolean debug = False;
  
  if (_armed)
    /* User armed button; just return so X doesn't get confused on button 
       drawing. */
    return;
  
  char errorBuf[errorMsgSize];
  Errno errno;
  DM_Time t;
  MBool active;
  
  if ((errno = _dmObject->read(&active, &t)) != SUCCESS)
  {
    sprintDmError(errno, "ValveControl::updateGui(), read dmOpen", errorBuf);
    setError(errorBuf);
    return;
  }

  if (active)
  {
    // Display button as "pressed in"
    XtVaSetValues(_button,
		  XmNbackground, _armColor,
		  XmNtopShadowColor, _darkEdgeColor, 
		  XmNbottomShadowColor, _lightEdgeColor, 
		  NULL);
  }
  else
  {
    // Display button as "out"
    XtVaSetValues(_button,
		  XmNbackground, _background, 
		  XmNtopShadowColor, _lightEdgeColor, 
		  XmNbottomShadowColor, _darkEdgeColor, 
		  NULL);
  }
}


void DmBooleanButton::buttonCallback(Widget w,
				     XtPointer clientData,
				     XtPointer callData)
{
  DmBooleanButton *obj = (DmBooleanButton *)clientData;

  XmPushButtonCallbackStruct *cbs = 
    (XmPushButtonCallbackStruct *)callData;

  if (cbs->reason = XmCR_ARM)
    obj->_armed = True;
  else
    obj->_armed = False;

  MBool set = obj->_armed;

  DM_Time t;
  gettimeofday(&t, 0);

  obj->_dmObject->write(set, &t);
}

