#include "DmMonitorUtils.h"
#include "gf_5vDm.h"
#include "gf5vDef.h"
#include "gf_5v.h"
#include "lps.h"
#include "hps.h"
#include "vspCmd.h"
#include "vicorBoard.h"

void DmMonitorUtils::addGf5vItems(ibcGf5vDmItems *dmItems, 
				  DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(dmItems->gf_enable);
  dmMonitor->addMonitoredItem(dmItems->selftestCmd);
  dmMonitor->addMonitoredItem(dmItems->tempWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->tempAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->voltageWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->voltageAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->busCapacitance);
  dmMonitor->addMonitoredItem(dmItems->gfChan[0].chargeTime);
  dmMonitor->addMonitoredItem(dmItems->gfChan[1].chargeTime);
  dmMonitor->addMonitoredItem(dmItems->gfChan[2].chargeTime);
  dmMonitor->addMonitoredItem(dmItems->gfChan[3].chargeTime);
}


void DmMonitorUtils::addHpsItems(ibcHpsDmItems *dmItems, DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(dmItems->currentWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->currentAlarmThresh);
}


void DmMonitorUtils::addLpsItems(ibcLpsDmItems *dmItems, DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(dmItems->sw0CurrentWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->sw0CurrentAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->sw1CurrentWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->sw1CurrentAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->sw2CurrentWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->sw2CurrentAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->sw3CurrentWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->sw3CurrentAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->vicorVoltageWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->vicorVoltageAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->vicorTempWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->vicorTempAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems->switchTempWarnThresh);
  dmMonitor->addMonitoredItem(dmItems->switchTempAlarmThresh);
}


void DmMonitorUtils::addVicorItems(vicorDmItems *dmItems, DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(dmItems[0].tempWarnThresh);
  dmMonitor->addMonitoredItem(dmItems[0].tempAlarmThresh);
  dmMonitor->addMonitoredItem(dmItems[1].tempWarnThresh);
  dmMonitor->addMonitoredItem(dmItems[1].tempAlarmThresh);
}


void DmMonitorUtils::addVspItems(ibcVspDmItems *dmItems, DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(dmItems->vspBaud);
  dmMonitor->addMonitoredItem(dmItems->vspData);
  dmMonitor->addMonitoredItem(dmItems->vspStop);
  dmMonitor->addMonitoredItem(dmItems->vspPar);
  dmMonitor->addMonitoredItem(dmItems->vspMsgOut);
  dmMonitor->addMonitoredItem(dmItems->vspHandshake);
  dmMonitor->addMonitoredItem(dmItems->vspProtocol);
  dmMonitor->addMonitoredItem(dmItems->vspBreak);
}


void DmMonitorUtils::processGf5vChanges(ibcGf5vDmItems *dmItems, 
					DmMonitor *dmMonitor,
					sio32Chan *channel, 
					Word boardAddr)
{
  Int32 chargeTimes[GF_MAX_CHANS];
  Int16 tempWarn, tempAlarm;
  Int16 voltageWarn, voltageAlarm;
  Nat16 busCapacitance;
  MBool gfEnable;
  
  if (!dmMonitor->itemsChanged())
    return;

  if (dmMonitor->itemChanged(dmItems->gf_enable))
  {
    dm_read(dmItems->gf_enable, (char *) &gfEnable,
            sizeof(gfEnable), (DM_Time *) NULL);

    IBC_gf5vEnableGf( channel, boardAddr, gfEnable );
  } 

  if (dmMonitor->itemChanged(dmItems->selftestCmd))
    IBC_gf5vRunSelftest( channel, boardAddr );

  /* GF/5V Board Temperature Thresholds    */
  if (dmMonitor->itemChanged(dmItems->tempWarnThresh) ||
      dmMonitor->itemChanged(dmItems->tempAlarmThresh))
  {
    /* Read Temp Thresholds from DMgr    */
    dm_read(dmItems->tempWarnThresh, (char *) &tempWarn,
            sizeof(tempWarn), (DM_Time *) NULL);

    dm_read(dmItems->tempAlarmThresh, (char *) &tempAlarm,
            sizeof(tempAlarm), (DM_Time *) NULL);

    IBC_gf5vSetTempThresh( channel, boardAddr, tempWarn, tempAlarm);
  } 

  /* GF/5V Board Voltage Thresholds        */
  if (dmMonitor->itemChanged(dmItems->voltageWarnThresh) ||
      dmMonitor->itemChanged(dmItems->voltageAlarmThresh))

  {
    /* Read Voltage Thresholds from DMgr */
    dm_read(dmItems->voltageWarnThresh, (char *) &voltageWarn,
            sizeof(voltageWarn), (DM_Time *) NULL);

    dm_read(dmItems->voltageAlarmThresh, (char *) &voltageAlarm,
            sizeof(voltageAlarm), (DM_Time *) NULL);

    IBC_gf5vSetVoltageThresh( channel, boardAddr,
			     voltageWarn, voltageAlarm );
  } 

  if (dmMonitor->itemChanged(dmItems->busCapacitance))
  {
    dm_read(dmItems->busCapacitance, (char *) &busCapacitance,
            sizeof(busCapacitance), (DM_Time *) NULL);

    IBC_gf5vSetBusCapacitance( channel, boardAddr, busCapacitance );
  } 

  /* GF/5V Board Charge Up Times           */

  if (dmMonitor->itemChanged(dmItems->gfChan[0].chargeTime) ||
      dmMonitor->itemChanged(dmItems->gfChan[1].chargeTime) ||
      dmMonitor->itemChanged(dmItems->gfChan[2].chargeTime) ||
      dmMonitor->itemChanged(dmItems->gfChan[3].chargeTime))
  {
    /* Read Charge Times from DMgr          */
    dm_read(dmItems->gfChan[0].chargeTime, (char *) &chargeTimes[0],
            sizeof(chargeTimes[0]), (DM_Time *) NULL);

    dm_read(dmItems->gfChan[1].chargeTime, (char *) &chargeTimes[1],
            sizeof(chargeTimes[1]), (DM_Time *) NULL);

    dm_read(dmItems->gfChan[2].chargeTime, (char *) &chargeTimes[2],
            sizeof(chargeTimes[2]), (DM_Time *) NULL);

    dm_read(dmItems->gfChan[3].chargeTime, (char *) &chargeTimes[3],
            sizeof(chargeTimes[3]), (DM_Time *) NULL);

    IBC_gf5vSetChargeTimes( channel, boardAddr, chargeTimes );
  }
}



void DmMonitorUtils::processHpsChanges(ibcHpsDmItems *dmItems, 
				       DmMonitor *dmMonitor,
				       sio32Chan *channel, 
				       Word boardAddr)
{
  if (!dmMonitor->itemsChanged())
    return;

  Nat16 warn, alarm;
  
  if (dmMonitor->itemChanged(dmItems->currentWarnThresh) ||
      dmMonitor->itemChanged(dmItems->currentAlarmThresh))
  {
    dm_read(dmItems->currentWarnThresh, (char *) &warn,
	    sizeof(warn), (DM_Time *) NULL);
	

    dm_read(dmItems->currentAlarmThresh, (char *) &alarm,
	    sizeof(alarm), (DM_Time *) NULL);
	

    IBC_HPS_SetCurrentThresh(channel, boardAddr, warn, alarm);
  }
}


void DmMonitorUtils::processLpsChanges(ibcLpsDmItems *dmItems, 
				       DmMonitor *dmMonitor,
				       sio32Chan *channel, 
				       Word boardAddr)
{
  if (!dmMonitor->itemsChanged())
    return;

  if (dmMonitor->itemChanged(dmItems->sw0CurrentWarnThresh) ||
      dmMonitor->itemChanged(dmItems->sw0CurrentAlarmThresh) ||
      dmMonitor->itemChanged(dmItems->sw1CurrentWarnThresh) ||
      dmMonitor->itemChanged(dmItems->sw1CurrentAlarmThresh) ||
      dmMonitor->itemChanged(dmItems->sw2CurrentWarnThresh) ||
      dmMonitor->itemChanged(dmItems->sw2CurrentAlarmThresh) ||
      dmMonitor->itemChanged(dmItems->sw3CurrentWarnThresh) ||
      dmMonitor->itemChanged(dmItems->sw3CurrentAlarmThresh))
  {
    writeLpsCurrentThresholds(channel, boardAddr, dmItems);
  }

  if (dmMonitor->itemChanged(dmItems->vicorVoltageWarnThresh) ||
      dmMonitor->itemChanged(dmItems->vicorVoltageAlarmThresh))
  {
    writeLpsVoltageThresholds(channel, boardAddr, dmItems);
  }

  if (dmMonitor->itemChanged(dmItems->vicorTempWarnThresh) ||
      dmMonitor->itemChanged(dmItems->vicorTempAlarmThresh) ||
      dmMonitor->itemChanged(dmItems->switchTempWarnThresh) ||
      dmMonitor->itemChanged(dmItems->switchTempAlarmThresh))
  {
    writeLpsTempThresholds(channel, boardAddr, dmItems);
  }
}


void DmMonitorUtils::processVicorChanges(vicorDmItems *dmItems, 
					 DmMonitor *dmMonitor,
					 sio32Chan *channel, 
					 Word boardAddr)
{
  if (!dmMonitor->itemsChanged())
    return;
  
  Int16 psu0TempWarn, psu0TempAlarm;
  Int16 psu1TempWarn, psu1TempAlarm;

  if (dmMonitor->itemChanged(dmItems[0].tempWarnThresh) ||
      dmMonitor->itemChanged(dmItems[0].tempAlarmThresh) ||
      dmMonitor->itemChanged(dmItems[1].tempWarnThresh) ||
      dmMonitor->itemChanged(dmItems[1].tempAlarmThresh))
  {
    dm_read(dmItems[0].tempWarnThresh, (char *) &psu0TempWarn,
	    sizeof(psu0TempWarn), (DM_Time *) NULL);
       
    dm_read(dmItems[0].tempAlarmThresh, (char *) &psu0TempAlarm,
	    sizeof(psu0TempAlarm), (DM_Time *) NULL);

    dm_read(dmItems[1].tempWarnThresh, (char *) &psu1TempWarn,
	    sizeof(psu1TempWarn), (DM_Time *) NULL);

    dm_read(dmItems[1].tempAlarmThresh, (char *) &psu1TempAlarm,
	    sizeof(psu1TempAlarm), (DM_Time *) NULL);
       
    IBC_DualVicorSetTempThresh(channel, boardAddr,
			       psu0TempWarn, psu0TempAlarm, 
			       psu1TempWarn, psu1TempAlarm );
  }
}


void DmMonitorUtils::processVspChanges(ibcVspDmItems *dmItems, 
				       DmMonitor *dmMonitor,
				       sio32Chan *channel, 
				       Word vspChannel, 
				       Word boardAddr)
{
  if (!dmMonitor->itemsChanged())
    return;
  
  Int16   baud;
  Nat16   data, stop, par, numOfBytes;
  MBool handshake;
  Int16   proto;
  Nat16   mode;
  messageStruct msgOut;

  if (dmMonitor->itemChanged(dmItems->vspBreak))
  {
    dm_read(dmItems->vspBreak, (char *) &mode,
            sizeof(mode), (DM_Time *) NULL);

    if (IBC_VSP_SendBreak(channel, boardAddr, vspChannel, mode) == ERROR)
      logMsg("%s:Error Sending VSP Break\n", vspChannel);
  }

  if  (dmMonitor->itemChanged(dmItems->vspMsgOut))
  {
    dm_read(dmItems->vspMsgOut, (char *) &msgOut,
            sizeof(msgOut), (DM_Time *) NULL);

    if (IBC_VSP_Write(channel, boardAddr, vspChannel, msgOut.buffer,
		      msgOut.len) == ERROR)
    {
      logMsg("%s:Error writing VSP\n", vspChannel);
    }
  }

  if (dmMonitor->itemChanged(dmItems->vspBaud) ||
      dmMonitor->itemChanged(dmItems->vspData) ||
      dmMonitor->itemChanged(dmItems->vspStop) ||
      dmMonitor->itemChanged(dmItems->vspPar) ||
      dmMonitor->itemChanged(dmItems->vspHandshake) ||
      dmMonitor->itemChanged(dmItems->vspProtocol))
  {                            
    /* Read VSP parameters from dmgr*/
    dm_read(dmItems->vspBaud, (char *) &baud,
	    sizeof(baud), (DM_Time *) NULL);

    dm_read(dmItems->vspData, (char *) &data,
	    sizeof(data), (DM_Time *) NULL);

    dm_read(dmItems->vspStop, (char *) &stop,
	    sizeof(stop), (DM_Time *) NULL);

    dm_read(dmItems->vspPar, (char *) &par,
	    sizeof(par), (DM_Time *) NULL);

    dm_read(dmItems->vspHandshake, (char *) &handshake,
	    sizeof(handshake), (DM_Time *) NULL);

    dm_read(dmItems->vspProtocol, (char *) &proto,
	    sizeof(proto), (DM_Time *) NULL);

    if (IBC_VSP_SetLineParm(channel, boardAddr, vspChannel, 
			    baud, data, stop, par, handshake, 
			    proto ) == ERROR)
    {
      logMsg("Error Setting up VSP\n");
    }
      
  } 
}
