/************************************************************************/
/* Copyright 1993 MBARI							*/
/************************************************************************/
/* $Header: /usr/tiburon/unix/gui/proto/RCS/gfcall.c,v 1.1 1998/01/28 16:17:12 oreilly Exp $			*/
/* Summary  : Callbacks for Ground Fault/Diagnostic Screen of ROV GUI	*/
/* Filename : gfcall.c							*/
/* Author   : Bob Herlien (rah)						*/
/* Project  : New ROV							*/
/* $Revision: 1.1 $							*/
/* Created  : 08/03/93							*/
/************************************************************************/
/* Modification History:						*/
/* $Log: gfcall.c,v $
 * Revision 1.1  1998/01/28 16:17:12  oreilly
 * Initial revision
 *
 * Revision 2.2  96/05/15  11:15:32  11:15:32  bobh (Bob Herlien)
 * Still supporting proto during final vehicle build
 * 
 * Revision 2.0  95/09/20  14:23:01  14:23:01  hebo (Bob Herlien)
 * Support for final vehicle integration.  AC, PDU micros.
 * 
 * Revision 1.8  94/08/19  17:20:21  17:20:21  hebo (Bob Herlien)
 * Interface to Unix version of Data Manager
 * 
 * Revision 1.6  93/12/17  15:04:53  15:04:53  hebo (Bob Herlien)
 * December Wet Test
 * 
*/
/************************************************************************/

#include <mbari/types.h>
#include <mbari/const.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <Xm/ToggleB.h>
#include <X11/Xc/Xc.h>
#include "rov.h"
#include "tiburon.h"
#include "rdmif.h"
#include "relay.h"


/********************************/
/*	External Functions	*/
/********************************/

Extern Void	createItems( rovItem **ipp, TimeoutStruct *tp );
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 );


/********************************/
/*	External Data		*/
/********************************/

Extern AppData		appdata;	/* Application-wide resources	*/
Extern Widget		sio32RelayForm,
			topsideTelemRelayForm, rovTelemRelayForm;


/****************************************/
/*	Forward Function Declarations	*/
/****************************************/

Void	updateSio32Relays( rovItem *ip );
Void	updateTopTelemRelays( rovItem *ip );
Void	updateRovTelemRelays( rovItem *ip );


/********************************/
/*	Module Local Data	*/
/********************************/

MLocal rovItem		sio32RelayItem =
{ TIBURON_DM_PREFIX "SIO32.RELAY_CONTROL", DM_NAT32, 1, FALSE, NO_ITEM, 0, NULLWP,
   updateSio32Relays, 0 };

MLocal rovItem		topsideTelemRelayItem =
{ TIBURON_DM_PREFIX "TELEMETRY.TOPSIDE.RELAY_CONTROL", DM_NAT32, 1, FALSE, NO_ITEM, 0, NULLWP,
   updateTopTelemRelays, 0 };

MLocal rovItem		rovTelemRelayItem =
{ TIBURON_DM_PREFIX "TELEMETRY.ROV.RELAY_CONTROL", DM_NAT32, 1, FALSE, NO_ITEM, 0, NULLWP,
   updateRovTelemRelays, 0 };

MLocal rovItem		*gfItems[] =
{ &sio32RelayItem, &topsideTelemRelayItem, &rovTelemRelayItem, NULLR };

MLocal TimeoutStruct	gfTimeoutStruct = 
{ &appdata.misc_update, 0, gfItems, 0, "Ground Fault Screen", NULLF };

MLocal relayToggleStruct sio32Relays[] =
{ {"AC Micro",          NULLW, 1,        0, 0, 0},
  {"VME IBC",           NULLW, 2,        0, 0, 0},
  {"Stbd Pan/Tilt",     NULLW, 4,        0, 0, 0},
  {"Port Pan/Tilt",     NULLW, 8,        0, 0, 0},
  {"Sonar IBC",         NULLW, 0x10,     0, 0, 0},
  {"Sensor IBC",        NULLW, 0x20,     0, 0, 0},
  {"Camera IBC",        NULLW, 0x40,     0, 0, 0},
  {"ERS",               NULLW, 0x80,     0, 0, 0},
  {"Power IBC A",       NULLW, 0x100,    0, 0, 0},
  {"Port Vert Thrust",  NULLW, 0x200,    0, 0, 0},
  {"Port Horiz Thrust", NULLW, 0x400,    0, 0, 0},
  {"Stbd Horiz Thrust", NULLW, 0x800,    0, 0, 0},
  {"VB Motor",          NULLW, 0x1000,   0, 0, 0},
  {"Toolsled RS485/0",  NULLW, 0x2000,   0, 0, 0},
  {"Manipulator",       NULLW, 0x4000,   0, 0, 0},
  {"Lighting IBC",      NULLW, 0x8000,   0, 0, 0},
  {"Stbd Vert Thrust",  NULLW, 0x10000,  0, 0, 0},
  {"Fwd Lat Thrust",    NULLW, 0x20000,  0, 0, 0},
  {"Power IBC B",       NULLW, 0x40000,  0, 0, 0},
  {"Aft Lat Thrust",    NULLW, 0x80000,  0, 0, 0},
  {"Toolsled RS485/1",  NULLW, 0x100000, 0, 0, 0},
  {"Toolsled RS232",    NULLW, 0x200000, 0, 0, 0},
  {"Spare RS232",       NULLW, 0x400000, 0, 0, 0}
};

MLocal relayToggleStruct topTelemRelays[] =
{ {"Relay 0",         NULLW, 1,        0, 0, 0},
  {"Relay 1",         NULLW, 2,        0, 0, 0},
  {"Relay 2",         NULLW, 4,        0, 0, 0},
  {"Relay 3",         NULLW, 8,        0, 0, 0},
  {"Relay 4",         NULLW, 0x10,     0, 0, 0},
  {"Console uplink",  NULLW, 0x20,     0, 0, 0},
  {"UDI Sonar 232",   NULLW, 0x40,     0, 0, 0},
  {"Relay 7 spare",   NULLW, 0x80,     0, 0, 0},
  {"Relay 8 spare",   NULLW, 0x100,    0, 0, 0},
  {"Relay 9 spare",   NULLW, 0x200,    0, 0, 0},
  {"Relay 10 spare",  NULLW, 0x400,    0, 0, 0},
  {"Front Panel 232", NULLW, 0x800,    0, 0, 0},
  {"Transponder Key", NULLW, 0x1000,   0, 0, 0},
  {"Relay 13 spare",  NULLW, 0x2000,   0, 0, 0},
  {"Relay 14 spare",  NULLW, 0x4000,   0, 0, 0},
  {"UDI Sonar 485",   NULLW, 0x8000,   0, 0, 0},
  {"PDU Micro",       NULLW, 0x10000,  0, 0, 0},
  {"UART 1 spare",    NULLW, 0x20000,  0, 0, 0},
  {"UART 2 spare",    NULLW, 0x40000,  0, 0, 0},
  {"Belly pack",      NULLW, 0x80000,  0, 0, 0},
  {"UART 4 spare",    NULLW, 0x100000, 0, 0, 0},
  {"UART 5 spare",    NULLW, 0x200000, 0, 0, 0},
  {"UART 6 spare",    NULLW, 0x400000, 0, 0, 0}
};

MLocal relayToggleStruct rovTelemRelays[] =
{ {"Hydrophone 1",    NULLW, 1,      0x7, 0, 0x7},
  {"Hydrophone 2",    NULLW, 2,      0x7, 0, 0x7},
  {"Hydrophone 3",    NULLW, 4,      0x7, 0, 0x7},
  {"Isolate spare",   NULLW, 8,        0, 0, 0},
  {"Telem GF Enable", NULLW, 0x10,     0, 0, 0},
  {"Console uplink",  NULLW, 0x20,     0, 0, 0},
  {"UDI Sonar 232",   NULLW, 0x40,     0, 0, 0},
  {"Relay 7 spare",   NULLW, 0x80,     0, 0, 0},
  {"Relay 8 spare",   NULLW, 0x100,    0, 0, 0},
  {"Relay 9 spare",   NULLW, 0x200,    0, 0, 0},
  {"Relay 10 spare",  NULLW, 0x400,    0, 0, 0},
  {"Front Panel 232", NULLW, 0x800,    0, 0, 0},
  {"Transponder Key", NULLW, 0x1000,   0, 0, 0},
  {"Relay 13 spare",  NULLW, 0x2000,   0, 0, 0},
  {"Relay 14 spare",  NULLW, 0x4000,   0, 0, 0},
  {"UDI Sonar 485",   NULLW, 0x8000,   0, 0, 0},
  {"UART 0 spare",    NULLW, 0x10000,  0, 0, 0},
  {"Stbd Camera 485", NULLW, 0x20000,  0, 0, 0},
  {"Port Camera 485", NULLW, 0x40000,  0, 0, 0},
  {"UART 3 spare",    NULLW, 0x80000,  0, 0, 0},
  {"UART 4 spare",    NULLW, 0x100000, 0, 0, 0},
  {"UART 5 spare",    NULLW, 0x200000, 0, 0, 0},
  {"UART 6 spare",    NULLW, 0x400000, 0, 0, 0}
};

MLocal relayToggleDesc sio32RelayDesc =
{ &sio32RelayItem, sio32Relays, XtNumber(sio32Relays) };

MLocal relayToggleDesc topsideTelemRelayDesc =
{ &topsideTelemRelayItem, topTelemRelays, XtNumber(topTelemRelays) };

MLocal relayToggleDesc rovTelemRelayDesc =
{ &rovTelemRelayItem, rovTelemRelays, XtNumber(rovTelemRelays) };


/************************************************************************/
/* Function    : updateRelayToggles					*/
/* Purpose     : Function to update Relay ToggleButtons			*/
/* Inputs      : relayToggleDesc Ptr					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
updateRelayToggles( relayToggleDesc *rtDescPtr )
{
    Reg rovItem		*rovItemPtr;
    Reg relayToggleStruct *rTogglePtr;
    DWord		state;
    Reg Nat32		i;
    Reg Boolean		toggle_state;

    rovItemPtr = rtDescPtr->rtRovItem;
    state = readIntItem( rovItemPtr->dmitem, rovItemPtr->dmtype );

    if ( state != rovItemPtr->value )
	for ( i = 0, rTogglePtr = rtDescPtr->rtStructs;
	      i < rtDescPtr->nRelays; i++, rTogglePtr++ )
	{
	    toggle_state = (state & rTogglePtr->sr_bit) ? True : False;
	    XmToggleButtonSetState(rTogglePtr->sr_toggle, toggle_state, False);
	}

    rovItemPtr->value = state;

} /* updateRelayToggles() */


/************************************************************************/
/* Function    : updateSio32Relays					*/
/* Purpose     : Function to update SIO32 Relay indicators		*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
updateSio32Relays( rovItem *ip )
{
    updateRelayToggles( &sio32RelayDesc );

} /* updateSio32Relays() */


/************************************************************************/
/* Function    : updateTopTelemRelays					*/
/* Purpose     : Function to update Topside Telemetry Relay indicators	*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
updateTopTelemRelays( rovItem *ip )
{
    updateRelayToggles( &topsideTelemRelayDesc );

} /* updateTopTelemRelays() */


/************************************************************************/
/* Function    : updateRovTelemRelays					*/
/* Purpose     : Function to update Bottomside Telemetry Relay indicators*/
/* Inputs      : rovItem pointer					*/
/* Outputs     : None							*/
/************************************************************************/
    Void
updateRovTelemRelays( rovItem *ip )
{
    updateRelayToggles( &rovTelemRelayDesc );

} /* updateRovTelemRelays() */


/************************************************************************/
/* Function    : activateRelayToggle					*/
/* Purpose     : Callback when user changes a relay toggleButton	*/
/* Inputs      : Widget, relayToggleDesc pointer, call_data		*/
/* Outputs     : None							*/
/************************************************************************/
    Void
activateRelayToggle( Widget w, relayToggleDesc *rtdp,
			  XmToggleButtonCallbackStruct *tbp )
{
    DWord		state;
    Reg Nat32		i;
    Reg rovItem		*rovItemPtr;
    Reg relayToggleStruct *rtsp;

    rovItemPtr = rtdp->rtRovItem;
    state = readIntItem( rovItemPtr->dmitem, rovItemPtr->dmtype );

    for ( i = 0, rtsp = rtdp->rtStructs; i < rtdp->nRelays; i++, rtsp++ )
	if ( rtsp->sr_toggle == w )
	    break;

    if ( tbp->set )
    {
	state |= (rtsp->sr_bit | rtsp->sr_auxOn);
	state &= ~rtsp->sr_auxOffSet;
    }
    else
	state &= ~(rtsp->sr_bit | rtsp->sr_auxOffReset);

    writeIntItem( rovItemPtr->dmitem, rovItemPtr->dmtype, state );
    updateRelayToggles( rtdp );

} /* activateRelayToggle() */


/************************************************************************/
/* Function    : createRelayToggleForm					*/
/* Purpose     : Create form for Relay control				*/
/* Inputs      : Widget ID, relayToggleDesc Ptr				*/
/* Outputs     : None							*/
/************************************************************************/
    Void
createRelayToggleForm( Widget parent, relayToggleDesc *rtDescPtr )
{
    Reg Nat32		i;
    Reg relayToggleStruct *rtStructPtr;
    Reg Widget		w, rc;
    Reg XmString	str;

    rc = XtVaCreateManagedWidget("relayRowCol", xmRowColumnWidgetClass, parent,
				 XmNpacking, XmPACK_TIGHT,
				 XmNtopAttachment, XmATTACH_FORM,
				 XmNbottomAttachment, XmATTACH_FORM,
				 XmNleftAttachment, XmATTACH_FORM,
				 XmNrightAttachment, XmATTACH_FORM, NULL );

    for ( i = 0, rtStructPtr = rtDescPtr->rtStructs;
	  i < rtDescPtr->nRelays; i++, rtStructPtr++ )
    {
	str = XmStringCreateSimple( rtStructPtr->sr_label );
	w = XtVaCreateManagedWidget( "relayToggle",
				     xmToggleButtonWidgetClass, rc,
				     XmNlabelString, str, NULL );
	XmStringFree( str );
	rtStructPtr->sr_toggle = w;

	XtAddCallback( w, XmNvalueChangedCallback,
		       (XtCallbackProc)activateRelayToggle, rtDescPtr );
    }

} /* createRelayToggleForm() */


/************************************************************************/
/* Function    : selectGf						*/
/* Purpose     : Callback to select the Ground Fault screen		*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
selectGf( Select *sp )
{
    startTimeout( &gfTimeoutStruct );

} /* selectGf() */


/************************************************************************/
/* Function    : unselectGf						*/
/* Purpose     : Callback to unselect the Ground Fault screen		*/
/* Inputs      : Select Ptr						*/
/* Outputs     : None							*/
/************************************************************************/
    Void
unselectGf( Select *sp )
{
    stopTimeout( &gfTimeoutStruct );

} /* unselectGf() */


/************************************************************************/
/* Function    : initGf							*/
/* Purpose     : Initialize function for Ground Fault Screen		*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
     Void
initGf( Void )
{
    createItems( gfItems, &gfTimeoutStruct );
    createRelayToggleForm( sio32RelayForm, &sio32RelayDesc );
    createRelayToggleForm( topsideTelemRelayForm, &topsideTelemRelayDesc );
    createRelayToggleForm( rovTelemRelayForm, &rovTelemRelayDesc );

} /* initGf() */
