#include "Sio32Interface.h"
#include "powerDM.h"
#include "MidwaterDm.h"
#include "mwsledDcon.h"
#include "MidWaterApp.h"
#include "MidWaterMonitor.h"
#include "MidWaterSampler.h"

MwsledDconDmItems::MwsledDconDmItems(const char *name,
                                     const char *dmPrefix,
                                     Sio32Interface *device)
                                    : MidwaterDm(name, dmPrefix)
{
  powerSwitch = new DmEnumObject(TOOLSLED_48V_SWITCH_STATUS_DM);

  Int16 lps, hps;

                                   /* Create IBC CPU Data Manager Items      */
  if (createIbcCpuDmItems(&ibcDm, dmPrefix, name)== ERROR)
     setError("Error Creating Cpu Dm Items");

                                /* Set Micro Water Alarms initial value      */
                                /* Declare this task an item provider        */
  canWaterAlarm->startProvide( DM_STATIC, ExclusiveProvider );
  jboxWaterAlarm->startProvide( DM_STATIC, ExclusiveProvider );

  if (MwsledDconDmItems::updateWaterAlarmDm(device->channel(),
              canWaterAlarm->getHandle(), jboxWaterAlarm->getHandle()) == ERROR)

     setError("Mid Water Toolsled Dcon: Error checking water alarm status\n");


  powerSwitch->startConsume(DM_STATIC, SEM_NULL);

                           /* Create Virtual Serial Port Data Manager Items */
  if (createIbcVspDmItems( &vspDm, dmPrefix, name, 0 )== ERROR)
      setError("Error Creating Vsp Dm Items");

  initIbcVspProvider  (&vspDm);

                                 /* Create GF/5V Board Data Manager Items */
  if (createIbcGf5vDmItems( &gf5vDm, dmPrefix, name )==ERROR)
      setError("Mid Water Toolsled Dcon: Error Creating Gf5v Items\n");

  initIbcGf5vAlarmProvider( &gf5vDm );

                                  /* Create Quad Serial Board Data Mgr Items*/
  if (createIbcQuadSerDmItems( &quadSerDm, dmPrefix, name, 0)==ERROR)
      setError("Mid Water Toolsled Dcon: Error Creating Quad Ser Items\n");

  initIbcQuadSerAlarmProvider( &quadSerDm );

  updateIbcQuadSerAlarmsDm(device->channel(),
                            SERIAL_BOARD_ADDR, &quadSerDm );

                                  /* Create IBC Dual Vicor DMgr Items        */
  if (createIbcVicorDmItems( vicorDm, dmPrefix, name )==ERROR)
      setError("Mid Water Toolsled Dcon: Error Creating Vicor Items\n");

  initIbcVicorAlarmProvider(vicorDm );

                                  /* Create IBC HPS Data Manager Items       */
  for (hps = 0; hps < HPS_BOARDS; hps++)
  {                               /* Create IBC HPS Data Manager Items       */
     if(createIbcHpsDmItems( &hpsDm[hps], dmPrefix, name, hps )==ERROR)
        setError("Mid Water Toolsled Dcon: Error Creating Hps Items\n");

     initIbcHpsAlarmProvider( &hpsDm[hps] );

     if(updateIbcHpsAlarmsDm( device->channel(), hpsBoardAddr[hps],
                         &hpsDm[hps] )==ERROR)
        setError("Mid Water Toolsled Dcon: Error Update Hps Alarms\n");
  }

                                  /* Create IBC LPS Data Manager Items       */
  for (lps = 0; lps < LPS_BOARDS; lps++)
  {                               /* Create IBC LPS Data Manager Items       */
     if(createIbcLpsDmItems( &lpsDm[lps], dmPrefix, name, lps )==ERROR)
        setError("Mid Water Toolsled Dcon: Error Creating Lps Items\n");

     initIbcLpsAlarmProvider( &lpsDm[lps] );

     if(updateIbcLpsAlarmsDm( device->channel(),
                             lpsBoardAddr[lps], &lpsDm[lps] )==ERROR)
        setError("Mid Water Toolsled Dcon: Error Update Lps Alarms\n");
  }
}



MwsledDconDmItems::~MwsledDconDmItems()
{
}




MidWaterApp::MidWaterApp(const char *name, Sio32Interface *device)
  : MicroApp(name, device, "TIBURON.MWSLED.")
{

  dmItems = new MwsledDconDmItems( name, MWSLED_DM_PREFIX, device);
  if(dmItems->error())
  {
    logMsg("Error Creating Dm Items\n");
  }
  sio32Interface = device;

}


MidWaterApp::~MidWaterApp()
{
}


void MidWaterApp::setTaskParams()
{
  _dmMonitorParams.priority = 66;
  _dmMonitorParams.floatingPoint = TRUE;
  _dmMonitorParams.stackSize = MID_WATER_MONITOR_STACKSIZE;

  _microSamplerParams.priority = 65;
  _microSamplerParams.floatingPoint = TRUE;
  _microSamplerParams.stackSize = MID_WATER_SAMPLER_STACKSIZE;
}


int MidWaterApp::handleMicroReset()
{
  Int16 lps,hps;

  MicroApp::handleMicroReset();
  if (taskSync->deviceLinkState() == DeviceInterface::LinkDown)
      return 0;

                                /* Read IBC Card Configuration               */
    if (updateIbcCardConfigDm(sio32Interface->channel(),
                              dmItems->ibcDm.ibcCardConfig,
                              dmItems->ibcDm.ibcCardConfigError,
                              ibcCardSet ) == ERROR)
        logMsg("MidWater Toolsled: Error checking IBC Card Configuration\n");

                                /* Set default humidity warn/alarm thresholds*/
    if (ibcCpuSetHumidityThresh( sio32Interface->channel(),
                                 ROV_HUMIDITY_WARN_THRESH,
                                 ROV_HUMIDITY_ALARM_THRESH ) == ERROR)
        logMsg("Midwater Toolsled: Error setting Humidity Alarm Thresholds\n");

                                /* Set Micro Humidity Alarm initial value    */
    if (updateIbcHumidityAlarmDm(sio32Interface->channel(),
                                 dmItems->ibcDm.humidityAlarm)
        == ERROR)
        logMsg("Midwater Toolsled: Error checking humidity alarm status\n");

    if (updateIbcGf5vAlarmsDm(sio32Interface->channel(),
                            GF5V_BOARD_ADDR, &dmItems->gf5vDm ) == ERROR)
        logMsg("Midwater Toolsled: Error Checking Gf5v Alarms\n");

    if (updateIbcVicorAlarmsDm(sio32Interface->channel(),
                            VICOR_BOARD_ADDR, dmItems->vicorDm ) == ERROR)
        logMsg("Midwater Toolsled: Error Checking Vicor Alarms\n");

    if (updateIbcQuadSerAlarmsDm(sio32Interface->channel(),
                            SERIAL_BOARD_ADDR, &dmItems->quadSerDm ) == ERROR)
        logMsg("Midwater Toolsled: Error Checking Quad Ser Alarms\n");

    for (hps = 0; hps < HPS_BOARDS; hps++)
       if (updateIbcHpsAlarmsDm( sio32Interface->channel(),
                             hpsBoardAddr[hps], &dmItems->hpsDm[hps])== ERROR)
           logMsg("Midwater Toolsled: Error Checking HPS Alarms\n");

    for (lps = 0; lps < LPS_BOARDS; lps++)
       if (updateIbcLpsAlarmsDm( sio32Interface->channel(),
                             lpsBoardAddr[lps], &dmItems->lpsDm[lps]) == ERROR)
           logMsg("Midwater Toolsled: Error Checking LPS Alarms\n");

    return 0;
}


int MidWaterApp::processSRQ(Byte *srqPacket, int nPacketBytes)
{
    Word srqRequest;

    fprintf(stderr, "MidWaterApp::processSRQ()\n");
                                    /* Service Request received so process it */
    srqRequest = wordFromBuf(srqPacket, 0);

    switch (srqRequest)             /* Decode Service Request from micro  */
    {
      case CAN_WATER_ALARM_ON_SRQ:    /* Housing Water Alarm Active     */
        writeBooleanDmItem(dmItems->canWaterAlarm->getHandle(), TRUE);
        break;

      case CAN_WATER_ALARM_OFF_SRQ:   /* Housing Water Alarm Inactive   */
        writeBooleanDmItem(dmItems->canWaterAlarm->getHandle(), FALSE);
        break;

      case JBOX_WATER_ALARM_ON_SRQ:   /* J Box Water Alarm Active       */
        writeBooleanDmItem(dmItems->jboxWaterAlarm->getHandle(), TRUE);
        break;

      case JBOX_WATER_ALARM_OFF_SRQ:  /* J Box Water Alarm Inactive     */
        writeBooleanDmItem(dmItems->jboxWaterAlarm->getHandle(), FALSE);
        break;

      default:
        if (processIbcCpuSRQ(srqRequest,  srqPacket, &dmItems->ibcDm )
            != TRUE)

        if (!processIbcLpsSRQ(srqRequest,  srqPacket, lpsBoardAddr[0],
                    &dmItems->lpsDm[0]))

        if (!processIbcLpsSRQ(srqRequest,  srqPacket, lpsBoardAddr[1],
                    &dmItems->lpsDm[1]))

        if (!processIbcLpsSRQ(srqRequest,  srqPacket, lpsBoardAddr[2],
                    &dmItems->lpsDm[2]))

        if (!processIbcHpsSRQ(srqRequest,  srqPacket, hpsBoardAddr[0],
                    &dmItems->hpsDm[0] ))

        if (!processIbcHpsSRQ(srqRequest,  srqPacket, hpsBoardAddr[1],
                    &dmItems->hpsDm[1] ))

        if (!processIbcGf5vSRQ(srqRequest, srqPacket, GF5V_BOARD_ADDR,
                    &dmItems->gf5vDm))

        if (!processIbcVicorSRQ(srqRequest, srqPacket, VICOR_BOARD_ADDR,
            dmItems->vicorDm ))

        if (!processIbcVspSRQ(srqRequest, srqPacket,
                   SERIAL_BOARD_ADDR, VSP_CHAN, &dmItems->vspDm ))

        if (!processIbcQuadSerSRQ(srqRequest, srqPacket,
                    SERIAL_BOARD_ADDR, &dmItems->quadSerDm ))

        printf("Toolsled Dcon: Unrecognized SRQ 0x%x\n", srqRequest);

        break;
    } /* switch */
    return (0);
}


DmMonitor *MidWaterApp::createDmMonitor()
{
  return new MidWaterMonitor("MidWaterMonitor", this);
}


MicroSampler *MidWaterApp::createMicroSampler()
{
  return new MidWaterSampler("MidWaterSampler", this);
}

/******************************************************************************/
/* Function    : mwsledCanGetWaterAlarm                                       */
/* Purpose     : Read water alarm status from sled Dcon microcontroller       */
/* Inputs      : Sio32 socket and pointer to water alarm status               */
/* Outputs     : Returns OK or ERROR                                          */
/******************************************************************************/
    LOCAL STATUS
mwsledCanGetWaterAlarm( sio32Chan *IBC_SerialChan, Word *waterAlarmStatus )
{
                                    /* Send command to microcontroller        */
    return( microCommand(IBC_SerialChan, MIDWATER_SLED_APP | GET_WATER_ALARM,
                        waterAlarmStatus) );
} /* mwsledCanGetWaterAlarm() */

/****************************************************************************/
/* Function    : mwsledGetWaterAlarmThresh                                  */
/* Purpose     : Reads water alarm threshold value from IBC CPU             */
/* Inputs      : Sio32 channel, pointer to water alarm threshold            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
mwsledGetWaterAlarmThresh( sio32Chan *IBC_SerialChan, Nat16 *waterAlarmThresh )
{
                                    /* Send command to microcontroller      */
    return (microCommand( IBC_SerialChan,
          MIDWATER_SLED_APP | GET_WATER_ALARM_THRESH, waterAlarmThresh) );
} /* mwsledGetWaterAlarmThresh() */

/****************************************************************************/
/* Function    : initWaterAlarmThreshDm                                     */
/* Purpose     : Read Water Alarm Threshold and update data manager item    */
/* Inputs      : Sio32 channel, water alarm threshold dm item handle        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
MidWaterApp::initWaterAlarmThreshDm( sio32Chan *IBC_SerialChan, DM_Item waterAlarmThreshDm )
{
    Nat16   waterAlarmThresh;           /* Water Alarm Threshold from IBC   */

                                        /* Get Water Alarm Threshold        */
    if (mwsledGetWaterAlarmThresh( IBC_SerialChan, &waterAlarmThresh ) != OK)
        return (ERROR);
                                        /* We MUST use urgent open here as  */
                                        /* another task is normal provider  */
    return (urgentWriteDmItem(waterAlarmThreshDm, &waterAlarmThresh,
                      sizeof(waterAlarmThresh)) );
} /* initWaterAlarmThreshDm() */

/****************************************************************************/
/* Function    : writeWaterAlarmThresh                                      */
/* Purpose     : Get water alarm threshold value from dm and send to IBC    */
/* Inputs      : Sio32 channel, water threshold dm item handle              */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
   STATUS
MidWaterApp::writeWaterAlarmThresh( sio32Chan *sio32DataChan, DM_Item waterAlarmThreshDm )
{
    Errno   status;                     /* Result of dm_read                */
    Int16   waterAlarmThresh;           /* Water Alarm Threshold            */

                                        /* Read Water Alarm Thresh from dmgr*/
    status = dm_read( waterAlarmThreshDm, (char *) &waterAlarmThresh,
         sizeof(waterAlarmThresh), (DM_Time *) NULL);
                                        /* Check for successful dm_read     */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))

                                    /* Send command to microcontroller      */
        if ( sendMicroCommand( sio32DataChan, &status, sizeof(status), 2,
             MIDWATER_SLED_APP | SET_WATER_ALARM_THRESH, waterAlarmThresh )
             != ERROR )
                                    /* Check command result                  */
            return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);

    return(ERROR);
} /* writeWaterAlarmThresh() */

/****************************************************************************/
/* Function    : updateWaterAlarmDm                                         */
/* Purpose     : Reads micro Water Alarm status & updates dmgr items        */
/* Inputs      : Sio32 chan & water alarm status data manager item handles  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
MwsledDconDmItems::updateWaterAlarmDm( sio32Chan *sio32DataChan,
    DM_Item canWaterAlarmDm, DM_Item jboxWaterAlarmDm )
{
    Word waterAlarmStatus;          /* Microcontroller Water Alarm Status   */
    MBool status;                   /* Boolean state of Water Alarm         */
                                    /* Read Water Alarm Status              */
    if (mwsledCanGetWaterAlarm(sio32DataChan, &waterAlarmStatus) != OK)
        return(ERROR);

    status = ( (waterAlarmStatus & HOUSING_WATER_ALARM_BIT) ? TRUE : FALSE);
    writeDmItem(canWaterAlarmDm, &status, sizeof(status));

    status = ( (waterAlarmStatus & JBOX_WATER_ALARM_BIT) ? TRUE : FALSE);

                                    /* Write water alarm status to Dmgr     */
    return ( writeDmItem(jboxWaterAlarmDm, &status, sizeof(status)) );
} /* updateWaterAlarmDm() */











