local MAJOR, MINOR = "DiesalMenu-2.0", 1
---@alias Diesal.Menu DiesalMenu-2.0

---@class DiesalMenu-2.0
local DiesalMenu = LibStub:NewLibrary(MAJOR, MINOR)

if not DiesalMenu then
    return
end -- No Upgrade needed.

---@type Diesal.Tools
local DiesalTools = LibStub("DiesalTools-2.0")
---@type Diesal.Style
local DiesalStyle = LibStub("DiesalStyle-2.0")
---@type Diesal.GUI
local DiesalGUI = LibStub("DiesalGUI-2.0")

local type, select, tonumber = type, select, tonumber
local setmetatable, getmetatable, next = setmetatable, getmetatable, next
local sub, format, lower, upper, match = string.sub, string.format, string.lower, string.upper, string.match
local pairs, ipairs = pairs, ipairs
local tinsert, tremove, tconcat, tsort = table.insert, table.remove, table.concat, table.sort
local floor, ceil, abs, modf = math.floor, math.ceil, math.abs, math.modf

local CreateFrame, UIParent = CreateFrame, UIParent

---@type Diesal.Menu.Menu
local MENU
local CLOSEDELAY = 2

---@class Diesal.Menu.CloseTimer : Frame
---@field closeDelay number
local closeTimer = CreateFrame("Frame")
closeTimer:Hide()

---@param this Diesal.Menu.CloseTimer
---@param elapsed number
closeTimer:SetScript("OnUpdate", function(this, elapsed)
    if this.count < 0 then
        DiesalMenu:Close()
        this:Hide()
    else
        this.count = this.count - elapsed
    end
end)

---@param menuData any
---@param anchor any
---@param x number
---@param y number
---@param closeDelay number
function DiesalMenu:Menu(menuData, anchor, x, y, closeDelay)
    MENU = MENU or DiesalGUI:Create("DiesalMenu")
    MENU:ResetSettings()
    if not MENU:BuildMenu(menuData) then
        MENU:Hide()
        return
    end
    MENU:Show()
    MENU:ClearAllPoints()
    MENU:SetPoint("TOPLEFT", anchor, "TOPLEFT", x, y)
    closeTimer.closeDelay = closeDelay or CLOSEDELAY
    DiesalMenu:StartCloseTimer()
    DiesalMenu:SetFocus()
end

function DiesalMenu:Close()
    DiesalMenu:StopCloseTimer()
    if not MENU or not MENU:IsVisible() then
        return
    end
    MENU:ResetSettings()
    MENU:ReleaseChildren()
    MENU:Hide()
    MENU:ClearAllPoints()
end

function DiesalMenu:StartCloseTimer()
    closeTimer.count = closeTimer.closeDelay
    closeTimer:Show()
end

function DiesalMenu:StopCloseTimer()
    closeTimer:Hide()
end

function DiesalMenu:ClearFocus()
    DiesalMenu:Close()
end

function DiesalMenu:SetFocus()
    DiesalGUI:SetFocus(DiesalMenu)
end
