#include <Xm/RowColumn.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/ToggleB.h>
#include <Xm/Frame.h>
#include <Xm/ScrollBar.h>
#include <Xm/PushB.h>
#include <Xm/ArrowB.h>
#include <Vk/VkInfoDialog.h>
#include <Vk/VkErrorDialog.h>
#include "PanasonicWVSetup.h"
#include "camera.h"
#include "DmErrno.h"

#define dprintf if (debug) fprintf

const int PanasonicWVSetup::LowGain = GAIN_0DB;
const int PanasonicWVSetup::MedGain = GAIN_9DB;
const int PanasonicWVSetup::HighGain = GAIN_18DB;
const int PanasonicWVSetup::AutoIris = FALSE;
const int PanasonicWVSetup::ManualIris = TRUE;
const int PanasonicWVSetup::ColorBarsOff = FALSE;
const int PanasonicWVSetup::ColorBarsOn = TRUE;

VkMenuDesc PanasonicWVSetup::_shutterMenuDesc[] = 
{ 
  {ACTION, "shutterOff", &PanasonicWVSetup::shutterCallback},
  {ACTION, "shutter100", &PanasonicWVSetup::shutterCallback},
  {ACTION, "shutter500", &PanasonicWVSetup::shutterCallback},
  {ACTION, "shutter1000", &PanasonicWVSetup::shutterCallback},
  {ACTION, "shutterSs", &PanasonicWVSetup::shutterCallback},
  {ACTION, "shutterElc", &PanasonicWVSetup::shutterCallback},
  {END}
};    


VkMenuDesc PanasonicWVSetup::_sceneMenuDesc[] = 
{ 
  {ACTION, "userSet", &PanasonicWVSetup::sceneCallback},
  {ACTION, "scene1", &PanasonicWVSetup::sceneCallback},
  {ACTION, "scene2", &PanasonicWVSetup::sceneCallback},
  {ACTION, "scene3", &PanasonicWVSetup::sceneCallback},
  {END}
};    


PanasonicWVSetup::PanasonicWVSetup(const char *name, Widget parent, 
				   const char *dmPrefix)
  : DmGuiObject(name, parent)
{
  _redPedestalValue = 0;
  _bluePedestalValue = 0;
  _totalPedestalValue = 0;
  _redGainValue = 0;
  _blueGainValue = 0;

  _baseWidget = XtVaCreateWidget(name, xmRowColumnWidgetClass, parent, 
				 NULL);
  installDestroyHandler();
  Widget mgr, mgr2;
  Widget frame;
  
  mgr = 
    XtVaCreateWidget("mgr", xmRowColumnWidgetClass, _baseWidget,
		     XmNorientation, XmHORIZONTAL,
		     NULL);

  mgr2 = 
    XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr,
		     XmNorientation, XmVERTICAL,
		     NULL);

  _colorBars = 
    XtVaCreateManagedWidget("colorBars", xmToggleButtonWidgetClass,
			    mgr2, NULL);

  XtAddCallback(_colorBars, XmNvalueChangedCallback, 
		&PanasonicWVSetup::colorBarsCallback, (XtPointer )this);

  _autoIris = 
    XtVaCreateManagedWidget("autoIris", xmToggleButtonWidgetClass,
			    mgr2, NULL);
  
  XtAddCallback(_autoIris, XmNvalueChangedCallback, 
		&PanasonicWVSetup::irisModeCallback, (XtPointer )this);

  XtManageChild(mgr2);

  frame = 
    XtVaCreateManagedWidget("frame", xmFrameWidgetClass, mgr, NULL);

  Widget gainMgr = 
    XtVaCreateWidget("gainMgr", xmRowColumnWidgetClass, frame,
		     XmNorientation, XmHORIZONTAL,
		     NULL);

  _gainMode = new VkRadioBox("gainMode", gainMgr);
  _manualGainMode = 
    _gainMode->addItem("manual", False, &PanasonicWVSetup::gainModeCallback,
		       this);

  _gainMode->addItem("lowAuto",  False, &PanasonicWVSetup::gainModeCallback,
		     this);

  _gainMode->addItem("highAuto",  False, &PanasonicWVSetup::gainModeCallback,
		     this);

  _gainMode->show();


  _gain = new VkRadioBox("gain", gainMgr);
  XtVaSetValues(_gain->baseWidget(),
		XmNorientation, XmHORIZONTAL,
		NULL);
  
  _gain->addItem("lowGain", False, &PanasonicWVSetup::gainSelectCallback,
		 this);

  _gain->addItem("medGain", False, &PanasonicWVSetup::gainSelectCallback,
		 this);

  _gain->addItem("highGain", False, &PanasonicWVSetup::gainSelectCallback,
		 this);

  _gain->show();

  XtManageChild(gainMgr);
  
  _sharpness = new VkRadioBox("sharpness", mgr);
  XtVaSetValues(_sharpness->baseWidget(),
		XmNorientation, XmHORIZONTAL,
		NULL);
  

  _sharpness->addItem("sharpOff", False, 
		      &PanasonicWVSetup::sharpSelectCallback,
		      this);

  _sharpness->addItem("lowSharp", False, 
		      &PanasonicWVSetup::sharpSelectCallback,
		      this);


  _sharpness->addItem("highSharp", False, 
		      &PanasonicWVSetup::sharpSelectCallback,
		      this);

  _sharpness->show();

  mgr2 = 
    XtVaCreateWidget("mgr2", xmRowColumnWidgetClass, mgr,
		     XmNorientation, XmVERTICAL,
		     NULL);

  _shutter = new VkOptionMenu(mgr2, "shutter", _shutterMenuDesc,
			      (XtPointer )this);

  _scene = new VkOptionMenu(mgr2, "scene", _sceneMenuDesc,
			    (XtPointer )this);
  
  XtManageChild(mgr2);
  XtManageChild(mgr);

  mgr = 
    XtVaCreateWidget("mgr", xmRowColumnWidgetClass, _baseWidget,
		     XmNorientation, XmHORIZONTAL,
		     NULL);

  _balanceMode = new VkRadioBox("balanceMode", mgr);
  XtVaSetValues(_balanceMode->baseWidget(),
		XmNorientation, XmHORIZONTAL,
		NULL);
  
  _manualBalanceMode = 
    _balanceMode->addItem("manual", False, 
			  &PanasonicWVSetup::balanceModeSelectCallback,
			  this);

  _balanceMode->addItem("autoA", False, 
			&PanasonicWVSetup::balanceModeSelectCallback,
			this);

  _balanceMode->addItem("autoB", False, 
			&PanasonicWVSetup::balanceModeSelectCallback,
			this);

  _balanceMode->show();

  Widget balanceMgr = 
    XtVaCreateWidget("balanceMgr", xmRowColumnWidgetClass, mgr,
		     XmNorientation, XmVERTICAL, NULL);

  frame = 
    XtVaCreateManagedWidget("frame", xmFrameWidgetClass, balanceMgr, NULL);
  
  _manualBalanceMgr = 
    XtVaCreateWidget("manualBalanceMgr", xmFormWidgetClass, frame,
		     NULL);
  
  const int sliderSize = 400;
  const int colorGainMin = 0;
  const int colorGainMax = 100;
  const int scrollBarLeftEdge = 25;
  
  Widget label;
  Widget mainLabel;
  
  mainLabel = 
    XtVaCreateManagedWidget("manualBalanceLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_FORM,
			    NULL);

  label = 
    XtVaCreateManagedWidget("redGainLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, mainLabel,
			    NULL);

  _redGainValue = new DynamicLabel("redGainValue", _manualBalanceMgr);

  XtVaSetValues(_redGainValue->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);

  _redGainValue->show();
  
  _redGain = 
    XtVaCreateManagedWidget("redGain", xmScrollBarWidgetClass, 
			    _manualBalanceMgr,
			    XmNorientation, XmHORIZONTAL,
			    XmNminimum, colorGainMin,
			    XmNmaximum, colorGainMax + sliderSize,
			    XmNleftAttachment, XmATTACH_POSITION,
			    XmNleftPosition, scrollBarLeftEdge,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, mainLabel,
			    NULL);

  XtAddCallback(_redGain, XmNvalueChangedCallback, 
		&PanasonicWVSetup::balanceAdjustCallback,
		(XtPointer )this);

  label = 
    XtVaCreateManagedWidget("blueGainLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _redGain,
			    NULL);

  _blueGainValue = new DynamicLabel("blueGainValue", _manualBalanceMgr);

  XtVaSetValues(_blueGainValue->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);

  _blueGainValue->show();

  _blueGain = 
    XtVaCreateManagedWidget("blueGain", xmScrollBarWidgetClass, 
			    _manualBalanceMgr,
			    XmNorientation, XmHORIZONTAL,
			    XmNminimum, colorGainMin,
			    XmNmaximum, colorGainMax + sliderSize,
			    XmNleftAttachment, XmATTACH_POSITION,
			    XmNleftPosition, scrollBarLeftEdge,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _redGain,
			    NULL);
  
  XtAddCallback(_blueGain, XmNvalueChangedCallback, 
		&PanasonicWVSetup::balanceAdjustCallback,
		(XtPointer )this);

  label = 
    XtVaCreateManagedWidget("redPedestalLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _blueGain,
			    NULL);

  _redPedestalValue = new DynamicLabel("redPedestalValue", _manualBalanceMgr);

  XtVaSetValues(_redPedestalValue->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);

  _redPedestalValue->show();

  _redPedestal =
    XtVaCreateManagedWidget("redPedestal", xmScrollBarWidgetClass, 
			    _manualBalanceMgr,
			    XmNorientation, XmHORIZONTAL,
			    XmNminimum, colorGainMin,
			    XmNmaximum, colorGainMax + sliderSize,
			    XmNleftAttachment, XmATTACH_POSITION,
			    XmNleftPosition, scrollBarLeftEdge,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _blueGain,
			    NULL);

  XtAddCallback(_redPedestal, XmNvalueChangedCallback, 
		&PanasonicWVSetup::balanceAdjustCallback,
		(XtPointer )this);

  label = 
    XtVaCreateManagedWidget("bluePedestalLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _redPedestal,
			    NULL);

  _bluePedestalValue = new DynamicLabel("bluePedestalValue", 
					_manualBalanceMgr);

  XtVaSetValues(_bluePedestalValue->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);

  _bluePedestalValue->show();

  _bluePedestal =
    XtVaCreateManagedWidget("bluePedestal", xmScrollBarWidgetClass, 
			    _manualBalanceMgr,
			    XmNorientation, XmHORIZONTAL,
			    XmNminimum, colorGainMin,
			    XmNmaximum, colorGainMax + sliderSize,
			    XmNleftAttachment, XmATTACH_POSITION,
			    XmNleftPosition, scrollBarLeftEdge,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _redPedestal,
			    NULL);

  XtAddCallback(_bluePedestal, XmNvalueChangedCallback, 
		&PanasonicWVSetup::balanceAdjustCallback,
		(XtPointer )this);


  label = 
    XtVaCreateManagedWidget("totalPedestalLabel", xmLabelWidgetClass, 
			    _manualBalanceMgr, 
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _bluePedestal,
			    NULL);

  _totalPedestalValue = new DynamicLabel("totalPedestalValue", 
					 _manualBalanceMgr);

  XtVaSetValues(_totalPedestalValue->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);

  _totalPedestalValue->show();

  _totalPedestal =
    XtVaCreateManagedWidget("totalPedestal", xmScrollBarWidgetClass, 
			    _manualBalanceMgr,
			    XmNorientation, XmHORIZONTAL,
			    XmNminimum, colorGainMin,
			    XmNmaximum, colorGainMax + sliderSize,
			    XmNleftAttachment, XmATTACH_POSITION,
			    XmNleftPosition, scrollBarLeftEdge,
			    XmNtopAttachment,  XmATTACH_WIDGET,
			    XmNtopWidget, _bluePedestal,
			    NULL);
  
  XtAddCallback(_totalPedestal, XmNvalueChangedCallback, 
		&PanasonicWVSetup::balanceAdjustCallback,
		(XtPointer )this);

  XtManageChild(_manualBalanceMgr);

  frame = 
    XtVaCreateManagedWidget("frame", xmFrameWidgetClass, balanceMgr, NULL);

  _autoBalanceMgr = 
    XtVaCreateWidget("autoBalanceMgr", xmRowColumnWidgetClass, frame,
		     XmNorientation, XmHORIZONTAL, 
		     XmNpacking, XmPACK_COLUMN,
		     NULL);
  
  label = 
    XtVaCreateManagedWidget("autoBalanceLabel", xmLabelWidgetClass, 
			    _autoBalanceMgr, 
			    NULL);

  _autoWhite = 
    XtVaCreateManagedWidget("autoWhite", xmPushButtonWidgetClass, 
			    _autoBalanceMgr, NULL);
  
  XtAddCallback(_autoWhite, XmNarmCallback,
		&PanasonicWVSetup::autoBalanceCallback,
		(XtPointer )this);

  XtAddCallback(_autoWhite, XmNdisarmCallback,
		&PanasonicWVSetup::holdBalanceCallback,
		(XtPointer )this);

  _autoBlack = 
    XtVaCreateManagedWidget("autoBlack", xmPushButtonWidgetClass, 
			    _autoBalanceMgr, NULL);
  
  XtAddCallback(_autoBlack, XmNarmCallback,
		&PanasonicWVSetup::autoBalanceCallback,
		(XtPointer )this);
		
  XtAddCallback(_autoBlack, XmNdisarmCallback,
		&PanasonicWVSetup::holdBalanceCallback,
		(XtPointer )this);

  XtManageChild(_autoBalanceMgr);
  
  XtManageChild(balanceMgr);
			    
  XtManageChild(mgr);

  mgr = 
    XtVaCreateWidget("mgr", xmRowColumnWidgetClass, _baseWidget,
		     XmNorientation, XmHORIZONTAL,
		     NULL);

  _menuMode = 
    XtVaCreateManagedWidget("menuMode", xmToggleButtonWidgetClass, mgr, NULL);
  
  XtAddCallback(_menuMode, XmNvalueChangedCallback, 
		&PanasonicWVSetup::menuModeCallback, (XtPointer )this);

  _menuMgr = 
    XtVaCreateWidget("menuMgr", xmFormWidgetClass, mgr, NULL);
  
  label = 
    XtVaCreateManagedWidget("menuPageLabel", xmLabelWidgetClass, _menuMgr,
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);
  
  _menuPage = 
    XtVaCreateManagedWidget("menuPage", xmArrowButtonWidgetClass, _menuMgr, 
			    XmNarrowDirection, XmARROW_RIGHT, 
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, label,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  label = 
    XtVaCreateManagedWidget("menuItemLabel", xmLabelWidgetClass, _menuMgr,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _menuPage,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  _menuItem =
    XtVaCreateManagedWidget("menuItem", xmArrowButtonWidgetClass, _menuMgr, 
			    XmNarrowDirection, XmARROW_DOWN, 
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, label,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  label = 
    XtVaCreateManagedWidget("menuItemValueLabel", xmLabelWidgetClass, 
			    _menuMgr,
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _menuItem,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  _menuUp =
    XtVaCreateManagedWidget("menuUp", xmArrowButtonWidgetClass, _menuMgr, 
			    XmNarrowDirection, XmARROW_UP, 
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, label,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  _menuDown =
    XtVaCreateManagedWidget("menuDown", xmArrowButtonWidgetClass, _menuMgr, 
			    XmNarrowDirection, XmARROW_DOWN, 
			    XmNleftAttachment, XmATTACH_WIDGET,
			    XmNleftWidget, _menuUp,
			    XmNtopAttachment, XmATTACH_FORM,
			    NULL);

  XtAddCallback(_menuPage, XmNarmCallback, 
		&PanasonicWVSetup::menuCmdArmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuPage, XmNdisarmCallback, 
		&PanasonicWVSetup::menuCmdDisarmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuItem, XmNarmCallback, 
		&PanasonicWVSetup::menuCmdArmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuItem, XmNdisarmCallback, 
		&PanasonicWVSetup::menuCmdDisarmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuUp, XmNarmCallback, 
		&PanasonicWVSetup::menuCmdArmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuUp, XmNdisarmCallback, 
		&PanasonicWVSetup::menuCmdDisarmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuDown, XmNarmCallback, 
		&PanasonicWVSetup::menuCmdArmCallback, 
		(XtPointer )this);

  XtAddCallback(_menuDown, XmNdisarmCallback, 
		&PanasonicWVSetup::menuCmdDisarmCallback, 
		(XtPointer )this);
  
  XtManageChild(_menuMgr);
  XtManageChild(mgr);
  
  char itemName[MaxDmNameLen];
  strcpy(itemName, dmPrefix);
  char *namePtr = itemName + strlen(itemName);
  
  strcpy(namePtr, GAIN_VALUE_DM);
  _dmGain = new DmEnumObject(itemName);
  if (addDmObject(_dmGain, DmConsumeFlag | DmProvideFlag) == -1)
    return;
  
  strcpy(namePtr, GAIN_MODE_DM);
  _dmGainMode = new DmEnumObject(itemName);
  if (addDmObject(_dmGainMode, DmConsumeFlag | DmProvideFlag) == -1)
    return;  

  strcpy(namePtr, IRIS_MODE_DM);
  _dmIrisMode = new DmBooleanObject(itemName);
  if (addDmObject(_dmIrisMode, DmConsumeFlag | DmProvideFlag) == -1)
    return;    

  strcpy(namePtr, COLOR_BARS_MODE_DM);
  _dmColorBars = new DmBooleanObject(itemName);
  if (addDmObject(_dmColorBars, DmConsumeFlag | DmProvideFlag) == -1)
    return;
  
  strcpy(namePtr, DETAIL_MODE_DM);
  _dmSharpness = new DmEnumObject(itemName);
  if (addDmObject(_dmSharpness, DmConsumeFlag | DmProvideFlag) == -1)
    return;
  
  strcpy(namePtr, SHUTTER_SPEED_DM);
  _dmShutter = new DmEnumObject(itemName);
  if (addDmObject(_dmShutter, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, SCENE_FILE_DM);
  _dmScene = new DmEnumObject(itemName);
  if (addDmObject(_dmScene, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, ATW_MODE_DM);
  _dmBalanceMode = new DmEnumObject(itemName);
  if (addDmObject(_dmBalanceMode, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, AWC_MODE_DM);
  _dmAutoBalance = new DmEnumObject(itemName);
  if (addDmObject(_dmAutoBalance, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, RED_PEDSTAL_DM);
  _dmRedPedestal = new DmInt16Object(itemName);
  if (addDmObject(_dmRedPedestal, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, BLUE_PEDSTAL_DM);
  _dmBluePedestal = new DmInt16Object(itemName);
  if (addDmObject(_dmBluePedestal, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, TOTAL_PEDSTAL_DM);
  _dmTotalPedestal = new DmInt16Object(itemName);
  if (addDmObject(_dmTotalPedestal, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, RED_GAIN_DM);
  _dmRedGain = new DmInt16Object(itemName);
  if (addDmObject(_dmRedGain, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, BLUE_GAIN_DM);
  _dmBlueGain = new DmInt16Object(itemName);
  if (addDmObject(_dmBlueGain, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, MENU_MODE_DM);
  _dmMenuMode = new DmBooleanObject(itemName);
  if (addDmObject(_dmMenuMode, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, PAGE_STATE_DM);
  _dmMenuPage = new DmBooleanObject(itemName);
  if (addDmObject(_dmMenuPage, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, ITEM_STATE_DM);
  _dmMenuItem = new DmBooleanObject(itemName);
  if (addDmObject(_dmMenuItem, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, UP_STATE_DM);
  _dmMenuUp = new DmBooleanObject(itemName);
  if (addDmObject(_dmMenuUp, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  strcpy(namePtr, DOWN_STATE_DM);
  _dmMenuDown = new DmBooleanObject(itemName);
  if (addDmObject(_dmMenuDown, DmConsumeFlag | DmProvideFlag) == -1)
    return;

  if (setConsumePeriod(Aperiodic) == -1)
    return;

  _externalChange = False;

  updateGui();
}


PanasonicWVSetup::~PanasonicWVSetup()
{
  delete _redPedestalValue;
  delete _bluePedestalValue;
  delete _totalPedestalValue;
  delete _redGainValue;
  delete _blueGainValue;
}


void PanasonicWVSetup::updateGui(DM_Item handle)
{
  Boolean debug = False;
  
  dprintf(stderr, "PanasonicWVSetup::updateGui()\n");
  
  Int32 value;
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];

  /* Set flag which tells widget callbacks not to fire. This is necessary
     because the ViewKit VkRadioBox::setValue() function *always* invokes
     the associated callbacks (dumb!). So we check the value of this flag
     in the callbacks themselves. */
  _externalChange = True;

  int index;
  
  if ((errno = _dmGainMode->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "PanasonicWVSetup::updateGui() - reading gain mode",
		  errorBuf);
    setError(errorBuf);
  }
  else
  {
    index = -1;  
    switch (value)
    {
      case AUTO_GAIN_OFF:
      index = 0;
      break;
      
      case AUTO_GAIN_LOW:
      index = 1;
      break;
      
      case AUTO_GAIN_HIGH:
      index = 2;
      break;

      default:
      sprintf(errorBuf, 
	      "PanasonicWVSetup::updateGui() - %d: invalid gain mode",
	      value);

      setError(errorBuf);
    }
    if (index != -1)
    {
      _gainMode->setValue(index, True);
    }

    if (value == AUTO_GAIN_OFF)
    {
      // Manual mode; sensitize gain value buttons
      XtSetSensitive(_gain->baseWidget(), True);
    }
    else
    {
      // Auto mode; de-sensitize gain value buttons
      XtSetSensitive(_gain->baseWidget(), False);
    }
  }

  if ((errno = _dmGain->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, "PanasonicWVSetup::updateGui() - reading gain",
		  errorBuf);
    setError(errorBuf);
  }
  else
  {
    index = -1;
  
    switch (value)
    {
      case LowGain:
      index = 0;
      break;
    
      case MedGain:
      index = 1;
      break;
    
      case HighGain:
      index = 2;
      break;
    
      default:
      sprintf(errorBuf, "PanasonicWVSetup::updateGui() - %d: invalid gain",
	      value);

      setError(errorBuf);
    }
    if (index != -1)
      _gain->setValue(index, True);
  }

  MBool manualIris;
  
  if ((errno = _dmIrisMode->read(&manualIris, &t)) != SUCCESS)
  {
    sprintDmError(errno, "PanasonicWVSetup::updateGui() - reading iris mode",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    if (manualIris)
      XtVaSetValues(_autoIris, XmNset, False, NULL);
    else
      XtVaSetValues(_autoIris, XmNset, True, NULL);
  }

  MBool showColorBars;
  if ((errno = _dmColorBars->read(&showColorBars, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading color bar mode",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    Boolean set;
    if (showColorBars)
      set = True;
    else
      set = False;
    
    XtVaSetValues(_colorBars, XmNset, set, NULL);
  }

  if ((errno = _dmSharpness->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading detail mode",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    if (value >= 0 && value <= DETAIL_HIGH)
      _sharpness->setValue(value, True);
  }

  if ((errno = _dmShutter->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading shutter speed",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    if (value >= SHUTTER_OFF && value <= SHUTTER_SPEED_ELC)
      _shutter->set(value);
  }
  
  if ((errno = _dmScene->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading scene file",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    if (value >= USER_SET && value <= SCENE_3)
      _scene->set(value);
  }
  
  if ((errno = _dmBalanceMode->read(&value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading balance mode",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    if (value >= ATW && value <= MODE_B)
      _balanceMode->setValue(value, True);
  }
  
  char buf[256];
  
  Int16 value16;

  if ((errno = _dmRedPedestal->read(&value16, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading red pedestal",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    sprintf(buf, "%-4d", value16);
    _redPedestalValue->setText(buf);
    XtVaSetValues(_redPedestal, XmNvalue, value16, NULL);
  }
  
  if ((errno = _dmBluePedestal->read(&value16, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading blue pedestal",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    sprintf(buf, "%-4d", value16);
    _bluePedestalValue->setText(buf);
    XtVaSetValues(_bluePedestal, XmNvalue, value16, NULL);
  }

  if ((errno = _dmTotalPedestal->read(&value16, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading total pedestal",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    sprintf(buf, "%-4d", value16);
    _totalPedestalValue->setText(buf);
    XtVaSetValues(_totalPedestal, XmNvalue, value16, NULL);
  }  

  if ((errno = _dmRedGain->read(&value16, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading red gain",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    sprintf(buf, "%-4d", value16);
    _redGainValue->setText(buf);
    XtVaSetValues(_redGain, XmNvalue, value16, NULL);
  }

  if ((errno = _dmBlueGain->read(&value16, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading blue gain",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    sprintf(buf, "%-4d", value16);
    _blueGainValue->setText(buf);
    XtVaSetValues(_blueGain, XmNvalue, value16, NULL);
  }

  MBool menuMode;
  if ((errno = _dmMenuMode->read(&menuMode, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::updateGui() - reading menu mode",
		  errorBuf);

    setError(errorBuf);
  }  
  else
  {
    Boolean set;
    if (menuMode)
      set = True;
    else
      set = False;

    XtVaSetValues(_menuMode, XmNset, set, NULL);

    // Sensitize or desensitize menu command buttons
    XtSetSensitive(_menuMgr, set);
  }
  

  _externalChange = False;
}


void PanasonicWVSetup::gainModeCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;
  
  if (!cb->set)
    return;

  Boolean debug = False;
  dprintf(stderr, "PanasonicWVSetup::gainModeCallback()\n");
  
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  dprintf(stderr, "_externalChange = %d\n", obj->_externalChange);

  if (obj->_externalChange)
    return;
  
  if (w == obj->_manualGainMode)
  {
    // Manual mode; sensitize gain value buttons
    XtSetSensitive(obj->_gain->baseWidget(), True);
  }
  else
  {
    // Auto mode; de-sensitize gain value buttons
    XtSetSensitive(obj->_gain->baseWidget(), False);
  }

  obj->writeGainMode();
}


void PanasonicWVSetup::irisModeCallback(Widget w,
					XtPointer clientData,
					XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "PanasonicWVSetup::valueChangedCallback()\n");
  
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeIrisMode();
}


void PanasonicWVSetup::colorBarsCallback(Widget w,
					 XtPointer clientData,
					 XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "PanasonicWVSetup::valueChangedCallback()\n");
  
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeColorBars();
}


void PanasonicWVSetup::sharpSelectCallback(Widget w,
					  XtPointer clientData,
					  XtPointer callData)
{
  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;
  
  if (!cb->set)
    return;

  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeDetailMode();
}


void PanasonicWVSetup::shutterCallback(Widget w,
				      XtPointer clientData,
				      XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeShutter();
}


void PanasonicWVSetup::sceneCallback(Widget w,
				      XtPointer clientData,
				      XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeScene();
}


void PanasonicWVSetup::balanceAdjustCallback(Widget w,
					    XtPointer clientData,
					    XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  Int16 value = ((XmScrollBarCallbackStruct *)callData)->value;
  obj->writeBalance(w, value);
}


void PanasonicWVSetup::autoBalanceCallback(Widget w,
					   XtPointer clientData,
					   XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeAutoBalance(w);
}


void PanasonicWVSetup::holdBalanceCallback(Widget w,
					   XtPointer clientData,
					   XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeAutoBalance(NULL);
}


void PanasonicWVSetup::balanceModeSelectCallback(Widget w,
						XtPointer clientData,
						XtPointer callData)
{
  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;
  
  if (!cb->set)
    return;

  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;

  obj->writeBalanceMode(w);
}


void PanasonicWVSetup::gainSelectCallback(Widget w,
					 XtPointer clientData,
					 XtPointer callData)
{
  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;
  
  if (!cb->set)
    return;
  
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  if (obj->_externalChange)
    return;
  
  obj->writeGain();
}


void PanasonicWVSetup::menuModeCallback(Widget w,
					XtPointer clientData,
					XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  
  XmToggleButtonCallbackStruct *cb = 
    (XmToggleButtonCallbackStruct *)callData;

  MBool set; 
  if (cb->set)
    set = TRUE;
  else
    set = FALSE;

  obj->writeMenuMode(set);
}


void PanasonicWVSetup::menuCmdArmCallback(Widget w,
					  XtPointer clientData,
					  XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeMenuCmd(w, TRUE);
}


void PanasonicWVSetup::menuCmdDisarmCallback(Widget w,
					     XtPointer clientData,
					     XtPointer callData)
{
  PanasonicWVSetup *obj = (PanasonicWVSetup *)clientData;
  obj->writeMenuCmd(w, FALSE);
}


void PanasonicWVSetup::writeAutoBalance(Widget w)
{
  Int32 value;
  
  if (w == _autoWhite)
    value = AWC;
  else if (w == _autoBlack)
    value = ABC;
  else if (w == NULL)
    value = HOLD;

  DM_Time t;
  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  
  Errno errno;
  
  if ((errno = _dmAutoBalance->write(value, &t)) != SUCCESS)
  {
    char errorBuf[errorMsgSize];
    sprintDmError(errno, "writeAutoBalance()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }
}


void PanasonicWVSetup::writeColorBars()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  Boolean set;
  XtVaGetValues(_colorBars, XmNset, &set, NULL);
  MBool colorBars;
  if (set)
    colorBars = ColorBarsOn;
  else
    colorBars = ColorBarsOff;
  
  if ((errno = _dmColorBars->write(colorBars, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeColorBars()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }  
}


void PanasonicWVSetup::writeIrisMode()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  Boolean set;
  MBool irisMode;
  
  XtVaGetValues(_autoIris, XmNset, &set, NULL);
  if (set)
    irisMode = AutoIris;
  else
    irisMode = ManualIris;
  
  if ((errno = _dmIrisMode->write(irisMode, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeIrisMode()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }  
}


void PanasonicWVSetup::writeGainMode()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  int i;
  for (i = 0; i <= 2; i++)
  {
    if (_gainMode->getValue(i))
      break;
  }

  Int32 value;
  
  switch (i)
  {
    case 0:
    value = AUTO_GAIN_OFF;
    break;
    
    case 1:
    value = AUTO_GAIN_LOW;
    break;
    
    case 2:
    value = AUTO_GAIN_HIGH;
    break;
  }
  
  if ((errno = _dmGainMode->write(value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeGainMode()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }

}


void PanasonicWVSetup::writeGain()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  for (Int32 i = LowGain; i <= HighGain; i++)
  {
    if (_gain->getValue(i))
    {
      if ((errno = _dmGain->write(i, &t)) != SUCCESS)
      {
	sprintDmError(errno, "PanasonicWVSetup::writeGain()", errorBuf);

	theErrorDialog->postAndWait(errorBuf);
	setError(errorBuf);
      }
    

      // Must reassert Manual gain
      i = AUTO_GAIN_OFF;
    
      if ((errno = _dmGainMode->write(i, &t)) != SUCCESS)
      {
	sprintDmError(errno, 
		      "PanasonicWVSetup::writeGain(), writing mode",
		      errorBuf);

	theErrorDialog->postAndWait(errorBuf);
	setError(errorBuf);
      }
      break;
    }
  }
}


void PanasonicWVSetup::writeDetailMode()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  for (Int32 i = DETAIL_0; i <= DETAIL_HIGH; i++)
  {
    if (_sharpness->getValue(i))
    {
      if ((errno = _dmSharpness->write(i, &t)) != SUCCESS)
      {
	sprintDmError(errno, 
		      "PanasonicWVSetup::writeDetailMode()", errorBuf);

	theErrorDialog->postAndWait(errorBuf);
	setError(errorBuf);
      }
      break;
    }
  }
}


void PanasonicWVSetup::writeShutter()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  Int32 value = _shutter->getIndex();
  if ((errno = _dmShutter->write(value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeShutter()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }  
}


void PanasonicWVSetup::writeScene()
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  Int32 value = _scene->getIndex();
  if ((errno = _dmScene->write(value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeScene()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }    
}


void PanasonicWVSetup::writeBalanceMode(Widget w)
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  for (Int32 i = ATW; i <= MODE_B; i++)
  { 
    if (_balanceMode->getValue(i))
    {
      if ((errno = _dmBalanceMode->write(i, &t)) != SUCCESS)
      {
	sprintDmError(errno, 
		      "PanasonicWVSetup::writeBalanceMode()", errorBuf);

	theErrorDialog->postAndWait(errorBuf);
	setError(errorBuf);
      }
      break;
      
    }
  }
}


void PanasonicWVSetup::writeBalance(Widget w, Int16 value)
{
  DM_Time t;
  Errno errno;
  char errorBuf[errorMsgSize];
  t.tv_sec = time(NULL);
  t.tv_usec = 0;

  DmInt16Object *dmObject;
  if (w == _redPedestal)
    dmObject = _dmRedPedestal;
  else if (w == _bluePedestal)
    dmObject = _dmBluePedestal;
  else if (w == _totalPedestal)
    dmObject = _dmTotalPedestal;
  else if (w == _redGain)
    dmObject = _dmRedGain;
  else if (w == _blueGain)
    dmObject = _dmBlueGain;
  else
    return;

  if ((errno = dmObject->write(value, &t)) != SUCCESS)
  {
    sprintDmError(errno, 
		  "PanasonicWVSetup::writeBalanceMode()", errorBuf);

    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }
}


void PanasonicWVSetup::writeMenuMode(MBool set)
{
  if (set)
    XtSetSensitive(_menuMgr, True);
  else
    XtSetSensitive(_menuMgr, False);

  DM_Time t;
  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  
  Errno errno;
  char errorBuf[errorMsgSize];
  
  if ((errno = _dmMenuMode->write(set, &t)) != SUCCESS)
  {
    sprintDmError(errno, "writeMenuMode()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }
}


void PanasonicWVSetup::writeMenuCmd(Widget w, MBool set)
{
  DmBooleanObject *dmObject;
  
  if (w == _menuPage)
    dmObject = _dmMenuPage;
  else if (w == _menuItem)
    dmObject = _dmMenuItem;
  else if (w == _menuUp)
    dmObject = _dmMenuUp;
  else if (w == _menuDown)
    dmObject = _dmMenuDown;
  else
    return;
  
  DM_Time t;
  t.tv_sec = time(NULL);
  t.tv_usec = 0;
  
  Errno errno;
  char errorBuf[errorMsgSize];

  if ((errno = dmObject->write(set, &t)) != SUCCESS)
  {
    sprintDmError(errno, "writeMenuMode()", errorBuf);
    theErrorDialog->postAndWait(errorBuf);
    setError(errorBuf);
  }
}



Widget PanasonicWVDialog::createDialog(Widget parent)
{
  Widget base = VkGenericDialog::createDialog(parent);

  setup = new PanasonicWVSetup("mainCameraSetup", base, _dmPrefix);
  setup->show();
  
  _showOK = False;
  _showApply = False;
  _showCancel = True;
  
  return base;
}


