-------------------------
--Import modules.
-------------------------
---@type QuestieQuest
local QuestieQuest = QuestieLoader:ImportModule("QuestieQuest");
---@type QuestieOptions
local QuestieOptions = QuestieLoader:ImportModule("QuestieOptions");
---@type QuestieOptionsDefaults
local QuestieOptionsDefaults = QuestieLoader:ImportModule("QuestieOptionsDefaults");
---@type QuestieOptionsUtils
local QuestieOptionsUtils = QuestieLoader:ImportModule("QuestieOptionsUtils");
---@type QuestiePlayer
local QuestiePlayer = QuestieLoader:ImportModule("QuestiePlayer");
---@type QuestieMenu
local QuestieMenu = QuestieLoader:ImportModule("QuestieMenu");
---@type l10n
local l10n = QuestieLoader:ImportModule("l10n")
---@type QuestieTooltips
local QuestieTooltips = QuestieLoader:ImportModule("QuestieTooltips");
---@type WorldMapButton
local WorldMapButton = QuestieLoader:ImportModule("WorldMapButton")
---@type QuestieCoords
local QuestieCoords = QuestieLoader:ImportModule("QuestieCoords");
---@type QuestieTracker
local QuestieTracker = QuestieLoader:ImportModule("QuestieTracker");
---@type QuestieShutUp
local QuestieShutUp = QuestieLoader:ImportModule("QuestieShutUp")
---@type Sounds
local Sounds = QuestieLoader:ImportModule("Sounds")
---@type AvailableQuests
local AvailableQuests = QuestieLoader:ImportModule("AvailableQuests")

QuestieOptions.tabs.general = { ... }
local optionsDefaults = QuestieOptionsDefaults:Load()

local _GetAnnounceChannels
local _IsAnnounceDisabled
local _GetQuestSoundChoices
local _GetQuestSoundChoicesSort
local _GetObjectiveSoundChoices
local _GetObjectiveSoundChoicesSort
local _GetObjectiveProgressSoundChoices
local _GetObjectiveProgressSoundChoicesSort

function QuestieOptions.tabs.general:Initialize()
    return {
        name = function() return l10n('General'); end,
        type = "group",
        order = 1,
        args = {
            questie_header = {
                type = "header",
                order = 1,
                name = function() return l10n('General Options'); end,
            },
            social_spacer = QuestieOptionsUtils:Spacer(1.5,nil,"minimal"),
            social_options_group = {
                type = "group",
                order = 2,
                inline = true,
                name = function() return l10n('Social Options'); end,
                args = {
                    filterQuestieAnnounce = {
                        type = "toggle",
                        order = 7.1,
                        name = function() return l10n('Questie ShutUp!'); end,
                        desc = function() return l10n('Remove all Questie chat messages coming from other players and disable sending your own.'); end,
                        descStyle = "inline",
                        disabled = function() return false end,
                        width = 2,
                        get = function () return Questie.db.profile.questieShutUp end,
                        set = function (_, value)
                            Questie.db.profile.questieShutUp = value
                            QuestieShutUp:ToggleFilters(value)
                        end,
                    },
                    questAnnounceChannel = {
                        type = "select",
                        order = 7.2,
                        values = _GetAnnounceChannels(),
                        style = 'dropdown',
                        disabled = function() return Questie.db.profile.questieShutUp end,
                        name = function() return l10n('Channels to announce in') end,
                        desc = function() return l10n('Announce quest updates to other players in your group'); end,
                        get = function() return Questie.db.profile.questAnnounceChannel; end,
                        set = function(_, key)
                            Questie.db.profile.questAnnounceChannel = key
                            Questie:Debug(Questie.DEBUG_DEVELOP, "Channels to announce changed to:", key)
                        end,
                    },
                    printLocalMessages = {
                        type = "toggle",
                        order = 7.3,
                        name = function() return l10n('Display announcements locally when outside of a group'); end,
                        desc = function() return l10n("Questie will print your progress messages to chat when not in a group. Other players will NOT be able to see this."); end,
                        disabled = function() return Questie.db.profile.questieShutUp end,
                        width = 2.5,
                        get = function () return Questie.db.profile.questAnnounceLocally end,
                        set = function (_, value)
                            Questie.db.profile.questAnnounceLocally = value
                            Questie:Debug(Questie.DEBUG_DEVELOP, "Quest announce locally changed to:", value)
                        end,
                    },
                    shareQuestsNearby = {
                        type = "toggle",
                        order = 7.4,
                        name = function() return l10n('Share quest progress with nearby players'); end,
                        desc = function() return l10n("Your quest progress will be periodically sent to nearby players. Disabling this doesn't affect sharing progress with party members."); end,
                        disabled = function() return false end,
                        width = 1.7,
                        hidden = true, -- does this even do anything anymore after YELL removed?
                        get = function () return not Questie.db.profile.disableYellComms end,
                        set = function (info, value)
                            Questie.db.profile.disableYellComms = not value
                            if not value then
                                QuestieLoader:ImportModule("QuestieComms"):RemoveAllRemotePlayers()
                            end
                        end,
                    },
                    questAnnounceTypes = {
                        type = "group",
                        order = 7.5,
                        inline = true,
                        name = function() return l10n('Types of updates to announce in chat'); end,
                        disabled = function() return _IsAnnounceDisabled() or Questie.db.profile.questieShutUp; end,
                        args = {
                            questAnnounceItems = {
                                type = "toggle",
                                order = 1,
                                name = function() return l10n('Items starting a quest'); end,
                                desc = function() return l10n('Announce looted items that start a quest to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceItems; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceItems = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Items starting a quest changed to:", value)
                                end,
                            },
                            questAnnounceAccepted = {
                                type = "toggle",
                                order = 2,
                                name = function() return l10n('Quest accepted'); end,
                                desc = function() return l10n('Announce quest acceptance to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceAccepted; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceAccepted = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Quest accepted announce changed to:", value)
                                end,
                            },
                            questAnnounceAbandoned = {
                                type = "toggle",
                                order = 3,
                                name = function() return l10n('Quest abandoned'); end,
                                desc = function() return l10n('Announce quest abortion to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceAbandoned; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceAbandoned = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Quest abandoned announce changed to:", value)
                                end,
                            },
                            questAnnounceCompleted = {
                                type = "toggle",
                                order = 4,
                                name = function() return l10n('Quest completed'); end,
                                desc = function() return l10n('Announce quest completion to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceCompleted; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceCompleted = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Quest completed announce changed to:", value)
                                end,
                            },
                            questAnnounceObjectives = {
                                type = "toggle",
                                order = 5,
                                name = function() return l10n('Objective completed'); end,
                                desc = function() return l10n('Announce completed objectives to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceObjectives; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceObjectives = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Objective completed announce changed to:", value)
                                end,
                            },
                            questAnnounceObjectiveProgress = {
                                type = "toggle",
                                order = 6,
                                name = function() return l10n('Objective progress'); end,
                                desc = function() return l10n('Announce objective progress to other players'); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceObjectiveProgress; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceObjectiveProgress = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Objective progress announce changed to:", value)
                                end,
                            },
                            questAnnounceIncompleteBreadcrumb = {
                                type = "toggle",
                                order = 7,
                                name = function() return l10n("Incomplete breadcrumb"); end,
                                desc = function() return l10n("Announce that you just picked up a quest for which you have an incomplete breadcrumb quest"); end,
                                width = 1.5,
                                get = function () return Questie.db.profile.questAnnounceIncompleteBreadcrumb; end,
                                set = function (_, value)
                                    Questie.db.profile.questAnnounceIncompleteBreadcrumb = value
                                    Questie:Debug(Questie.DEBUG_DEVELOP, "Quest announce incomplete breadcrumb changed to:", value)
                                end,
                            },
                        },
                    },
                },
            },
            interface_spacer = QuestieOptionsUtils:Spacer(2.5,nil,"minimal"),
            interface_options_group = {
                type = "group",
                order = 3,
                inline = true,
                name = function() return l10n('Interface Options'); end,
                args = {
                    instantQuest = {
                        type = "toggle",
                        order = 5.1,
                        name = function() return l10n('Enable Instant Quest Text'); end,
                        desc = function() return l10n('Toggles the default Instant Quest Text option. This is just a shortcut for the WoW option in Interface.'); end,
                        width = 1.55,
                        get = function()
                            if GetCVar("instantQuestText") == '1' then
                                return true;
                            else
                                return false;
                            end
                        end,
                        set = function(info, value)
                            if value then
                                SetCVar("instantQuestText", 1);
                            else
                                SetCVar("instantQuestText", 0);
                            end
                        end,
                    },
                    showCustomQuestFrameIcons = {
                        type = "toggle",
                        order = 5.2,
                        name = function() return l10n('Show custom quest frame icons'); end,
                        desc = function() return l10n('Use custom Questie icons for NPC dialogs, reflecting the status and type of each quest.'); end,
                        width = 1.55,
                        get = function() return Questie.db.profile.enableQuestFrameIcons; end,
                        set = function(info, value)
                            Questie.db.profile.enableQuestFrameIcons = value
                        end,
                    },
                    mapShowHideEnabled = {
                        type = "toggle",
                        order = 5.25,
                        name = function() return l10n('Show Questie Map Button'); end,
                        desc = function() return l10n('Enable or disable the Show/Hide Questie Button on Map (May fix some Map Addon interactions).'); end,
                        width = 1.55,
                        get = function(info) return QuestieOptions:GetProfileValue(info); end,
                        set = function (info, value)
                            QuestieOptions:SetProfileValue(info, value)

                            WorldMapButton.Toggle(value)
                        end,
                    },
                    minimapButtonEnabled = {
                        type = "toggle",
                        order = 5.3,
                        name = function() return l10n('Enable Minimap Button'); end,
                        desc = function() return l10n('Enable or disable the Questie minimap button. You can still access the options menu with /questie.'); end,
                        width = 1.55,
                        get = function() return not Questie.db.profile.minimap.hide; end,
                        set = function(info, value)
                            Questie.db.profile.minimap.hide = not value;

                            if value then
                                Questie.minimapConfigIcon:Show("Questie");
                            else
                                Questie.minimapConfigIcon:Hide("Questie");
                            end
                        end,
                    },
                    mapCoordinatesEnabled = {
                        type = "toggle",
                        order = 5.4,
                        name = function() return l10n('Show Map Coordinates'); end,
                        desc = function() return l10n("Place the Player's coordinates and Cursor's coordinates on the Map's title."); end,
                        width = 1.55,
                        get = function(info) return QuestieOptions:GetProfileValue(info); end,
                        set = function (info, value)
                            QuestieOptions:SetProfileValue(info, value)

                            if not value then
                                QuestieCoords:ResetMapText();
                                QuestieCoords:ResetMiniWorldMapText();
                            end
                        end,
                    },
                    minimapCoordinatesEnabled = {
                        type = "toggle",
                        order = 5.5,
                        name = function() return l10n('Show Minimap Coordinates'); end,
                        desc = function() return l10n("Place the Player's coordinates on the Minimap title."); end,
                        width = 1.55,
                        get = function(info) return QuestieOptions:GetProfileValue(info); end,
                        set = function (info, value)
                            QuestieOptions:SetProfileValue(info, value)

                            if not value then
                                QuestieCoords:ResetMinimapText();
                            end
                        end,
                    },
                    mapCoordinatePrecision = {
                        type = "range",
                        order = 5.6,
                        name = function() return l10n('Map Coordinates Decimal Precision'); end,
                        desc = function() return l10n('How many decimals to include in the precision on the Map for Player and Cursor coordinates.\n(Default: %s)', optionsDefaults.profile.mapCoordinatePrecision); end,
                        width = 1.4,
                        min = 0,
                        max = 5,
                        step = 1,
                        disabled = function() return not Questie.db.profile.mapCoordinatesEnabled end,
                        get = function(info) return QuestieOptions:GetProfileValue(info); end,
                        set = function (info, value)
                            QuestieOptions:SetProfileValue(info, value)
                        end,
                    },
                },
            },
            level_spacer = QuestieOptionsUtils:Spacer(3.5,nil,"minimal"),
            level_options_group = {
                type = "group",
                order = 4,
                inline = true,
                name = function() return l10n('Quest Level Options'); end,
                args = {
                    level_text = {
                        type = "description",
                        order = 1,
                        name = function() return Questie:Colorize(l10n('By default, Questie only shows quests that are relevant for your level. You can change this behavior below.'), 'gray'); end,
                        fontSize = "small",
                    },
                    level_spacer = QuestieOptionsUtils:Spacer(2),
                    radio = {
                        order = 3.0,
                        type = "select",
                        style = "radio",
                        width = 3,
                        name = l10n("Which available quests should be displayed"),
                        values = {
                            [Questie.LOWLEVEL_NONE] = l10n("Show only quests granting experience (Default)"),
                            [Questie.LOWLEVEL_ALL] = l10n("Show all low level quests"),
                            [Questie.LOWLEVEL_OFFSET] = l10n("Show quests to a set level below the player"),
                            [Questie.LOWLEVEL_RANGE] = l10n("Show quests between two set levels"),
                        },
                        get = function () return Questie.db.profile.lowLevelStyle end,
                        set = function (_, value)
                            Questie.db.profile.lowLevelStyle = value
                            AvailableQuests.ResetLevelRequirementCache()
                            AvailableQuests.CalculateAndDrawAll()
                            Questie:Debug(Questie.DEBUG_DEVELOP, "Lowlevel Quests set to:", value)
                        end,
                    },
                    manualOffset = {
                        type = "range",
                        order = 3.1,
                        name = function() return l10n('Player level offset'); end,
                        desc = function()
                            return l10n('How many levels below your character to show. ( Default: %s )', optionsDefaults.profile.manualLevelOffset);
                        end,
                        width = 1.063,
                        min = 0,
                        max = 60 + 10 * GetExpansionLevel(),
                        step = 1,
                        disabled = function() return (Questie.db.profile.lowLevelStyle ~= Questie.LOWLEVEL_OFFSET) end,
                        get = function() return Questie.db.profile.manualLevelOffset end,
                        set = function(info, value)
                            Questie.db.profile.manualLevelOffset = value;
                            QuestieOptionsUtils:Delay(0.3, function()
                                AvailableQuests.ResetLevelRequirementCache()
                                AvailableQuests.CalculateAndDrawAll()
                            end, "manualLevelOffset set to " .. value)
                        end,
                    },
                    minLevelFilter = {
                        type = "range",
                        order = 3.2,
                        name = function() return l10n('Level from'); end,
                        desc = function() return l10n('Minimum quest level to show.'); end,
                        width = 1.063,
                        min = 0,
                        max = 60 + 10 * GetExpansionLevel(),
                        step = 1,
                        disabled = function() return (Questie.db.profile.lowLevelStyle ~= Questie.LOWLEVEL_RANGE) end,
                        get = function() return Questie.db.profile.minLevelFilter; end,
                        set = function(info, value)
                            if value > Questie.db.profile.maxLevelFilter then
                                value = Questie.db.profile.maxLevelFilter
                            end
                            Questie.db.profile.minLevelFilter = value;
                            QuestieOptionsUtils:Delay(0.3, function()
                                AvailableQuests.ResetLevelRequirementCache()
                                AvailableQuests.CalculateAndDrawAll()
                            end, "minLevelFilter set to " .. value)
                        end,
                    },
                    maxLevelFilter = {
                        type = "range",
                        order = 3.3,
                        name = function()
                            return l10n('Level to');
                        end,
                        desc = function()
                            return l10n('Maximum quest level to show.');
                        end,
                        width = 1.063,
                        min = 0,
                        max = 60 + 10 * GetExpansionLevel(),
                        step = 1,
                        disabled = function() return (Questie.db.profile.lowLevelStyle ~= Questie.LOWLEVEL_RANGE) end,
                        get = function(info) return Questie.db.profile.maxLevelFilter; end,
                        set = function(info, value)
                            if value < Questie.db.profile.minLevelFilter then
                                value = Questie.db.profile.minLevelFilter
                            end
                            Questie.db.profile.maxLevelFilter = value;
                            QuestieOptionsUtils:Delay(0.3, function()
                                AvailableQuests.ResetLevelRequirementCache()
                                AvailableQuests.CalculateAndDrawAll()
                            end, "maxLevelFilter set to " .. value)
                        end,
                    },
                },
            },
            tooltip_spacer = QuestieOptionsUtils:Spacer(4.5,nil,"minimal"),
            tooltip_options_group = {
                type = "group",
                order = 5,
                inline = true,
                name = function() return l10n('Tooltip Options'); end,
                args = {
                    enableTooltipsToggle = {
                        type = "toggle",
                        order = 8.1,
                        name = function() return l10n('Enable World Tooltips'); end,
                        desc = function() return l10n('When this is enabled, quest info will be added to relevant mob/item tooltips.'); end,
                        width = 1.5,
                        get = function () return Questie.db.profile.enableTooltips; end,
                        set = function (_, value) Questie.db.profile.enableTooltips = value end
                    },
                    questsInNpcTooltip = {
                        type = "toggle",
                        order = 8.2,
                        name = function() return l10n('Show quests in NPC tooltips'); end,
                        desc = function() return l10n('Show quests (available/complete) in the NPC tooltips.'); end,
                        width = 1.5,
                        disabled = function() return not Questie.db.profile.enableTooltips; end,
                        get = function () return Questie.db.profile.showQuestsInNpcTooltip; end,
                        set = function (_, value) Questie.db.profile.showQuestsInNpcTooltip = value end
                    },
                    showQuestLevels = {
                        type = "toggle",
                        order = 8.3,
                        name = function() return l10n('Show quest level in tooltips'); end,
                        desc = function() return l10n('When this is checked, the level of quests will show in the tooltips.'); end,
                        width = 1.5,
                        get = function() return Questie.db.profile.enableTooltipsQuestLevel; end,
                        set = function (_, value)
                            Questie.db.profile.enableTooltipsQuestLevel = value
                            if value and not Questie.db.profile.trackerShowQuestLevel then
                                Questie.db.profile.trackerShowQuestLevel = true
                                QuestieTracker:Update()
                            end
                        end
                    },
                    questXpAtMaxLevel = {
                        type = "toggle",
                        order = 8.4,
                        name = function() return l10n('Show quest XP at max level'); end,
                        desc = function() return l10n('Shows the quest XP values on quests even at max level.'); end,
                        width = 1.5,
                        get = function () return Questie.db.profile.showQuestXpAtMaxLevel; end,
                        set = function (_, value) Questie.db.profile.showQuestXpAtMaxLevel = value end
                    },
                    showNextInChain = {
                        type = "toggle",
                        order = 8.5,
                        name = function() return l10n('Show next quests in chain'); end,
                        desc = function() return l10n('When this is checked, the next quests in the chain will show in the expanded map tooltips.'); end,
                        width = 1.5,
                        get = function() return Questie.db.profile.enableTooltipsNextInChain; end,
                        set = function (_, value)
                            Questie.db.profile.enableTooltipsNextInChain = value
                        end
                    },
                    showDropRates = {
                        type = "toggle",
                        order = 8.6,
                        name = function() return l10n("Show item drop rates"); end,
                        desc = function() return l10n("When this is checked, drop rates for quest objectives will show on mob tooltips."); end,
                        width = 1.5,
                        get = function() return Questie.db.profile.enableTooltipDroprates; end,
                        set = function (_, value)
                            Questie.db.profile.enableTooltipDroprates = value
                        end
                    },
                    partyOnlyToggle = {
                        type = "toggle",
                        order = 8.76,
                        name = function() return l10n("Only show party members"); end,
                        desc = function() return l10n("When this is enabled, shared quest info will only show players in your party."); end,
                        width = 1.5,
                        hidden = true, -- does this even do anything anymore after YELL removed?
                        get = function () return Questie.db.profile.onlyPartyShared; end,
                        set = function (_, value) Questie.db.profile.onlyPartyShared = value end
                    },
                },
            },
            sound_spacer = QuestieOptionsUtils:Spacer(5.5,nil,"minimal"),
            sound_options_group = {
                type = "group",
                order = 6,
                inline = true,
                name = function() return l10n('Sound Options'); end,
                args = {
                    questCompleteSound = {
                        type = "toggle",
                        order = 9.01,
                        name = function() return l10n('Quest completed'); end,
                        desc = function() return l10n('Play a short sound when completing a quest when it is ready to turn in.'); end,
                        width = 1.2,
                        get = function() return Questie.db.profile.soundOnQuestComplete; end,
                        set = function(_, value)
                            Questie.db.profile.soundOnQuestComplete = value
                        end,
                    },
                    questCompleteSoundButton = {
                        type = "execute",
                        order = 9.02,
                        name = "",
                        width = 0.5,
                        image = function()
                            return "Interface\\OptionsFrame\\VoiceChat-Play", 15, 15
                        end,
                        func = function()
                            PlaySoundFile(Sounds.GetSelectedSoundFile(Questie.db.profile.questCompleteSoundChoiceName), "Master")
                        end
                    },
                    questCompleteSoundChoice = {
                        type = "select",
                        order = 9.03,
                        values = _GetQuestSoundChoices(),
                        sorting = _GetQuestSoundChoicesSort(),
                        style = 'dropdown',
                        name = function() return l10n('Quest Complete Sound Selection') end,
                        desc = function() return l10n('The sound you hear when a quest is completed'); end,
                        get = function() return Questie.db.profile.questCompleteSoundChoiceName or "None"; end,
                        disabled = function() return (not Questie.db.profile.soundOnQuestComplete); end,
                        set = function(_, value)
                            Questie.db.profile.questCompleteSoundChoiceName = value
                        end,
                    },
                    soundLineBreak = {
                        type = "description",
                        name = " ",
                        width = 0.1,
                        order = 9.04,
                    },
                    objectiveCompleteSound = {
                        type = "toggle",
                        order = 9.05,
                        name = function() return l10n('Quest objective completed'); end,
                        desc = function() return l10n('Play a short sound when completing a quest objective.'); end,
                        width = 1.2,
                        get = function() return Questie.db.profile.soundOnObjectiveComplete; end,
                        set = function(_, value)
                            Questie.db.profile.soundOnObjectiveComplete = value
                        end,
                    },
                    objectiveCompleteSoundButton = {
                        type = "execute",
                        order = 9.06,
                        name = "",
                        width = 0.5,
                        image = function()
                            return "Interface\\OptionsFrame\\VoiceChat-Play", 15, 15
                        end,
                        func = function()
                            PlaySoundFile(Sounds.GetSelectedSoundFile(Questie.db.profile.objectiveCompleteSoundChoiceName), "Master")
                        end
                    },
                    objectiveCompleteSoundChoice = {
                        type = "select",
                        order = 9.07,
                        values = _GetObjectiveSoundChoices(),
                        sorting = _GetObjectiveSoundChoicesSort(),
                        style = 'dropdown',
                        name = function() return l10n('Objective Complete Sound Selection') end,
                        desc = function() return l10n('The sound you hear when an objective is completed'); end,
                        get = function() return  Questie.db.profile.objectiveCompleteSoundChoiceName; end,
                        disabled = function() return (not Questie.db.profile.soundOnObjectiveComplete); end,
                        set = function(_, value)
                            Questie.db.profile.objectiveCompleteSoundChoiceName = value
                        end,
                    },
                    objectiveProgressSound = {
                        type = "toggle",
                        order = 9.08,
                        name = function() return l10n('Quest objective progress'); end,
                        desc = function() return l10n('Play a short sound when making progress on a quest objective.'); end,
                        width = 1.2,
                        get = function() return Questie.db.profile.soundOnObjectiveProgress; end,
                        set = function(_, value)
                            Questie.db.profile.soundOnObjectiveProgress = value
                        end,
                    },
                    objectiveProgressSoundButton = {
                        type = "execute",
                        order = 9.09,
                        name = "",
                        width = 0.5,
                        image = function()
                            return "Interface\\OptionsFrame\\VoiceChat-Play", 15, 15
                        end,
                        func = function()
                            PlaySoundFile(Sounds.GetSelectedSoundFile(Questie.db.profile.objectiveProgressSoundChoiceName), "Master")
                        end
                    },
                    objectiveProgressSoundChoice = {
                        type = "select",
                        order = 9.10,
                        values = _GetObjectiveProgressSoundChoices(),
                        sorting = _GetObjectiveProgressSoundChoicesSort(),
                        style = 'dropdown',
                        name = function() return l10n('Objective Progress Sound Selection') end,
                        desc = function() return l10n('The sound you hear when you make progress on a quest objective'); end,
                        get = function() return  Questie.db.profile.objectiveProgressSoundChoiceName; end,
                        disabled = function() return (not Questie.db.profile.soundOnObjectiveProgress); end,
                        set = function(_, value)
                            Questie.db.profile.objectiveProgressSoundChoiceName = value
                        end,
                    },
                },
            },
        },
    }
end

_GetAnnounceChannels = function()
    return {
        ['disabled'] = l10n('Disabled'),
        ['party'] = l10n('Party'),
        ['raid'] = l10n('Raid'),
        ['both'] = l10n('Both'),
    }
end

---@return boolean
_IsAnnounceDisabled = function()
    return (not Questie.db.profile.questAnnounceChannel) or (Questie.db.profile.questAnnounceChannel == "disabled")
end

_GetQuestSoundChoices = function()
    return {
        ["QuestDefault"]     = "Default",
        ["GameDefault"]      = "Game Default",
        ["Troll Male"]       = "Troll Male",
        ["Troll Female"]     = "Troll Female",
        ["Tauren Male"]      = "Tauren Male",
        ["Tauren Female"]    = "Tauren Female",
        ["Undead Male"]      = "Undead Male",
        ["Undead Female"]    = "Undead Female",
        ["Orc Male"]         = "Orc Male",
        ["Orc Female"]       = "Orc Female",
        ["Night Elf Female"] = "Night Elf Female",
        ["Night Elf Male"]   = "Night Elf Male",
        ["Human Female"]     = "Human Female",
        ["Human Male"]       = "Human Male",
        ["Gnome Male"]       = "Gnome Male",
        ["Gnome Female"]     = "Gnome Female",
        ["Dwarf Male"]       = "Dwarf Male",
        ["Dwarf Female"]     = "Dwarf Female",
        ["Draenei Male"]     = "Draenei Male",
        ["Draenei Female"]   = "Draenei Female",
        ["Blood Elf Female"] = "Blood Elf Female",
        ["Blood Elf Male"]   = "Blood Elf Male",
    }
end

_GetQuestSoundChoicesSort = function()
    return {
        "QuestDefault",
        "GameDefault",
        "Troll Male",
        "Troll Female",
        "Tauren Male",
        "Tauren Female",
        "Undead Male",
        "Undead Female",
        "Orc Male",
        "Orc Female",
        "Night Elf Female",
        "Night Elf Male",
        "Human Female",
        "Human Male",
        "Gnome Male",
        "Gnome Female",
        "Dwarf Male",
        "Dwarf Female",
        "Draenei Male",
        "Draenei Female",
        "Blood Elf Female",
        "Blood Elf Male",
    }
end

_GetObjectiveSoundChoices = function()
    local choices = {
        ["ObjectiveDefault"]   = "Default",
        ["Map Ping"]           = "Map Ping",
        ["Window Close"]       = "Window Close",
        ["Window Open"]        = "Window Open",
        ["Boat Docked"]        = "Boat Docked",
        ["Bell Toll Alliance"] = "Bell Toll Alliance",
        ["Bell Toll Horde"]    = "Bell Toll Horde",
    }
    if Questie.IsWotlk or QuestieCompat.Is335 then
        choices["Explosion"] = "Explosion"
        choices["Shing!"] = "Shing!"
        choices["Wham!"] = "Wham!"
        choices["Simon Chime"] = "Simon Chime"
        choices["War Drums"] = "War Drums"
        choices["Humm"] = "Humm"
        choices["Short Circuit"] = "Short Circuit"
    end
    return choices
end

_GetObjectiveSoundChoicesSort = function()
    local sorting = {
        "ObjectiveDefault",
        "Map Ping",
        "Window Close",
        "Window Open",
        "Boat Docked",
        "Bell Toll Alliance",
        "Bell Toll Horde",
    }
    if Questie.IsWotlk or QuestieCompat.Is335 then
        tinsert(sorting, "Explosion")
        tinsert(sorting, "Shing!")
        tinsert(sorting, "Wham!")
        tinsert(sorting, "Simon Chime")
        tinsert(sorting, "War Drums")
        tinsert(sorting, "Humm")
        tinsert(sorting, "Short Circuit")
    end
    return sorting
end

_GetObjectiveProgressSoundChoices = function()
    local choices = {
        ["ObjectiveProgress"]  = "Default",
        ["ObjectiveDefault"]   = "Objective Complete",
        ["Map Ping"]           = "Map Ping",
        ["Window Close"]       = "Window Close",
        ["Window Open"]        = "Window Open",
        ["Boat Docked"]        = "Boat Docked",
        ["Bell Toll Alliance"] = "Bell Toll Alliance",
        ["Bell Toll Horde"]    = "Bell Toll Horde",
    }
    if Questie.IsWotlk or QuestieCompat.Is335 then
        choices["Explosion"] = "Explosion"
        choices["Shing!"] = "Shing!"
        choices["Wham!"] = "Wham!"
        choices["Simon Chime"] = "Simon Chime"
        choices["War Drums"] = "War Drums"
        choices["Humm"] = "Humm"
        choices["Short Circuit"] = "Short Circuit"
    end
    return choices
end

_GetObjectiveProgressSoundChoicesSort = function()
    local sorting = {
        "ObjectiveProgress",
        "ObjectiveDefault",
        "Map Ping",
        "Window Close",
        "Window Open",
        "Boat Docked",
        "Bell Toll Alliance",
        "Bell Toll Horde",
    }
    if Questie.IsWotlk or QuestieCompat.Is335 then
        tinsert(sorting, "Explosion")
        tinsert(sorting, "Shing!")
        tinsert(sorting, "Wham!")
        tinsert(sorting, "Simon Chime")
        tinsert(sorting, "War Drums")
        tinsert(sorting, "Humm")
        tinsert(sorting, "Short Circuit")
    end
    return sorting
end
