-- This Source Code Form is subject to the terms of the bCDDL, v. 1.1.
-- If a copy of the bCDDL was not distributed with this
-- file, You can obtain one at http://beamng.com/bCDDL-1.1.txt

local M = {}

local SmoothedTable = {}

local function initTable(electric, type, suffix)
  local newSmooth = {}
  newSmooth.electric = electric .. suffix
  newSmooth.baseElectric = electric
  newSmooth.type = type
  electrics.values[newSmooth.electric] = 0
  return newSmooth
end

local function addSmoothedTemporal(name, p0, p1, p2)
  local newSmooth = initTable(name, "temporal", "smooth")
  newSmooth.smoother = newTemporalSmoothingNonLinear(p0, p1, p2)
  table.insert(SmoothedTable, newSmooth)
end

local function addSmoothedLinear(name, speed)
  local newSmooth = initTable(name, "linear", "linear")
  newSmooth.speed = speed
  table.insert(SmoothedTable, newSmooth)
end

local function deleteSmoothed(name)
  local tbl = SmoothedTable[name]
  electrics.values[tbl.electric] = nil
  SmoothedTable[name] = nil
end

local function init()
  SmoothedTable = {}
  addSmoothedLinear("turnsignal", 0.1)
  addSmoothedLinear("hood_releaser", 0.2)
  addSmoothedLinear("ignitionLevel", 0.1)
  addSmoothedLinear("lights", 0.3)
end

local function updateTemporal(st, dt)
  if electrics.values[st.baseElectric] ~= nil then
    electrics.values[st.electric] = st.smoother:get(electrics.values[st.baseElectric], dt)
  end
end

local function updateLinear(st, dt)
  if electrics.values[st.baseElectric] == nil then return end --can't update if we're nil
  
  --get values
  local targetValue = electrics.values[st.baseElectric]
  local targetSpeed = st.speed
  local currentValue = electrics.values[st.electric]
  
  --value < target need negative speed
  if targetValue < currentValue then targetSpeed = targetSpeed * -1 end
  
  --move currentValue towards targetValue
  currentValue = currentValue + (dt / targetSpeed)
  if currentValue < targetValue and targetSpeed < 0 then currentValue = targetValue end
  if currentValue > targetValue and targetSpeed > 0 then currentValue = targetValue end
  
  --set smoothed value
  electrics.values[st.electric] = currentValue
end


local function updateGFX(dt)
  for k,st in ipairs(SmoothedTable) do
    if st.type == "temporal" then
      updateTemporal(st, dt)
    elseif st.type == "linear" then
      updateLinear(st, dt)
    end
  end
end

-- public interface
M.updateGFX      = updateGFX
M.onInit      = init
M.onReset     = init
return M