-- Copyright © 2024 @Groick (Twitch). All rights reserved.
local function L(key, ...) return EasyOptions:Localize(key, ...) end

local m_SlashCommandArgsDelimiter = "|"

local m_EasyOptionsDataKey = "EasyOptionsData"
local m_AddonVersionKey = "AddonVersion"


function EasyOptions:SaveAddonSettings(addonName, saveName, allowPromptIfOverwrite, allowPrintMessage)
  if (EasyOptionsAddonSettingsDB[addonName] ~= nil) and (EasyOptionsAddonSettingsDB[addonName][saveName] ~= nil) and (EasyOptionsDB["PromptBeforeOverwritingExistingSave"]) and (allowPromptIfOverwrite) then
    -- Validate parameters before we prompt the user.
    if (not EasyOptions:SaveAddonSettings_CanSave(addonName, saveName)) then
      return
    end
    -- Prompt the user.
    local addonVersion = EasyOptions:GetAddonVersion(addonName, true)
    local addonAndVersionName = EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, false)
    local promptText = L("Do you want to overwrite {1} settings for \"{2}\"?", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName))
    local uniqueID = "EasyOptions.SaveAddonSettings"
    local onAcceptHandler = function(userText)
      EasyOptions:SaveAddonSettings_Save(addonName, saveName, allowPrintMessage)
    end
    local onCancelHandler = nil
    EasyOptions:ShowDialogOkCancel(promptText, uniqueID, onAcceptHandler, onCancelHandler)
  else
    -- Save without prompting the user.
    EasyOptions:SaveAddonSettings_Save(addonName, saveName, allowPrintMessage)
  end
end
function EasyOptions:SaveAddonSettings_Save(addonName, saveName, allowPrintMessage)
  -- Validate parameters.
  --  IMPORTANT: We must validate parameters in this method even if the parameters were validated in EasyOptions:LoadAddonSettings in case changes were made while a confirmation dialog was shown (e.g., the user clicks the "Save As..." button and then clicks and accepts "Save As..." again before they accept the initial "Save As..." dialog).
  if (not EasyOptions:SaveAddonSettings_CanSave(addonName, saveName)) then
    return
  end

  local addonVersion = EasyOptions:GetAddonVersion(addonName, true)
  local addonAndVersionName = EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, false)
  --
  local addonInfo = EasyOptions.Fields.AddonInfo[addonName] -- [AddonName] = {AddonName, AddonDB, OptionItems, OptionItemsDictionary, MainOptionPanelFrame, OptionPanelFrames, OptionControls, OptionControlCounts, OnOptionValueChangedHandler (Optional), OnOptionValuesChangingHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionPanelFrameShowHandler (Optional), IsValidSaveDataVersionProvider (Optional)} -- Stores all data for each addon.
  local optionItemsDictionary = addonInfo.OptionItemsDictionary
  
  -- EasyOptions:PrintMessage(L("Saving {1} settings to \"{2}\"...", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
  
  local addonSettings = {}
  addonSettings[m_EasyOptionsDataKey] = {}
  addonSettings[m_EasyOptionsDataKey][m_AddonVersionKey] = addonVersion
  addonSettings[m_EasyOptionsDataKey]["OnlySaveSettingsSetToCustomValues"] = EasyOptionsDB["OnlySaveSettingsSetToCustomValues"]

  local optionName
  local optionItem
  local optionValue
  local numberOfSavedOptions = 0 -- init
  local numberOfOptionsTotal = 0 -- init
  for key, value in pairs(optionItemsDictionary) do -- Iterate through all key, value pairs in the table.
    optionName = key
    optionItem = value
    if (EasyOptions:ShouldSaveOptionItem(addonName, optionName)) then
      optionValue = EasyOptions:GetOptionValue(addonName, optionName)
      if (optionValue == nil) then
        optionValue = EasyOptions.Fields.NilValueIndicator -- IMPORTANT: We must set optionValue = EasyOptions.Fields.NilValueIndicator because setting addonSettings[optionName] = nil will remove the entry for optionName from addonSettings rather than store a value of nil for the optionName entry in addonSettings.
      end
      addonSettings[optionName] = optionValue
      numberOfSavedOptions = numberOfSavedOptions + 1
      -- EasyOptions:Print("  "..EasyOptions:FormatInteger(numberOfSavedOptions)..": "..optionName.." = "..EasyOptions:Format(optionValue))
    end
    numberOfOptionsTotal = numberOfOptionsTotal + 1
  end
  
  if (EasyOptionsAddonSettingsDB[addonName] == nil) then
    EasyOptionsAddonSettingsDB[addonName] = {}
  end
  EasyOptionsAddonSettingsDB[addonName][saveName] = addonSettings
  
  local allowUpdateControl = true
  EasyOptions:SetOptionValue("EasyOptions", "ActiveAddon", addonName, allowUpdateControl)
  EasyOptions:SetOptionValue("EasyOptions", "ActiveSaveName", saveName, allowUpdateControl)
  EasyOptions:UpdateAllAddonManagerControls()

  if (EasyOptionsDB["PrintMessageAfterSave"]) and (allowPrintMessage) then
    EasyOptions:PrintMessage(L("Saved {1} settings to \"{2}\".", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
  end
  -- EasyOptions:PrintMessage(L("Saved {1} of {2} {3} settings to \"{4}\".", EasyOptions:FormatInteger(numberOfSavedOptions), EasyOptions:FormatInteger(numberOfOptionsTotal), EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
end
function EasyOptions:SaveAddonSettings_CanSave(addonName, saveName)
  local allowPrintMessage = true
  local allowShowDialog = EasyOptionsDB["ShowDialogForErrorMessageDuringSave"]
  if (addonName == nil) or (addonName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to save options data because the specified addon name is nil or an empty string."), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(addonName) ~= "string") then
    EasyOptions:PrintErrorMessage(L("Unable to save options data because the specified addon name is of type {1}. The addon name must be a string.", type(addonName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (saveName == nil) or (saveName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to save options data for {1} because the specified save name is nil or an empty string.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(saveName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to save options data for {1} because the specified save name is of type {2}. The save name must be a string.", addonName, type(saveName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (not EasyOptions:IsManagedAddon(addonName)) then
    EasyOptions:HandleErrorMessage(L("Unable to save options for the addon \"{1}\" because that addon is not managed by EasyOptions.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  return true
end
function EasyOptions:SaveAddonSettings_HandleInvalidArgs()
  EasyOptions:PrintErrorMessage(L("Invalid format for save. The slash command must be in the following format:\n  {1}", EasyOptions:SaveAddonSettings_GetSampleFormat()))
end
function EasyOptions:SaveAddonSettings_GetSampleFormat()
  return "/EOSave AddonName|SaveName"
end

function EasyOptions:LoadAddonSettings(addonName, saveName, allowPromptBeforeLoad, allowPrintMessage)
  if (EasyOptionsDB["PromptBeforeLoad"]) and (allowPromptBeforeLoad) then
    -- Validate parameters before we prompt the user.
    if (not EasyOptions:LoadAddonSettings_CanLoad(addonName, saveName)) then
      return
    end
    -- Prompt the user.
    local addonVersion, onlySaveSettingsSetToCustomValues = EasyOptions:GetEasyOptionsAddonSettingsDBInfo(addonName, saveName)
    local addonAndVersionName = EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, false)
    -- local addonVersionCurrent = EasyOptions:GetAddonVersion(addonName, true)
    -- local hasAddonVersionChanged = (addonVersion ~= addonVersionCurrent)
    local promptText = L("Do you want to load {1} settings from \"{2}\"?\n\nThis will overwrite the current settings for that addon and cannot be undone.", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName))
    -- if (hasAddonVersionChanged) then
    --   promptText = promptText..L("\n\nNote that the version of {1} has changed from {2} to {3} since \"{4}\" was saved.", EasyOptions:FormatName(addonName), EasyOptions:Format(addonVersion), EasyOptions:Format(addonVersionCurrent), EasyOptions:FormatName(saveName))
    -- end
    local uniqueID = "EasyOptions.LoadAddonSettings"
    local onAcceptHandler = function(userText)
      EasyOptions:LoadAddonSettings_Load(addonName, saveName, allowPrintMessage)
    end
    local onCancelHandler = nil
    EasyOptions:ShowDialogOkCancel(promptText, uniqueID, onAcceptHandler, onCancelHandler)
  else
    -- Load without prompting the user.
    EasyOptions:LoadAddonSettings_Load(addonName, saveName, allowPrintMessage)
  end
end
function EasyOptions:LoadAddonSettings_Load(addonName, saveName, allowPrintMessage)
  -- Validate parameters.
  --  IMPORTANT: We must validate parameters in this method even if the parameters were validated in EasyOptions:LoadAddonSettings in case changes were made while a confirmation dialog was shown (e.g., the user clicks the "Load" button and then clicks and accepts "Delete" before they accept the "Load" dialog).
  if (not EasyOptions:LoadAddonSettings_CanLoad(addonName, saveName)) then
    return
  end

  local addonVersion, onlySaveSettingsSetToCustomValues = EasyOptions:GetEasyOptionsAddonSettingsDBInfo(addonName, saveName)
  local addonAndVersionName = EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, false)
  --
  local addonInfo = EasyOptions.Fields.AddonInfo[addonName] -- [AddonName] = {AddonName, AddonDB, OptionItems, OptionItemsDictionary, MainOptionPanelFrame, OptionPanelFrames, OptionControls, OptionControlCounts, OnOptionValueChangedHandler (Optional), OnOptionValuesChangingHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionPanelFrameShowHandler (Optional), IsValidSaveDataVersionProvider (Optional)} -- Stores all data for each addon.
  local optionItemsDictionary = addonInfo.OptionItemsDictionary
  --
  local addonSettings = EasyOptionsAddonSettingsDB[addonName][saveName]
  
  -- EasyOptions:PrintMessage(L("Loading {1} settings from \"{2}\"...", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
  
  local previousAreOptionValuesChanging
  if (EasyOptions:IsManagedAddon(addonName)) then
    previousAreOptionValuesChanging = EasyOptions.Fields.AreOptionValuesChanging[addonName] or false
    EasyOptions:SetAreOptionValuesChanging(addonName, true)
  end

  local optionName
  local optionItem
  local optionValue
  local allowUpdateControl = true
  local numberOfLoadedOptions = 0 -- init
  local numberOfOptionsTotal = 0 -- init
  for key, value in pairs(optionItemsDictionary) do -- Iterate through all key, value pairs in the table.
    optionName = key
    optionItem = value
    optionValue = addonSettings[optionName]
    if (optionValue ~= nil) then
      if (optionValue == EasyOptions.Fields.NilValueIndicator) then
        optionValue = nil -- IMPORTANT: We must set optionValue to nil if its saved value is EasyOptions.Fields.NilValueIndicator.
      end
      EasyOptions:SetOptionValue(addonName, optionName, optionValue, allowUpdateControl)
      numberOfLoadedOptions = numberOfLoadedOptions + 1
      -- EasyOptions:Print("  "..EasyOptions:FormatInteger(numberOfLoadedOptions)..": "..optionName.." = "..EasyOptions:Format(optionValue))
    elseif (onlySaveSettingsSetToCustomValues) then
      EasyOptions:SetOptionValueToDefaultValue(addonName, optionName, allowUpdateControl) -- IMPORTANT: We must reset options that are not contained in addonSettings so all options will be set to the appropriate value if EasyOptionsDB["OnlySaveSettingsSetToCustomValues"] was true when the options were saved (i.e., option values that were not set to their default value were not saved) in which case we assume that all option items that do not have an entry in addonSettings should be set to their default value.
    end
    numberOfOptionsTotal = numberOfOptionsTotal + 1
  end
  
  if (EasyOptions:IsManagedAddon(addonName)) then
    EasyOptions:SetAreOptionValuesChanging(addonName, previousAreOptionValuesChanging)
  end
  
  local allowUpdateControl = true
  EasyOptions:SetOptionValue("EasyOptions", "ActiveAddon", addonName, allowUpdateControl)
  EasyOptions:SetOptionValue("EasyOptions", "ActiveSaveName", saveName, allowUpdateControl)
  EasyOptions:UpdateAllAddonManagerControls()

  if (EasyOptionsDB["PrintMessageAfterLoad"]) and (allowPrintMessage) then
    EasyOptions:PrintMessage(L("Loaded {1} settings from \"{2}\".", EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
  end
  -- EasyOptions:PrintMessage(L("Loaded {1} of {2} {3} settings from \"{4}\".", EasyOptions:FormatInteger(numberOfLoadedOptions), EasyOptions:FormatInteger(numberOfOptionsTotal), EasyOptions:FormatName(addonAndVersionName), EasyOptions:FormatName(saveName)))
end
function EasyOptions:LoadAddonSettings_CanLoad(addonName, saveName)
  local allowPrintMessage = true
  local allowShowDialog = EasyOptionsDB["ShowDialogForErrorMessageDuringLoad"]
  if (addonName == nil) or (addonName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to load options data because the specified addon name is nil or an empty string."), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(addonName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to load options data because the specified addon name is of type {1}. The addon name must be a string.", type(addonName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (saveName == nil) or (saveName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to load options data for {1} because the specified save name is nil or an empty string.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(saveName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to load options data for {1} because the specified save name is of type {2}. The save name must be a string.", addonName, type(saveName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (not EasyOptions:IsManagedAddon(addonName)) then
    EasyOptions:HandleErrorMessage(L("Unable to load options for the addon {1} because that addon is not managed by EasyOptions.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (EasyOptionsAddonSettingsDB[addonName] == nil) or (EasyOptionsAddonSettingsDB[addonName][saveName] == nil) then
    EasyOptions:HandleErrorMessage(L("Unable to load \"{1}\" for the addon {2} because no options with that name exist.", saveName, addonName), allowPrintMessage, allowShowDialog)
    return false
  end

  local addonInfo = EasyOptions.Fields.AddonInfo[addonName] -- [AddonName] = {AddonName, AddonDB, OptionItems, OptionItemsDictionary, MainOptionPanelFrame, OptionPanelFrames, OptionControls, OptionControlCounts, OnOptionValueChangedHandler (Optional), OnOptionValuesChangingHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionValuesChangedHandler (Optional), OnOptionPanelFrameShowHandler (Optional), IsValidSaveDataVersionProvider (Optional)} -- Stores all data for each addon.
  local addonVersion, onlySaveSettingsSetToCustomValues = EasyOptions:GetEasyOptionsAddonSettingsDBInfo(addonName, saveName)
  local addonAndVersionName = EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, false)
  local addonVersionCurrent = EasyOptions:GetAddonVersion(addonName, true)
  if (addonInfo.IsValidSaveDataVersionProvider ~= nil) and (not addonInfo:IsValidSaveDataVersionProvider(addonVersion)) then
    EasyOptions:HandleErrorMessage(L("Unable to load \"{1}\" for the addon {2} because the current version of {3} ({4}) does not support data that were saved in version {5}.", saveName, addonAndVersionName, addonName, addonVersionCurrent, EasyOptions:GetAddonVersionString(addonVersion, true)))
    return false
  end

  return true
end
function EasyOptions:LoadAddonSettings_HandleInvalidArgs()
  EasyOptions:PrintErrorMessage(L("Invalid format for load. The slash command must be in the following format:\n  {1}", EasyOptions:LoadAddonSettings_GetSampleFormat()))
end
function EasyOptions:LoadAddonSettings_GetSampleFormat()
  return "/EOLoad AddonName|SaveName"
end

function EasyOptions:DeleteAddonSettings(addonName, saveName, allowPromptBeforeDelete, allowPrintMessage)
  if (EasyOptionsDB["PromptBeforeDelete"]) and (allowPromptBeforeDelete) then
    -- Validate parameters before we prompt the user.
    if (not EasyOptions:DeleteAddonSettings_CanDelete(addonName, saveName)) then
      return
    end
    -- Prompt the user.
    local promptText = L("Do you want to delete \"{1}\" settings for {2}?\n\nThis operation cannot be undone.", EasyOptions:FormatName(saveName), EasyOptions:FormatName(addonName))
    local uniqueID = "EasyOptions.DeleteAddonSettings"
    local onAcceptHandler = function(userText)
      EasyOptions:DeleteAddonSettings_Delete(addonName, saveName, allowPrintMessage)
    end
    local onCancelHandler = nil
    EasyOptions:ShowDialogOkCancel(promptText, uniqueID, onAcceptHandler, onCancelHandler)
  else
    -- Delete without prompting the user.
    EasyOptions:DeleteAddonSettings_Delete(addonName, saveName, allowPrintMessage)
  end
end
function EasyOptions:DeleteAddonSettings_Delete(addonName, saveName, allowPrintMessage)
  -- Validate parameters.
  --  IMPORTANT: We must validate parameters in this method even if the parameters were validated in EasyOptions:LoadAddonSettings in case changes were made while a confirmation dialog was shown (e.g., the user clicks the "Delete" button and then clicks and accepts "Delete" again before they accept the initial "Delete" dialog).
  if (not EasyOptions:DeleteAddonSettings_CanDelete(addonName, saveName)) then
    return
  end

  -- EasyOptions:PrintMessage(L("Deleting \"{1}\" settings for {2}...", EasyOptions:FormatName(saveName), EasyOptions:FormatName(addonName)))

  EasyOptionsAddonSettingsDB[addonName][saveName] = nil
  
  local allowUpdateControl = true
  EasyOptions:SetOptionValue("EasyOptions", "ActiveAddon", addonName, allowUpdateControl)
  -- EasyOptions:SetOptionValue("EasyOptions", "ActiveSaveName", nil, allowUpdateControl) -- Do not clear the OptionValue for "ActiveSaveName" because doing so will clear the selected item in the corresponding DropDown control which will then prevent us from selecting an adjacent item in the DropDown's list after the current item is removed from the list.
  EasyOptions:UpdateAllAddonManagerControls()

  if (EasyOptionsDB["PrintMessageAfterDelete"]) and (allowPrintMessage) then
    EasyOptions:PrintMessage(L("Deleted \"{1}\" settings for {2}.", EasyOptions:FormatName(saveName), EasyOptions:FormatName(addonName)))
  end
  -- EasyOptions:PrintMessage(L("Deleted \"{1}\" settings for {2}.", EasyOptions:FormatName(saveName), EasyOptions:FormatName(addonName)))
end
function EasyOptions:DeleteAddonSettings_CanDelete(addonName, saveName)
  local allowPrintMessage = true
  local allowShowDialog = EasyOptionsDB["ShowDialogForErrorMessageDuringDelete"]
  if (addonName == nil) or (addonName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data because the specified addon name is nil or an empty string."), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(addonName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data because the specified addon name is of type {1}. The addon name must be a string.", type(addonName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (saveName == nil) or (saveName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data for {1} because the specified save name is nil or an empty string.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(saveName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data for {1} because the specified save name is of type {2}. The save name must be a string.", addonName, type(saveName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (not EasyOptions:IsManagedAddon(addonName)) then
    EasyOptions:HandleErrorMessage(L("Unable to delete options for the addon {1} because that addon is not managed by EasyOptions.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (EasyOptionsAddonSettingsDB[addonName] == nil) or (EasyOptionsAddonSettingsDB[addonName][saveName] == nil) then
    EasyOptions:HandleErrorMessage(L("Unable to delete \"{1}\" for the addon {2} because no options with that name exist.", saveName, addonName), allowPrintMessage, allowShowDialog)
    return false
  end

  return true
end
function EasyOptions:DeleteAddonSettings_HandleInvalidArgs()
  EasyOptions:PrintErrorMessage(L("Invalid format for delete. The slash command must be in the following format:\n  {1}", EasyOptions:DeleteAddonSettings_GetSampleFormat()))
end
function EasyOptions:DeleteAddonSettings_GetSampleFormat()
  return "/EODelete AddonName|SaveName"
end

function EasyOptions:DeleteAllAddonSettings(addonName)
  -- Validate parameters before we prompt the user.
  if (not EasyOptions:DeleteAllAddonSettings_CanDeleteAll(addonName)) then
    return
  end
  -- Prompt the user.
  local promptText = L("Do you want to delete all saved options data for {1}?\n\nThis operation cannot be undone.", EasyOptions:FormatName(addonName))
  local uniqueID = "EasyOptions.DeleteAllAddonSettings"
  local onAcceptHandler = function(userText)
    local allowPrintMessage = true
    EasyOptions:DeleteAllAddonSettings_DeleteAll(addonName, allowPrintMessage)
  end
  local onCancelHandler = nil
  EasyOptions:ShowDialogOkCancel(promptText, uniqueID, onAcceptHandler, onCancelHandler)
end
function EasyOptions:DeleteAllAddonSettings_DeleteAll(addonName, allowPrintMessage)
  -- Validate parameters.
  --  IMPORTANT: We must validate parameters in this method even if the parameters were validated in EasyOptions:LoadAddonSettings in case changes were made while a confirmation dialog was shown (e.g., the user clicks the "Delete All" button and then clicks and accepts "Delete All" again before they accept the initial "Delete All" dialog).
  if (not EasyOptions:DeleteAllAddonSettings_CanDeleteAll(addonName)) then
    return
  end

  -- EasyOptions:PrintMessage(L("Deleting all saved options data for {1}...", EasyOptions:FormatName(addonName)))
  
  EasyOptionsAddonSettingsDB[addonName] = nil
  
  local allowUpdateControl = true
  EasyOptions:SetOptionValue("EasyOptions", "ActiveAddon", addonName, allowUpdateControl)
  EasyOptions:SetOptionValue("EasyOptions", "ActiveSaveName", nil, allowUpdateControl)
  EasyOptions:UpdateAllAddonManagerControls()

  if (EasyOptionsDB["PrintMessageAfterDelete"]) and (allowPrintMessage) then
    EasyOptions:PrintMessage(L("Deleted all saved options data for {1}.", EasyOptions:FormatName(addonName)))
  end
  -- EasyOptions:PrintMessage(L("Deleted all saved options data for {1}.", EasyOptions:FormatName(addonName)))
end
function EasyOptions:DeleteAllAddonSettings_CanDeleteAll(addonName)
  local allowPrintMessage = true
  local allowShowDialog = EasyOptionsDB["ShowDialogForErrorMessageDuringDelete"]
  if (addonName == nil) or (addonName == "") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data because the specified addon name is nil or an empty string."), allowPrintMessage, allowShowDialog)
    return false
  end
  if (type(addonName) ~= "string") then
    EasyOptions:HandleErrorMessage(L("Unable to delete options data because the specified addon name is of type {1}. The addon name must be a string.", type(addonName)), allowPrintMessage, allowShowDialog)
    return false
  end
  if (not EasyOptions:IsManagedAddon(addonName)) then
    EasyOptions:HandleErrorMessage(L("Unable to delete options for the addon {1} because that addon is not managed by EasyOptions.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end
  if (EasyOptionsAddonSettingsDB[addonName] == nil) then
    EasyOptions:HandleErrorMessage(L("Unable to delete options for the addon {1} because no saved options exist for that addon.", addonName), allowPrintMessage, allowShowDialog)
    return false
  end

  return true
end

function EasyOptions:SaveBackupOfAddonSettings(addonName, allowPrintMessage)
  local saveName = EasyOptions:GetNextAvailableBackupSaveName(addonName)
  local allowPromptIfOverwrite = true -- We never expect an overwrite to be necessary.
  EasyOptions:SaveAddonSettings(addonName, saveName, allowPromptIfOverwrite, allowPrintMessage)
end
function EasyOptions:GetBackupSaveName(index)
  return L("Backup").." "..string.format("%02i", index) -- Example: "Backup 01"
end
function EasyOptions:GetNextAvailableBackupSaveName(addonName)
  local index = 1
  local saveName = EasyOptions:GetBackupSaveName(index)
  if (addonName == nil) or (EasyOptionsAddonSettingsDB[addonName] == nil) then
    return saveName
  end
  while (EasyOptionsAddonSettingsDB[addonName][saveName] ~= nil) do
    index = index + 1
    saveName = EasyOptions:GetBackupSaveName(index)
  end
  return saveName
end

function EasyOptions:GetSlashCommandArgsForManageAddonSettings(msg) -- areValidArgs, addonName, saveName
  local args, msgLocal = EasyOptions:GetSlashCommandArgs(msg, m_SlashCommandArgsDelimiter)
  return EasyOptions:AreValidArgsForManageAddonSettings(args)
end

function EasyOptions:GetAddonAndVersionNameForManageAddonSettings(addonName, addonVersion, forceIncludeVersion)
  if (addonName == nil) then
    return ""
  end

  local addonVersionCurrent = EasyOptions:GetAddonVersion(addonName, true)
  if (addonVersion == nil) or ((addonVersion == addonVersionCurrent) and (not forceIncludeVersion)) then
    return addonName -- Don't include version information if the reference addon version is the same as the current addon version.
  else
    return L("{1} (Version {2})", addonName, EasyOptions:Format(addonVersion))
  end
end

function EasyOptions:GetEasyOptionsAddonSettingsDBInfo(addonName, saveName) -- addonVersion, onlySaveSettingsSetToCustomValues
  if (EasyOptionsAddonSettingsDB[addonName] == nil) or (EasyOptionsAddonSettingsDB[addonName][saveName] == nil) then
    return nil, nil
  end
  local addonSettings = EasyOptionsAddonSettingsDB[addonName][saveName]
  local addonVersion = nil -- init
  local onlySaveSettingsSetToCustomValues = true -- init
  if (addonSettings[m_EasyOptionsDataKey] ~= nil) then
    if (addonSettings[m_EasyOptionsDataKey][m_AddonVersionKey] ~= nil) then
      addonVersion = addonSettings[m_EasyOptionsDataKey][m_AddonVersionKey]
    end
    if (addonSettings[m_EasyOptionsDataKey]["OnlySaveSettingsSetToCustomValues"] ~= nil) then
      onlySaveSettingsSetToCustomValues = addonSettings[m_EasyOptionsDataKey]["OnlySaveSettingsSetToCustomValues"]
    end
  end
  return addonVersion, onlySaveSettingsSetToCustomValues
end

function EasyOptions:AreValidArgsForManageAddonSettings(args) -- areValidArgs, addonName, saveName
  local length = EasyOptions:GetLength(args)
  if (length ~= 2) then
    return false, nil, nil
  end
  if (type(args[1]) ~= "string") or (args[1] == "") or (type(args[2]) ~= "string") or (args[2] == "") then
    return false, nil, nil
  end
  return true, args[1], args[2]
end

function EasyOptions:ShouldSaveOptionItem(addonName, optionName)
  if (not EasyOptions:IsManagedAddon(addonName)) then
    return false
  end

  local optionItem = EasyOptions:GetOptionItem(addonName, optionName)
  if (optionItem == nil) then
    return false
  end

  if (not EasyOptionsDB["OnlySaveSettingsSetToCustomValues"]) then
    return true
  else
    return (not EasyOptions:IsOptionValueSetToDefaultValue(optionItem))
  end
end

function EasyOptions:UpdateAllAddonManagerControls()
  EasyOptions:UpdateActiveAddonDropDown()
  EasyOptions:UpdateActiveSaveNameDropDown()
  EasyOptions:UpdateAddonManagerSlashCommandTextBox()
  EasyOptions:UpdateAddonManagerControlStates()
end
function EasyOptions:UpdateActiveAddonDropDown()
  local optionItem = EasyOptions:GetOptionItem("EasyOptions", "ActiveAddon")
  --
  local sortResult = true
  local ignoreCase = true
  local itemNames = EasyOptions:GetManagedAddonNames(sortResult, ignoreCase)
  --
  EasyOptions:UpdateAddonManagerDropDown(optionItem, itemNames)
end
function EasyOptions:UpdateActiveSaveNameDropDown()
  local optionItem = EasyOptions:GetOptionItem("EasyOptions", "ActiveSaveName")
  --
  -- Set the DropDown items to the SaveNames that exist for the addon that is selected in the "ActiveAddon" DropDown.
  local addonName = EasyOptionsDB["ActiveAddon"]
  local itemNames
  if (addonName == nil) or (addonName == "") then
    itemNames = nil
  else
    local addonSettings = EasyOptionsAddonSettingsDB[addonName]
    local sortResult = true
    local ignoreCase = true
    itemNames = EasyOptions:GetKeys(addonSettings, sortResult, ignoreCase)
  end
  --
  EasyOptions:UpdateAddonManagerDropDown(optionItem, itemNames)
end
function EasyOptions:UpdateAddonManagerDropDown(optionItem, itemNames)
  local control = optionItem.Control
  local dropDown = control.DropDown
  
  local dropDownItemInfos = itemNames -- NOTE: We assume that itemNames is a list of strings which is a valid format for DropDownItemInfos.
  local valueToSelect, indexToSelect = dropDown:GetValueToSelectAfterRemoveDropDownItem(dropDownItemInfos)

  local defaultValue = valueToSelect
  optionItem.DefaultValue = defaultValue

  -- Do not set the Enabled state in this method because the Enabled state of all controls is set in EasyOptions:UpdateAddonManagerControlStates.
  -- local enabled = (length >= 1)
  -- control:SetEnabled(enabled)

  local allowSetToDefaultValue = true
  dropDown:SetDropDownItemInfos(dropDownItemInfos, defaultValue, allowSetToDefaultValue)
end
function EasyOptions:UpdateAddonManagerSlashCommandTextBox()
  local optionItem = EasyOptions:GetOptionItem("EasyOptions", "AddonSettingsSlashCommand")
  
  local text = EasyOptions:GetDefaultAddonManagerSlashCommandText()
  optionItem.DefaultValue = text

  local allowUpdateControl = true
  EasyOptions:SetOptionValue("EasyOptions", "AddonSettingsSlashCommand", text, allowUpdateControl)
end
function EasyOptions:GetDefaultAddonManagerSlashCommandText()
  local addonName = EasyOptionsDB["ActiveAddon"]
  local saveName = EasyOptionsDB["ActiveSaveName"]
  if (addonName == nil) or (addonName == "") then
    addonName = "AddonName"
  end
  if (saveName == nil) or (saveName == "") then
    saveName = "SaveName"
  end
  return L("/EOLoad {1}||{2}", addonName, saveName) -- IMPORTANT: We must include two "|" characters in order to prevent a bug that can cause the output of some strings to have missing characters (e.g., "\\EOLoad AddonName|a" is output by the WoW API as "\\EOLoad AddonName|").
end
function EasyOptions:UpdateAddonManagerControlStates()
  local addonName = EasyOptionsDB["ActiveAddon"]
  local saveName = EasyOptionsDB["ActiveSaveName"]
  local hasAddonNames = (EasyOptions:GetLength(EasyOptions:GetOptionItem("EasyOptions", "ActiveAddon").Control.DropDown.DropDownItemInfos) >= 1)
  local hasSaveNames = (EasyOptions:GetLength(EasyOptions:GetOptionItem("EasyOptions", "ActiveSaveName").Control.DropDown.DropDownItemInfos) >= 1)
  local hasAddonName = (addonName ~= nil) and (addonName ~= "")
  local hasSaveName = (saveName ~= nil) and (saveName ~= "")
  local hasAddonNameAndSaveName = (hasAddonName and hasSaveName)
  local isDefaultSlashCommandText = (EasyOptions:GetOptionItem("EasyOptions", "AddonSettingsSlashCommand").Control:GetText() == EasyOptions:GetDefaultAddonManagerSlashCommandText())

  EasyOptions:GetOptionItem("EasyOptions", "ActiveAddon").Control:SetEnabled(hasAddonNames)
  EasyOptions:GetOptionItem("EasyOptions", "ActiveSaveName").Control:SetEnabled(hasSaveNames and hasAddonName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonSettingsSlashCommand").Control:SetEnabled(hasAddonNameAndSaveName)
  --
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_Save").Control:SetEnabled(hasAddonNameAndSaveName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_SaveAs").Control:SetEnabled(hasAddonName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_QuickBackup").Control:SetEnabled(hasAddonName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_ResetSlashCommand").Control:SetEnabled(hasAddonNameAndSaveName and (not isDefaultSlashCommandText))
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_Load").Control:SetEnabled(hasAddonNameAndSaveName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_Delete").Control:SetEnabled(hasAddonNameAndSaveName)
  EasyOptions:GetOptionItem("EasyOptions", "AddonManager_DeleteAll").Control:SetEnabled(hasAddonName and hasSaveNames)
end
