--    ======================
--    Description
--    ======================
--
--    module defines State class
--
--    ======================
--    ChangeLog
--    ======================
--
--    2017-03-29 ver 0.1.1
--
--    # isChanged() fix
--
--    2017-03-19 ver 0.0.0
--
--    # First release
--

-- add script directory to package path
package.path = package.path .. ";./logic/scripts/utils/?.lua";

-- use script - without .lua extension - delta class
require("Functions");

-- class definition
State = {};

State.__index = State;

-- constructor
function State.create(defaultValue, minValue, maxValue, operateOnce)
  local state = {};           -- our new object
  setmetatable(state, State); -- make State handle lookup

  -- initialize our object
  state.value = defaultValue;
  state.minValue = minValue;
  state.maxValue = maxValue;
  state.operateOnce = operateOnce;
  state.changed = false;
  state.oldValue = -1;

  return state;
end

-- main call function
function State:call()
  self.changed = false;
  self.oldValue = self.value;
end

function State:isChanged()
  local result = false

  if (self.value ~= self.oldValue) then
    result = true;
  end

  return result
end

-- set value function
function State:setValue(value)
  if ((self.changed == false) or (self.operateOnce == false)) then
    self.value = value;
    self.changed = true;

    if (self.value > self.maxValue) then
      self.value = self.maxValue;
    end

    if (self.value < self.minValue) then
      self.value = self.minValue;
    end
  end

  local result = false
  if (self.value ~= self.oldValue) then
    result = true;
  end

  return result
end

-- get value function
function State:getValue()
  return self.value;
end

-- set state value to 1 if currentValue <= demandValue including hysteresis.
-- If currentValue >= demandValue, state value is changed to 0
function State:set1IfLowerThan(currentValue, demandValue, hysteresis)
  self:setValue(lowerThan(self.value, currentValue, demandValue, hysteresis));

  return self:getValue();
end

-- set state value to 1 if currentValue >= demandValue including hysteresis.
-- If currentValue <= demandValue, state value is changed to 0
function State:set1IfHigherThan(currentValue, demandValue, hysteresis)
  self:setValue(higherThan(self.value, currentValue, demandValue, hysteresis));

  return self:getValue();
end

-- set state value to 1 if delta condition is valid. Otherwise sets value to 0
function State:setIfDelta(sourceValue, targetValue, dtOn, dtOff)
  self:setValue(checkDelta(self.value, sourceValue, targetValue, dtOn, dtOff));

  return self:getValue();
end

-- set state value to newValue if newValue is higher than current state value
function State:setValueIfHigher(newValue)
  if (self:getValue() < newValue) then
    self:setValue(newValue);
  end

  return self:getValue();
end

-- set state value to newValue if newValue is lower than current state value
function State:setValueIfLower(newValue)
  if (self:getValue() > newValue) then
    self:setValue(newValue);
  end

  return self:getValue();
end

-- set maxValue
function State:setMax(maxValue)
  if maxValue >= self.minValue then
    self.maxValue = maxValue;
  end
end
