#include "GeoApp.h"
#include "GeoMonitor.h"
#include "GeoSampler.h"
#include "Toolsled.h"
#include "toolsledNames.h"
#include "geoNames.h"
#include "ibcItemNames.h"
#include "ECUBoard.h"
#include "VirtualSerialPort.h"

GeoApp::GeoApp(const char *systemName, Sio32Interface *device)
  : IbcApp(systemName, GeoAppName, device)
{ 
  static char errorBuf[512];
  
  dmItems = new GeoDm(systemName);
  
  //Log DataManager item names,for later incorporation into powerDM.h
  ibc->logPowerMgrNames("powerMgrNames.txt");

//  try 
//  {
  Gf5vCard *gf5vCard = ibc->addGf5v(Gf5vName, GROUND_FAULT_0_ADDR);
  if (gf5vCard->error())
  {
    gf5vCard->prtErrorMsg();
  }
    
  // External switches
  ExternalSwitch *externalHps = 
    ibc->addExternalSwitch(ExternalHpsName,
			   TOOLSLED_240V_SWITCH_REQ_DM,
			   TOOLSLED_240V_SWITCH_STATUS_DM);

  ExternalSwitch *externalLps = 
    ibc->addExternalSwitch(ExternalLpsName,
			   TOOLSLED_48V_SWITCH_REQ_DM,
			   TOOLSLED_48V_SWITCH_STATUS_DM,
			   IbcPowerSwitch);

  // High power switches
  ibc->addHps(TungstenLampName, HIGH_PWR_SWITCH_1_ADDR, 
	      externalHps->switchChannel(), 
	      TUNGSTEN_LAMP_POWER, HpBusB, Toolsled, SwitchedByFramework);
  

  // Isolated IO switches
  IsolatedIoCard *isolatedIo = 
    ibc->addIsolatedIo(IsolatedIoName, ISO_IO_0_ADDR, 
		       externalLps->switchChannel(), LpBusB, Toolsled, 
		       SwitchedByFramework );
		     
  isolatedIo->addOutput(SpareDigitalOutput0Name, SwitchedByFramework);
  isolatedIo->addOutput(SpareDigitalOutput1Name, SwitchedByFramework);

  // Quad Serial board
  QuadSerialCard *quadSerial =
    ibc->addQuadSerial(QuadSerialName, QUAD_SERIAL_0_ADDR);

  // ECU Board
  ecuBoard =
    new ECUBoard(systemName, GeoAppName, ECUBoardName,
                 VALVE_PACK_CHAN, this);

  quadSerial->addDevice(ecuBoard, VALVE_PACK_CHAN); 

  ecuBoard->addOutput(Valve1aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve1bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve2aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve2bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve3aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve3bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve4aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve4bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve5aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve5bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve6aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve6bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve7aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve7bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve8aName, SwitchedByFramework);
  // Valve Pack Enable
  ecuBoard->addOutput(ValvePackEnableName, SwitchedByFramework);

  ecuBoard->addOutput(Valve9aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve9bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve10aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve10bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve11aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve11bName, SwitchedByFramework);
  ecuBoard->addOutput(Valve12aName, SwitchedByFramework);
  ecuBoard->addOutput(Valve12bName, SwitchedByFramework);




#if 0
  VirtualSerialPort *vsp = 
    new VirtualSerialPort(systemName, GeoAppName, QuadSerialName,
                          VspChannel0,
			  device->channel(), 
                          0, QUAD_SERIAL_0_ADDR);

  // VSP Channel  
  quadSerial->addDevice(vsp, VspChannel0);

  vsp = 
    new VirtualSerialPort(systemName, GeoAppName, QuadSerialName, 
                          VspChannel1,
			  device->channel(), 
                          0, QUAD_SERIAL_0_ADDR);

  quadSerial->addDevice(vsp, VspChannel1);
#endif
  VicorLpsCard *vicorLps;
  // 12v LPS  
  vicorLps = ibc->addVicorLps(Vicor12vName, LOW_PWR_SWITCH_12V_0_ADDR, 
			      externalLps->switchChannel(), 
			      LpBusB, Toolsled, 
			      VICOR_STANDBY_POWER, 
			      SwitchedByFramework,
			      SwitchOn);
  //Channel 0
  vicorLps->addChannel(SciencePort12v0Name, 
		       LPS_12V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);
  //Channel 1
  vicorLps->addChannel(SciencePort12v1Name,
		       LPS_12V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 2
  vicorLps->addChannel(Camera12vName,
		       GEN_COLOR_CAMERA_POWER,
		       SwitchedByFramework,
		       SwitchOff);  

  //24v LPS
  vicorLps = ibc->addVicorLps(Vicor24v0Name, LOW_PWR_SWITCH_24V_0_ADDR, 
			      externalLps->switchChannel(), 
			      LpBusB, Toolsled, 
			      VICOR_STANDBY_POWER, 
			      SwitchedByFramework,
			      SwitchOn);
  //Channel 0
  vicorLps->addChannel(ManipulatorName,
				  MANIPULATOR_POWER,
				  SwitchedByFramework,
				  SwitchOff);
  //24v LPS
  vicorLps = ibc->addVicorLps(Vicor24v1Name, LOW_PWR_SWITCH_24V_1_ADDR, 
			      externalLps->switchChannel(), 
			      LpBusB, Toolsled, 
			      VICOR_STANDBY_POWER, 
			      SwitchedByFramework,
			      SwitchOn);
  //Channel 0
  vicorLps->addChannel(SciencePort24v0Name, 
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);
  //Channel 1
  vicorLps->addChannel(SciencePort24v1Name,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 2
  valvePack = vicorLps->addChannel(ValvePackName,
		       VALVE_PACK_POWER,
		       SwitchedByApp,
		       SwitchOff);  

  //Quad AtoD Card
  QuadAtoDCard *quadAtoD = 
    ibc->addQuadAtoD(QuadAtoDName, QUAD_A_TO_D_0_ADDR,
		     GEO_SLED_APP | GET_ATOD_DATA);

  quadAtoD->addChannel(SpareAtoD0Name, &GeoApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD1Name, &GeoApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD2Name, &GeoApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD3Name, &GeoApp::swingArmDegrees);

  //Dual Vicor Card
  VicorCard *vicorCard =
    ibc->addVicor(DualVicorName, VICOR_BOARD_ADDR,
			      externalLps->switchChannel(), 
          		      LpBusB, Toolsled);
    
    vicorCard->addChannel(Camera1Name,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  

    vicorCard->addChannel(Camera2Name,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
				    
  addWaterAlarm(HousingWaterAlarm,
		BEN_BIO_SLED_APP | GET_WATER_ALARM,
		HOUSING_WATER_ALARM_BIT,
		BEN_BIO_SLED_APP | GET_WATER_ALARM_THRESH,
		BEN_BIO_SLED_APP | SET_WATER_ALARM_THRESH,
		CAN_WATER_ALARM_ON_SRQ,
		CAN_WATER_ALARM_OFF_SRQ);

  addWaterAlarm(JboxWaterAlarm,
		BEN_BIO_SLED_APP | GET_WATER_ALARM,
		JBOX_WATER_ALARM_BIT,
		BEN_BIO_SLED_APP | GET_WATER_ALARM_THRESH,
		BEN_BIO_SLED_APP | SET_WATER_ALARM_THRESH,
		JBOX_WATER_ALARM_ON_SRQ,
		JBOX_WATER_ALARM_OFF_SRQ);
    
//  }

//  catch (IbcAppError ibcAppError)
//  {
//    strcpy(errorBuf, ibcAppError.msg);
//    logMsg(errorBuf);
//    exit(1);
//  }

//  catch (DmError dmError)
//  {
//    strcpy(errorBuf, dmError.msg);
//    logMsg(errorBuf);
//    exit(1);
//  }

}
  

GeoApp::~GeoApp()
{
}


void GeoApp::setTaskParams()
{
  _dmMonitorParams.priority = MonitorTaskPriority;
  _dmMonitorParams.floatingPoint = TRUE;
  _dmMonitorParams.stackSize = MonitorTaskStacksize;

  _microSamplerParams.priority = SamplerTaskPriority;
  _microSamplerParams.floatingPoint = TRUE;
  _microSamplerParams.stackSize = SamplerTaskStacksize;
}


DmMonitor *GeoApp::createDmMonitor()
{
  return new GeoMonitor("GeoMonitor", this);
}


MicroSampler *GeoApp::createMicroSampler()
{
  return new GeoSampler("GeoSampler", this);
}

//Scale routine if swingArm Pot is implemented
Flt32 GeoApp::swingArmDegrees(Word rawBits)
{
  Nat16 unipolarBits;
  Int16 bipolarBits;
  
  //Put Word into proper numerical representation
  unipolarBits = (Nat16)rawBits;

  // Scale and return
  //  return (unipolarBits / 193) - 10;
  return (unipolarBits);
}
 







