CompressorHandToolAccess = {}

function CompressorHandToolAccess.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(HandToolHolders, specializations)
end

function CompressorHandToolAccess.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", CompressorHandToolAccess)
    SpecializationUtil.registerEventListener(vehicleType, "onDelete", CompressorHandToolAccess)
    SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", CompressorHandToolAccess)
end

function CompressorHandToolAccess:onLoad(savegame)
    self.spec_compressorHandToolAccess = {
        isCompressorActive = false,
        activatableEnabled = false,
        actionEventId = nil,
        inputAction = InputAction.KANGOO_TAKE_AIRLANCE
    }
end

function CompressorHandToolAccess:onDelete()
    local spec = self.spec_compressorHandToolAccess
    if spec ~= nil and spec.actionEventId ~= nil and g_inputBinding ~= nil then
        g_inputBinding:removeActionEvent(spec.actionEventId)
        spec.actionEventId = nil
    end
end

function CompressorHandToolAccess:onAirLanceAction(actionName, inputValue, callbackState, isAnalog)
    if inputValue == 0 then
        return
    end

    if g_localPlayer == nil then
        return
    end

    local spec = self.spec_compressorHandToolAccess
    local holdersSpec = self.spec_handToolHolders
    if spec == nil or holdersSpec == nil or holdersSpec.handToolHolders == nil then
        return
    end

    local holder = holdersSpec.handToolHolders[1]
    if holder == nil then
        return
    end

    local holderHandTool = holder:getHandTool() or holder:getSpawnedHandTool()
    local playerHandTool = g_localPlayer:getHeldHandTool()

    if playerHandTool == nil and holderHandTool ~= nil then
        if g_localPlayer:getCanPickupHandTool(holderHandTool) then
            holderHandTool:setHolder(g_localPlayer)
            g_localPlayer:setCurrentHandTool(holderHandTool)
        end
    elseif playerHandTool ~= nil and holder:getCanPickupHandTool(playerHandTool) then
        playerHandTool:setHolder(holder)
    end
end

function CompressorHandToolAccess:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
    local spec = self.spec_compressorHandToolAccess
    local holdersSpec = self.spec_handToolHolders

    if spec == nil or holdersSpec == nil or holdersSpec.handToolHolders == nil then
        return
    end

    local holder = holdersSpec.handToolHolders[1]
    if holder == nil or holder.activatable == nil then
        return
    end

    local isCompressorActive = (self.getAnimationTime ~= nil and (self:getAnimationTime("groupCharge") or 0) > 0.01) or false
    local activatableSystem = g_currentMission.activatableObjectsSystem
    local localPlayer = g_localPlayer
    local canUseShortcut = false

    if localPlayer ~= nil and holder.holderNode ~= nil then
        local px, py, pz = getWorldTranslation(localPlayer.rootNode)
        local hx, hy, hz = getWorldTranslation(holder.holderNode)
        local distance = MathUtil.vector3Length(px - hx, py - hy, pz - hz)

        if distance < 5 and isCompressorActive then
            canUseShortcut = true
        end
    end

    if isCompressorActive then
        if isCompressorActive ~= spec.isCompressorActive then
            if holder.isPlayerInRange or holder.activationTrigger == nil then
                activatableSystem:addActivatable(holder.activatable)
            end
            spec.activatableEnabled = true
        end
    else
        if spec.activatableEnabled or holder.isPlayerInRange then
            activatableSystem:removeActivatable(holder.activatable)
            spec.activatableEnabled = false

            local handTool = holder:getSpawnedHandTool()
            if handTool ~= nil and handTool.spec_highPressureWasherLance ~= nil and handTool.spec_highPressureWasherLance.isActivated then
                handTool:setIsActivated(false)
            end
        end
    end

    if canUseShortcut and spec.inputAction ~= nil then
        if spec.actionEventId == nil then
            local _, actionEventId = g_inputBinding:registerActionEvent(spec.inputAction, self, CompressorHandToolAccess.onAirLanceAction, false, true, false, true, nil)
            spec.actionEventId = actionEventId

            if actionEventId ~= nil then
                g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("input_KANGOO_TAKE_AIRLANCE"))
                g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
                g_inputBinding:setActionEventTextVisibility(actionEventId, true)
            end
        end
    elseif spec.actionEventId ~= nil then
        g_inputBinding:removeActionEvent(spec.actionEventId)
        spec.actionEventId = nil
    end

    spec.isCompressorActive = isCompressorActive
end
