//=========================================================================
// Summary  : */
// Filename : VehicleConfigurationServer.cc
// Author   : */
// Project  : */
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#include "VehicleConfigurationServer.h"
#include "FloatAttribute.h"
#include "AngleAttribute.h"
#include "StringAttribute.h"
#include "Math.h"
#include "Syslog.h"
#include "Sysinfo.h"
#include "System.h"
#include "AttributeParser.h"
#include "Device.h"
#include "Time.h"

#include <signal.h>

#include "VehicleConfigurationServer.h"

VehicleConfigurationServer *VehicleConfigurationServer::_theServer = NULL;


VehicleConfigurationServer::VehicleConfigurationServer(const char *name,
						       const char *filename,
						       Boolean isSim )
  : VehicleConfigurationIF_SK()
{
     // Should be loaded from somewhere
     debug = 1;

     _theServer = this;

     // Disown these to make this server immune to ctrl-c on the console
     // (normally TaskServer points signals to it's signalHandler, which
     // causes an exit()
     signal( SIGINT, SIG_IGN );
     signal( SIGHUP, VehicleConfigurationServer::signalHandler );

     _constants = NULL;
     _procList = NULL;

     // Save these for later
     _isSim = isSim;
     _filename = filename;

     if( loadTables() < 0 ) {
	  Syslog::write("Failed to load table froms file \'%s\'", _filename );
	  exit(-1);
     }

//   _procList = NULL;
//   try {
//        _procList = new DeviceList( );
//   }
//   catch(...)
//   {
//        Syslog::write("VehicleConfigurationServer -- Caught exception while "
// 		     "initializing device list");
//   }
//   if( _procList->loadDevices( "dev.cfg" ) )
//   {
//        Syslog::write("VehicleConfigurationServer -- Failed to load device "
// 		     "table.  Exiting...");
//        exit(-1);
//   }

     // startTime = -1;

  // Report success to Supervisor
  Sysinfo::setStatus( Sysinfo::Ready );
}


VehicleConfigurationServer::~VehicleConfigurationServer()
{
     if( _constants != NULL ) delete _constants;

     if( _procList != NULL ) delete _procList;

}

//=========================================================================
//
short VehicleConfigurationServer::loadTables( void )
{
    
    // -- Start by loading vehicular constants ---------------

    clean( _constants );
    try {
	_constants = new VehicleConstants();
    }
    catch(...)
	{
	    Syslog::write(" Caught exception while "
			  "initializing vehicle constants");
	}
    
    if( _constants->loadConstants( _filename ) )
	{
	    Syslog::write(" Failed to load vehicle "
			  "constants.  Exiting...");
	    return -1;
	}
 
    // -- Then take care of device config -------------------

    clean( _procList);
    try {
	_procList = new ProcessList( _isSim );
    }
    catch(...)
	{
	    Syslog::write(" Caught exception while "
			  "initializing device list");
	}
    if( _procList->loadProcesses( "process.cfg" ) )
	{
	    Syslog::write(" Failed to load process "
			  "table.  Exiting...");
	    return -1;
	}
    
    return 0;
}

//=========================================================================
//

void VehicleConfigurationServer::kill( void )
{
     // Is there a cleaner way to do this?
     exit(0);
}

void VehicleConfigurationServer::reloadTables( void )
{
	// Okay, so this is a bit hairy. This function really
	// just clears all the tables and starts from scratch.
	// It throws away any information about interfaces, PIDs,
	// etc. It's a lot like restarting the vehicleConfigurationServer.
	//
	// So, DON'T CALL THIS FUNCTION UNLESS YOU MEAN IT!
	//
	// Seriously, the supervisor function reloadConfig() knows what it's
	// doing, so it calls this function, but it also restarts all the
	// servers to ensure that PID's & interfaces are registered properly.
	loadTables();
}


//- deviceCount() ----------------------------------------
short VehicleConfigurationServer::processCount()
{
     return _procList->count();
}

//- findDevice() -----------------------------------------
short VehicleConfigurationServer::findProcess( VehicleConfigurationIF::Name name )
{
     return _procList->findItemIndex( name );
}

short VehicleConfigurationServer::findProcessByServerName( VehicleConfigurationIF::Name name )
{
	Process *current;
	for( int i = 0; i < _procList->count() ; i++ ) {
		current = (Process *) _procList->findItem(i);
		if ( ! stricmp( current->server(), name ) )
			return i;
	}

	return -1;

}

//- getDeviceServer() ------------------------------------
short VehicleConfigurationServer::getProcessServer(
     short index,
     VehicleConfigurationIF::Driver server )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

//     Syslog::write("Returning driver for %s = %s", current->name(),
//		   current->driver() );

     strcpy( server, current->server() );

//     Syslog::write("Returning driver for %s = %s", current->name(),
//		   driver );
     return 0;
}
short VehicleConfigurationServer::getProcessServer(
     VehicleConfigurationIF::Name name,
     VehicleConfigurationIF::Driver server )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     strcpy( server, current->server() );
     return 0;
}

//- getDeviceDriver() ------------------------------------
short VehicleConfigurationServer::getProcessDriver(
     short index,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     strcpy( driver, current->driver() );
     return 0;
}

short VehicleConfigurationServer::getProcessDriver(
     VehicleConfigurationIF::Name name,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     strcpy( driver, current->driver() );
     return 0;
}

short VehicleConfigurationServer::getProcessDriver2(
     short index,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     strcpy( driver, current->driver2() );
     return 0;
}

short VehicleConfigurationServer::getProcessDriver2(
     VehicleConfigurationIF::Name name,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     strcpy( driver, current->driver2() );
     return 0;
}

short VehicleConfigurationServer::getProcessDriver3(
     short index,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     strcpy( driver, current->driver3() );
     return 0;
}

short VehicleConfigurationServer::getProcessDriver3(
     VehicleConfigurationIF::Name name,
     VehicleConfigurationIF::Driver driver )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     strcpy( driver, current->driver3() );
     return 0;
}

Boolean VehicleConfigurationServer::getDriverPersists(short index, short driverIndex) 
{
    Process *current;
    if( (current=(Process *)_procList->findItem( index )) == NULL )
	return False;
  
    return current->getDriverPersists(driverIndex);
}
    
Boolean VehicleConfigurationServer::getDriverPersists(VehicleConfigurationIF::Name name, short driverIndex)
{
    Process *current;
    if( (current=(Process *)_procList->findItem( name )) == NULL )
	return -1;
    
    return current->getDriverPersists(driverIndex);
}
     

//- getDeviceDriver() ------------------------------------
short VehicleConfigurationServer::getProcessName(
     short index,
     VehicleConfigurationIF::Name name )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     strcpy( name, current->name() );
     return 0;
}

short VehicleConfigurationServer::getProcessName( VehicleConfigurationIF::Name ifName,
                   VehicleConfigurationIF::Name processName )
{
	Process *current;

	for( int i = 0; i < _procList->count() ; i++ ) {

		current=(Process *)_procList->findItem( i );

		if ( ! stricmp( current->IFName(), ifName ) )
		{
			strcpy(processName, current->name());
			return 0;
		}
	}

	strcpy(processName, "");
	return 1;
}

short VehicleConfigurationServer::getProcessNameFromDriver(VehicleConfigurationIF::Driver driver, VehicleConfigurationIF::Name processName )
{
	Process *current;

	for( int i = 0; i < _procList->count() ; i++ ) {

		current=(Process *)_procList->findItem( i );

		if ( (stricmp( current->driver(), driver ) == 0)
		     || (stricmp( current->driver2(), driver ) == 0)
		     || (stricmp( current->driver3(), driver ) == 0)
		     )
		    {
			strcpy(processName, current->name());
			return 0;
		    }
	}

	strcpy(processName, "");
	return 1;
}


//- processInfo() -----------------------------------------
short VehicleConfigurationServer::processInfo(short index,
					     VehicleConfigurationIF::Name name,
					      VehicleConfigurationIF::Driver driver,
					     short *priority)
{
     Process *current;

     if( ( current = (Process *) _procList->findItem( index ) ) == NULL )
     {
	  dprintf("processInfo - Couldn't find a device named %s",
		  name );
	  return -1;
     }

     strcpy( name, current->name() );
     strcpy( driver, current->driver() );
     *priority = current->priority();

     return 0;

}

short VehicleConfigurationServer::processInfo(VehicleConfigurationIF::Name name,
			  VehicleConfigurationIF::Driver driver, short *priority)
{
     Process *current;

     if( ( current = (Process *) _procList->findItem( name ) ) == NULL )
     {
	  dprintf("processInfo - Couldn't find a device named %s",
		  name );
	  return -1;
     }

     strcpy( driver, current->driver() );
     *priority = current->priority();

     return 0;
}

//- getNode() ---------------------------------------
short VehicleConfigurationServer::getNode( short index )
{
     Process *current;
     if( ( current = (Device *) _procList->findItem( index ) ) == NULL )
     {
	  Syslog::write("getNode - Couldn't find device %d",
		  index );
	  return -1;
     }
     return current->node();
}

short VehicleConfigurationServer::getNode( VehicleConfigurationIF::Name name )
{
     Process *current;
     if( ( current = (Device *) _procList->findItem( name ) ) == NULL )
     {
	  Syslog::write("getNode - Couldn't find a device named %s",
		  name );
	  return -1;
     }
     return current->node();
}

//- getLogNode() ---------------------------------------
short VehicleConfigurationServer::getLogNode( short index )
{
     Process *current;
     if( ( current = (Device *) _procList->findItem( index ) ) == NULL )
     {
	  Syslog::write("getLogNode - Couldn't find device %d",
		  index );
	  return -1;
     }
     return current->logNode();
}

short VehicleConfigurationServer::getLogNode( VehicleConfigurationIF::Name name )
{
     Process *current;
     if( ( current = (Device *) _procList->findItem( name ) ) == NULL )
     {
	  Syslog::write("getLogNode - Couldn't find a device named %s",
		  name );
	  return -1;
     }
     return current->logNode();
}

//- deviceInfo() -----------------------------------------
short VehicleConfigurationServer::deviceInfo(short index,
					     VehicleConfigurationIF::DeviceInfo *devInfo )
{
     Device *current;

     if( ( current = (Device *) _procList->findItem( index ) ) == NULL ) {
	 dprintf("deviceInfo - Couldn't find a device named %s",
		 name );
	 return -1;
     }

     strcpy(devInfo->name, current->name() );
     strcpy(devInfo->server, current->server() );
     strcpy(devInfo->driver, current->driver() );
     strcpy(devInfo->driver2, current->driver2() );
     strcpy(devInfo->driver3, current->driver3() );
     devInfo->driver1Persists = current->getDriverPersists(1);
     devInfo->driver2Persists = current->getDriverPersists(2);
     devInfo->driver3Persists = current->getDriverPersists(3);
     strcpy(devInfo->port, current->port() );
     devInfo->powerCircuit = current->circuit();
     devInfo->priority = current->priority();
     devInfo->pid = current->pid();
     devInfo->debug = current->debug();
     devInfo->node = current->node();
     devInfo->logNode = current->logNode();

     devInfo->ifNameCount = current->getIFNameCount();
     strcpy( devInfo->IFName, current->IFName() );

     strcpy( devInfo->onFault, current->onFault() );
     strcpy( devInfo->onFailure, current->onFailure() );

     return 0;
}


short VehicleConfigurationServer::deviceInfo( VehicleConfigurationIF::Name name,
					      VehicleConfigurationIF::DeviceInfo *devInfo )
{
     Device *current;

     if( ( current = (Device *) _procList->findItem( name ) ) == NULL ) {
	 dprintf("deviceInfo - Couldn't find a device named %s",
		 name );
	 return -1;
     }

     strcpy( devInfo->name, current->name() );
     strcpy( devInfo->server, current->server() );
     strcpy( devInfo->driver, current->driver() );
     strcpy( devInfo->driver2, current->driver2() );
     strcpy( devInfo->driver3, current->driver3() );
     strcpy( devInfo->port, current->port() );
     devInfo->powerCircuit = current->circuit();
     devInfo->priority = current->priority();
     devInfo->pid = current->pid();
     devInfo->debug = current->debug();
     devInfo->node = current->node();
     devInfo->logNode = current->logNode();

     devInfo->ifNameCount = current->getIFNameCount();
     strcpy( devInfo->IFName, current->IFName() );

     strcpy( devInfo->onFault, current->onFault() );
     strcpy( devInfo->onFailure, current->onFailure() );

     return 0;
}


//- PID functions ----------------------------------------
short VehicleConfigurationServer::getPID( short index )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     return current->pid();
}

short VehicleConfigurationServer::getPID( VehicleConfigurationIF::Name name )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     return current->pid();
}

short VehicleConfigurationServer::setPID( short index, short pid )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;
     current->setPid( pid );
     return 0;
}

short VehicleConfigurationServer::setPID(
     VehicleConfigurationIF::Name name,
     short pid )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;
     current->setPid( pid );
     return 0;
}

//- Server Name functions -----------------------------
short VehicleConfigurationServer::getIFName( short index,
						    VehicleConfigurationIF::Name IFName )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     strcpy( IFName, current->IFName() );

     return 0;
}


short VehicleConfigurationServer::getIFName(

     VehicleConfigurationIF::Name name,
     VehicleConfigurationIF::Name IFName )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     strcpy( IFName, current->IFName() );

     return 0;
}

short VehicleConfigurationServer::getTaskName( VehicleConfigurationIF::Name ifName, VehicleConfigurationIF::Name taskName )
{
	short index=-1;

	dwrite(3)("Looking for interface name %s", ifName );

	for( int i = 0; i < _procList->count() ; i++ ) {
		if( hasInterface( i, ifName ) ) {
			dwrite(3)("Found the interface %s in item %d", name, i );
			index = i;
		}
	}

	if ( index == -1 )
		strcpy(taskName, "");
	else
		getIFName(index, taskName);

	return 0;

}

short VehicleConfigurationServer::setIFName( short index,
					     VehicleConfigurationIF::Name IFName )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;
     current->setIFName( IFName );
     return 0;
}


short VehicleConfigurationServer::setIFName( VehicleConfigurationIF::Name name,
					     VehicleConfigurationIF::Name IFName )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;
     current->setIFName( IFName );
     return 0;
}

//- Interface information --------------------------------


short VehicleConfigurationServer::registerInterfaceName(VehicleConfigurationIF::Name name, VehicleConfigurationIF::Name ifName)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL ) {
	  // Interesting choice -- if I can't find the process,
	  // add it.
	  current = (Process *)_procList->addItem( ifName );
     }
     dwrite(3)("Process %s registering interface name: %s",
		   current->name(), ifName );
     current->registerIFName( ifName );
     return 0;
}

short VehicleConfigurationServer::registerInterfaceName(short index, VehicleConfigurationIF::Name ifName)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL ) {
	  current = (Process *)_procList->addItem( ifName );
     }
     dwrite(3)("Process %s registering interface name: %s",
		   current->name(), ifName );
     current->registerIFName( ifName );
     return 0;
}

short VehicleConfigurationServer::getInterfaceCount(VehicleConfigurationIF::Name name)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;
     short ifCount = current->getIFNameCount();
     dwrite(3)("Process %s has %d names", current->name(), ifCount );
     return ifCount;
}

short VehicleConfigurationServer::getInterfaceCount(short index)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;
     short ifCount = current->getIFNameCount();
     dwrite(3)("Process %s has %d names", current->name(), ifCount );
     return ifCount;
}

short VehicleConfigurationServer::getInterface(VehicleConfigurationIF::Name name, short ifNum, VehicleConfigurationIF::Name ifName)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return -1;

     // The 32 value is actually hard-coded in the VehicleConfigurationIF...?
     return current->getIFByIndex( ifNum, ifName, 32 );
}

short VehicleConfigurationServer::getInterface(short index, short ifNum, VehicleConfigurationIF::Name ifName)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return -1;

     // The 32 value is actually hard-coded in the VehicleConfigurationIF...?
     return current->getIFByIndex( ifNum, ifName, 32 );
}

short VehicleConfigurationServer::findInterface(VehicleConfigurationIF::Name name, short *index )
{
     dwrite(3)("Looking for interface name %s", name );
     for( int i = 0; i < _procList->count() ; i++ ) {
	  if( hasInterface( i, name ) ) {
	       dwrite(3)("Found the interface %s in item %d", name, i );
	       *index = i;
	       return i;
	  }
     }


     return *index = -1;
}

Boolean VehicleConfigurationServer::hasInterface(VehicleConfigurationIF::Name name, VehicleConfigurationIF::Name ifName)
{
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return False;
     dwrite(3)("Checking item %s for interface %s", current->name(),
	       ifName );
     return current->hasIFName( ifName );
}

Boolean VehicleConfigurationServer::hasInterface( short index, VehicleConfigurationIF::Name ifName )
{
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return False;
     dwrite(3)("Checking item %s for interface %s", current->name(),
	       ifName );
     return current->hasIFName( ifName );
}

//- Clear an entry

short VehicleConfigurationServer::invalidateEntry( short index )
{
          Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return 0;
     return current->invalidate();
}

//- Debug information ------------------------------------

short VehicleConfigurationServer::getDebug( short index )
{
	// If you can't find it, return 0 -- a safe value.
     Process *current;
     if( (current=(Process *)_procList->findItem( index )) == NULL )
	  return 0;

     return current->debug();
}

short VehicleConfigurationServer::getDebug( VehicleConfigurationIF::Name name )
{
	// If you can't find it, return 0 -- a safe value.
     Process *current;
     if( (current=(Process *)_procList->findItem( name )) == NULL )
	  return 0;

     return current->debug();
}


short VehicleConfigurationServer::getProcessFaultAction(VehicleConfigurationIF::Name name,
				 VehicleConfigurationIF::Name onFault )
{
    Process *current;
    if( (current=(Process *)_procList->findItem( name )) == NULL )
	return -1;
    dwrite(3)("Item %s has fault action: %s", current->name(),
	      current->onFault() );
    strcpy( onFault, current->onFault() );
    return 0;
}

short VehicleConfigurationServer::getProcessFailureAction(VehicleConfigurationIF::Name name,
				 VehicleConfigurationIF::Name onFailure )
{
    Process *current;
    if( (current=(Process *)_procList->findItem( name )) == NULL )
	return -1;
    dwrite(3)("Item %s has failure action: %s", current->name(),
	      current->onFailure() );
    strcpy( onFailure, current->onFailure() );
    return 0;
}


//- deviceInfo() -----------------------------------------

void VehicleConfigurationServer::vehicleName(VehicleConfigurationIF::Name name)
{
  strcpy(name, _constants->_vehicleName);
}

double VehicleConfigurationServer::getMissionStartTime( void )
{
     if( _startTime < 0 )
	  _startTime = Time::secondsNow( False );

     return _startTime;
}


double VehicleConfigurationServer::propPitch()
{
  return _constants->_propPitch;
}


double VehicleConfigurationServer::mass()
{
  return _constants->_mass;
}


double VehicleConfigurationServer::buoyancy()
{
  return _constants->_buoyancy;
}


double VehicleConfigurationServer::kpHeading()
{
  return _constants->_kpHeading;
}


double VehicleConfigurationServer::kdHeading()
{
  return _constants->_kdHeading;
}


double VehicleConfigurationServer::kiHeading()
{
  return _constants->_kiHeading;
}


double VehicleConfigurationServer::kiHeadingLimit()
{
  return _constants->_kiHeadingLimit;
}


double VehicleConfigurationServer::kwpHeading()
{
  return _constants->_kwpHeading;
}


double VehicleConfigurationServer::maxHdgRate()
{
  return _constants->_maxHdgRate;
}


double VehicleConfigurationServer::rudLimit()
{
  return _constants->_rudLimit;
}


double VehicleConfigurationServer::rudActLimit()
{
  return _constants->_rudActLimit;
}


double VehicleConfigurationServer::rudActRateLimit()
{
  return _constants->_rudActRateLimit;
}


double VehicleConfigurationServer::kpPitch()
{
  return _constants->_kpPitch;
}

double VehicleConfigurationServer::kdPitch()
{
  return _constants->_kdPitch;
}


double VehicleConfigurationServer::kiPitch()
{
  return _constants->_kiPitch;
}


double VehicleConfigurationServer::kiPitchLimit()
{
  return _constants->_kiPitchLimit;
}


double VehicleConfigurationServer::pitchLimit()
{
  return _constants->_pitchLimit;
}


double VehicleConfigurationServer::maxDiveRate()
{
  return _constants->_maxDiveRate;
}


double VehicleConfigurationServer::kpDepth()
{
  return _constants->_kpDepth;
}


double VehicleConfigurationServer::kiDepth()
{
  return _constants->_kiDepth;
}


double VehicleConfigurationServer::propEfficiency()
{
  return _constants->_propEfficiency;
}


double VehicleConfigurationServer::elevLimit()
{
  return _constants->_elevLimit;
}


double VehicleConfigurationServer::elevActLimit()
{
  return _constants->_elevActLimit;
}


double VehicleConfigurationServer::elevActRateLimit()
{
  return _constants->_elevActRateLimit;
}


double VehicleConfigurationServer::Ts()
{
  return _constants->_ts;
}


double VehicleConfigurationServer::effDragCoef()
{
  return _constants->_effDragCoef;
}


double VehicleConfigurationServer::tau()
{
  return _constants->_tau;
}


double VehicleConfigurationServer::maxDepthInt()
{
  return _constants->_maxDepthInt;
}


double VehicleConfigurationServer::maxHdgInt()
{
  return _constants->_maxHdgInt;
}


double VehicleConfigurationServer::maxPitchInt()
{
  return _constants->_maxPitchInt;
}


int VehicleConfigurationServer::spawnAuxTasks()
{
  return 0;
}


void VehicleConfigurationServer::centerOfMass(VehicleConfigurationIF::Vector v)
{
  memcpy((void *)v, (void *)_constants->_centerOfMass,
	 sizeof(VehicleConfigurationIF::Vector));
}


void VehicleConfigurationServer::centerOfBuoyancy(VehicleConfigurationIF::Vector v)
{
  memcpy((void *)v, (void *)_constants->_centerOfBuoyancy,
	 sizeof(VehicleConfigurationIF::Vector));
}


void VehicleConfigurationServer::finLocations(VehicleConfigurationIF::Vector
					      lowerRudder,

					      VehicleConfigurationIF::Vector
					      upperRudder,

					      VehicleConfigurationIF::Vector
					      portElevator,

					      VehicleConfigurationIF::Vector
					      stbdElevator)
{
  memcpy((void *)lowerRudder, (void *)_constants->_lowerRudderLoc,
	 sizeof(VehicleConfigurationIF::Vector));

  memcpy((void *)upperRudder, (void *)_constants->_upperRudderLoc,
	 sizeof(VehicleConfigurationIF::Vector));

  memcpy((void *)portElevator, (void *)_constants->_portElevatorLoc,
	 sizeof(VehicleConfigurationIF::Vector));

  memcpy((void *)stbdElevator, (void *)_constants->_stbdElevatorLoc,
	 sizeof(VehicleConfigurationIF::Vector));
}


double VehicleConfigurationServer::ductArea()
{
  return _constants->_ductArea;
}


short VehicleConfigurationServer::nDropWeights()
{
  return (short )_constants->_dropWeights.size();
}


short VehicleConfigurationServer::dropWeight(short weightNo,
					    double *mass,
					    double *buoyancy,
					    VehicleConfigurationIF::Vector
					    location)
{
  if (weightNo < 0 || weightNo >= _constants->_dropWeights.size()) {
    return -1;
  }

  VehicleConstants::DropWeight *dropWeight;
  _constants->_dropWeights.get(weightNo, &dropWeight);

  *mass = dropWeight->mass;
  *buoyancy = dropWeight->buoyancy;

  memcpy(location, dropWeight->location,
	 sizeof(VehicleConfigurationIF::Vector));

  return 0;
}


double VehicleConfigurationServer::xuabu()
{
  return _constants->_Xuabu;
}

double VehicleConfigurationServer::highModePercent()
{
  return _constants->_highModePercent;
}

double VehicleConfigurationServer::lowModePercent()
{
  return _constants->_lowModePercent;
}


//===============================================================

void VehicleConfigurationServer::signalHandler( int sigNo )
{
     switch( sigNo ) {
     case SIGHUP:
	  if( _theServer->loadTables() < 0 ) {
	       Syslog::write("Failed to reload tables");
	       exit(-1);
	  }

	  break;
     default:
	  Syslog::write("Caught signal %d in %s", sigNo, _theServer->name());
     }
}
