/************************************************************************/
/* Copyright 1992 MBARI							*/
/************************************************************************/
/* $Header: /usr/tiburon/unix/gui/proto/RCS/cameracall.c,v 1.1 1998/01/28 16:17:12 oreilly Exp $		*/
/* Summary  : Callbacks for ROV User Interface				*/
/* Filename : rovcall.c							*/
/* Author   : Bob Herlien (rah)						*/
/* Project  : New ROV							*/
/* $Revision: 1.1 $							*/
/* Created  : 05/21/92							*/
/************************************************************************/
/* Modification History:						*/
/* $Log: cameracall.c,v $
 * Revision 1.1  1998/01/28 16:17:12  oreilly
 * Initial revision
 *
 * Revision 2.2  96/05/15  11:15:33  11:15:33  bobh (Bob Herlien)
 * Still supporting proto during final vehicle build
 * 
 * Revision 1.4  93/05/27  15:48:00  15:48:00  hebo (Bob Herlien)
 * Data Manager Interface
 * 
 * Revision 1.2  93/01/21  10:34:16  10:34:16  hebo (Bob Herlien)
 * Changes after Level 0
 * 
 * Revision 1.0  92/11/20  12:03:27  12:03:27  hebo (Bob Herlien)
 * Initial revision
 * 
*/
/************************************************************************/

#include <sys/types.h>
#include <mbari/types.h>
#include <mbari/const.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/ScrollBar.h>
#include <Xm/ToggleB.h>
#include "rov.h"
#include "relay.h"
#include <camera.h>
#include <vmeIbc.h>


/********************************/
/*	External Functions	*/
/********************************/

Extern Void	startTimeout( TimeoutStruct *tp );
Extern Void	stopTimeout( TimeoutStruct *tp );
Extern Int32	readIntItem( DM_Item dmitem, DM_Type dmtype );
Extern Void	writeIntItem( DM_Item dmitem, DM_Type dmtype, Nat32 dat );
Extern Void	createRelayToggleForm( Widget parent,
				       relayToggleDesc *rtDescPtr );
Extern Void	updateRelayToggles( relayToggleDesc *rtDescPtr );
Extern Widget	rovError( Widget parent, char *msg );


/************************/
/*	External Data	*/
/************************/

Extern AppData	appdata;
Extern Widget	zoomScrollBar, zoomSetLabel, zoomValueLabel;
Extern Widget	focusScrollBar, focusSetLabel, focusValueLabel;
Extern Widget	irisScrollBar, irisValueLabel, autoIrisToggleButton;
Extern Widget	cameraGainRadioBox, manualGainToggleButton;
Extern Widget	lowAutoGainToggleButton, highAutoGainToggleButton;
Extern Widget	gain0ToggleButton, gain9ToggleButton, gain18ToggleButton;
Extern Widget	colorBarToggleButton, videoSwitchForm;


/********************************/
/*	Forward Declarations	*/
/********************************/

Void	updateRovIntLabel( rovItem *ip );
Void	updateRovScrollAndLabel( rovItem *ip );
Void	updateIrisMode( rovItem *ip );
Void	updateCameraGain( rovItem *ip );
Void	updateCameraGainMode( rovItem *ip );
Void	updateVideoRelays( rovItem *ip );
Void	updateRovXmToggle( rovItem *ip );
Void	selectCamera( Select *sp );
Void	unselectCamera( Select *sp );


/********************************/
/*	Global and Local Data	*/
/********************************/

MLocal Widget	last_camera = NULLW;

MLocal Widget *zoomValueWidgets[] = { &zoomScrollBar, &zoomSetLabel };
MLocal Widget *focusValueWidgets[] = { &focusScrollBar, &focusSetLabel };
MLocal Widget *irisValueWidgets[] = { &irisScrollBar, &irisValueLabel };


Global rovItem		zoomSetPtItem =
{ ZOOM_SET_POINT_DM, DM_INT16, 1, FALSE, NO_ITEM, 0,
  (Widget *)zoomValueWidgets, updateRovScrollAndLabel, 0 };

MLocal rovItem		zoomValueItem =
{ ZOOM_POSITION_DM, DM_INT16, 1, FALSE, NO_ITEM, 0,
  &zoomValueLabel, updateRovIntLabel, 0 };

Global rovItem		focusSetPtItem =
{ FOCUS_SET_POINT_DM, DM_INT16, 1, FALSE, NO_ITEM, 0,
  (Widget *)focusValueWidgets, updateRovScrollAndLabel, 0 };

MLocal rovItem		focusValueItem =
{ FOCUS_POSITION_DM, DM_INT16, 1, FALSE, NO_ITEM, 0,
  &focusValueLabel, updateRovIntLabel, 0 };

Global rovItem		irisValueItem =
{ IRIS_VALUE_DM, DM_INT16, 1, FALSE, NO_ITEM, 0,
  (Widget *)irisValueWidgets, updateRovScrollAndLabel, 0 };

MLocal rovItem		irisModeItem =
{ IRIS_MODE_DM, DM_INT16, 1, FALSE, NO_ITEM, -2,
  &autoIrisToggleButton, updateIrisMode, 0 };

MLocal rovItem		cameraGainItem =
{ GAIN_VALUE_DM, DM_INT16, 1, FALSE, NO_ITEM, -2,
  NULLWP, updateCameraGain, 0 };

MLocal rovItem		cameraGainModeItem =
{ GAIN_MODE_DM, DM_INT16, 1, FALSE, NO_ITEM, -2,
  NULLWP, updateCameraGainMode, 0 };

Global rovItem		cameraColorBarItem =
{ COLOR_BARS_MODE_DM, DM_MBOOL, 1, FALSE, NO_ITEM, -2,
  &colorBarToggleButton, updateRovXmToggle, 0 };

MLocal rovItem		*cameraItems[] =
{ &zoomSetPtItem, &zoomValueItem, &focusSetPtItem, &focusValueItem,
  &irisValueItem, &irisModeItem, &cameraGainItem, &cameraGainModeItem,
  &cameraColorBarItem, NULLR };

MLocal TimeoutStruct	portCameraTimeoutStruct = 
{ &appdata.misc_update, 0, cameraItems, 0, "Camera Screen", NULLF };

MLocal TimeoutStruct	stbdCameraTimeoutStruct = 
{ &appdata.misc_update, 0, cameraItems, 0, "Camera Screen", NULLF };

MLocal char		cameraBuff[1024];

MLocal rovItem		videoSwitchRelayItem =
{ VME_VIDEO_SWITCH_DM, DM_NAT16, 1, FALSE, NO_ITEM, 0, NULLWP,
   updateVideoRelays, 0 };

MLocal rovItem		*videoSwitchItems[] =
{ &videoSwitchRelayItem, NULLR };

MLocal TimeoutStruct	videoSwitchTimeoutStruct = 
{ &appdata.misc_update, 0, videoSwitchItems, 0, "Camera Screen", NULLF };

MLocal relayToggleStruct videoSwitchRelays[] =
{ {"Stbd Main Red",      NULLW, 1, 0x15, 0x2a, 0},
  {"Stbd Main NTSC",     NULLW, 2, 0x2a, 0x15, 0},
  {"Stbd Main Green",    NULLW, 4, 0x15, 0x2a, 0},
  {"Science Aux Camera", NULLW, 8, 0x2a, 0x15, 0},
  {"Stbd Main Blue",     NULLW, 0x10, 0x15, 0x2a, 0},
  {"Aux Camera 1",       NULLW, 0x20, 0x2a, 0x15, 0},
  {"Port Main NTSC",     NULLW, 0x40, 0, 0x80, 0},
  {"Pilot SIT Camera",   NULLW, 0x80, 0, 0x40, 0},
  {"Aux Camera 3",       NULLW, 0x100, 0, 0x200, 0},
  {"Toolsled Camera 1",  NULLW, 0x200, 0, 0x100, 0},
  {"Aux Camera 2",       NULLW, 0x400, 0, 0x800, 0},
  {"Toolsled Camera 2",  NULLW, 0x800, 0, 0x400, 0}
};

MLocal relayToggleDesc videoSwitchRelayDesc =
{ &videoSwitchRelayItem, videoSwitchRelays, XtNumber(videoSwitchRelays) };

Global SelectStatus	cameraSts;

Global Select portCameraSel =  { selectCamera, unselectCamera, NULLWP,
				 &cameraSts, NULLSS, PORT_CAMERA_DM_PREFIX,
				 &portCameraTimeoutStruct };

Global Select stbdCameraSel =  { selectCamera, unselectCamera, NULLWP,
				 &cameraSts, NULLSS, STBD_CAMERA_DM_PREFIX,
				 &stbdCameraTimeoutStruct };


/************************************************************************/
/* Function    : updateRovIntLabel					*/
/* Purpose     : Update a Label with Integer data			*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateRovIntLabel( rovItem *ip )
{
    Reg Int32	new;
    XmString	str;
    
    new = readIntItem( ip->dmitem, ip->dmtype );

    if ( new != ip->value )
    {
	switch( ip->dmtype )
	{
	  case DM_NAT16:
	  case DM_NAT32:
	    sprintf( cameraBuff, "%u", new );
	    break;

	  default:
	    sprintf( cameraBuff, "%d", new );
	}
	str = XmStringCreateSimple( cameraBuff );
	XtVaSetValues( *ip->widget, XmNlabelString, str, NULL );
	XmStringFree( str );
	ip->value = new;
    }

} /* updateRovIntLabel() */


/************************************************************************/
/* Function    : updateRovScrollAndLabel				*/
/* Purpose     : Update a ScrollBar and Label with Integer data		*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateRovScrollAndLabel( rovItem *ip )
{
    Reg Int32	new;
    Reg Widget	**widgetpp;
    XmString	str;

    new = readIntItem( ip->dmitem, ip->dmtype );
    widgetpp = (Widget **)(ip->widget);

    if ( new != ip->value )
    {
	XtVaSetValues( **(widgetpp++), XmNvalue, new, NULL );

	sprintf( cameraBuff, "%d", new );
	str = XmStringCreateSimple( cameraBuff );
	XtVaSetValues( **widgetpp, XmNlabelString, str, NULL );
	XmStringFree( str );
	ip->value = new;
    }

} /* updateRovScrollAndLabel() */


/************************************************************************/
/* Function    : updateRovXmToggle					*/
/* Purpose     : Update an XmToggleButton				*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateRovXmToggle( rovItem *ip )
{
    MBool	state;
    
    rdm_read( ip->dmitem, (char *)&state, sizeof(MBool) );

    if ( state != ip->value )
	XmToggleButtonSetState( *ip->widget, (state ? True : False), False);

    ip->value = state;

} /* updateRovXmToggle() */


/************************************************************************/
/* Function    : updateIrisMode						*/
/* Purpose     : Update Iris Mode ToggleButton				*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateIrisMode( rovItem *ip )
{
    Int16	state;

    rdm_read( ip->dmitem, (char *)&state, sizeof(MBool) );

    if ( state != ip->value )
    {
	XmToggleButtonSetState( *ip->widget, (state ? False : True), False);
	XtSetSensitive( irisScrollBar, (state ? True : False) );
    }

    ip->value = state;

} /* updateIrisMode() */


/************************************************************************/
/* Function    : updateCameraGain					*/
/* Purpose     : Update Camera Gain ToggleButtons			*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateCameraGain( rovItem *ip )
{
    Int16	gain;

    rdm_read( ip->dmitem, (char *)&gain, sizeof(Int16) );

    if ( gain != ip->value )
    {
	XmToggleButtonSetState( gain0ToggleButton, 
			        (gain == 0 ? True : False), False );
	XmToggleButtonSetState( gain9ToggleButton, 
			        (gain == 9 ? True : False), False );
	XmToggleButtonSetState( gain18ToggleButton, 
			        (gain == 18 ? True : False), False );
	ip->value = gain;
    }


} /* updateCameraGain() */


/************************************************************************/
/* Function    : updateCameraGainMode					*/
/* Purpose     : Update Camera Gain Mode ToggleButtons			*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
updateCameraGainMode( rovItem *ip )
{
    Int16	mode;

    rdm_read( ip->dmitem, (char *)&mode, sizeof(Int16) );

    if ( mode != ip->value )
    {
	XmToggleButtonSetState( manualGainToggleButton, 
			        (mode == 0 ? True : False), False );
	XmToggleButtonSetState( lowAutoGainToggleButton, 
			        (mode == 1 ? True : False), False );
	XmToggleButtonSetState( highAutoGainToggleButton, 
			        (mode == 2 ? True : False), False );
	ip->value = mode;
    }

    XtSetSensitive( cameraGainRadioBox, (mode ? False : True) );

} /* updateCameraGainMode() */


/************************************************************************/
/* Function    : updateVideoRelays					*/
/* Purpose     : Function to update Video Switch Relay indicators	*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
updateVideoRelays( rovItem *ip )
{
    updateRelayToggles( &videoSwitchRelayDesc );

} /* updateVideoRelays() */


/************************************************************************/
/* Function    : rovScrollbarCallback					*/
/* Purpose     : Callback function when Scrollbar is changed		*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
    Void
rovScrollbarCallback( Widget w, rovItem *ip, XmScrollBarCallbackStruct *callP )
{
    writeIntItem( ip->dmitem, ip->dmtype, callP->value );

} /* rovScrollbarCallback() */


/************************************************************************/
/* Function    : setIrisMode						*/
/* Purpose     : Callback function when Iris Auto mode is toggled	*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
    Void
setIrisMode( Widget w, XtPointer unused, XmToggleButtonCallbackStruct *callP )
{
    Int16	mode;

    mode = callP->set ? 0 : -1;
    rdm_write_once( irisModeItem.dmitem, (char *)&mode, sizeof(Int16) );

} /* setIrisMode() */


/************************************************************************/
/* Function    : setCameraGain						*/
/* Purpose     : Callback function when a Manual gain is selected for camera*/
/* Inputs      : Gain (0, 9, or 18)					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
setCameraGain(Widget w, Int32 gain, XmToggleButtonCallbackStruct *callP )
{
    Int16	gain16;

    gain16 = (Int16)gain;

    if ( callP->set )
	rdm_write_once( cameraGainItem.dmitem, (char *)&gain16, sizeof(Int16) );

} /* setCameraGain() */


/************************************************************************/
/* Function    : setCameraGainMode					*/
/* Purpose     : Callback function when Gain Mode button is selected	*/
/* Inputs      : Mode (0 for Manual, 1 for Low Auto, 2 for High Auto)	*/
/* Outputs     : None							*/
/************************************************************************/
    Void
setCameraGainMode(Widget w, Int32 mode, XmToggleButtonCallbackStruct *callP )
{
    Int16	mode16;

    mode16 = (Int16)mode;

    if ( callP->set )
	rdm_write_once( cameraGainModeItem.dmitem, (char *)&mode16,
		        sizeof(Int16) );

} /* setCameraGainMode() */


/************************************************************************/
/* Function    : setRovXmToggle						*/
/* Purpose     : Callback function when XmToggleButton is changed	*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
	Void
setRovXmToggle( Widget w, rovItem *ip, XmToggleButtonCallbackStruct *callP )
{
    MBool	state;
    
    state = (callP->set) ? TRUE : FALSE;

    rdm_write_once( ip->dmitem, (char *)&state, sizeof(state) );

    ip->value = state;

} /* setRovXmToggle() */


/************************************************************************/
/* Function    : selectCamera						*/
/* Purpose     : Callback to select a Camera				*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
selectCamera( Select *sp )
{
    Reg rovItem		*ip, **ipp;

    for ( ipp = cameraItems; (ip = *ipp) != NULLR; ipp++ )
    {
	if ( ip->dmname != NULL )
	{
	    sprintf(cameraBuff, "%s%s", sp->ptr1, ip->dmname);
	    ip->dmitem = rdm_lookup( cameraBuff, 0 );
	}
	else
	    ip->dmitem = NO_ITEM;

	ip->value = 0x12345678;
    }

    startTimeout( (TimeoutStruct *)(sp->ptr2) );

} /* selectCamera() */


/************************************************************************/
/* Function    : unselectCamera						*/
/* Purpose     : Callback to unselect a Camera				*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
unselectCamera( Select *sp )
{
    stopTimeout( (TimeoutStruct *)(sp->ptr2) );

} /* unselectCamera() */


/************************************************************************/
/* Function    : selectCameraScreen					*/
/* Purpose     : Callback to select the Camera Screen			*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
selectCameraScreen( Select *sp )
{
    startTimeout( &videoSwitchTimeoutStruct );

} /* selectCameraScreen() */


/************************************************************************/
/* Function    : unselectCameraScreen					*/
/* Purpose     : Callback to unselect the Camera Screen			*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
unselectCameraScreen( Select *sp )
{
    stopTimeout( &videoSwitchTimeoutStruct );

} /* unselectCameraScreen() */


/************************************************************************/
/* Function    : createPrefixedItems					*/
/* Purpose     : Create DM Items for rovItems with DM Prefixes		*/
/* Inputs      : Ptr to array of rovItems, ptr to TimeoutStruct		*/
/* Outputs     : None							*/
/* Comment     : Can be used to create only elemental types or arrays	*/
/************************************************************************/
    Void
createPrefixedItems( rovItem **ipp, TimeoutStruct *tp, char *dmprefix )
{
    Reg rovItem		*ip;

    tp->grpId = rdm_create_group( tp->idStr );

    for ( ; (ip = *ipp) != NULLR; ipp++ )
	if ( ip->dmname != NULL )
	{
	    sprintf( cameraBuff, "%s%s", dmprefix, ip->dmname );
	    rdm_create( cameraBuff, 1, &ip->dmitem, ip->dmtype, ip->dm_nels );
	}

} /* createPrefixedItems() */


/************************************************************************/
/* Function    : initCamera						*/
/* Purpose     : Initialize function for Camera Screen			*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
     Void
initCamera( Void )
{
    createPrefixedItems( cameraItems, &stbdCameraTimeoutStruct,
			 PORT_CAMERA_DM_PREFIX );

    createPrefixedItems( cameraItems, &portCameraTimeoutStruct,
			 STBD_CAMERA_DM_PREFIX );

    createPrefixedItems( videoSwitchItems, &videoSwitchTimeoutStruct,
			 VMEIBC_DM_PREFIX );

    createRelayToggleForm( videoSwitchForm, &videoSwitchRelayDesc );

} /* initCamera() */
