#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/ScrollBar.h>
#include <Vk/VkErrorDialog.h>
#include "LapBoxGuiApp.h"
#include "LapBoxGui.h"
#include "DmErrno.h"

#define dprintf if (debug) fprintf

DM_Time LapBoxGui::_t;
struct timezone LapBoxGui::_tz = {0, 0};

LapBoxGui::LapBoxGui(const char *name, Widget parent, 
		     const char *lapBoxName)
  : DmGuiObject(name, parent)
{
  _baseWidget = XtVaCreateWidget(name, xmFormWidgetClass, parent, NULL);
  installDestroyHandler();

  char errorBuf[errorMsgSize];
  
  const char *dmPrefix = lapBoxName;
  
  _events = new LapBoxUiEvents(dmPrefix, DmProvideFlag);
  _data = new LapBoxUiData(dmPrefix, DmProvideFlag);
  _settings = new LapBoxUiSettings(dmPrefix, DmConsumeFlag);

  _portCamButton = 
    XtVaCreateManagedWidget("portCamSelect", 
			    xmPushButtonWidgetClass, _baseWidget,
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);
  
  XtAddCallback(_portCamButton, XmNactivateCallback,
		&LapBoxGui::cameraSelectCallback,
		(XtPointer )this);
  
  _stbdCamButton = 
    XtVaCreateManagedWidget("stbdCamSelect", 
			    xmPushButtonWidgetClass, _baseWidget,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _portCamButton,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  XtAddCallback(_stbdCamButton, XmNactivateCallback,
		&LapBoxGui::cameraSelectCallback,
		(XtPointer )this);


  _camera = new ZoomFocusIris("camera", _baseWidget, 
			      _data->zoom,
			      _data->focus,
			      _data->iris,
			      _events->autoIris);

  if (_camera->error())
  {
    _camera->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  XtVaSetValues(_camera->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, _portCamButton,
		NULL);
  
  _camera->show();
  
  _panoramicButton = 
    XtVaCreateManagedWidget("panoramic", 
			    xmPushButtonWidgetClass, _baseWidget,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _stbdCamButton,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  XtAddCallback(_panoramicButton, XmNactivateCallback,
		&LapBoxGui::panoramicCallback,
		(XtPointer )this);

  _panTilt = new Joystick("panTilt", _baseWidget, 
			  _data->pan,
			  _data->tilt,
			  _events->portLight,
			  _events->portCamera,
			  _events->stbdLight,
			  _events->stbdCamera);

  if (_panTilt->error())
  {
    _panTilt->errorMsg(errorBuf);
    setError(errorBuf);
    return;
  }
  
  XtVaSetValues(_panTilt->baseWidget(),
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, _stbdCamButton,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, _panoramicButton,
		NULL);
  
  _panTilt->show();

  _enableButton = 
    XtVaCreateManagedWidget("enable", 
			    xmPushButtonWidgetClass, _baseWidget,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _panTilt->baseWidget(),
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  XtAddCallback(_enableButton, XmNactivateCallback,
		&LapBoxGui::enableCallback,
		(XtPointer )this);


  LapBoxGuiApp *app = (LapBoxGuiApp *)theApplication;

  app->powerOnColors(&_onForeground, &_onBackground);
  app->faultColors(&_errorForeground, &_errorBackground);
  
  XtVaGetValues(_baseWidget, 
		XmNforeground, &_offForeground,
		XmNbackground, &_offBackground,
		NULL);

  if (addDmObject(_settings->portLight, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->portCamera, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->stbdLight, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->stbdCamera, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->portCameraSelect, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->stbdCameraSelect, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->panoramic, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->enable, DmConsumeFlag) == -1)
    return;
  
  if (addDmObject(_settings->autoIris, DmConsumeFlag) == -1)
    return;

  if (setConsumePeriod(Aperiodic) == -1)
    return;
  
  updateGui();
}


LapBoxGui::~LapBoxGui()
{
}


void LapBoxGui::updateGui(DM_Item handle)
{
  LapBoxButtonState state;
  MBool flash;
  DM_Time t;
  Nat16 value;
  Errno errno;
  char errorBuf[errorMsgSize];
  
  if ((errno = _settings->portLight->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading portLight", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_panTilt->deviceButton(IviewPortLight), state, flash);
  
  if ((errno = _settings->portCamera->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading portCamera", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_panTilt->deviceButton(IviewPortCamera), state, flash);
  
  if ((errno = _settings->stbdLight->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading stbdLight", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_panTilt->deviceButton(IviewStbdLight), state, flash);
  
    
  if ((errno = _settings->stbdCamera->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading stbdCamera", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_panTilt->deviceButton(IviewStbdCamera), state, flash);

  if ((errno = _settings->portCameraSelect->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading portCameraSelect", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_portCamButton, state, flash);

  if ((errno = _settings->stbdCameraSelect->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading stbdCameraSelect", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_stbdCamButton, state, flash);

  if ((errno = _settings->panoramic->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading panoramic", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_panoramicButton, state, flash);

  if ((errno = _settings->enable->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading enable", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_enableButton, state, flash);

  if ((errno = _settings->autoIris->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "updateGui(), reading autoIris", errorBuf);
    setError(errorBuf);
    return;
  }
  
  LapBoxUiSettings::decode(value, &state, &flash);
  setButtonState(_camera->autoIrisButton(), state, flash);

}


void LapBoxGui::cameraSelectCallback(Widget w, 
				     XtPointer clientData,
				     XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "LapBoxGui::cameraSelectCallback()\n");
  LapBoxGui *obj = (LapBoxGui *)clientData;
  gettimeofday(&_t, &_tz);
  
  if (w == obj->_portCamButton)
    obj->_events->portCameraSelect->write(&_t);
  else
    obj->_events->stbdCameraSelect->write(&_t);
}


void LapBoxGui::enableCallback(Widget w, 
			       XtPointer clientData,
			       XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "LapBoxGui::enableCallback()\n");

  LapBoxGui *obj = (LapBoxGui *)clientData;
  
  gettimeofday(&_t, &_tz);
  Errno err;
  if ((err = obj->_events->enable->write(&_t)) != SUCCESS)
  {
    char errorBuf[errorMsgSize];
    
    sprintDmError(err, "LapBoxGui::enableCallback(), write()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
  }
  
}


void LapBoxGui::panoramicCallback(Widget w, 
				  XtPointer clientData,
				  XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "LapBoxGui::panoramicCallback()\n");

  LapBoxGui *obj = (LapBoxGui *)clientData;
  gettimeofday(&_t, &_tz);
  obj->_events->panoramic->write(&_t);
}




void LapBoxGui::setButtonState(Widget button,
			       LapBoxButtonState state,
			       MBool flash)
{
  Pixel foreground, background;

  switch (state)
  {
    case LapBoxButtonOff:
    foreground = _offForeground;
    background = _offBackground;
    break;

    case LapBoxButtonOn:
    foreground = _onForeground;
    background = _onBackground;
    break;
    
    case LapBoxButtonError:
    foreground = _errorForeground;
    background = _errorBackground;
    break;
  }

  XtVaSetValues(button, XmNforeground, foreground, XmNbackground, background, 
		NULL);
}

