local M = {}
M.autosave = true

--All code by dummiesman, I just slapped the electrics.values thing in here in order to use it for my gauge screen as I currently do not posess the knowledge
--needed in order to do the whole screen thing like Dummies did, basing on what I have from TrackPadUser instead as I know how to not break things with that
local saveInterval = 60
local saveAccumulator = 0

local value = 0

local function getSaveFilePath()
  local vehicleFolder = string.sub(v.vehicleDirectory,10,-2)
  return "settings/dm_odometer/" .. vehicleFolder .. ".save.json"
end

local function getSaveVersion()
  return  1.01
end

local function serialize()
    local serializedData = {}
    serializedData.version = getSaveVersion()
    serializedData.value = value
    return serializedData
end

local function deserialize(serializedData)
    if serializedData.version ~= getSaveVersion() then
        log("E", "dm.odo.deserialize", "bad version passed to deserialize")
        return
    end
    value = serializedData.value
end

local function saveOdometer(checkFileFirst)
  checkFileFirst = checkFileFirst or true
  if checkFileFirst then
    --load the existing save
    local serializedData = jsonReadFile(getSaveFilePath())
    if serializedData ~= nil then 
      --check version
      if serializedData.version ~= getSaveVersion() then
          log("E", "dm.odo.deserialize", "bad version passed to deserialize")
      else
            --check if existing save is >= ours, or within 1m
            local diff = math.abs(value - serializedData.value)
            if serializedData.value > value or diff < 0.001 then 
                --print(string.format("ODO: not saving because the saved value is too close or greater, diff is %3.f, value is %3.f, sd.value is %3.f", diff, value, serializedData.value))
                return 
            end 
      end      
    end  
  end
  
  --
  jsonWriteFile(getSaveFilePath(), serialize(), true)
end

local function loadOdometer()
  local serializedData = jsonReadFile(getSaveFilePath())
  if serializedData ~= nil then deserialize(serializedData) end
end

local function onInit()
    loadOdometer()
end

local function onReset()
end

local function getIsEngineRunning()
  return (electrics.values["engineRunning"] or 0) > 0.5
end

local function getGear()
  return electrics.values.gearIndex or 1
end

local function isNaN( v ) return type( v ) == "number" and v ~= v end 

local function updateGFX(dt)
  if M.autosave then
    saveAccumulator = saveAccumulator + dt
    if saveAccumulator >= saveInterval then
        saveOdometer()
        saveAccumulator = 0
    end
  end
  
  -- things
  -- roughly 1.1mph
  local speedMin = 0.5
  -- roughly 1118mph (too fast!!, might be an instability)
  local speedMax= 600

  -- the actual logic
  if not electrics.values["focusOdometer"] then
	electrics.values["focusOdometer"] = value
  end
  if getIsEngineRunning() and getGear() ~= 0 then
    local curSpeed = electrics.values["wheelspeed"] or 0
    if isNaN(curSpeed) then return end -- can't do anything
    if curSpeed > speedMin and curSpeed < speedMax then
      value = value + ((curSpeed * dt) * 0.001) -- (m/s * time) = distance, * 0.001 = m to km
	  
	  electrics.values["focusOdometer"] = value 
    end
  end
end

local function getValue()
  return value
end

local function setValue(val)
  value = val
end

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

M.setValue = setValue
M.getValue = getValue
M.saveOdometer = saveOdometer

return M