local addonName, addon = ...

addon.UI = addon.UI or {}

local UI = addon.UI

------------------------------------------------------------
-- LAYOUT
------------------------------------------------------------

local FRAME_WIDTH = 1380
local FRAME_HEIGHT = 800

local HEADER_HEIGHT = 55
local INPUT_HEIGHT = 190

local SIDEBAR_WIDTH = 300
local NAV_WIDTH = 185

local PADDING = 15
local GAP = 10

------------------------------------------------------------
-- MAIN FRAME
------------------------------------------------------------

local frame = CreateFrame(
    "Frame",
    "WhatsNextMainFrame",
    UIParent,
    "BackdropTemplate"
)

UI.MainFrame = frame

frame:SetSize(FRAME_WIDTH, FRAME_HEIGHT)
frame:SetPoint("CENTER")
frame:SetFrameStrata("DIALOG")
frame:SetClampedToScreen(true)

frame:SetMovable(true)
frame:EnableMouse(true)
frame:RegisterForDrag("LeftButton")

frame:SetScript("OnDragStart", function(self)
    self:StartMoving()
end)

frame:SetScript("OnDragStop", function(self)
    self:StopMovingOrSizing()
end)

frame:SetBackdrop({
    bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
    tile = true,
    tileSize = 16,
    edgeSize = 16,
    insets = {
        left = 4,
        right = 4,
        top = 4,
        bottom = 4,
    },
})

frame:SetBackdropColor(unpack(UI.COLORS.background))
frame:SetBackdropBorderColor(unpack(UI.COLORS.border))

if UI.RegisterTypographyRoot then
    UI:RegisterTypographyRoot(frame)
end

------------------------------------------------------------
-- HEADER
------------------------------------------------------------

local header = CreateFrame("Frame", nil, frame)

UI.Header = header

header:SetPoint("TOPLEFT", frame, "TOPLEFT")
header:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
header:SetHeight(HEADER_HEIGHT)

local headerBackground = header:CreateTexture(nil, "BACKGROUND")
headerBackground:SetAllPoints()
headerBackground:SetColorTexture(unpack(UI.COLORS.header))

local title = header:CreateFontString(nil, "OVERLAY")
title:SetFontObject(GameFontNormalLarge)
title:SetPoint("LEFT", header, "LEFT", PADDING, 0)
local addonVersion = C_AddOns and C_AddOns.GetAddOnMetadata and C_AddOns.GetAddOnMetadata(addonName, "Version")
    or GetAddOnMetadata and GetAddOnMetadata(addonName, "Version")
    or "?"
title:SetText(UI:T("TITLE", "WHATS NEXT?") .. "   v" .. tostring(addonVersion))
title:SetTextColor(unpack(UI.COLORS.gold))

local closeButton = CreateFrame(
    "Button",
    nil,
    header,
    "UIPanelCloseButton"
)

closeButton:SetPoint("TOPRIGHT", header, "TOPRIGHT", -2, -2)

closeButton:SetScript("OnClick", function()
    UI:Hide()
end)

------------------------------------------------------------
-- GLOBAL NAVIGATION
------------------------------------------------------------

local navigation = CreateFrame(
    "Frame",
    nil,
    frame,
    "BackdropTemplate"
)

UI.Navigation = navigation

navigation:SetPoint(
    "TOPLEFT",
    frame,
    "TOPLEFT",
    PADDING,
    -(HEADER_HEIGHT + GAP)
)

navigation:SetPoint(
    "BOTTOMLEFT",
    frame,
    "BOTTOMLEFT",
    PADDING,
    PADDING
)

navigation:SetWidth(NAV_WIDTH)
UI:ApplyPanelBackdrop(navigation)

local navTitle = navigation:CreateFontString(nil, "OVERLAY")
navTitle:SetFontObject(GameFontNormalSmall)
navTitle:SetPoint("TOPLEFT", navigation, "TOPLEFT", 12, -12)
navTitle:SetText(UI:T("NAVIGATION", "NAVIGATION"))
navTitle:SetTextColor(unpack(UI.COLORS.muted))

local navDivider = navigation:CreateTexture(nil, "ARTWORK")
navDivider:SetPoint("TOPLEFT", navigation, "TOPLEFT", 8, -34)
navDivider:SetPoint("TOPRIGHT", navigation, "TOPRIGHT", -8, -34)
navDivider:SetHeight(1)
navDivider:SetColorTexture(unpack(UI.COLORS.border))

UI.NavigationButtons = {}
UI.NavigationOrder = { "tasks", "loot", "myloot", "loottest", "tank", "about", "settings" }

local function GetEffectiveNavigationSection()
    -- Loot Browser and My Loot share one physical frame.  Use the view that
    -- is actually being displayed as the navigation source of truth.
    if UI.LootTrackerFrame and UI.LootTrackerFrame:IsShown() then
        if UI.LootViewMode == "myloot" then
            return "myloot"
        end
        if UI.LootViewMode == "browse" then
            return "loot"
        end
    end

    return UI.ActiveSection or "tasks"
end

UI.GetEffectiveNavigationSection = GetEffectiveNavigationSection

local function CreateNavigationButton(key, label, y)
    local button = CreateFrame("Button", nil, navigation)
    button:SetPoint("TOPLEFT", navigation, "TOPLEFT", 8, y)
    button:SetPoint("TOPRIGHT", navigation, "TOPRIGHT", -8, y)
    button:SetHeight(34)

    local bg = button:CreateTexture(nil, "BACKGROUND")
    bg:SetAllPoints()
    bg:SetColorTexture(0, 0, 0, 0)
    button.Background = bg

    local text = button:CreateFontString(nil, "OVERLAY")
    text:SetFontObject(GameFontHighlight)
    text:SetPoint("LEFT", button, "LEFT", 10, 0)
    text:SetPoint("RIGHT", button, "RIGHT", -8, 0)
    text:SetJustifyH("LEFT")
    text:SetText(label)
    button.Label = text

    button:SetScript("OnEnter", function(self)
        if GetEffectiveNavigationSection() ~= key then
            self.Background:SetColorTexture(
                UI.COLORS.panelAlt[1],
                UI.COLORS.panelAlt[2],
                UI.COLORS.panelAlt[3],
                0.90
            )
        end
    end)

    button:SetScript("OnLeave", function(self)
        if GetEffectiveNavigationSection() ~= key then
            self.Background:SetColorTexture(0, 0, 0, 0)
        end
    end)

    button:SetScript("OnClick", function()
        if UI.SetActiveSection then
            UI:SetActiveSection(key)
        end
    end)

    UI.NavigationButtons[key] = button
    return button
end

CreateNavigationButton("tasks", UI:T("NAV_TASKS", "TASKS"), -44)
CreateNavigationButton("loot", UI:T("NAV_LOOT", "LOOT BROWSER"), -80)
CreateNavigationButton("myloot", UI:T("NAV_MY_LOOT", "MY LOOT"), -116)
CreateNavigationButton("loottest", UI:T("NAV_LOOT_TEST", "EQUIPMENT LOOT TEST"), -152)
CreateNavigationButton("tank", UI:T("NAV_TANK", "TANK ASSISTANT"), -188)
CreateNavigationButton("about", UI:T("NAV_ABOUT", "ABOUT"), -234)
CreateNavigationButton("settings", UI:T("NAV_SETTINGS", "SETTINGS"), -270)

function UI:UpdateNavigationSelection()
    local activeSection = GetEffectiveNavigationSection()

    for key, button in pairs(self.NavigationButtons or {}) do
        local active = activeSection == key
        if active then
            button.Background:SetColorTexture(unpack(self.COLORS.selected))
            button.Label:SetTextColor(unpack(self.COLORS.gold))
        else
            button.Background:SetColorTexture(0, 0, 0, 0)
            button.Label:SetTextColor(unpack(self.COLORS.text))
        end
    end
end

------------------------------------------------------------
-- PAGE HOST
------------------------------------------------------------

local pageHost = CreateFrame("Frame", nil, frame)
UI.PageHost = pageHost

pageHost:SetPoint(
    "TOPLEFT",
    navigation,
    "TOPRIGHT",
    GAP,
    0
)

pageHost:SetPoint(
    "BOTTOMRIGHT",
    frame,
    "BOTTOMRIGHT",
    -PADDING,
    PADDING
)

------------------------------------------------------------
-- ABOUT PAGE
------------------------------------------------------------

local aboutPage = CreateFrame("Frame", nil, pageHost, "BackdropTemplate")
UI.AboutPage = aboutPage
aboutPage:SetAllPoints(pageHost)
UI:ApplyPanelBackdrop(aboutPage)
aboutPage:Hide()

local aboutTitle = aboutPage:CreateFontString(nil, "OVERLAY")
aboutTitle:SetFontObject(GameFontNormalLarge)
aboutTitle:SetPoint("TOPLEFT", aboutPage, "TOPLEFT", 18, -18)
aboutTitle:SetText(UI:T("ABOUT_TITLE", "ABOUT WHATS NEXT?"))
aboutTitle:SetTextColor(unpack(UI.COLORS.gold))

local aboutVersion = aboutPage:CreateFontString(nil, "OVERLAY")
aboutVersion:SetFontObject(GameFontHighlight)
aboutVersion:SetPoint("TOPLEFT", aboutTitle, "BOTTOMLEFT", 0, -8)
aboutVersion:SetText(UI:T("VERSION", "Version") .. " " .. tostring(addonVersion))
aboutVersion:SetTextColor(unpack(UI.COLORS.muted))

local aboutDescription = aboutPage:CreateFontString(nil, "OVERLAY")
aboutDescription:SetFontObject(GameFontHighlight)
aboutDescription:SetPoint("TOPLEFT", aboutVersion, "BOTTOMLEFT", 0, -24)
aboutDescription:SetPoint("RIGHT", aboutPage, "RIGHT", -24, 0)
aboutDescription:SetJustifyH("LEFT")
aboutDescription:SetJustifyV("TOP")
aboutDescription:SetWordWrap(true)
aboutDescription:SetText(UI:T("ABOUT_DESCRIPTION", "Whats Next? is a World of Warcraft task, loot, equipment and route planner."))

local aboutFeaturesTitle = aboutPage:CreateFontString(nil, "OVERLAY")
aboutFeaturesTitle:SetFontObject(GameFontNormal)
aboutFeaturesTitle:SetPoint("TOPLEFT", aboutDescription, "BOTTOMLEFT", 0, -28)
aboutFeaturesTitle:SetText(UI:T("CURRENT_FEATURES", "CURRENT FEATURES"))
aboutFeaturesTitle:SetTextColor(unpack(UI.COLORS.gold))

local aboutFeatures = aboutPage:CreateFontString(nil, "OVERLAY")
aboutFeatures:SetFontObject(GameFontHighlight)
aboutFeatures:SetPoint("TOPLEFT", aboutFeaturesTitle, "BOTTOMLEFT", 0, -10)
aboutFeatures:SetPoint("RIGHT", aboutPage, "RIGHT", -24, 0)
aboutFeatures:SetJustifyH("LEFT")
aboutFeatures:SetJustifyV("TOP")
aboutFeatures:SetWordWrap(true)
aboutFeatures:SetText(UI:T("ABOUT_FEATURES", ""))

------------------------------------------------------------
-- SETTINGS PAGE
------------------------------------------------------------

local settingsPage = CreateFrame("Frame", nil, pageHost, "BackdropTemplate")
UI.SettingsPage = settingsPage
settingsPage:SetAllPoints(pageHost)
UI:ApplyPanelBackdrop(settingsPage)
settingsPage:Hide()

local settingsTitle = settingsPage:CreateFontString(nil, "OVERLAY")
settingsTitle:SetFontObject(GameFontNormalLarge)
settingsTitle:SetPoint("TOPLEFT", settingsPage, "TOPLEFT", 18, -18)
settingsTitle:SetText(UI:T("SETTINGS", "SETTINGS"))
settingsTitle:SetTextColor(unpack(UI.COLORS.gold))

local settingsIntro = settingsPage:CreateFontString(nil, "OVERLAY")
settingsIntro:SetFontObject(GameFontHighlight)
settingsIntro:SetPoint("TOPLEFT", settingsTitle, "BOTTOMLEFT", 0, -14)
settingsIntro:SetPoint("RIGHT", settingsPage, "RIGHT", -24, 0)
settingsIntro:SetJustifyH("LEFT")
settingsIntro:SetWordWrap(true)
settingsIntro:SetText(UI:T("SETTINGS_INTRO", "Configure Whats Next? windows and interface preferences."))
settingsIntro:SetTextColor(unpack(UI.COLORS.muted))

local function CreateSettingsLabel(parent, anchor, text, x, y)
    local label = parent:CreateFontString(nil, "OVERLAY")
    label:SetFontObject(GameFontNormal)
    label:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", x or 0, y or -12)
    label:SetText(text)
    label:SetTextColor(unpack(UI.COLORS.gold))
    return label
end

-- Whats Next? does not expose a separate font or UI scale control.
-- All frames inherit Blizzard UI scale from UIParent and use GameFont objects.

-- TODAY TIMERS
local timersSection = CreateSettingsLabel(settingsPage, settingsIntro, UI:T("TODAY_TIMERS_WINDOW", "TODAY TIMERS WINDOW"), 0, -24)

local timersCheck = CreateFrame("CheckButton", nil, settingsPage, "UICheckButtonTemplate")
UI.TodayTimersSettingCheck = timersCheck
timersCheck:SetSize(28, 28)
timersCheck:SetPoint("TOPLEFT", timersSection, "BOTTOMLEFT", 0, -10)

local timersLabel = settingsPage:CreateFontString(nil, "OVERLAY")
timersLabel:SetFontObject(GameFontHighlight)
timersLabel:SetPoint("LEFT", timersCheck, "RIGHT", 6, 1)
timersLabel:SetText(UI:T("SHOW_WINDOW", "SHOW WINDOW"))

timersCheck:SetScript("OnClick", function(button)
    if UI.SetTodayTimersWindowEnabled then
        UI:SetTodayTimersWindowEnabled(button:GetChecked())
    end
end)

local timersLock = CreateFrame("CheckButton", nil, settingsPage, "UICheckButtonTemplate")
UI.TodayTimersLockCheck = timersLock
timersLock:SetSize(28, 28)
timersLock:SetPoint("TOPLEFT", timersCheck, "BOTTOMLEFT", 0, -6)

local timersLockLabel = settingsPage:CreateFontString(nil, "OVERLAY")
timersLockLabel:SetFontObject(GameFontHighlight)
timersLockLabel:SetPoint("LEFT", timersLock, "RIGHT", 6, 1)
timersLockLabel:SetText(UI:T("LOCK_WINDOW", "LOCK WINDOW"))

timersLock:SetScript("OnClick", function(button)
    if UI.SetTodayTimersWindowLocked then
        UI:SetTodayTimersWindowLocked(button:GetChecked())
    end
end)

-- TODAY TASKS
local tasksSection = settingsPage:CreateFontString(nil, "OVERLAY")
tasksSection:SetFontObject(GameFontNormal)
tasksSection:SetPoint("TOPLEFT", timersLock, "BOTTOMLEFT", 0, -24)
tasksSection:SetText(UI:T("TODAY_TASKS_WINDOW", "TODAY TASKS WINDOW"))
tasksSection:SetTextColor(unpack(UI.COLORS.gold))

local tasksCheck = CreateFrame("CheckButton", nil, settingsPage, "UICheckButtonTemplate")
UI.TodayTasksSettingCheck = tasksCheck
tasksCheck:SetSize(28, 28)
tasksCheck:SetPoint("TOPLEFT", tasksSection, "BOTTOMLEFT", 0, -10)

local tasksLabel = settingsPage:CreateFontString(nil, "OVERLAY")
tasksLabel:SetFontObject(GameFontHighlight)
tasksLabel:SetPoint("LEFT", tasksCheck, "RIGHT", 6, 1)
tasksLabel:SetText(UI:T("SHOW_WINDOW", "SHOW WINDOW"))

tasksCheck:SetScript("OnClick", function(button)
    if UI.SetTodayTasksWindowEnabled then
        UI:SetTodayTasksWindowEnabled(button:GetChecked())
    end
end)

local tasksLock = CreateFrame("CheckButton", nil, settingsPage, "UICheckButtonTemplate")
UI.TodayTasksLockCheck = tasksLock
tasksLock:SetSize(28, 28)
tasksLock:SetPoint("TOPLEFT", tasksCheck, "BOTTOMLEFT", 0, -6)

local tasksLockLabel = settingsPage:CreateFontString(nil, "OVERLAY")
tasksLockLabel:SetFontObject(GameFontHighlight)
tasksLockLabel:SetPoint("LEFT", tasksLock, "RIGHT", 6, 1)
tasksLockLabel:SetText(UI:T("LOCK_WINDOW", "LOCK WINDOW"))

tasksLock:SetScript("OnClick", function(button)
    if UI.SetTodayTasksWindowLocked then
        UI:SetTodayTasksWindowLocked(button:GetChecked())
    end
end)

local minimapSection = settingsPage:CreateFontString(nil, "OVERLAY")
minimapSection:SetFontObject(GameFontNormal)
minimapSection:SetPoint("TOPLEFT", tasksLock, "BOTTOMLEFT", 0, -24)
minimapSection:SetText(UI:T("MINIMAP_BUTTON", "MINIMAP BUTTON"))
minimapSection:SetTextColor(unpack(UI.COLORS.gold))

local minimapCheck = CreateFrame("CheckButton", nil, settingsPage, "UICheckButtonTemplate")
UI.MinimapButtonSettingCheck = minimapCheck
minimapCheck:SetSize(28,28)
minimapCheck:SetPoint("TOPLEFT", minimapSection, "BOTTOMLEFT", 0, -10)

local minimapLabel = settingsPage:CreateFontString(nil, "OVERLAY")
minimapLabel:SetFontObject(GameFontHighlight)
minimapLabel:SetPoint("LEFT", minimapCheck, "RIGHT", 6, 1)
minimapLabel:SetText(UI:T("SHOW_MINIMAP_BUTTON", "SHOW MINIMAP BUTTON"))

minimapCheck:SetScript("OnClick", function(button)
    if addon.MinimapButton and addon.MinimapButton.SetShown then
        addon.MinimapButton:SetShown(button:GetChecked())
    end
end)

settingsPage:SetScript("OnShow", function()
    if UI.ApplyDetachedWindowSettings then UI:ApplyDetachedWindowSettings() end
    if addon.MinimapButton and addon.MinimapButton.Refresh then addon.MinimapButton:Refresh() end
end)


------------------------------------------------------------
-- INPUT PANEL
------------------------------------------------------------

local inputPanel = CreateFrame(
    "Frame",
    nil,
    frame,
    "BackdropTemplate"
)

UI.InputPanel = inputPanel

inputPanel:SetPoint(
    "TOPLEFT",
    pageHost,
    "TOPLEFT"
)

inputPanel:SetPoint(
    "TOPRIGHT",
    pageHost,
    "TOPRIGHT"
)

inputPanel:SetHeight(INPUT_HEIGHT)
UI:ApplyPanelBackdrop(inputPanel)

------------------------------------------------------------
-- MAIN CONTENT
------------------------------------------------------------

local mainContent = CreateFrame("Frame", nil, frame)

UI.MainContent = mainContent

mainContent:SetPoint(
    "TOPLEFT",
    inputPanel,
    "BOTTOMLEFT",
    0,
    -GAP
)

mainContent:SetPoint(
    "BOTTOMRIGHT",
    pageHost,
    "BOTTOMRIGHT"
)

------------------------------------------------------------
-- TASK PANEL
------------------------------------------------------------

local taskPanel = CreateFrame(
    "Frame",
    nil,
    mainContent,
    "BackdropTemplate"
)

UI.TaskPanel = taskPanel

taskPanel:SetPoint("TOPLEFT", mainContent, "TOPLEFT")
taskPanel:SetPoint("BOTTOMLEFT", mainContent, "BOTTOMLEFT")

taskPanel:SetPoint(
    "RIGHT",
    mainContent,
    "RIGHT",
    -(SIDEBAR_WIDTH + GAP),
    0
)

UI:ApplyPanelBackdrop(taskPanel)

local allButton = CreateFrame(
    "Button",
    nil,
    taskPanel,
    "UIPanelButtonTemplate"
)

UI.AllButton = allButton

allButton:SetSize(120, 28)
allButton:SetPoint("TOPLEFT", taskPanel, "TOPLEFT", 12, -12)
allButton:SetText(UI:LT("ALL TASKS"))
UI:ApplyRedButton(allButton)

local scrollFrame = CreateFrame(
    "ScrollFrame",
    "WhatsNextScrollFrame",
    taskPanel,
    "UIPanelScrollFrameTemplate"
)

UI.ScrollFrame = scrollFrame

scrollFrame:SetPoint(
    "TOPLEFT",
    taskPanel,
    "TOPLEFT",
    12,
    -50
)

scrollFrame:SetPoint(
    "BOTTOMRIGHT",
    taskPanel,
    "BOTTOMRIGHT",
    -30,
    12
)

local content = CreateFrame("Frame", nil, scrollFrame)

UI.Content = content

content:SetWidth(800)
content:SetHeight(100)

scrollFrame:SetScrollChild(content)

------------------------------------------------------------
-- SIDEBAR
------------------------------------------------------------

local sidebar = CreateFrame(
    "Frame",
    nil,
    mainContent,
    "BackdropTemplate"
)

UI.Sidebar = sidebar

sidebar:SetPoint("TOPRIGHT", mainContent, "TOPRIGHT")
sidebar:SetPoint("BOTTOMRIGHT", mainContent, "BOTTOMRIGHT")
sidebar:SetWidth(SIDEBAR_WIDTH)

UI:ApplyPanelBackdrop(sidebar)

------------------------------------------------------------
-- STATE
------------------------------------------------------------

UI.ViewMode = "day"
UI.SelectedDate = UI:GetToday()

UI.NewTaskHasDate = true
UI.NewTaskHasTime = false

UI.CategoryFilter = "ALL"

UI.FilterCharacterKey = "ALL"
UI.FilterSpecID = "ALL"
UI.FilterProfessionID = "ALL"
UI.FilterInstanceID = "ALL"
UI.FilterRaidExpansion = "ALL"

------------------------------------------------------------
-- ALL TASKS
------------------------------------------------------------

allButton:SetScript("OnClick", function()

    UI.ViewMode = "all"

    if UI.ResetAllFilters then
        UI:ResetAllFilters()
    else
        UI.CategoryFilter = "ALL"
    end

    if UI.RefreshDynamicSelectors then
        UI:RefreshDynamicSelectors()
    end

    UI:Refresh()

end)

------------------------------------------------------------
-- REFRESH
------------------------------------------------------------

function UI:Refresh()

    if self.RefreshDetachedWindows then
        self:RefreshDetachedWindows()
    end

    if self.ActiveSection == "loottest" then
        if self.RefreshEquipmentLootTest then self:RefreshEquipmentLootTest() end
        return
    end

    if self.ActiveSection == "tank" then
        if self.RefreshTankAssistant then self:RefreshTankAssistant() end
        return
    end

    if self.ActiveSection == "loot" or self.ActiveSection == "myloot" then
        if self.RefreshLootTracker then
            self:RefreshLootTracker()
        end
        if self.ApplyGlobalTypography then
            C_Timer.After(0, function() UI:ApplyGlobalTypography() end)
        end
        return
    end

    if self.ActiveSection == "tasks" then
        if self.RefreshTaskList then self:RefreshTaskList() end
        if self.RefreshCalendar then self:RefreshCalendar() end
        if self.RefreshTimers then self:RefreshTimers() end
    end

    if self.ApplyGlobalTypography then
        C_Timer.After(0, function() UI:ApplyGlobalTypography() end)
    end

end

------------------------------------------------------------
-- SHOW / HIDE
------------------------------------------------------------

function UI:Show()

    if addon.GameData
        and addon.GameData.RefreshAll
    then
        addon.GameData:RefreshAll()
    end

    if self.RefreshDynamicSelectors then
        self:RefreshDynamicSelectors()
    end

    frame:Show()

    if self.ShowLanguageSetupIfNeeded and self:ShowLanguageSetupIfNeeded() then
        return
    end

    if self.SetActiveSection then
        self:SetActiveSection(self.ActiveSection or "tasks")
    else
        self:Refresh()
    end

end

function UI:Hide()
    frame:Hide()
end

function UI:Toggle()

    if frame:IsShown() then
        self:Hide()
    else
        self:Show()
    end

end

------------------------------------------------------------
-- TIMER UPDATE
------------------------------------------------------------

local elapsedTotal = 0

frame:SetScript("OnUpdate", function(_, elapsed)

    if not frame:IsShown() then
        return
    end

    elapsedTotal = elapsedTotal + elapsed

    if elapsedTotal >= 1 then

        elapsedTotal = 0

        if UI.UpdateTimers then
            UI:UpdateTimers()
        end

    end

end)

------------------------------------------------------------
-- INITIALIZE
------------------------------------------------------------

function UI:Initialize()

    frame:Hide()

    if self.InitializeLanguageSettings then
        self:InitializeLanguageSettings()
    end

    if self.InitializeTaskInput then
        self:InitializeTaskInput()
    end

    if self.InitializeTaskList then
        self:InitializeTaskList()
    end

    if self.InitializeCalendar then
        self:InitializeCalendar()
    end

    if self.InitializeTimers then
        self:InitializeTimers()
    end

    if self.InitializeDetachedWindows then
        self:InitializeDetachedWindows()
    end

    if self.InitializeTankAssistant then
        self:InitializeTankAssistant()
    end

    if self.InitializeLootTracker then
        self:InitializeLootTracker()
    end

    self.ActiveSection = "tasks"

    if self.UpdateNavigationSelection then
        self:UpdateNavigationSelection()
    end

    if self.ApplyDetachedWindowSettings then
        self:ApplyDetachedWindowSettings()
    end

    if self.ApplyGlobalTypography then
        self:ApplyGlobalTypography()
    end

    if self.RefreshCalendar then
        self:RefreshCalendar()
    end

    if WhatsNextUserData and WhatsNextUserData.settings and WhatsNextUserData.settings.reopenAfterLanguageReload then
        WhatsNextUserData.settings.reopenAfterLanguageReload = nil
        C_Timer.After(0.2, function() if UI and UI.Show then UI:Show() end end)
    end

end
