#include "BenthicBioApp.h"
#include "BenthicBioMonitor.h"
#include "BenthicBioSampler.h"
#include "Toolsled.h"
#include "toolsledNames.h"
#include "benthicBioNames.h"
#include "ibcItemNames.h"
#include "ECUBoard.h"
#include "VirtualSerialPort.h"

BenthicBioApp::BenthicBioApp(const char *systemName, Sio32Interface *device)
  : IbcApp(systemName, BenthicBioAppName, device)
{ 
  static char errorBuf[512];
  
  dmItems = new BenthicBioDm(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
  ssPump = ibc->addHps(SSPumpName, HIGH_PWR_SWITCH_0_ADDR, 
		       externalHps->switchChannel(), 
		       SS_PUMP_POWER, HpBusB, Toolsled, SwitchedByApp);

  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(SpareDigitalOutputName, SwitchedByFramework);

  // Quad Serial board
  QuadSerialCard *quadSerial =
    ibc->addQuadSerial(QuadSerialName, QUAD_SERIAL_0_ADDR);


  // ECU Board
  ecuBoard =
    new ECUBoard(systemName, BenthicBioAppName, 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);


  VirtualSerialPort *vsp = 
    new VirtualSerialPort(systemName, BenthicBioAppName, QuadSerialName,
                          VspChannel0,
			  device->channel(), 
                          0, QUAD_SERIAL_0_ADDR);

  // VSP Channel  
  quadSerial->addDevice(vsp, VspChannel0);
#if 0
  vsp = 
    new VirtualSerialPort(systemName, BenthicBioAppName, 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(IndexExciteName, 
		       SS_INDEX_EXCITE_POWER,
		       SwitchedByFramework,
		       SwitchOff);
  //Channel 1
  vicorLps->addChannel(ArmPositionExciteName,
		       SA_POT_EXCITE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 2
  vicorLps->addChannel(SciencePort12vName,
		       LPS_12V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 3
  vicorLps->addChannel(Camera12vName,
		       CAMERA_POWER,
		       SwitchedByFramework,
		       SwitchOff);  

  //24v 0 LPS
  vicorLps = ibc->addVicorLps(Vicor24v0Name, LOW_PWR_SWITCH_24V_0_ADDR, 
			      externalLps->switchChannel(), 
			      LpBusB, Toolsled, 
			      VICOR_STANDBY_POWER, 
			      SwitchedByFramework,
			      SwitchOn);
  //Channel 0
  indexFwd = vicorLps->addChannel(SSIndexFwdName,
				  SS_INDEX_POWER,
				  SwitchedByApp,
				  SwitchOff);
  //Channel 1
  indexRev = vicorLps->addChannel(SSIndexRevName,
				  SS_INDEX_POWER,
				  SwitchedByApp,
				  SwitchOff);  
  //Channel 2
  vicorLps->addChannel(Camera24vName,
		       CAMERA_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 3
  vicorLps->addChannel(SciencePort24vName,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  

  //24v 1 LPS
  vicorLps = ibc->addVicorLps(Vicor24v1Name, LOW_PWR_SWITCH_24V_1_ADDR, 
			      externalLps->switchChannel(), 
			      LpBusB, Toolsled, 
			      VICOR_STANDBY_POWER, 
			      SwitchedByFramework,
			      SwitchOn);

  //Channel 0
  vicorLps->addChannel(ManipulatorName, 
                       MANIPULATOR_POWER,
		       SwitchedByFramework,
		       SwitchOff);
  //Channel 1
  vicorLps->addChannel(Spare24v0Name,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  
  //Channel 2
  valvePack = vicorLps->addChannel(ValvePackName,
		       VALVE_PACK_POWER,
		       SwitchedByApp,
		       SwitchOff);  
  //Channel 3
  vicorLps->addChannel(Spare24v1Name,
		       LPS_24V_SPARE_POWER,
		       SwitchedByFramework,
		       SwitchOff);  

  QuadAtoDCard *quadAtoD = 
    ibc->addQuadAtoD(QuadAtoDName, QUAD_A_TO_D_0_ADDR,
		     BEN_BIO_SLED_APP | GET_ATOD_DATA);

  quadAtoD->addChannel(SpareAtoD0Name, &BenthicBioApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD1Name, &BenthicBioApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD2Name, &BenthicBioApp::swingArmDegrees);
  quadAtoD->addChannel(SpareAtoD3Name, &BenthicBioApp::swingArmDegrees);

					    
  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);
//  }

}
  

BenthicBioApp::~BenthicBioApp()
{
}


void BenthicBioApp::setTaskParams()
{
  _dmMonitorParams.priority = MonitorTaskPriority;
  _dmMonitorParams.floatingPoint = TRUE;
  _dmMonitorParams.stackSize = MonitorTaskStacksize;

  _microSamplerParams.priority = SamplerTaskPriority;
  _microSamplerParams.floatingPoint = TRUE;
  _microSamplerParams.stackSize = SamplerTaskStacksize;
}


DmMonitor *BenthicBioApp::createDmMonitor()
{
  return new BenthicBioMonitor("BenthicBioMonitor", this);
}


MicroSampler *BenthicBioApp::createMicroSampler()
{
  return new BenthicBioSampler("BenthicBioSampler", this);
}

//Scale routine if swingArm Pot is implemented
Flt32 BenthicBioApp::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);
}
 







