--[[
Author: Jarth
Filename: CBs_Constants.lua
]] --
-------------------------------------------------------------------------------------------------
-- VARIABLES --
-------------------------------------------------------------------------------------------------
CollectionBars = {
    WM = GetWindowManager(),
    Addon = {Name = "CollectionBars", DisplayName = "Collection Bars", Abbreviation = "CBs", Version = 1.0, MinorVersion = 11, SettingsSlash = "/cb", Author = "Jarth"},
    Buttons = {},
    Default = {
        BarDepth = 5,
        BarWidth = 0,
        ButtonXY = ZO_GAMEPAD_ACTION_BUTTON_SIZE,
        UseAccountSettings = true,
        ShowBarOnHud = true,
        ShowBarOnHudUI = true,
        ShowBarInMenu = true,
        ShowBarInInventory = false,
        ShowBarInInteract = false,
        ShowBarInBank = false,
        ShowBarInFence = false,
        ShowBarInStore = false,
        SnapSize = 5,
        ShowBinding = true,
        Bindings = {
            [1] = 0,
            [2] = 0,
            [3] = 0,
            [4] = 0,
            [5] = 0,
            [6] = 0,
            [7] = 0,
            [8] = 0,
            [9] = 0,
            [10] = 0,
            [11] = 0,
            [12] = 0,
            [13] = 0,
            [14] = 0,
            [15] = 0,
            [16] = 0,
            [17] = 0,
            [18] = 0,
            [19] = 0,
            [20] = 0
        },
        IsAudioEnabled = true,
        IsActiveActivationEnabled = true,
        Combine = {BarDepth = 0, BarWidth = 0, X = CENTER, Y = CENTER, Display = "CombineBar", Label = {OffsetX = 0, OffsetY = 0, Position = BOTTOMLEFT, PositionTarget = TOPLEFT}}
    },
    Global = {
        EnableSettings = false,
        IsMoveEnabled = false,
        ReverseBindings = {},
        SettingsFrame = nil,
        SettingsList = nil,
        SettingsFilters = {["Categories"] = "Categories", ["Collectibles"] = "Collectibles", ["Category"] = "Category", ["General"] = "General", ["Combined"] = "Combined bar"},
        Combine = {Name = "Combine", EventTS = nil, MoveFrame = nil, Frame = nil, category = nil, HideAll = nil, Fragment = nil, IsEmpty = false},
        ChoiceLocations = {"top", "topright", "right", "bottomright", "bottom", "bottomleft", "left", "topleft", "center"},
        AvailableFonts = {"ZoFontGameSmall", "ZoFontGameLarge", "ZoFontGameLargeBold", "ZoFontGameLargeBoldShadow", "ZoFontHeader", "ZoFontHeader2", "ZoFontHeader3", "ZoFontHeader4"},
        ScenePairs = {
            ShowBarOnHud = HUD_SCENE,
            ShowBarOnHudUI = HUD_UI_SCENE,
            ShowBarInMenu = SCENE_MANAGER:GetScene("gameMenuInGame"),
            ShowBarInInventory = SCENE_MANAGER:GetScene("inventory"),
            ShowBarInInteract = SCENE_MANAGER:GetScene("interact"),
            ShowBarInBank = SCENE_MANAGER:GetScene("bank"),
            ShowBarInFence = SCENE_MANAGER:GetScene("fence_keyboard"),
            ShowBarInStore = SCENE_MANAGER:GetScene("store")
        },
        HighestUnlocked = 0
    },
    Categories = {},
    CategoriesOrdered = {},
    Texts = {
        Font = {ZoFontWinT1 = "ZoFontWinT1", ZoFontWinH4 = "ZoFontWinH4"},
        Format = {Number = "%.2f", Decimal = "%d", Comma = "%s,%s"},
        Location = {
            Bottom = "bottom",
            BottomLeft = "bottomleft",
            BottomRight = "bottomright",
            Center = "center",
            Left = "left",
            Right = "right",
            Top = "top",
            TopLeft = "topleft",
            TopRight = "topright"
        },
        Settings = {ToggleMoveFrameText = "Toggle move frame", ReloadText = "Reload list of 'Collectibles'\nHint: Usefull after gaining a new collectible)"}
    }
}

CollectionBars.Texts.FormatAbbreviation = string.format("%s%%s", CollectionBars.Addon.Abbreviation)
CollectionBars.Texts.FormatAbbreviationLowDash = string.format("%s_%%s", CollectionBars.Addon.Abbreviation)
CollectionBars.Texts.FormatBindingName = string.format("SI_BINDING_NAME_%s", CollectionBars.Texts.FormatAbbreviationLowDash)

CollectionBars.Texts.CombineFrameName = string.format(CollectionBars.Texts.FormatAbbreviationLowDash, "CombineFrame")
CollectionBars.Texts.CombineFrameNameHideAll = string.format("%s%s", CollectionBars.Texts.CombineFrameName, "HideAll")

CollectionBars.Texts.AccountKey = string.format("%s_Account", CollectionBars.Addon.Name)
CollectionBars.Texts.CharacterKey = string.format("%s_Character", CollectionBars.Addon.Name)

-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-------------------------------------------------------------------------------------------------

function CollectionBars.GenerateCategories()
    CollectionBars.Categories = {}

    for _, categoryData in ZO_COLLECTIBLE_DATA_MANAGER:CategoryIterator({ZO_CollectibleCategoryData.HasShownCollectiblesInCollection}) do
        if categoryData ~= nil and categoryData:IsStandardCategory() then
            local type = CollectionBars.GetType(categoryData)
            if type ~= nil and CollectionBars.CategoryHasUsableCollectible(categoryData) then
                CollectionBars.AddCategory(type, categoryData)
            else
                if categoryData:IsTopLevelCategory() and CollectionBars.SubCategoryHasUsableCollectible(categoryData) then
                    local parentIcons = {categoryData:GetKeyboardIcons()}
                    CollectionBars.AddCategory(nil, categoryData, parentIcons, true)
                    for _, subcategoryData in categoryData:SubcategoryIterator({ZO_CollectibleCategoryData.HasShownCollectiblesInCollection}) do
                        type = CollectionBars.GetType(subcategoryData)
                        if type ~= nil and subcategoryData ~= nil and subcategoryData:HasShownCollectiblesInCollection() then
                            CollectionBars.AddCategory(type, subcategoryData, parentIcons, false, categoryData:GetFormattedName())
                        end
                    end
                end
            end
        end
    end
end

function CollectionBars.GetType(categoryData)
    local type = nil
    local collectibles = categoryData:GetCollectibleDataBySpecializedSort()
    if collectibles ~= nil and collectibles[1] ~= nil then type = collectibles[1]:GetCategoryType() end

    return type
end

function CollectionBars.AddCategory(type, categoryData, parentIcons, hasChildren, parentKey)
    local categoryName = categoryData:GetFormattedName()
    local icon = parentIcons or {categoryData:GetKeyboardIcons()}
    if icon ~= nil and icon[1] == ZO_NO_TEXTURE_FILE then icon = nil end
    CollectionBars.Categories[categoryName] = {
        Collection = {},
        CollectionOrdered = {},
        Type = type,
        CategoryData = categoryData,
        Icon = icon,
        HasChildren = hasChildren,
        ParentKey = parentKey,
        Unlocked = 0,
        Name = categoryName,
        FrameLabel = nil,
        FrameLabelButton = nil,
        FrameToggleSettings = nil,
        MoveFrame = nil,
        Frame = nil,
        BarDepth = 0,
        BarWidth = nil,
        Cooldown = {Event = string.format("Cooldown%s", categoryName), CollectibleId = nil, StartTime = nil, Tick = 100},
        Fragment = nil
    }
    table.insert(CollectionBars.CategoriesOrdered, CollectionBars.Categories[categoryName])
    CollectionBars.Default[categoryName] = {
        Selected = {},
        Enabled = false,
        HideAll = true,
        HideAllEnabled = true,
        MenuShowDisabled = false,
        Tooltip = {Show = true, Position = TOP},
        Horizontal = true,
        BarDepth = 0,
        BarWidth = 0,
        X = CENTER,
        Y = CENTER,
        Display = categoryName,
        LabelShow = true,
        Label = {OffsetX = 0, OffsetY = 0, Height = 19, Width = 75, Font = "ZoFontGameSmall", Position = BOTTOMLEFT, PositionTarget = TOPLEFT},
        IsCombined = true,
        ShowChildren = true
    }
end

function CollectionBars.CategoryHasUnlockedValidAndUsableCollectible(categoryData)
    if GetTotalCollectiblesByCategoryType(categoryData:GetId()) > 0 then
        for _, collectibleData in ZO_CollectibleCategoryData.CollectibleIterator(categoryData, {ZO_CollectibleData.IsShownInCollection}) do
            if collectibleData:IsUnlocked() and collectibleData:IsValidForPlayer() and collectibleData:IsUsable() then return true end
        end
    end
    return false
end

function CollectionBars.CategoryHasUsableCollectible(categoryData)
    if categoryData ~= nil and CollectionBars.CategoryHasUnlockedValidAndUsableCollectible(categoryData) then return true end
    return false
end

function CollectionBars.SubCategoryHasUsableCollectible(categoryData)
    for _, subcategoryData in categoryData:SubcategoryIterator({ZO_CollectibleCategoryData.HasShownCollectiblesInCollection}) do
        local type = CollectionBars.GetType(subcategoryData)
        if type ~= nil and subcategoryData ~= nil and CollectionBars.CategoryHasUnlockedValidAndUsableCollectible(subcategoryData) then return true end
    end
    return false
end