#include "WaterAlarm.h"
#include "IbcAppError.h"
#include "DmError.h"

extern "C"
{
# include "usrTime.h"
};


WaterAlarm::WaterAlarm(DmBooleanObject *status,
		       DmNat16Object *threshold,
		       Word getStatusCmd,
		       Word getStatusMask,
		       Word getThreshCmd,
		       Word setThreshCmd,
		       Word onSrqCode,
		       Word offSrqCode
		       )
{
  WaterAlarm::status = status;
  WaterAlarm::threshold = threshold;
    
  init(getStatusCmd, getStatusMask, getThreshCmd, setThreshCmd, 
       onSrqCode, offSrqCode);
}


WaterAlarm::WaterAlarm(const char *statusName,
		       const char *threshName,
		       Word getStatusCmd,
		       Word getStatusMask,
		       Word getThreshCmd,
		       Word setThreshCmd,
		       Word onSrqCode,
		       Word offSrqCode
		       )
{
  status = new DmBooleanObject(statusName);
  threshold = new DmNat16Object(threshName);

  init(getStatusCmd, getStatusMask, getThreshCmd, setThreshCmd, 
       onSrqCode, offSrqCode);
}


WaterAlarm::~WaterAlarm()
{
}

		       
MBool WaterAlarm::statusChanged(Word srqCode)
{
  DM_Time t;

  if (srqCode == _onSrqCode || srqCode == _offSrqCode)
  {
    gettimeofday(&t, 0);
    MBool value;
    if (srqCode == _onSrqCode)
      value = TRUE;
    else
      value = FALSE;
    
    status->write(value, &t);
    return TRUE;
  }
  else
    return FALSE;
}


int WaterAlarm::updateThreshold(sio32Chan *channel)
{
  Nat16 value;
  DM_Time t;
  Errno err;
  
  if ((err = threshold->read(&value, &t)) != SUCCESS)
  {
    setError("WaterAlarm::updateThreshold() - threshold->read() failed");
    return -1;
  }
  
  if (sendMicroCommand(channel, &status, sizeof(status), 2,
		       _setThreshCmd, value) != ERROR)
  {
    if (wordFromBuf(&status, 0) != CMD_OK)
    {
      setError("WaterAlarm::updateThreshold() - sendMicroCommand() failed");
      return -1;
    }
  }
  else
  {
    setError("WaterAlarm::updateThreshold() - sendMicroCommand() failed");
    return -1;
  }

  return 0;
}


int WaterAlarm::updateThresholdDm(sio32Chan *channel)
{
  Nat16 value;
  
  if (microCommand(channel, _getThreshCmd, &value) != OK)
  {
    setError("WaterAlarm::updateThresholdDm() - microCommand() failed");
    return -1;
  }
  

  DM_Time t;
  gettimeofday(&t, NULL);
  Errno err;
  
  if ((err = threshold->write(value, &t)) != SUCCESS)
  {
    setError("WaterAlarm::updateThresholdDm() - threshold->write() failed");
    return -1;
  }

  return 0;
}


int WaterAlarm::updateDm(sio32Chan *channel)
{
  Word alarmStatusBits;
  
  if (microCommand(channel, _getStatusCmd, &alarmStatusBits) != OK)
  {
    setError("WaterAlarm::updateDm() - microCommand() failed");
    return -1;
  }
  
  MBool alarmValue = alarmStatusBits & _getStatusMask;
  DM_Time t;
  gettimeofday(&t, NULL);
  Errno err;
  
  if ((err = status->write(alarmValue, &t)) != SUCCESS)
  {
    setError("WaterAlarm::updateDm() - status->write() failed");
    return -1;
  }

  return 0;
}


Errno WaterAlarm::init(Word getStatusCmd,
		       Word getStatusMask,
		       Word getThreshCmd,
		       Word setThreshCmd,
		       Word onSrqCode,
		       Word offSrqCode)
{
  Errno err;
  if ((err = status->startProvide(DM_STATIC, ExclusiveProvider)) != SUCCESS)
  {
    setError("WaterAlarm::WaterAlarm() - status->startProvide() failed");
    return err;
  }

  if ((err = threshold->startProvide(DM_STATIC, ExclusiveProvider)) 
      != SUCCESS)
  {
    setError("WaterAlarm::WaterAlarm() - status->startProvide() failed");
    return err;
  }
  
  _getStatusCmd = getStatusCmd;
  _getStatusMask = getStatusMask;
  _getThreshCmd = getThreshCmd;
  _setThreshCmd = setThreshCmd;
  _onSrqCode = onSrqCode;
  _offSrqCode = offSrqCode;
  return SUCCESS;
}



