static char RovMainWindow_id[] = "$Header: /usr/tiburon/unix/gui/tmacs/RCS/RovMainWindow.cc,v 1.24 1998/03/18 16:26:00 oreilly Exp $";


/*
$Log: RovMainWindow.cc,v $
Revision 1.24  1998/03/18 16:26:00  oreilly
*** empty log message ***

Revision 1.23  1998/02/26 23:11:34  oreilly
*** empty log message ***

Revision 1.22  1998/02/23 18:53:48  oreilly
Ensure that all children of _parentView are sticky consumers

Revision 1.21  1998/02/23 17:34:48  oreilly
*** empty log message ***

Revision 1.20  1998/02/23 17:21:24  oreilly
*** empty log message ***

Revision 1.19  1998/02/23 16:14:03  oreilly
*** empty log message ***

Revision 1.18  1997/12/12 17:56:38  oreilly
*** empty log message ***

Revision 1.17  1997/11/20 13:21:03  oreilly
*** empty log message ***

Revision 1.16  97/10/03  09:32:46  09:32:46  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.15  97/09/10  21:07:03  21:07:03  oreilly (Thomas C. O'Reilly)
Use local iterator in stopAllConsumers()

Revision 1.14  97/09/10  08:53:18  08:53:18  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.13  97/08/15  08:05:57  08:05:57  oreilly (Thomas C. O'Reilly)
Video setup dialog is now a public object

Revision 1.12  97/08/12  14:57:22  14:57:22  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.11  97/06/16  15:59:45  15:59:45  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.10  97/06/03  13:06:35  13:06:35  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.9  97/05/07  14:54:46  14:54:46  oreilly (Thomas C. O'Reilly)
Make sure to call show() after creating components.

Revision 1.8  97/05/06  16:30:34  16:30:34  oreilly (Thomas C. O'Reilly)
Added PduGfAlarm to parent view

Revision 1.7  97/04/30  19:45:38  19:45:38  oreilly (Thomas C. O'Reilly)
Attach AdvControl to right edge as well as left edge

Revision 1.6  97/04/09  14:02:37  14:02:37  oreilly (Thomas C. O'Reilly)
Added Adv controls and log to pilot page

Revision 1.5  97/03/25  15:40:53  15:40:53  oreilly (Thomas C. O'Reilly)
Launch CTD displayer, DM viewer, from App menu

Revision 1.4  97/03/20  12:30:53  12:30:53  oreilly (Thomas C. O'Reilly)
..

Revision 1.3  96/12/10  09:53:51  09:53:51  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.2  96/10/28  09:12:40  09:12:40  oreilly (Thomas C. O'Reilly)
*** empty log message ***

Revision 1.1  96/07/22  10:42:08  10:42:08  oreilly (Thomas C. O'Reilly)
First external release

*/
#include <malloc.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/XrtGraph.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/ScrolledW.h>
#include <Xm/Separator.h>
#include <Vk/VkSubMenu.h>
#include <Vk/VkApp.h>
#include <Vk/VkSimpleWindow.h>
#include <Vk/VkGenericDialog.h>
#include <Vk/VkErrorDialog.h>
#include <Vk/VkInfoDialog.h>
#include <Vk/VkFileSelectionDialog.h>
#include "RovMainWindow.h"
#include "controlDM.h"
#include "TiburonApp.h"
#include "RovMainWindow.h"
#include "RovCompass.h"
#include "ErsGui.h"
#include "ErsMode.h"
#include "VehicleState.h"
#include "ViewButton.h"
#include "VbGui.h"
#include "PowerAllocation.h"
#include "DmBarGraph.h"
#include "tiburon.h"
#include "controlDM.h"
#include "vbSystem.h"
#include "DepthAltitude.h"
#include "PanTiltAttitude.h"
#include "RovDiagram.h"
#include "PowerPage.h"
#include "MicroPage.h"
#include "VehicleConfiguration.h"
#include "ConfigurationDisplay.h"
#include "HeartBeat.h"
#include "Predive.h"
#include "ViewingPage.h"
#include "ToolsledPage.h"
#include "MidwaterGui.h"
#include "ExternalApp.h"
#include "AdvControl.h"
#include "AdvLogger.h"
#include "Uhs.h"
#include "ToolsledInterface.h"
#include "JoystickSetup.h"
#include "JoystickRangeIndicator.h"
#include "Clock.h"
#include "CommsPage.h"
#include "VehicleRelease.h"
#include "VspPage.h"

#define DmViewerName "dmviewer"
#define dprintf if (debug) fprintf

enum
{
  PilotView = 0, PowerView, ErsView, MicroEnvView, ViewingView, ToolsledView,
  AdvView, CommsView, VspView,
  NViews 
};
 
VkMenuDesc RovMainWindow::_lowerMenuDesc[] = 
{
  { ACTION, "lowerWindow", &RovMainWindow::lowerCallback },
  { END }
};


RovMainWindow::RovMainWindow(const char *name, 
			     int width, int height,
			     int viewPortWidth, int viewPortHeight) 
  : VkWindow(name)
{
  _currentView = NULL;

  _parentView = new ParentView("coreView", mainWindowWidget());
  XtVaSetValues(_parentView->baseWidget(), 
		XmNwidth, width,
		XmNheight, height,
		XmNfractionBase, FractionBase,
		XmNx, 0, XmNy, 0,
		NULL, 0);
  
  _viewPort = 
    XtVaCreateManagedWidget("viewPort", xmFormWidgetClass,
			    _parentView->baseWidget(),
			    XmNwidth, viewPortWidth, 
			    XmNheight, viewPortHeight,
			    NULL);
  
  // Center the viewport with top edge at bottom of menubar, centered
  // horizontally.
  int leftX, rightX;
  
  leftX = width / 2 - viewPortWidth / 2;
  leftX = leftX * FractionBase / width;
  rightX = FractionBase - leftX;
  int y = viewPortHeight * FractionBase / height;
  
  XtVaSetValues(_viewPort,
		XmNleftAttachment, XmATTACH_POSITION,
		XmNleftPosition, leftX,
		XmNrightAttachment, XmATTACH_POSITION,
		XmNrightPosition, rightX,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_POSITION,
		XmNbottomPosition, y,
		NULL);

  _viewWidth = viewPortWidth;
  _viewHeight = viewPortHeight;

  MBool debug = FALSE;
  
  const int viewButtonBarOffset = 50;

  _viewButtonBar = 
    XtVaCreateManagedWidget("viewButtonBar", xmSeparatorWidgetClass,
			    _parentView->baseWidget(),
			    XmNbottomAttachment, XmATTACH_FORM,
			    XmNbottomOffset, viewButtonBarOffset,
			    XmNleftAttachment, XmATTACH_FORM,
			    XmNrightAttachment, XmATTACH_FORM,
			    NULL);
					       
  VkSubMenu *fileMenuPane = addMenuPane("fileMenu");

  fileMenuPane->addAction("quit",
			  &RovMainWindow::quitCallback,
			  (XtPointer )this);
  
  setupMenuPane = addMenuPane("setupMenu");
  setupMenuPane->addAction("dive",
			    &RovMainWindow::showDiveCallback,
			    (XtPointer )this);

  setupMenuPane->addAction("showVehicleConfiguration",
			   &RovMainWindow::showConfigCallback,
			   (XtPointer )this);

  VkSubMenu *preferencesMenuPane = addMenuPane("preferencesMenu");

  preferencesMenuPane->addAction("editAlarms",
				 &RovMainWindow::editAlarmsCallback,
				 (XtPointer )this);

  preferencesMenuPane->addAction("loadAlarms",
				 &RovMainWindow::loadAlarmsCallback,
				 (XtPointer )this);

  preferencesMenuPane->addAction("saveAlarms",
				 &RovMainWindow::saveAlarmsCallback,
				 (XtPointer )this);
  
  preferencesMenuPane->addAction("priorityActions",
				 &showAlarmActionCallback,
				 (XtPointer )this);
  

  VkSubMenu *appMenuPane = addMenuPane("appMenu");
  appMenuPane->addAction("ctd",
			 &RovMainWindow::showCtdCallback,
			 (XtPointer )this);
			   
  appMenuPane->addAction("datamgr",
			 &RovMainWindow::dmViewerCallback,
			 (XtPointer )this);
  
  VkSubMenu *windowMgrPane = addMenuPane("windowMgrMenu", _lowerMenuDesc);


  _prediveDialog = new PrediveDialog("prediveDialog");
  _ctdSetupDialog = new CtdSetupDialog("ctdSetup");

  alarmLogger = NULL;
}


RovMainWindow::~RovMainWindow()
{
}


void RovMainWindow::show()
{
  VkWindow::show();
  _parentView->show();
}


void RovMainWindow::viewPortSize(int *width, int *height)
{
  *width = _viewWidth;
  *height = _viewHeight;
}


View *RovMainWindow::createView(const char *name)
{    
  View *view = new View(name, _viewPort); 
  // Leave a little offset along edges for viewport shadow
  XtVaSetValues(view->baseWidget(),
		XmNtopAttachment, XmATTACH_FORM,
		XmNtopOffset, 3,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNbottomOffset, 3,
		XmNleftAttachment, XmATTACH_FORM,
		XmNleftOffset, 3,
		XmNrightAttachment, XmATTACH_FORM,
		XmNrightOffset, 3,
		NULL);
  
  _parentView->addChildView(view);
  
  return view;
}


void RovMainWindow::setView(View *view)
{
  if (_currentView)
  {
    // Hide current view and stop contained consumers 
    _currentView->hide();
  }

  _currentView = view;

  // Show new view and start contained consumers
  _currentView->show();
}


// Create Gui elements in Views, based on user configuration file.
// For now, just hardcode stuff. 
void RovMainWindow::createGui()
{
  Widget label;
  Widget separator;
  char itemName[MaxDmNameLen];
  char alarmName[MaxDmNameLen];

  Layout *layout = new Layout();

  Clock *clock = new Clock("clock", _parentView->baseWidget());
  clock->show();
  layout->attachToEdge(Top);
  layout->attachToEdge(Left);
  layout->attach(Right, _viewPort);
  _parentView->add(clock, layout);

  layout->reset();
  
  RovCompass *compass = 
    new RovCompass("compass", _parentView->baseWidget(), 100, 120);

  if (compass->error())
  {
    compass->prtErrorMsg();
    exit(1);
  }
  
  compass->show();
  
  layout->attach(Top, clock->baseWidget());
  layout->attachToEdge(Left);
  layout->attach(Right, _viewPort);
  
  _parentView->add(compass, layout);

  layout->reset();
  
  TiburonApp *app = (TiburonApp *)theApplication;

  alarmLogger = 
    new AlarmLogger("alarmLogger", 
		    _parentView->baseWidget(),
		    app->systemAlarms);

  if (alarmLogger->error())
  {
    alarmLogger->prtErrorMsg();
    exit(1);
  }
  
  layout->attach(Top, compass);
  layout->attachToEdge(Left);
  layout->attach(Right, _viewPort);
  _parentView->add(alarmLogger, layout);
  alarmLogger->show();
  
  layout->reset();
  DepthAltitude *depthAltitude = 
    new DepthAltitude("depthAltitude", _parentView->baseWidget(), 200,
		      2, 1000);
  
  if (depthAltitude->error())
  {
    depthAltitude->prtErrorMsg();
    exit(1);
  }
  layout->attach(Top, alarmLogger);
  layout->attachToEdge(Left);
  layout->attach(Right, _viewPort);
  layout->attach(Bottom, _viewPort, 0, AttachToOpposite);
  _parentView->add(depthAltitude, layout);
  depthAltitude->show();
  
  layout->reset();
  PowerAllocation *powerAllocation = 
    new PowerAllocation("powerAllocation", 
		     _parentView->baseWidget(), 100);
  
  if (powerAllocation->error())
  {
    powerAllocation->prtErrorMsg();
    exit(1);
  }
  
  layout->attachToEdge(Left);
  layout->attach(Top, _viewPort, 4);
  layout->attach(Bottom, _viewButtonBar);
  _parentView->add(powerAllocation, layout);
  powerAllocation->show();
  
  const int horizontalOffset = 10;
  int barWidth = 20;
  
  layout->reset();
  float min = 0.;
  float max = 3000.;
  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, HYDRAULIC_PRESSURE_DM);
  
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, HYDRAULIC_PRESSURE_ALARM_DM);
 
  DmNat16BarGraph *hydraulic =
    new DmNat16BarGraph("hydraulicGuage", _parentView->baseWidget(),
			itemName, 500, alarmName, 0, 3000);

  if (hydraulic->error())
  {
    hydraulic->prtErrorMsg();
    exit(1);
  }
  hydraulic->setTickmarks(9);
  
  layout->attach(Left, powerAllocation, horizontalOffset);
  layout->attach(Top, depthAltitude);
  layout->attach(Bottom, _viewButtonBar);
  
  _parentView->add(hydraulic, layout);
  hydraulic->show();

  layout->reset();
  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, COMP_SYSTEM_LEVEL_PERCENT_DM);
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, COMP_SYSTEM_LEVEL_ALARM_DM);
  
  DmNat16BarGraph *compLevel =
    new DmNat16BarGraph("compLevelGuage", _parentView->baseWidget(),
			itemName, 500, alarmName, 0, 100);

  if (compLevel->error())
  {
    compLevel->prtErrorMsg();
    exit(1);
  }

  compLevel->setTickmarks(9);
  layout->attach(Left, hydraulic, horizontalOffset);
  layout->attach(Top, _viewPort);
  layout->attach(Bottom, _viewButtonBar);

  _parentView->add(compLevel, layout);
  compLevel->show();
  
  layout->reset();

  JoystickRangeIndicator *joystick = 
    new JoystickRangeIndicator("joystickGuage", _parentView->baseWidget());
  
  
  if (joystick->error())
  {
    joystick->prtErrorMsg();
    exit(1);
  }

  joystick->setTickmarks(9);
  layout->attach(Left, compLevel, horizontalOffset);
  layout->attach(Top, _viewPort);
  layout->attach(Bottom, _viewButtonBar);
  
  _parentView->add(joystick, layout);
  joystick->show();

  layout->reset();
  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, VB_SYSTEM_LEVEL_MM_DM);

  DmFlt32BarGraph *vbHeight = 
    new DmFlt32BarGraph("vbHeightGuage", _parentView->baseWidget(),
			itemName, 500, NULL, 0., 350.);
  
  if (vbHeight->error())
  {
    vbHeight->prtErrorMsg();
    exit(1);
  }

  vbHeight->setTickmarks(9);
  layout->attach(Left, joystick, horizontalOffset);
  layout->attach(Top, _viewPort);
  layout->attach(Bottom, _viewButtonBar);
  _parentView->add(vbHeight, layout);
  vbHeight->show();

  const int statusColumn = (int )(0.75 * FractionBase);
  const int statusEndColumn = (int )(0.87 * FractionBase);
  const int ersColumn = (int )(0.88 * FractionBase);
  
  layout->reset();
  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, TIBURON_IDLE_CPU_PERCENT_DM);
  
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, TIBURON_IDLE_CPU_ALARM_DM);
  
  DmNat16BarGraph *vehicleCpuIdle =
    new DmNat16BarGraph("vehicleCpuIdle", _parentView->baseWidget(),
			itemName, 500, alarmName, 0, 100);

  if (vehicleCpuIdle->error())
  {
    vehicleCpuIdle->prtErrorMsg();
    exit(1);
  }
  vehicleCpuIdle->setHorizontal();
  
  vehicleCpuIdle->setTickmarks(9);
  layout->attach(Left, vbHeight, 10);
  layout->attach(Top, _viewPort);
  
  _parentView->add(vehicleCpuIdle, layout);
  vehicleCpuIdle->show();

  layout->reset();
  
  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, TIBURON_IDLE_CPU2_PERCENT_DM);
  
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, TIBURON_IDLE_CPU2_ALARM_DM);
  DmInt16BarGraph *vehicleCpu2Idle =
    new DmInt16BarGraph("vehicleCpu2Idle", _parentView->baseWidget(),
			itemName, 500, alarmName, 0, 100);

  if (vehicleCpu2Idle->error())
  {
    vehicleCpu2Idle->prtErrorMsg();
    exit(1);
  }
  vehicleCpu2Idle->setHorizontal();
  
  vehicleCpu2Idle->setTickmarks(9);
  layout->attach(Left, vehicleCpuIdle);
  layout->attach(Top, _viewPort);
  
  _parentView->add(vehicleCpu2Idle, layout);
  vehicleCpu2Idle->show();

  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, CONSOLE_IDLE_CPU_PERCENT_DM);
  
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, CONSOLE_IDLE_CPU_ALARM_DM);

  DmNat16BarGraph *consoleCpuIdle =
    new DmNat16BarGraph("consoleCpuIdle", _parentView->baseWidget(),
			itemName, 500, alarmName, 0, 100);

  if (consoleCpuIdle->error())
  {
    consoleCpuIdle->prtErrorMsg();
    exit(1);
  }
  
  consoleCpuIdle->setHorizontal();
  consoleCpuIdle->setTickmarks(9);
  layout->attach(Left, vehicleCpu2Idle);
  layout->attach(Top, _viewPort);
  
  _parentView->add(consoleCpuIdle, layout);
  consoleCpuIdle->show();

  Widget uhsFrame = 
    XtVaCreateManagedWidget("uhsFrame", xmFrameWidgetClass, 
			    _parentView->baseWidget(),
			    NULL);
  
  Uhs *uhs = new Uhs("uhs", uhsFrame);
  
  if (uhs->error())
  {
    uhs->prtErrorMsg();
    exit(1);
  }
  
  layout->reset();
  layout->attach(Left, consoleCpuIdle);
  layout->attach(Top, _viewPort);
  _parentView->add(uhsFrame, layout);
  uhs->show();

  
  layout->reset();
  HeartBeat *vehicleHeartBeat =
    new HeartBeat("vehicleHeartBeat", _parentView->baseWidget(), 
		  TIBURON_DM_PREFIX TIBURON_HEARTBEAT_DM,
		  TIBURON_HEARTBEAT_RATE / 1000);

  if (vehicleHeartBeat->error())
  {
    vehicleHeartBeat->prtErrorMsg();
    exit(1);
  }
  
  layout->attach(Left, vehicleCpu2Idle, 0, AttachToOpposite);
  layout->attach(Top, vehicleCpu2Idle);
  _parentView->add(vehicleHeartBeat, layout);
  vehicleHeartBeat->show();

  layout->reset();
 
  layout->reset();
  HeartBeat *consoleHeartBeat =
    new HeartBeat("consoleHeartBeat", _parentView->baseWidget(), 
		  TIBURON_DM_PREFIX CONSOLE_HEARTBEAT_DM,
		  TIBURON_HEARTBEAT_RATE / 1000);

  if (consoleHeartBeat->error())
  {
    consoleHeartBeat->prtErrorMsg();
    exit(1);
  }
  
  layout->attach(Left, consoleCpuIdle, 0, AttachToOpposite);
  layout->attach(Top, consoleCpuIdle);
  _parentView->add(consoleHeartBeat, layout);
  consoleHeartBeat->show();

  strcpy(itemName, TIBURON_DM_PREFIX);
  strcat(itemName, CONSOLE_IDLE_CPU_PERCENT_DM);
  
  strcpy(alarmName, TIBURON_DM_PREFIX);
  strcat(alarmName, CONSOLE_IDLE_CPU_ALARM_DM);
 
  layout->reset();
  
  label = 
    XtVaCreateManagedWidget("vehicleStateLabel",
			    xmLabelWidgetClass, 
			    _parentView->baseWidget(),
			    NULL);

  layout->attach(Left, vehicleCpuIdle, 0, AttachToOpposite);
  layout->attach(Top, vehicleCpuIdle);

  _parentView->add(label, layout);

  layout->reset();
  VehicleState *vehicleState = 
    new VehicleState("vehicleState", _parentView->baseWidget());
  
  if (vehicleState->error())
  {
    vehicleState->prtErrorMsg();
    exit(1);
  }
  
  layout->attach(Left, label, 5);
  layout->attach(Right, vehicleCpu2Idle);
  layout->attach(Top, vehicleCpuIdle);

  _parentView->add(vehicleState, layout);
  vehicleState->show();

  layout->reset();
  label = 
    XtVaCreateManagedWidget("ersModeLabel",
			    xmLabelWidgetClass, _parentView->baseWidget(),
			    NULL);
  
  Widget ersLabel = label;
  
  layout->attach(Left, vbHeight, 10);
  layout->attach(Top, vehicleState);
  _parentView->add(label, layout);

  layout->reset();
  ErsMode *ersMode = new ErsMode("ersMode", _parentView->baseWidget());
  if (ersMode->error())
  {
    ersMode->prtErrorMsg();
    exit(1);
  }

  layout->attach(Left, vehicleState, 0, AttachToOpposite);
  layout->attach(Top, vehicleState);
  layout->attach(Right, vehicleCpu2Idle);
  
  _parentView->add(ersMode, layout);

  ersMode->show();

  layout->reset();
  PanTiltAttitude *attitude =
    new PanTiltAttitude("attitude", _parentView->baseWidget(), 200);
  
  if (attitude->error())
  {
    attitude->prtErrorMsg();
    exit(1);
  }
  
  attitude->show();
  layout->attachToEdge(Top);
  layout->attach(Left, _viewPort);
  layout->attachToEdge(Right);
  _parentView->add(attitude, layout);
  attitude->show();
  
  layout->reset();
  RovDiagram *rovDiagram = 
    new RovDiagram("rovDiagram", _parentView->baseWidget(), 200);
  
  if (rovDiagram->error())
  {
    rovDiagram->prtErrorMsg();
    exit(1);
  }
  Widget test = rovDiagram->VkDoubleBuffer::baseWidget();
  
  rovDiagram->VkDoubleBuffer::show();
  layout->attach(Left, _viewPort);
  layout->attach(Top, attitude->baseWidget());
  layout->attachToEdge(Right);
  layout->attach(Bottom, _viewPort, 0, AttachToOpposite);
  
  _parentView->add(rovDiagram, layout);

  createViewButtons(NViews);
  

  ViewButton *alarmViewButton = 
    new ViewButton("alarmViewButton",
		   _parentView->baseWidget(),
		   alarmLogger->alarmPageView());
  
  layout->reset();
  layout->attach(Top, _viewButtonBar);
  layout->attach(Left, _selectViewButton[_nViews-1], 5);
  layout->attachToEdge(Bottom);
  _parentView->add(alarmViewButton, layout);
  alarmViewButton->show();
  

  // Add stuff to forms

  Widget vbFrame;
  Widget mgr;
  
  vbFrame = 
    XtVaCreateManagedWidget("vbFrame", xmFrameWidgetClass,
			    _view[PilotView]->baseWidget(), NULL);

  mgr = XtVaCreateWidget("vbMgr", xmFormWidgetClass, vbFrame, NULL);
			 
  label = 
    XtVaCreateManagedWidget("vbLabel", 
			    xmLabelWidgetClass, mgr, 
			    XmNtopAttachment, XmATTACH_FORM,
			    XmNleftAttachment, XmATTACH_FORM,
			    NULL);
  
  VbGui *vb = new VbGui("vbGui", mgr, 100);
  if (vb->error())
  {
    vb->prtErrorMsg();
    exit(1);
  }
  
  XtVaSetValues(vb->baseWidget(),
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, label,
		NULL);
  
  vb->show();
  
  XtManageChild(mgr);
  
  layout->reset();
  layout->attachToEdge(Top);
  layout->attachToEdge(Left);
  _view[PilotView]->add(vbFrame, layout);

  Widget joystickFrame = 
    XtVaCreateManagedWidget("joystickFrame", xmFrameWidgetClass,
			    _view[PilotView]->baseWidget(), NULL);

  JoystickSetup *joystickSetup =
    new JoystickSetup("joystickSetup", joystickFrame);
  
  if (joystickSetup->error())
  {
    joystickSetup->prtErrorMsg();
    exit(1);
  }
  
  joystickSetup->show();
  
  layout->reset();
  layout->attachToEdge(Left);
  layout->attach(Top, vbFrame);
  _view[PilotView]->add(joystickFrame, layout);

  layout->reset();
  VehicleRelease *deployRelease =
    new VehicleRelease("deployRelease", _view[PilotView]->baseWidget());
  
  deployRelease->show();
  
  layout->attachToEdge(Left);
  layout->attachToEdge(Bottom);
  layout->attachToEdge(Right);
  _view[PilotView]->add(deployRelease, layout);
  
  layout->reset();
  label = 
    XtVaCreateManagedWidget("advControlLabel", 
			    xmLabelWidgetClass, 
			    _view[AdvView]->baseWidget(), NULL);
  
  layout->attach(Top, separator);
  layout->attachToEdge(Left);
  _view[AdvView]->add(label, layout);

  AdvControl *advControl = 
    new AdvControl("advControl", _view[AdvView]->baseWidget());

  if (advControl->error())
  {
    advControl->prtErrorMsg();
    exit(1);
  }
  layout->attach(Top, label);
  layout->attachToEdge(Left);
  layout->attachToEdge(Right);
  _view[AdvView]->add(advControl, layout);
  advControl->show();

  layout->reset();

  separator = 
    XtVaCreateManagedWidget("viewButtonBar", xmSeparatorWidgetClass,
			    _view[AdvView]->baseWidget(), NULL);
  
  layout->attach(Top, advControl);
  layout->attachToEdge(Left);
  layout->attachToEdge(Right);
  _view[AdvView]->add(separator, layout);
					       

  layout->reset();
  label = 
    XtVaCreateManagedWidget("advLoggerLabel", 
			    xmLabelWidgetClass, 
			    _view[AdvView]->baseWidget(), NULL);
  
  layout->attach(Top, separator);
  layout->attachToEdge(Left);
  _view[AdvView]->add(label, layout);

  AdvLogger *advLogger = 
    new AdvLogger("advLogger", _view[AdvView]->baseWidget(), 300);

  if (advLogger->error())
  {
    advLogger->prtErrorMsg();
    exit(1);
  }
  layout->attach(Top, label);
  layout->attachToEdge(Left);
  layout->attachToEdge(Right);
  _view[AdvView]->add(advLogger, layout);
  advLogger->show();
  
  layout->reset();
  label = XtVaCreateManagedWidget("ersPageLabel", xmLabelWidgetClass,
				  _view[ErsView]->baseWidget(), NULL);
  layout->attachToEdge(Top);
  layout->attachToEdge(Left);
  _view[ErsView]->add(label, layout);
  
  layout->reset();
  ErsGui *ersGui = new ErsGui("ersGui", _view[ErsView]->baseWidget(), 1000);
  if (ersGui->error())
  {
    ersGui->prtErrorMsg();
    exit(1);
  }
  
  layout->attachToEdge(Left);
  layout->attachToEdge(Right);
  layout->attach(Top, label);
  layout->attachToEdge(Bottom);
  _view[ErsView]->add(ersGui, layout);
  ersGui->show();
  
  MicroPage *microPage = 
    new MicroPage("microPage", _view[MicroEnvView]->baseWidget());

  if (microPage->error())
  {
    microPage->prtErrorMsg();
    exit(1);
  }
  
  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Right);
  layout->attachToEdge(Top);
  layout->attachToEdge(Bottom);
  
  _view[MicroEnvView]->add(microPage, layout);
  microPage->show();


  PowerPage *powerPage =
    new PowerPage("powerPage", _view[PowerView]->baseWidget());

  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Top);
  layout->attachToEdge(Bottom);
  layout->attachToEdge(Right);

  _view[PowerView]->add(powerPage, layout);
  powerPage->show();

  ViewingPage *viewingPage =
    new ViewingPage("viewingPage", _view[ViewingView]->baseWidget());
	
  if (viewingPage->error())
  {
    viewingPage->prtErrorMsg();
    exit(1);
  }	   
  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Top);
  layout->attachToEdge(Bottom);
  layout->attachToEdge(Right);
  _view[ViewingView]->add(viewingPage, layout);
  viewingPage->show();
  
  ToolsledPage *toolsled = 
    new ToolsledPage("toolsled", _view[ToolsledView]->baseWidget());

#if 0

  MidwaterGui *toolsled = 
    new MidwaterGui("midwaterGui", _view[ToolsledView]->baseWidget());

  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Top);
  layout->attachToEdge(Right);
  layout->attachToEdge(Bottom);

  _view[ToolsledView]->add(toolsled, layout);
#endif

  toolsled->show();

  
  CommsPage *commsPage = 
    new CommsPage("commsPage", _view[CommsView]->baseWidget());
  
  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Top);
  layout->attachToEdge(Bottom);
  layout->attachToEdge(Right);

  _view[CommsView]->add(commsPage, layout);
  commsPage->show();
  

  VspPage *vspPage = 
    new VspPage("vspPage", _view[VspView]->baseWidget());

  layout->reset();
  layout->attachToEdge(Left);
  layout->attachToEdge(Top);
  layout->attachToEdge(Bottom);
  layout->attachToEdge(Right);

  _view[VspView]->add(vspPage, layout);
  vspPage->show();

  // Stop all consumers before showing first view
  stopAllConsumers();

  _parentView->show();

  // First hide all views
  for (int i = 0; i < _nViews; i++)
    _view[i]->hide();
  
  setView(_view[PilotView]);  
}


void RovMainWindow::selectViewCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  MBool debug = FALSE;
  dprintf(stderr, "RovMainWindow::selectViewCallback()\n");
  
  RovMainWindow *obj = (RovMainWindow *)clientData;
  for (int i = 0; i < obj->_nViews; i++)
  {
    if (w == obj->_selectViewButton[i])
    {
      dprintf(stderr, "Selected view button #%d\n", i);
      obj->setView(obj->_view[i]);
      break;
    }
  }
}


void RovMainWindow::postAlarmFileList(XtCallbackProc okCallback)
{
  TiburonApp *app = (TiburonApp *)theApplication;
  const char *filename = app->systemAlarms->fileName();
  char *ptr;
  char buf[256];
  
  theFileSelectionDialog->setSelection(filename);
  
  if ((ptr = strrchr((const char *)filename, '/')) != NULL)
  {
    int nbytes = ptr - filename + 1;
    strncpy(buf, filename, nbytes);
    buf[nbytes] = '\0';
    theFileSelectionDialog->setDirectory((const char *)buf);
  }
      
  theFileSelectionDialog->setFilterPattern("*.alarm");
  
  theFileSelectionDialog->post("Select Alarm Definition File",
			       okCallback);
}


void RovMainWindow::editAlarmsCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  RovMainWindow *obj = (RovMainWindow *)clientData;

  AlarmLogger::showAlarmSetupCallback(w,
				      obj->alarmLogger,
				      callData);
}


void RovMainWindow::loadAlarmsCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  RovMainWindow::postAlarmFileList(&RovMainWindow::loadAlarmsOkCallback);
}


void RovMainWindow::loadAlarmsOkCallback(Widget w, XtPointer clientData,
					 XtPointer callData)
{
  TiburonApp *app = (TiburonApp *)theApplication;

  // Clone current system alarms in case load fails
  SystemAlarms *oldSystemAlarms = new SystemAlarms(*app->systemAlarms);
  
  char *filename;

  XmFileSelectionBoxCallbackStruct *cbs = 
    (XmFileSelectionBoxCallbackStruct *)callData;

  XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &filename);
  
  char buf[256];
  
  if (app->systemAlarms->load(filename) == -1)
  {
    app->systemAlarms->errorMsg(buf);
    theErrorDialog->postAndWait(buf);

    // Restore backed up SystemAlarms
    delete app->systemAlarms;
    app->systemAlarms = new SystemAlarms(*oldSystemAlarms);
  }
  else
  {
    sprintf(buf, "Successfully loaded alarms from file \"%s\"", filename);
    theInfoDialog->postAndWait(buf);
  }
  
  // Delete backup SystemAlarms
  delete oldSystemAlarms;
}


void RovMainWindow::saveAlarmsCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  RovMainWindow::postAlarmFileList(&RovMainWindow::saveAlarmsOkCallback);
}


void RovMainWindow::saveAlarmsOkCallback(Widget w, XtPointer clientData,
					 XtPointer callData)
{
  char *filename;

  XmFileSelectionBoxCallbackStruct *cbs = 
    (XmFileSelectionBoxCallbackStruct *)callData;

  XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &filename);
  
  TiburonApp *app = (TiburonApp *)theApplication;

  char buf[256];
  
  if (app->systemAlarms->save(filename) == -1)
  {
    app->systemAlarms->errorMsg(buf);
    theErrorDialog->postAndWait(buf);
  }
  else
  {
    sprintf(buf, "Successfully saved alarms into file \"%s\"", filename);
    theInfoDialog->postAndWait(buf);
  }
}


void RovMainWindow::quitCallback(Widget w, XtPointer clientData,
				 XtPointer callData)
{
  fprintf(stderr, "RovMainWindow::quitCallback()\n");
  TiburonApp *app = (TiburonApp *)theApplication;
  app->exit(0);
}


void RovMainWindow::showConfigCallback(Widget w, XtPointer clientData,
				       XtPointer callData)
{
  Boolean debug = False;
  dprintf(stderr, "RovMainWindow::showConfigCallback()\n");
  ConfigurationDisplay *configDisplay = 
    new ConfigurationDisplay("configurationDisplay");
  
  configDisplay->show();
}


void RovMainWindow::showDiveCallback(Widget w, XtPointer clientData,
				     XtPointer callData)
{
  RovMainWindow *obj = (RovMainWindow *)clientData;
  
  obj->_prediveDialog->setTitle("prediveTitle");
  
  obj->_prediveDialog->post(NULL, NULL, NULL, 
			    &PrediveDialog::applyCallback,
			    (XtPointer )obj->_prediveDialog);
  
}


void RovMainWindow::showCtdCallback(Widget w, XtPointer clientData,
				    XtPointer callData)
{
  RovMainWindow *obj = (RovMainWindow *)clientData;
  obj->_ctdSetupDialog->setTitle("ctdSetupTitle");
  
  obj->_ctdSetupDialog->post(NULL, NULL, NULL, 
			     &CtdSetupDialog::applyCallback,
			     (XtPointer )obj->_ctdSetupDialog);
}


void RovMainWindow::showParentView()
{
  // Show parentView and restart contained consumers
  _parentView->show();
}



ParentView *RovMainWindow::parentView()
{
  return _parentView;
}


void RovMainWindow::stopAllConsumers()
{
  MBool error = FALSE;
  MBool debug = ((TiburonApp *)theApplication)->debug();
  
  // Stop consumers of all DmGuiObjects
  DmGuiObject **obj;
  DmGuiApp *app = (DmGuiApp *)theApplication;

  SListIter<DmGuiObject *> *objects = 
    new SListIter<DmGuiObject *>(app->dmGuiObjectList);

  objects->reset();
  // Ensure that all DmGuiObjects managed by _parentView are
  // "sticky" consumers
  while (obj = objects->next())
  {
    if (_parentView->manages(*obj))
      (*obj)->setStickyConsumer(True);
  }
  
  objects->reset();

  while (obj = objects->next())
  {
    if (!(*obj)->stickyConsumer())
    {
      dprintf(stderr, 
	      "RovMainWindow::stopAllConsumers() - \"%s\" is NOT sticky\n", 
	      (*obj)->name());
    }
    
    if (!(*obj)->stickyConsumer() && (*obj)->stopConsume(CheckSticky) == -1)
    {
      (*obj)->prtErrorMsg();
      error = TRUE;
      (*obj)->clearError();
    }
  }  

  // Done with iterator
  delete objects;
  
  if (error)
  {
    char errbuf[errorMsgSize];
    
    sprintf(errbuf, 
	    "RovMainWindow::stopAllConsumers() - stopConsume() failed for "
	    "one or more DmGuiObjects: see stderr\n");

    fprintf(stderr, "%s\n", errbuf);
  }
}


void RovMainWindow::dmViewerCallback(Widget w, XtPointer clientData,
				     XtPointer callData)
{
  ExternalApp *dmViewer = new ExternalApp(DmViewerName);
  char *argv[10];
  argv[0] = DmViewerName;
  argv[1] = NULL;
  char errorBuf[512];

  int pid;
  
  if ((pid = dmViewer->run(argv, errorBuf)) == -1)
    theErrorDialog->postAndWait(errorBuf);
  else
  {
    TiburonApp *app = (TiburonApp *)theApplication;
    app->subPrograms->add(DmViewerName, pid, 
			 &RovMainWindow::dmViewerExitCallback);
    
  }
  

  delete dmViewer;
}


void RovMainWindow::dmViewerExitCallback(int status)
{
  if (status)
  {
    theErrorDialog->postAndWait(DmViewerName " failed");
  }
}


void RovMainWindow::lowerCallback(Widget w, XtPointer clientData,
				  XtPointer callData)
{
  RovMainWindow *obj = (RovMainWindow *)clientData;
  obj->lower();
}


void RovMainWindow::showAlarmActionCallback(Widget w, XtPointer clientData,
					    XtPointer callData)
{
  RovMainWindow *obj = (RovMainWindow *)clientData;
  AlarmLogger::showActionSetupCallback(w,
				       obj->alarmLogger,
				       callData);
}


void RovMainWindow::createViewButtons(int nViews)
{
  _nViews = nViews;
  _selectViewButton = (Widget *)malloc(_nViews * sizeof(Widget));
  _view = (View **)malloc(_nViews * sizeof(View *));
  
  Layout *layout = new Layout();

  char name[100];
  for (int i = 0; i < _nViews; i++)
  {
    sprintf(name, "view%d", i);
    _view[i] = createView(name);  
    
    sprintf(name, "viewButton%d", i);
    
    _selectViewButton[i] = 
      XtVaCreateManagedWidget(name,
			      xmPushButtonWidgetClass, 
			      _parentView->baseWidget(),
			      NULL);

    layout->reset();
    layout->attach(Top, _viewButtonBar);
    layout->attachToEdge(Bottom);

    if (i == 0)
      layout->attachToEdge(Left);
    else
      layout->attach(Left, _selectViewButton[i-1], 5);

    XtAddCallback(_selectViewButton[i], XmNactivateCallback,
		  &RovMainWindow::selectViewCallback,
		  (XtPointer )this);
    
    _parentView->add(_selectViewButton[i], layout);
  }
}
