--[[
SlowLowerDistance.lua

Author: Truflos
Game: FS25
Date: 10/10/2025

]]-- 

SlowLowerDistance = {}
SlowLowerDistance.MOD_NAME = g_currentModName or "UnknownMod"

function SlowLowerDistance.initSpecialization()
    local schema = Vehicle.xmlSchema
    schema:setXMLSpecializationType("slowLowerDistance")
    schema:register(XMLValueType.FLOAT, "vehicle.slowLowerDistance#maxDistance", "Dystans wymagany do pełnej animacji", 5)
    schema:register(XMLValueType.FLOAT, "vehicle.slowLowerDistance#liftMultiplier", "Mnożnik dla podnoszenia (szybsze cofanie)", 2)
    schema:setXMLSpecializationType()
end

function SlowLowerDistance.prerequisitesPresent(specializations)
    return true
end

function SlowLowerDistance.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", SlowLowerDistance)
    SpecializationUtil.registerEventListener(vehicleType, "onUpdate", SlowLowerDistance)
    SpecializationUtil.registerEventListener(vehicleType, "onReadStream", SlowLowerDistance)
    SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", SlowLowerDistance)
end

function SlowLowerDistance:onLoad(savegame)
    self.spec_slowLowerDistance = {}
    local spec = self.spec_slowLowerDistance

    spec.maxDistance = tonumber(self.xmlFile:getValue("vehicle.slowLowerDistance#maxDistance")) or 5.0
    spec.liftMultiplier = tonumber(self.xmlFile:getValue("vehicle.slowLowerDistance#liftMultiplier")) or 2.0

    -- stan
    spec.distance = 0.0
    spec.progress = 0.0
    spec.isLowered = false

    spec.lastWorldX, spec.lastWorldZ = nil, nil

end

function SlowLowerDistance:onUpdate(dt)
    local spec = self.spec_slowLowerDistance
    if spec == nil then
        return
    end
	-- pobranie pozycji na świecie
    local isLoweredNow = false
    if self.getIsLowered ~= nil then
        isLoweredNow = self:getIsLowered()
    end

    local x, _, z = getWorldTranslation(self.rootNode)

    local frameDist = 0
    if spec.lastWorldX ~= nil and spec.lastWorldZ ~= nil then
        local dx = x - spec.lastWorldX
        local dz = z - spec.lastWorldZ
        frameDist = math.sqrt(dx*dx + dz*dz)
    end
    spec.lastWorldX, spec.lastWorldZ = x, z

    -- wykrycie zmiany trybu (opuszczanie/podnoszenie)
    if isLoweredNow ~= spec.isLowered then
        spec.isLowered = isLoweredNow
    end

    if spec.isLowered then
        spec.distance = math.min(spec.maxDistance, spec.distance + frameDist)
    else
        spec.distance = math.max(0, spec.distance - frameDist * spec.liftMultiplier)
    end

    -- obliczenie progressu i ustawienie animacj
    local newProgress = 0.0
    if spec.maxDistance > 0 then
        newProgress = spec.distance / spec.maxDistance
    end
    if newProgress < 0 then newProgress = 0 end
    if newProgress > 1 then newProgress = 1 end

    if math.abs(newProgress - spec.progress) > 0.0005 then
        spec.progress = newProgress
    end

    local canSetAnim = (self.setAnimationTime ~= nil)
    local animExists = true
    if self.getAnimationTime ~= nil then
 
        if self:getAnimationTime("lowerImplement") == nil then
            animExists = false
        end
    end

    if canSetAnim and animExists then
        self:setAnimationTime("lowerImplement", spec.progress, true)
    end
end

-- multiplayer sync
function SlowLowerDistance:onReadStream(streamId, connection)
    local spec = self.spec_slowLowerDistance
    spec.distance = streamReadFloat32(streamId)
    spec.progress = spec.maxDistance > 0 and (spec.distance / spec.maxDistance) or 0
    if self.setAnimationTime ~= nil then
        self:setAnimationTime("lowerImplement", spec.progress, true)
    end
end

function SlowLowerDistance:onWriteStream(streamId, connection)
    local spec = self.spec_slowLowerDistance
    streamWriteFloat32(streamId, spec.distance)
end
