-- Saved settings setup for OmniCC
local AddonName, Addon = ...

local DB_NAME = AddonName .. 'DB'
local DB_VERSION = 6
local LEGACY_DB_NAME = 'OmniCC4Config'

function Addon:InitializeDB()
    self.db = LibStub('AceDB-3.0'):New(DB_NAME, self:GetDBDefaults(), DEFAULT)
    self.db.RegisterCallback(self, 'OnNewProfile', 'OnNewProfile')
    self.db.RegisterCallback(self, 'OnProfileChanged', 'OnProfileChanged')
    self.db.RegisterCallback(self, 'OnProfileCopied', 'OnProfileChanged')
    self.db.RegisterCallback(self, 'OnProfileReset', 'OnProfileReset')

    self:UpgradeDB()
end

-- add default rules when a profile is created
function Addon:OnNewProfile(_, db)
    self:AddDefaultRulesets(db)
end

function Addon:OnProfileReset(_, db)
    self:AddDefaultRulesets(db)
    self:OnProfileChanged()
end

function Addon:OnProfileChanged()
    self.Cooldown:ForAll('UpdateSettings')
end

function Addon:GetDBDefaults()
    return {
        global = {
            -- force disable Blizzard's default cooldown text implementation
            disableBlizzardCooldownText = true
        },
        profile = {
            rules = {
                ['**'] = {
                    -- what theme to apply for this rule
                    theme = DEFAULT,
                    -- enable checking the rule
                    enabled = true,
                    -- rule evaluation order
                    priority = 0,
                    -- lua patterns to check against frame names
                    patterns = {}
                }
            },
            defaultTheme = DEFAULT,
            themes = {
                ['**'] = {
                    -- name = "localized theme name",
                    -- cooldown text configuration
                    enableText = true,
                    -- what font to use (an actual path)
                    fontFace = STANDARD_TEXT_FONT,
                    -- the default font size
                    fontSize = 18,
                    -- font outline settings (NONE, OUTLINE, THICKOUTLINE, MONOCHROME)
                    fontOutline = 'OUTLINE',
                    -- font shadow color and offsets
                    fontShadow = {
                        -- color
                        r = 1,
                        g = 1,
                        b = 1,
                        a = 0,
                        -- offset
                        x = 0,
                        y = 0
                    },
                    -- timer offset (ms)
                    -- used to adjust timer end points
                    timerOffset = 0,
                    -- enable/disable resizing text based off of frame size
                    scaleText = true,
                    -- text display conditions
                    -- how big something must be to display cooldown text
                    -- this is a percentage of the size of an action button
                    minSize = 0.5,
                    -- how long a cooldown (in seconds) must be to display text
                    minDuration = 2,
                    -- how long a cooldown (in seconds) can at most be to display text
                    -- set to zero for unlimited maximum durations
                    maxDuration = 0,
                    -- at what duration (in seconds) remaining should start
                    -- displaying cooldowns in tenths of seconds format (ex, 3.1)
                    tenthsDuration = 0,
                    -- at what duration (in seconds) remaining should start
                    -- displaying cooldowns in MM:SS format
                    mmSSDuration = 0,
                    -- what finish effect to display
                    effect = 'pulse',
                    -- how long a cooldown must be (in seconds) to trigger
                    -- a finish effect
                    minEffectDuration = 30,
                    -- where to position cooldown text within a frame
                    anchor = 'CENTER',
                    xOff = 0,
                    yOff = 0,
                    -- cooldown opacity
                    cooldownOpacity = 1,
                    textStyles = {
                        ['**'] = {r = 1, g = 1, b = 1, a = 1, scale = 1},
                        soon = {r = 1, g = .1, b = .1, scale = 1.5},
                        seconds = {r = 1, g = 1, b = .1},
                        minutes = {r = 1, g = 1, b = 1},
                        hours = {r = .7, g = .7, b = .7, scale = .75},
                        days = {r = .7, g = .7, b = .7, scale = .75},
                        charging = {r = 0.8, g = 1, b = .3, a = .8, scale = .75},
                        controlled = {r = 1, g = .1, b = .1, scale = 1.5}
                    }
                },
                [DEFAULT] = {name = DEFAULT}
            }
        }
    }
end

function Addon:AddDefaultRulesets(db)
    table.insert(db.profile.rules, {
        id = 'auras',
        name = AURAS,
        enabled = false,
        patterns = {'Aura', 'Buff', 'Debuff'}
    })

    table.insert(db.profile.rules, {
        id = 'plates',
        enabled = false,
        name = UNIT_NAMEPLATES,
        patterns = {'Plate'}
    })

    table.insert(db.profile.rules, {
        id = 'actions',
        enabled = false,
        name = ACTIONBARS_LABEL,
        patterns = {'ActionButton', "MultiBar"}
    })
end

function Addon:UpgradeDB()
    local dbVersion = self.db.global.dbVersion

    if dbVersion ~= DB_VERSION then
        if dbVersion == nil then
            self:MigrateLegacySettings(_G[LEGACY_DB_NAME])
        elseif dbVersion < 6 then
            self:MigrateDrawSwipesSetting()
        end

        self.db.global.dbVersion = DB_VERSION
    end

    local addonVersion = self.db.global.addonVersion
    if addonVersion ~= C_AddOns.GetAddOnMetadata(AddonName, 'Version') then
        self.db.global.addonVersion = C_AddOns.GetAddOnMetadata(AddonName, 'Version')
    end
end

function Addon:MigrateLegacySettings(legacyDb)
    if type(legacyDb) ~= 'table' then
        return
    end

    local function getThemeID(id)
        if id == 'base' then
            return DEFAULT
        end

        return id
    end

    local function copyTable(src, dest)
        if type(dest) ~= 'table' then
            dest = {}
        end

        for k, v in pairs(src) do
            if type(v) == 'table' then
                dest[k] = copyTable(v, dest[k])
            else
                dest[k] = v
            end
        end

        return dest
    end

    -- groupSettings -> themes
    local oldGroupSettings = legacyDb and legacyDb.groupSettings
    if type(oldGroupSettings) == 'table' then
        for id, group in pairs(oldGroupSettings) do
            -- apply the old settings
            local theme = copyTable(group,
                                    self.db.profile.themes[getThemeID(id)])

            -- enabled -> enableText
            theme.enableText = theme.enabled
            theme.enabled = nil

            -- styles -> textStyles
            copyTable(theme.styles, theme.textStyles)
            theme.styles = nil
        end
    end

    -- groups -> rules
    local oldGroups = legacyDb.groups
    if type(oldGroups) == 'table' then
        for i = #oldGroups, 1, -1 do
            local group = oldGroups[i]

            table.insert(self.db.profile.rules, 1, {
                id = getThemeID(group.id),
                theme = getThemeID(group.id),
                -- group.rules -> patterns
                patterns = copyTable(group.rules),
                enabled = group.enabled,
                priority = i
            })
        end
    end

    return true
end

function Addon:MigrateDrawSwipesSetting()
    for _, theme in pairs(self.db.profile.themes) do
        if theme.drawSwipes == false then
            theme.cooldownOpacity = 0
        end
    end

    return true
end
