-- Odometer.lua
--
-- author  	VolgaFS 
-- date  	01-07-2025.
-- https://vk.com/volgafs


OdometerSpecialization = {}

function OdometerSpecialization.prerequisitesPresent(specializations)
  return SpecializationUtil.hasSpecialization(Drivable, specializations)
end

function OdometerSpecialization.initSpecialization()
  local schema = Vehicle.xmlSchema
  schema:register(XMLValueType.FLOAT, "vehicle.odometer#initialValue", "Начальный пробег в км", 0)
end

function OdometerSpecialization.registerFunctions(vehicleType)
  SpecializationUtil.registerFunction(vehicleType, "updateOdometer", OdometerSpecialization.updateOdometer)
end


function OdometerSpecialization.registerOverwrittenFunctions(vehicleType)
  SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDashboardFloatValue", OdometerSpecialization.getDashboardFloatValue)
end

function OdometerSpecialization.registerEventListeners(vehicleType)
  SpecializationUtil.registerEventListener(vehicleType, "onLoad", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onUpdate", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onDraw", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onReadStream", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onLoadSavegame", OdometerSpecialization)
  SpecializationUtil.registerEventListener(vehicleType, "onSaveSavegame", OdometerSpecialization)
end

function OdometerSpecialization:onLoad(savegame)
  local value = self.xmlFile:getValue("vehicle.odometer#initialValue", 0)
  self.spec_odometer = {
    totalDistance = value * 1000,
    lastPosition = nil
  }
end

function OdometerSpecialization:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
  local spec = self.spec_odometer
  if spec == nil then return end

  local x, _, z = getWorldTranslation(self.rootNode)
  if spec.lastPosition ~= nil then
    local dx = x - spec.lastPosition[1]
    local dz = z - spec.lastPosition[2]
    local dist = math.sqrt(dx * dx + dz * dz)
    spec.totalDistance = spec.totalDistance + dist
  end
  spec.lastPosition = {x, z}
end

function OdometerSpecialization:onDraw(isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
  if self:getIsActive() and self.getIsEntered ~= nil and self:getIsEntered() then
    local spec = self.spec_odometer
    local km = math.floor((spec.totalDistance / 1000) * 10 + 0.5) / 10
    setTextAlignment(RenderText.ALIGN_RIGHT)
    setTextColor(1, 1, 1, 1)
    renderText(0.98, 0.01, 0.02, string.format("Пробег: %.1f км", km))
  end
end

function OdometerSpecialization:onReadStream(streamId, connection)
  local spec = self.spec_odometer
  spec.totalDistance = streamReadFloat32(streamId)
end

function OdometerSpecialization:onWriteStream(streamId, connection)
  local spec = self.spec_odometer
  streamWriteFloat32(streamId, spec.totalDistance)
end

function OdometerSpecialization:onLoadSavegame(xmlFile, key)
  local spec = self.spec_odometer
  spec.totalDistance = xmlFile:getFloat(key .. "#odometerKM", spec.totalDistance / 1000) * 1000
end

function OdometerSpecialization:onSaveSavegame(xmlFile, key)
  local spec = self.spec_odometer
  xmlFile:setFloat(key .. "#odometerKM", spec.totalDistance / 1000)
end

function OdometerSpecialization:getDashboardFloatValue(superFunc, id)
    if id == "odometer" then
        local spec = self.spec_odometer
        return (spec and spec.totalDistance or 0) / 1000
    end
    return superFunc(self, id)
end