local function predicateNotFull(item)
    return item:getCurrentUsesFloat() < 1
end

local function predicateNotFullModItem(item)
    return item:getCurrentUsesFloat() < 1 and item:getType() ~= "CarBattery1" and item:getType() ~= "CarBattery2" and
               item:getType() ~= "CarBattery3"
end

local function onCarBatteryCharger_ConnectBattery(carBatteryCharger, playerObj, battery)
    if luautils.walkAdj(playerObj, carBatteryCharger:getSquare()) then
        ISWorldObjectContextMenu.transferIfNeeded(playerObj, battery)
        ISTimedActionQueue.add(ISConnectCarBatteryToChargerAction:new(playerObj, carBatteryCharger, battery))
    end
end
local function onCarBatteryCharger_RemoveBattery(carBatteryCharger, playerObj)
    if luautils.walkAdj(playerObj, carBatteryCharger:getSquare()) then
        ISTimedActionQueue.add(ISRemoveCarBatteryFromChargerAction:new(playerObj, carBatteryCharger))
    end
end

local function onCarBatteryCharger_Activate(carBatteryCharger, playerObj)
    if luautils.walkAdj(playerObj, carBatteryCharger:getSquare()) then
        ISTimedActionQueue.add(ISActivateCarBatteryChargerAction:new(playerObj, carBatteryCharger, true))
    end
end

local function onCarBatteryCharger_Deactivate(carBatteryCharger, playerObj)
    if luautils.walkAdj(playerObj, carBatteryCharger:getSquare()) then
        ISTimedActionQueue.add(ISActivateCarBatteryChargerAction:new(playerObj, carBatteryCharger, false))
    end
end
local function onCarBatteryCharger_Take(carBatteryCharger, playerObj)
    if luautils.walkAdj(playerObj, carBatteryCharger:getSquare()) then
        ISTimedActionQueue.add(ISTakeCarBatteryChargerAction:new(playerObj, carBatteryCharger))
    end
end

function ISWorldObjectContextMenu.handleCarBatteryCharger(test, context, worldobjects, playerObj, playerInv)
    local fetch = ISWorldObjectContextMenu.fetchVars
    local carBatteryCharger = fetch.carBatteryCharger
    if test == true then
        return true
    end
    if carBatteryCharger:getBattery() then
        if carBatteryCharger:isActivated() then
            context:addGetUpOption(getText("ContextMenu_Turn_Off"), carBatteryCharger, onCarBatteryCharger_Deactivate,
                playerObj)
        else
            local option = context:addGetUpOption(getText("ContextMenu_Turn_On"), carBatteryCharger,
                onCarBatteryCharger_Activate, playerObj)
            if not (carBatteryCharger:getSquare():haveElectricity() or
                ((getGameTime():getWorldAgeHours() / 24 + (getSandboxOptions():getTimeSinceApo() - 1) * 30) <
                    getSandboxOptions():getElecShutModifier() and carBatteryCharger:getSquare():getRoom())) then
                option.notAvailable = true
                option.toolTip = ISWorldObjectContextMenu.addToolTip()
                option.toolTip:setVisible(false)
                option.toolTip.description = getText("IGUI_RadioRequiresPowerNearby")
            end
        end
        local label = getText("ContextMenu_CarBatteryCharger_RemoveBattery") .. " (" ..
                          math.floor(carBatteryCharger:getBattery():getCurrentUsesFloat() * 100) .. "%)"
        context:addGetUpOption(label, carBatteryCharger, onCarBatteryCharger_RemoveBattery, playerObj)
    else
        local batteryList = playerInv:getAllTypeEvalRecurse("Base.CarBattery1", predicateNotFull)
        playerInv:getAllTypeEvalRecurse("Base.CarBattery2", predicateNotFull, batteryList)
        playerInv:getAllTypeEvalRecurse("Base.CarBattery3", predicateNotFull, batteryList)
        playerInv:getAllTypeEvalRecurse("Base.CarBattery10", predicateNotFull, batteryList)
        playerInv:getAllTagEvalRecurse("Base.CarBattery", predicateNotFullModItem, batteryList)
        if not batteryList:isEmpty() then
            local chargeOption = context:addOption(getText("ContextMenu_CarBatteryCharger_ConnectBattery"))
            local subMenuCharge = context:getNew(context)
            context:addSubMenu(chargeOption, subMenuCharge)
            local done = false
            for i = 1, batteryList:size() do
                local battery = batteryList:get(i - 1)
                if battery:getCurrentUsesFloat() < 1 then
                    local label = battery:getName() .. " (" .. math.floor(battery:getCurrentUsesFloat() * 100) .. "%)"
                    subMenuCharge:addGetUpOption(label, carBatteryCharger, onCarBatteryCharger_ConnectBattery,
                        playerObj, battery)
                    done = true
                end
            end
            if not done then
                context:removeLastOption()
            end
        end
        context:addGetUpOption(getText("ContextMenu_CarBatteryCharger_Take"), carBatteryCharger,
            onCarBatteryCharger_Take, playerObj)
    end
end
Events.OnGameBoot.Add(function()
    SystemDisabler.setEnableAdvancedSoundOptions(true)
end)
