-- Rack & Ruin: Compat.lua
-- Blizzard's Options/Settings panel has some transparency in its content
-- area, and our windows can visually bleed through it if left open behind
-- it. Rather than fight frame strata/toplevel ordering, we just hide all
-- our windows whenever a major Blizzard panel opens, and restore whichever
-- ones were actually open once it closes.

RackAndRuin = RackAndRuin or {}
RackAndRuin.ManagedFrames = RackAndRuin.ManagedFrames or {}

-- Any UI file that creates a top-level window should call this once, right
-- after creating its frame.
function RackAndRuin.RegisterManagedFrame(frame)
    table.insert(RackAndRuin.ManagedFrames, frame)
end

local hiddenSet = {}

local function HideOurs()
    for _, f in ipairs(RackAndRuin.ManagedFrames) do
        if f:IsShown() then
            hiddenSet[f] = true
            f:Hide()
        end
    end
end

local function RestoreOurs()
    for f in pairs(hiddenSet) do
        f:Show()
    end
    wipe(hiddenSet)
end

local watcher = CreateFrame("Frame")
watcher:RegisterEvent("PLAYER_LOGIN")
watcher:RegisterEvent("ADDON_LOADED")

local alreadyHooked = {}

local function TryHook(globalName)
    if alreadyHooked[globalName] then return end
    local f = _G[globalName]
    if f then
        f:HookScript("OnShow", HideOurs)
        f:HookScript("OnHide", RestoreOurs)
        alreadyHooked[globalName] = true
    end
end

local CANDIDATE_FRAMES = {
    "SettingsPanel",
    "InterfaceOptionsFrame",
    "VideoOptionsFrame",
    "GameMenuFrame",
}

watcher:SetScript("OnEvent", function(self, event, addonName)
    -- Try immediately (covers the case where the frame already exists),
    -- and also retry on every ADDON_LOADED, since Blizzard's options panel
    -- is provided by a lazy-loaded addon (commonly Blizzard_Settings) that
    -- often isn't loaded yet at PLAYER_LOGIN - it only loads the first time
    -- the panel is actually opened, or shortly after.
    for _, name in ipairs(CANDIDATE_FRAMES) do
        TryHook(name)
    end
end)

SLASH_RRDEBUG1 = "/rrdebug"
SlashCmdList["RRDEBUG"] = function()
    print("Rack & Ruin compat status:")
    for _, name in ipairs(CANDIDATE_FRAMES) do
        local exists = _G[name] ~= nil
        local hooked = alreadyHooked[name] == true
        print(string.format("  %s: exists=%s, hooked=%s", name, tostring(exists), tostring(hooked)))
    end
    print("Managed frames tracked: " .. #RackAndRuin.ManagedFrames)
end
