if not TowBarMod then TowBarMod = {} end
if not TowBarMod.UI then TowBarMod.UI = {} end

---------------------------------------------------------------------------
--- UI functions
---------------------------------------------------------------------------

function TowBarMod.UI.removeDefaultDetachOption(playerObj)
   local menu = getPlayerRadialMenu(playerObj:getPlayerNum())
   if menu == nil then return end

   local tmpSlices = {}
   for i, slice in ipairs(menu.slices or {}) do
      tmpSlices[i] = slice
   end
   menu:clear()
   for _, slice in ipairs(tmpSlices) do
      local command = slice.command and slice.command[1]
      local args = slice.command or {}
      if command ~= ISVehicleMenu.onDetachTrailer then
         menu:addSlice(
            slice.text,
            slice.texture,
            args[1],
            args[2],
            args[3],
            args[4],
            args[5],
            args[6],
            args[7]
         )
      end
   end
end

--- Show menu with available vehicles for tow bar hook.
function TowBarMod.UI.showChooseVehicleMenu(playerObj, vehicle, vehicles, hasTowBar)
   local playerIndex = playerObj:getPlayerNum()
   local menu = getPlayerRadialMenu(playerIndex)
   menu:clear()

   local added = 0
   for _, veh in ipairs(vehicles) do
      local hookTypeVariants = TowBarMod.Utils.getHookTypeVariants(vehicle, veh, hasTowBar)
      if #hookTypeVariants > 0 then
         local hookType = hookTypeVariants[1]
         menu:addSlice(
            hookType.name,
            getTexture("media/textures/tow_bar_attach.png"),
            hookType.func,
            playerObj,
            hookType.towingVehicle,
            hookType.towedVehicle,
            hookType.towingPoint,
            hookType.towedPoint
         )
         added = added + 1
      end
   end

   if added == 0 then return end

   menu:setX(getPlayerScreenLeft(playerIndex) + getPlayerScreenWidth(playerIndex) / 2 - menu:getWidth() / 2)
   menu:setY(getPlayerScreenTop(playerIndex) + getPlayerScreenHeight(playerIndex) / 2 - menu:getHeight() / 2)
   menu:addToUIManager()
   if JoypadState.players[playerObj:getPlayerNum()+1] then
      menu:setHideWhenButtonReleased(Joypad.DPadUp)
      setJoypadFocus(playerObj:getPlayerNum(), menu)
      playerObj:setJoypadIgnoreAimUntilCentered(true)
   end
end

function TowBarMod.UI.addHookOptionToMenu(playerObj, vehicle)
   local menu = getPlayerRadialMenu(playerObj:getPlayerNum())
   if menu == nil then return end

   local hasTowBar = playerObj:getInventory():getItemFromTypeRecurse("TowBar.TowBar") ~= nil
   if not hasTowBar then return end

   local vehicles = TowBarMod.Utils.getAviableVehicles(vehicle, hasTowBar)

   if #vehicles == 0 then
      return
   elseif #vehicles == 1 then
      local hookTypeVariants = TowBarMod.Utils.getHookTypeVariants(vehicle, vehicles[1], hasTowBar)
      if #hookTypeVariants > 0 then
         local hookType = hookTypeVariants[1]
         menu:addSlice(
            hookType.name,
            getTexture("media/textures/tow_bar_attach.png"),
            hookType.func,
            playerObj,
            hookType.towingVehicle,
            hookType.towedVehicle,
            hookType.towingPoint,
            hookType.towedPoint
         )
      end
   else
      menu:addSlice(
         getText("UI_Text_Towing_attach") .. "...",
         getTexture("media/textures/tow_bar_attach.png"),
         TowBarMod.UI.showChooseVehicleMenu,
         playerObj,
         vehicle,
         vehicles,
         hasTowBar
      )
   end
end

function TowBarMod.UI.addUnhookOptionToMenu(playerObj, vehicle)
   local menu = getPlayerRadialMenu(playerObj:getPlayerNum())
   if menu == nil then return end
   if not vehicle:getModData()["isTowingByTowBar"] then return end
   if not vehicle:getVehicleTowing() and not vehicle:getVehicleTowedBy() then return end

   local towedVehicle = vehicle
   if vehicle:getVehicleTowing() then
      towedVehicle = vehicle:getVehicleTowing()
   end

   menu:addSlice(
      getText("ContextMenu_Vehicle_DetachTrailer", ISVehicleMenu.getVehicleDisplayName(towedVehicle)),
      getTexture("media/textures/tow_bar_detach.png"),
      TowBarMod.Hook.deattachTowBarAction,
      playerObj,
      towedVehicle
   )
end


---------------------------------------------------------------------------
--- Dev menu
---------------------------------------------------------------------------

function TowBarMod.UI.showDevSingleTowbarMenu(playerObj, vehicle)
    local playerIndex = playerObj:getPlayerNum()
    local menu = getPlayerRadialMenu(playerIndex)
    menu:clear()

    for j = 0, 47 do
        local zIndex = j % 24
        local modelType = (j >= 24) and "large" or "normal"
        menu:addSlice(
            "towbar" .. j .. " [" .. modelType .. "] (Z=" .. tostring(1.0 + zIndex * 0.1) .. ")",
            getTexture("media/textures/tow_bar_icon.png"),
            TowBarMod.Hook.devShowSingleTowbar,
            playerObj,
            vehicle,
            j
        )
    end

    menu:setX(getPlayerScreenLeft(playerIndex) + getPlayerScreenWidth(playerIndex) / 2 - menu:getWidth() / 2)
    menu:setY(getPlayerScreenTop(playerIndex) + getPlayerScreenHeight(playerIndex) / 2 - menu:getHeight() / 2)
    menu:addToUIManager()
    if JoypadState.players[playerObj:getPlayerNum()+1] then
        menu:setHideWhenButtonReleased(Joypad.DPadUp)
        setJoypadFocus(playerObj:getPlayerNum(), menu)
        playerObj:setJoypadIgnoreAimUntilCentered(true)
    end
end

function TowBarMod.UI.addDevOptionsToMenu(playerObj, vehicle)
    local devModeEnabled = (TowBarMod.Config and TowBarMod.Config.devMode) or getDebug()
    if not devModeEnabled then return end
    if not vehicle then return end

    local menu = getPlayerRadialMenu(playerObj:getPlayerNum())
    if menu == nil then return end

    menu:addSlice(
        "[DEV] Show ALL Towbars",
        getTexture("media/textures/tow_bar_icon.png"),
        TowBarMod.Hook.devShowAllTowbarModels,
        playerObj,
        vehicle
    )

    menu:addSlice(
        "[DEV] Hide ALL Towbars",
        getTexture("media/textures/tow_bar_icon.png"),
        TowBarMod.Hook.devHideAllTowbarModels,
        playerObj,
        vehicle
    )

    menu:addSlice(
        "[DEV] Pick Single Towbar...",
        getTexture("media/textures/tow_bar_icon.png"),
        TowBarMod.UI.showDevSingleTowbarMenu,
        playerObj,
        vehicle
    )
end

---------------------------------------------------------------------------
--- Mod compability
---------------------------------------------------------------------------

if getActivatedMods():contains("vehicle_additions") then
   require("Vehicles/ISUI/Oven_Mattress_RadialMenu")
   require("Vehicles/ISUI/FuelTruckTank_ISVehicleMenu_FillPartMenu")
end

---------------------------------------------------------------------------
--- Attach to default menu method
---------------------------------------------------------------------------

if TowBarMod.UI.defaultShowRadialMenu == nil then
   TowBarMod.UI.defaultShowRadialMenu = ISVehicleMenu.showRadialMenu
end

function ISVehicleMenu.showRadialMenu(playerObj)
   TowBarMod.UI.defaultShowRadialMenu(playerObj)

   if playerObj:getVehicle() then return end

   local vehicle = ISVehicleMenu.getVehicleToInteractWith(playerObj)
   if vehicle == nil then return end

   if vehicle:getModData()["isTowingByTowBar"] then
      TowBarMod.UI.removeDefaultDetachOption(playerObj)
      TowBarMod.UI.addUnhookOptionToMenu(playerObj, vehicle)
   elseif not vehicle:getVehicleTowing() and not vehicle:getVehicleTowedBy() then
      TowBarMod.UI.addHookOptionToMenu(playerObj, vehicle)
   end

   TowBarMod.UI.addDevOptionsToMenu(playerObj, vehicle)
end
