--- Configuration Preview Panel
--
local AddOnName, nsVars = ...
local ss = nsVars.SS

ss.ConfigPreview = {}

local type, next = type, next
local getglobal, tonumber, table = getglobal, tonumber, table
local pairs, string, getmetatable = pairs, string, getmetatable
local CustomDropDownMenu_SetSelectedID, CustomDropDownMenu_SetSelectedValue = CustomDropDownMenu_SetSelectedID, CustomDropDownMenu_SetSelectedValue
local CustomDropDownMenu_SetText, CloseCustomDropDownMenus = CustomDropDownMenu_SetText, CloseCustomDropDownMenus

local ColorPickerFrame = ColorPickerFrame
local GetScreenHeight, GetScreenWidth = GetScreenHeight, GetScreenWidth
local UIDropDownMenu_GetText = ss.APIUtils.UIDropDownMenu_GetText
local CreateFrame = ss.CreateFrame

local UnitInVehicle = UnitInVehicle or function()
  return false
end

--- Sets preview sphere value for the target propety.
-- @param self Reference to the slider.
--
local targetSliderSetValue = function(self)
  if self:IsVisible() then
    local target = UIDropDownMenu_GetText(ss.ConfigPreview.SliderTargetDropDown)

    if target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_scale"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimationScale(self:GetValue())
    elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_x_pos"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimationOffset(self:GetValue(), nil)
    elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_y_pos"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimationOffset(nil, self:GetValue())
    elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_strata"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.animation:SetFrameLevel((self:GetValue() + ss.private.layout.config.frameLevelAdjust) or 3)
    elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_alpha"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimationAlpha(self:GetValue())
    elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_x_pos"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetPos(nil, self:GetValue(), nil, true)
    elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_y_pos"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetPos(nil, nil, self:GetValue(), true)
    elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_animation_scale"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetGlobalScale(self:GetValue())
    elseif target == ss.T["menu_item_customize_swirl"] .. " - " .. ss.T["menu_item_customize_speed"] then
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlSpeed(self:GetValue())
    end

    if ss.ConfigPreview.SSTargetSliderEditBox then
      ss.ConfigPreview.SSTargetSliderEditBox:SetText(self:GetValue())
    end

    ss.ConfigPreview.ResetButton:Show()
    ss.ConfigPreview.CommitButton:Show()
  end
end

--- Returns the preview sphere value for the target propety.
-- @param target The target property.
-- @return The property value.
--
local targetSliderGetValue = function(target)
  if target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_scale"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animCamDist
  elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_x_pos"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animPosX
  elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_y_pos"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animPosY
  elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_strata"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.animation:GetFrameLevel() - ss.private.layout.config.frameLevelAdjust
  elseif target == ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_alpha"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animAlpha
  elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_x_pos"] then
    local _, x = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetPos(true)
    return x
  elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_y_pos"] then
    local _, _, y = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetPos(true)
    return y
  elseif target == ss.T["menu_item_customize_general"] .. " - " .. ss.T["menu_item_customize_animation_scale"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetGlobalScale()
  elseif target == ss.T["menu_item_customize_swirl"] .. " - " .. ss.T["menu_item_customize_speed"] then
    return ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirl1:GetSpeed()
  else
    return 1
  end
end

local configTargets = {
  [ss.T["menu_item_customize_swirl"]] = {
    ss.T["menu_item_customize_speed"],
    ss.T["menu_item_customize_color"],
    ss.T["menu_item_customize_color1"],
    ss.T["menu_item_customize_color2"],
    ss.T["menu_item_customize_color3"],
  },
  [ss.T["menu_item_customize_filling"]] = {
    ss.T["menu_item_customize_color"],
  },
  [ss.T["menu_item_customize_font_1"]] = {
    ss.T["menu_item_customize_color"],
  },
  [ss.T["menu_item_customize_font_2"]] = {
    ss.T["menu_item_customize_color"],
  },
  [ss.T["menu_item_customize_animation"]] = {
    ss.T["menu_item_customize_animation_alpha"],
    ss.T["menu_item_customize_animation_scale"],
    ss.T["menu_item_customize_animation_strata"],
    ss.T["menu_item_customize_x_pos"],
    ss.T["menu_item_customize_y_pos"],
  },
  [ss.T["menu_item_customize_general"]] = {
    ss.T["menu_item_customize_animation_scale"],
    ss.T["menu_item_customize_x_pos"],
    ss.T["menu_item_customize_y_pos"],
  },
  [ss.T["menu_item_load_values"]] = {},
};

local targetSliderValues = {
  [ss.T["menu_item_customize_swirl"]] = {
    [ss.T["menu_item_customize_speed"]] = {
      low = 1,
      high = 10,
      step = 1,
    },
  },
  [ss.T["menu_item_customize_animation"]] = {
    [ss.T["menu_item_customize_animation_alpha"]] = {
      low = 0,
      high = 1,
      step = 0.001,
    },
    [ss.T["menu_item_customize_animation_scale"]] = {
      low = 0.001,
      high = 10,
      step = 0.001,
    },
    [ss.T["menu_item_customize_animation_strata"]] = {
      low = 1,
      high = 5,
      step = 0.001,
    },
    [ss.T["menu_item_customize_x_pos"]] = {
      low = -2,
      high = 2,
      step = 0.001,
    },
    [ss.T["menu_item_customize_y_pos"]] = {
      low = -2,
      high = 2,
      step = 0.001,
    },
  },
  [ss.T["menu_item_customize_general"]] = {
    [ss.T["menu_item_customize_animation_scale"]] = {
      low = 50,
      high = 150,
      step = 1,
    },
    [ss.T["menu_item_customize_y_pos"]] = {
      low = 0,
      high = 1,
      step = 1,
    },
    [ss.T["menu_item_customize_x_pos"]] = {
      low = 0,
      high = 1,
      step = 1,
    },
  },
};

--- Default event handler for the target slider.
-- @param target The target event.
--
local configTargetRun = function(target)
  -- Generic event handler for string targetted behavior.
  if string.match(target, ss.T["menu_item_load_values"]) then
    -- Get the name of the copy.
    local copyName = string.gsub(target, "(" .. ss.T["menu_item_load_values"] .. "%s%-%s)", "")
    ss.ConfigPreview.loadCopy(copyName)
  end
end

--- Resets the target slider fields.
--
local resetSliderDropdown = function()
  ColorPickerFrame.elementToChange = ""
  ss.ConfigPreview.SSTargetSlider:Hide()
  ss.ConfigPreview.colorFields:Hide()
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:UpdateScale()
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:RefreshPos()

  CustomDropDownMenu_SetText(ss.ConfigPreview.SliderTargetDropDown, ss.T["menu_item_customize_configure"])
end

--- Displays or hides the fill texture frame.
--
local toggleFillTextureDropdown = function()
  -- Fix default value for fill texture dropdown
  if ss.ConfigPreview.FillTexturesDropDown and not ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2] then
    local text = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.fillId
    text = (text == 1) and ss.FillTextures.defaultId or text

    CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.FillTexturesDropDown, text)
    CustomDropDownMenu_SetText(ss.ConfigPreview.FillTexturesDropDown, text)
    ss.ConfigPreview.FillTexturesDropDown:Show()
    ss.ConfigPreview.FillTexturesDropDown.label:Show()
  else
    ss.ConfigPreview.FillTexturesDropDown:Hide()
    ss.ConfigPreview.FillTexturesDropDown.label:Hide()
  end
end

--- Sets the sphere's font text.
--
local updateXMLText = function()
  local configName = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName
  configName = configName == "vehicle" and "health" or configName
  configName = configName == "vehicleResource" and "mainResource" or configName

  if configName and ss.Layout.spheres[configName] then
    local text = ss.Layout.spheres[configName].sphere.font1:GetText()
    local text2 = ss.Layout.spheres[configName].sphere.font2:GetText()

    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setText(text)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setText2(text2)
  else
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setText("")
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setText2("")
  end
end

---
-- @param textFormat Sets the text format dropdown value.
--
local setTextFormatText = function(textFormat)
  if textFormat == "truncated" then
    textFormat = ss.T["text_format_truncate"]
  elseif textFormat == "commaSeparated" then
    textFormat = ss.T["text_format_comma"]
  else
    textFormat = ss.T["text_format_raw"]
  end

  CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.TextFormattingDropdown, textFormat)
  CustomDropDownMenu_SetText(ss.ConfigPreview.TextFormattingDropdown, textFormat)
end

--- Sets the layout field values.
--
local updateXMLTextures = function()
  local configName = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName

  if ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2] then
    ss.ConfigPreview.TextFormattingDropdown:Hide()
    ss.ConfigPreview.widgetFrame.SSSpherePercentageCheckBox:SetLabel(ss.T["chk_show_value_left"])
    ss.ConfigPreview.widgetFrame.SSSphereValueCheckBox:SetLabel(ss.T["chk_show_value_right"])

    configTargets[ss.T["menu_item_customize_filling"]] = {
      ss.T["menu_item_customize_color1"],
      ss.T["menu_item_customize_color2"],
    };
  else
    ss.ConfigPreview.TextFormattingDropdown:Show()
    ss.ConfigPreview.widgetFrame.SSSpherePercentageCheckBox:SetLabel(ss.T["chk_show_percentage"])
    ss.ConfigPreview.widgetFrame.SSSphereValueCheckBox:SetLabel(ss.T["chk_show_value"])

    configTargets[ss.T["menu_item_customize_filling"]] = {
      ss.T["menu_item_customize_color"],
    };
  end

  targetSliderValues[ss.T["menu_item_customize_general"]][ss.T["menu_item_customize_y_pos"]].high = GetScreenHeight() - ss.global.general.SphereSize
  targetSliderValues[ss.T["menu_item_customize_general"]][ss.T["menu_item_customize_x_pos"]].high = GetScreenWidth() - ss.global.general.SphereSize
  configTargets[ss.T["menu_item_customize_copy"]] = ss.ConfigPreview.copyMode

  -- set animation texture dropdown.
  if ss.ConfigPreview.RotationTexturesDropDown then
    CustomDropDownMenu_SetText(ss.ConfigPreview.RotationTexturesDropDown, ss.db[configName].animation.id)
  end

  -- set swirl texture dropdown text
  if ss.ConfigPreview.SwirlTexturesDropDown then
    CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)
    CustomDropDownMenu_SetText(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)
  end

  -- Fix default value for fill texture dropdown
  toggleFillTextureDropdown()

  if ss.ConfigPreview.TextFormattingDropdown then
    --set the selected value appropriately
    local textFormat = ss.db[configName].textFormat
    setTextFormatText(textFormat)
  end

  ss.ConfigPreview.widgetFrame.SSSpherePercentageCheckBox:SetChecked(ss.db[ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName].font[1].show)
  ss.ConfigPreview.widgetFrame.SSSphereValueCheckBox:SetChecked(ss.db[ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName].font[2].show)
end

--- Previews the selected resource.
-- @param label The title to display.
-- @param dbConfig The storage index.
--
local previewSphere = function(label, dbConfig)
  -- Reset unsaved scale change before changing resources.
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:UpdateScale()
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:RefreshPos()

  -- TODO: This needs adjusting to work for XML.
  ss.ConfigPreview.dbConfig = dbConfig
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setResource(ss.db[dbConfig])
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetMode(ss.db[dbConfig].modes[ss.profile.modeInfo[dbConfig].modeSpec].default, "default")

  if ss.ConfigPreview.widgetFrame.AnimatePreviewCheckBox:GetChecked() == true then
    ss.ConfigPreview.widgetFrame.AnimatePreviewCheckBox:Click()
  end

  updateXMLTextures()
  updateXMLText()
  resetSliderDropdown()

  ss.ConfigPreview.widgetFrame.Title:SetText(label)
  ss.ConfigPreview.widgetFrame.Title:SetTextColor(ss.ConfigTools.titleColor.r, ss.ConfigTools.titleColor.g, ss.ConfigTools.titleColor.b, ss.ConfigTools.titleColor.a)

  CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.ConfigSphereOptionsDropDown, "default")
  CustomDropDownMenu_SetText(ss.ConfigPreview.ConfigSphereOptionsDropDown, ss.T["mode_name_default"])
  ss.ConfigPreview.ResetButton:Hide()
  ss.ConfigPreview.CommitButton:Hide()
end

--- Sets the default preview values.
--
local initPreviewOption = function()
  CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.PreviewDropDown, ss.T["resource_name_health"])
  CustomDropDownMenu_SetText(ss.ConfigPreview.PreviewDropDown, ss.T["resource_name_health"])
  previewSphere(ss.T["resource_name_health"], "health")
end

--- Displayes the ColorSelect fields.
-- @param xmlElement The target color.
--
local showColorSelect = function(xmlElement)
  local r, g, b, a

  if xmlElement == ss.T["menu_item_customize_filling"] then
    local fillColor = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()
    r, g, b, a = ss.Utils:GetRGBAValues(fillColor[1])

    a = a or 1
  elseif xmlElement == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor()
  elseif xmlElement == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color1"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(1)
  elseif xmlElement == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color2"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(2)
  elseif xmlElement == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color3"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(3)
  elseif xmlElement == ss.T["menu_item_customize_font_1"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font1:GetTextColor()
  elseif xmlElement == ss.T["menu_item_customize_font_2"] then
    r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font2:GetTextColor()
  elseif xmlElement == ss.T["menu_item_customize_second_filling"] then
    local fillColor = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()
    if fillColor[2] then
      r, g, b, a = ss.Utils:GetRGBAValues(fillColor[2])
    else
      r, g, b, a = ss.Utils:GetRGBAValues(fillColor[1])
    end

    a = a or 1
  end

  ss.ConfigPreview.colorFields.elementToChange = xmlElement
  ss.ConfigPreview.colorFields:SetColorRGBA(r, g, b, a)
  ss.ConfigPreview.colorFields:Show()
end

--- Copies the current preview values.
--
local copyMode = function()
  local resourceName = UIDropDownMenu_GetText(ss.ConfigPreview.PreviewDropDown)
  local modeName = UIDropDownMenu_GetText(ss.ConfigPreview.ConfigSphereOptionsDropDown)
  local copyName = ss.profile.profileName .. ": " .. ss.curSpecName .. " - " .. resourceName .. " (" .. modeName .. " " .. GetTime() .. ")"
  local anch, x, y = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetPos(true)
  local r, g, b, a

  local swirlColor = {}
  r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(1)
  swirlColor[1] = { r = r, g = g, b = b, a = a }

  r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(2)
  swirlColor[2] = { r = r, g = g, b = b, a = a }

  r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetSwirlColor(3)
  swirlColor[3] = { r = r, g = g, b = b, a = a }

  local fontColor = {}
  r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font1:GetTextColor()
  fontColor[1] = { r = r, g = g, b = b, a = a }

  r, g, b, a = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font2:GetTextColor()
  fontColor[2] = { r = r, g = g, b = b, a = a }

  -- Store a temporary copy of the values.
  local copy = {
    name = copyName,
    mode = {
      fillColor = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor(),
      swirlColor = swirlColor,
      fontColor = fontColor,
      fillInfo = {
        fillGroup = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.fillGroup,
        fillId = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.fillId,
      },
      swirl = {
        id = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId,
        speed = targetSliderGetValue(ss.T["menu_item_customize_swirl"] .. " - " .. ss.T["menu_item_customize_speed"]),
      },
    },
    animation = {
      posX = targetSliderGetValue(ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_x_pos"]),
      posY = targetSliderGetValue(ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_y_pos"]),
      alpha = targetSliderGetValue(ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_alpha"]),
      camDistance = targetSliderGetValue(ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_scale"]),
      frameLevel = targetSliderGetValue(ss.T["menu_item_customize_animation"] .. " - " .. ss.T["menu_item_customize_animation_strata"]) + ss.private.layout.config.frameLevelAdjust,
      id = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animId,
      groupId = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animGroup,
    },
    font = {
      [1] = {
        show = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font1:IsVisible(),
      },
      [2] = {
        show = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.font2:IsVisible(),
      },
    },
    textFormat = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.textFormat,
    general = {
      globalScale = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetGlobalScale(),
      posX = y,
      posY = x,
      anchor = anch,
    },
  }

  if configTargets[ss.T["menu_item_load_values"]][copyName] then
    table.remove(configTargets[ss.T["menu_item_load_values"]], copyName)
  end

  ss.Utils:NewTemp(copyName, copy)

  -- Add an option to the "Load Values" target.
  table.insert(configTargets[ss.T["menu_item_load_values"]], copyName)
end

--- Loads copied values.
-- @param copyName The copy index.
--
local loadCopy = function(copyName)
  local copy = ss.Utils:GetTemp(copyName)

  if copy and next(copy) ~= nil then
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:UpdateScale()
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:RefreshPos()

    -- Updated spheres values.
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextFormat(copy.textFormat)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:showFont(1, copy.font[1].show)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:showFont(2, copy.font[2].show)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimation(copy.animation)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlTexture(copy.mode.swirl.id)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlSpeed(copy.mode.swirl.speed)
    --    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetGlobalScale(copy.general.globalScale)
    --    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetPos(copy.general.anchor, copy.general.posX, copy.general.posY, true)

    -- Set sphere colors.
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor(copy.mode.swirlColor[1], 1)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor(copy.mode.swirlColor[2] or copy.mode.swirlColor[1], 2)
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor(copy.mode.swirlColor[3] or copy.mode.swirlColor[1], 3)

    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextColor(copy.mode.fontColor[1])
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextColor2(copy.mode.fontColor[2])

    local fillColor = ss.Utils.tcopy(copy.mode.fillColor, true)

    if not ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2] then
      -- Copying into single resource sphere.
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetFillTexture(copy.mode.fillInfo.fillGroup, copy.mode.fillInfo.fillId)
      fillColor[2] = nil
    elseif ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2] then
      -- Copying into split resource sphere.
      fillColor[2] = fillColor[2] or ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2]
    end

    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetFillColor(fillColor)

    -- Update UI components.
    toggleFillTextureDropdown()
    updateXMLText()
    CustomDropDownMenu_SetText(ss.ConfigPreview.RotationTexturesDropDown, copy.animation.id)
    CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)
    CustomDropDownMenu_SetText(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)
    setTextFormatText(copy.textFormat)
    ss.ConfigPreview.widgetFrame.SSSpherePercentageCheckBox:SetChecked(copy.font[1].show)
    ss.ConfigPreview.widgetFrame.SSSphereValueCheckBox:SetChecked(copy.font[2].show)
  end
end

--- Resource emulation
local resourceMonitor

--- Toggles the preview's animation.
-- @param emulate Flag to begin or end the emulator.
--
local emulateResource = function(emulate)
  resourceMonitor = resourceMonitor or ss.ResourceMonitor:New()
  local isDual = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()[2]

  if emulate == true then
    resourceMonitor:Emulate(ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere, isDual)
  else
    resourceMonitor:EmulateFinish(ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere)
  end
end

--- Initializes the micro sphere config panel.
--
function ss:InitializeConfigPreviewPanel()
  -- Create the config preview frame.
  ss.ConfigPreview = ss.Config:AddTab(ss._f .. "Config_Preview", ss.T["tab_label_preview"], initPreviewOption)

  ss.ConfigPreview:HookScript("OnHide", function()
    if ss.ConfigPreview.widgetFrame.AnimatePreviewCheckBox:GetChecked() == true then
      -- Cancel running emulation.
      ss.ConfigPreview.widgetFrame.AnimatePreviewCheckBox:Click()
    end

    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:UpdateScale()
    ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:RefreshPos()
  end)

  ss.ConfigPreview.loadCopy = loadCopy
  ss.ConfigPreview.copyMode = copyMode

  ss.ConfigPreview.dbConfig = "health"

  -- Add the widget container
  ss.ConfigPreview.widgetFrame = ss.ConfigTools.getWidgetContainer(ss.ConfigPreview, "PreviewWidgetFrame")

  -- Add the title
  ss.ConfigPreview.widgetFrame.Title = ss.ConfigTools.createTitle("", ss.ConfigPreview.widgetFrame)

  -- Add preview sphere select dropdown
  ss.Config.previewSphereList = {}
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "PreviewDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 125,
    height = 50,
    anchor = "TOPLEFT",
    x = ss.ConfigTools.itemPadCorner + ss.ConfigTools.leftLabelMargin,
    y = 5 - ss.ConfigTools.itemPadCorner,
    init = function(_, level)
      for k, v in ss.Utils.pairsByKeys(ss.Config.previewSphereList) do
        local stuff = {
          fontObject = "Exo2Medium12",
        }
        stuff.text = v[1]
        stuff.value = v[1]

        stuff.func = function(self)
          if self:GetText() ~= ss.T["menu_item_select_sphere"] then
            CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.PreviewDropDown, self:GetText())
            CustomDropDownMenu_SetText(ss.ConfigPreview.PreviewDropDown, self:GetText())
            previewSphere(self:GetText(), k)
            CloseCustomDropDownMenus()
          end
        end

        securecall("CustomDropDownMenu_AddButton", stuff, level)
      end
    end,
    label = {
      name = "PreviewSphereLabel",
      text = ss.T["menu_label_preview_sphere"],
      location = "left",
      color = ss.ConfigTools.headerItemColor,
    },
  }

  -- Add the mode dropdown
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "ConfigSphereOptionsDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 125,
    height = 50,
    anchor = "TOPLEFT",
    x = ss.ConfigTools.itemPadCorner + ss.ConfigTools.leftLabelMargin,
    y = 5 - ss.ConfigTools.itemPadCorner - ss.ConfigTools.itemHeight,
    init = function(_, level)
      for k, v in ss.Utils.pairsByKeys(ss.db[ss.ConfigPreview.dbConfig].modes[ss.profile.modeInfo[ss.ConfigPreview.dbConfig].modeSpec]) do
        if getmetatable(v) and (ss.curClass ~= "druid" or k ~= "combat" or (k == "combat" and ss.ConfigPreview.dbConfig == "health")) then
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          -- Ensure that defaults are available.
          stuff.text = ss.T["mode_name_" .. k]
          stuff.value = k
          stuff.func = function(self)
            -- Update fill texture dropdown.
            local text = (v.fillInfo.fillId == 1) and ss.FillTextures.defaultId or v.fillInfo.fillId
            CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.FillTexturesDropDown, text)
            CustomDropDownMenu_SetText(ss.ConfigPreview.FillTexturesDropDown, text)

            CustomDropDownMenu_SetSelectedID(ss.ConfigPreview.ConfigSphereOptionsDropDown, self:GetID())
            CustomDropDownMenu_SetText(ss.ConfigPreview.ConfigSphereOptionsDropDown, ss.T["mode_name_" .. k])

            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetMode(v, k)
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.modeId = k

            updateXMLTextures()
            updateXMLText()
            resetSliderDropdown()

            CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)
            CustomDropDownMenu_SetText(ss.ConfigPreview.SwirlTexturesDropDown, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId)

            -- Fix default value for fill texture dropdown
            toggleFillTextureDropdown()

            CloseCustomDropDownMenus()
            ss.ConfigPreview.ResetButton:Hide()
            ss.ConfigPreview.CommitButton:Hide()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "SphereModeLabel",
      text = ss.T["menu_label_mode"],
      location = "left",
      color = ss.ConfigTools.headerItemColor,
    },
  }

  -- TextFormattingDropdown
  local textFormats = {
    ss.T["text_format_comma"],
    ss.T["text_format_truncate"],
    ss.T["text_format_raw"]
  }

  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "TextFormattingDropdown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 150,
    height = 45,
    anchor = "TOPLEFT",
    x = 0,
    y = ss.ConfigTools.topMargin - ss.ConfigTools.itemHeight,
    init = function(_, level)
      for _, v in pairs(textFormats) do
        local stuff = {
          fontObject = "Exo2Medium12",
        }

        stuff.text = v
        stuff.value = v
        stuff.func = function(self)
          CustomDropDownMenu_SetSelectedID(ss.ConfigPreview.TextFormattingDropdown, self:GetID())
          CustomDropDownMenu_SetText(ss.ConfigPreview.TextFormattingDropdown, self:GetText())

          if self:GetText() == ss.T["text_format_truncate"] then
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextFormat("truncated")
          elseif self:GetText() == ss.T["text_format_comma"] then
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextFormat("commaSeparated")
          elseif self:GetText() == ss.T["text_format_raw"] then
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextFormat("raw")
          end

          updateXMLText()
          CloseCustomDropDownMenus()
          ss.ConfigPreview.ResetButton:Show()
          ss.ConfigPreview.CommitButton:Show()
        end

        securecall("CustomDropDownMenu_AddButton", stuff, level)
      end
    end,
    label = {
      name = "TextFormattingDropdownLabel",
      text = ss.T["menu_label_text_format"],
      location = "top",
    },
  }

  -- Add the show percentage checkbox.
  ss.ConfigTools.addWidget {
    type = "Checkbox",
    name = "SSSpherePercentageCheckBox",
    parent = ss.ConfigPreview.widgetFrame,
    anch = "TOPLEFT",
    x = 22,
    y = ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 2),
    width = 125,
    justifyH = "LEFT",
    text = ss.T["chk_show_percentage"],
    onClick = function(self)
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:showFont(1, self:GetChecked())
      ss.ConfigPreview.ResetButton:Show()
      ss.ConfigPreview.CommitButton:Show()
    end,
  }

  -- Add the show value checkbox.
  ss.ConfigTools.addWidget {
    type = "Checkbox",
    name = "SSSphereValueCheckBox",
    parent = ss.ConfigPreview.widgetFrame,
    anch = "TOPLEFT",
    x = 22,
    y = ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 3),
    width = 125,
    justifyH = "LEFT",
    text = ss.T["chk_show_value"],
    onClick = function(self)
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:showFont(2, self:GetChecked())
      ss.ConfigPreview.ResetButton:Show()
      ss.ConfigPreview.CommitButton:Show()
    end,
  }

  -- Add the Animate Preview checkbox.
  ss.ConfigTools.addWidget {
    type = "Checkbox",
    name = "AnimatePreviewCheckBox",
    parent = ss.ConfigPreview.widgetFrame,
    anch = "TOPRIGHT",
    x = -135,
    y = ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 2),
    width = 120,
    justifyH = "LEFT",
    text = ss.T["chk_animate_preview"],
    onClick = function(self)
      emulateResource(self:GetChecked())
    end,
  }

  -- Add the preview sphere
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2 = CreateFrame("Frame", ss._f .. "cfg_preview_sphere", ss.ConfigPreview.widgetFrame)
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2:SetPoint("TOP", 0, (ss.ConfigTools.topMargin - 45))
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2:SetSize(ss.private.general.SphereSize, ss.private.general.SphereSize)

  -- Initialize the sphere
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere = SeamoreSpheresUnitFrame:New(ss.db.health, ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2, "preview")
  ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2:SetScale(1.5)

  -- Background textures
  local textureNameTable = ss.FillTextures.listAll()

  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "FillTexturesDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 100,
    height = 45,
    anchor = "BOTTOMLEFT",
    x = 0,
    y = 15,
    init = function(_, level, menuList)
      if level == 1 then
        for k in ss.Utils.pairsByKeys(textureNameTable) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          local text = (k == "split") and ss.FillTextures.defaultGroup or k
          stuff.text = text
          stuff.menuList = text
          stuff.hasArrow = true
          stuff.notCheckable = true
          stuff.keepShownOnClick = true

          securecall("CustomDropDownMenu_AddButton", stuff)
        end
      elseif level == 2 then
        for k in ss.Utils.pairsByKeys(textureNameTable[menuList]) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          local text = (k == 1) and ss.FillTextures.defaultId or k
          stuff.text = text
          stuff.value = text
          stuff.keepShownOnClick = true
          stuff.checked = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.fillId == text
          stuff.func = function(self)
            CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.FillTexturesDropDown, text)
            CustomDropDownMenu_SetText(ss.ConfigPreview.FillTexturesDropDown, self:GetText())
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetFillTexture(menuList, self:GetText())
            ss.ConfigPreview.ResetButton:Show()
            ss.ConfigPreview.CommitButton:Show()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "FillTextureLabel",
      text = ss.T["menu_label_background"],
      location = "top",
    },
  }

  -- Animations
  local animationNameTable = ss.Animations.list()

  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "RotationTexturesDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 100,
    height = 45,
    anchor = "BOTTOMLEFT",
    x = 150,
    y = 15,
    init = function(_, level, menuList)
      if level == 1 then
        for k in ss.Utils.pairsByKeys(animationNameTable) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.text = k
          stuff.menuList = k
          stuff.hasArrow = true
          stuff.notCheckable = true
          stuff.keepShownOnClick = true

          securecall("CustomDropDownMenu_AddButton", stuff)
        end
      elseif level == 2 then
        for k in ss.Utils.pairsByKeys(animationNameTable[menuList]) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.text = k
          stuff.value = k
          stuff.keepShownOnClick = true
          stuff.checked = (ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.animId == k)
          stuff.func = function(self)
            CustomDropDownMenu_SetSelectedValue(ss.ConfigPreview.RotationTexturesDropDown, self:GetText())
            CustomDropDownMenu_SetText(ss.ConfigPreview.RotationTexturesDropDown, self:GetText())
            ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetAnimationDisplayInfo(ss.ConfigPreview.RotationTexturesDropDown.menuList, self:GetText())
            ss.ConfigPreview.ResetButton:Show()
            ss.ConfigPreview.CommitButton:Show()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "SphereTextureLabel",
      text = ss.T["menu_item_customize_animation"],
      location = "top",
    },
  }

  -- Swirl textures
  local swirlTextureNameTable = ss.FillTextures.list("swirl")
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "SwirlTexturesDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 100,
    height = 45,
    anchor = "BOTTOMLEFT",
    x = 300,
    y = 15,
    init = function(_, level)
      for k in ss.Utils.pairsByKeys(swirlTextureNameTable) do
        local stuff = {
          fontObject = "Exo2Medium12",
        }

        stuff.text = k
        stuff.value = k
        stuff.keepShownOnClick = true
        stuff.checked = (ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.sphere.swirlId == k)
        stuff.func = function(self)
          CustomDropDownMenu_SetSelectedID(ss.ConfigPreview.SwirlTexturesDropDown, self:GetID())
          CustomDropDownMenu_SetText(ss.ConfigPreview.SwirlTexturesDropDown, self:GetText())
          ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlTexture(k)
          ss.ConfigPreview.ResetButton:Show()
          ss.ConfigPreview.CommitButton:Show()
        end

        securecall("CustomDropDownMenu_AddButton", stuff, level)
      end
    end,
    label = {
      name = "SwirlTextureLabel",
      text = ss.T["menu_item_customize_swirl"],
      location = "top",
    },
  }

  -- Display the "slider target" dropdown to determine which value the slider should manage
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "SliderTargetDropDown",
    parent = ss.ConfigPreview,
    tAlign = "LEFT",
    width = 175,
    height = 45,
    anchor = "BOTTOMLEFT",
    x = 0,
    y = 112,
    init = function(_, level, menuList)
      if level == 1 then
        for k, v in ss.Utils.pairsByKeys(configTargets) do
          local stuff = {
            fontObject = "Exo2Medium12",
            notCheckable = true,
          }

          local skip
          stuff.text = k

          if type(v) == "table" then
            if next(v) ~= nil then
              stuff.menuList = k
              stuff.hasArrow = true
              stuff.func = nil
            else
              stuff.text = nil
              skip = true
            end
          elseif type(v) == "function" then
            stuff.func = v
            stuff.menuList = nil
            stuff.hasArrow = false
          end

          if not skip then
            securecall("CustomDropDownMenu_AddButton", stuff)
          end
        end
      elseif level == 2 then
        for _, v in ss.Utils.pairsByKeys(configTargets[menuList]) do
          local stuff = {
            fontObject = "Exo2Medium12",
            notCheckable = true,
          }

          stuff.text = v
          stuff.arg1 = menuList
          stuff.func = function(self, arg1)
            if string.match(self:GetText(), ss.T["menu_item_customize_color"]) then
              ss.ConfigPreview.SSTargetSlider:Hide()
              local target = arg1 .. " - " .. self:GetText()

              CustomDropDownMenu_SetSelectedID(ss.ConfigPreview.SliderTargetDropDown, self:GetID())
              CustomDropDownMenu_SetText(ss.ConfigPreview.SliderTargetDropDown, target)

              if arg1 == ss.T["menu_item_customize_filling"] then
                showColorSelect((self:GetText() == ss.T["menu_item_customize_color2"]) and ss.T["menu_item_customize_second_filling"] or arg1)
              elseif arg1 == ss.T["menu_item_customize_swirl"] then
                showColorSelect(arg1 .. self:GetText())
              else
                showColorSelect(arg1)
              end
            elseif targetSliderValues[arg1] and targetSliderValues[arg1][self:GetText()] then
              ss.ConfigPreview.colorFields:Hide()
              ss.ConfigPreview.SSTargetSlider:Hide()
              local target = arg1 .. " - " .. self:GetText()
              local sliderVals = targetSliderValues[arg1][self:GetText()]

              CustomDropDownMenu_SetSelectedID(ss.ConfigPreview.SliderTargetDropDown, self:GetID())
              CustomDropDownMenu_SetText(ss.ConfigPreview.SliderTargetDropDown, target)

              getglobal(ss.ConfigPreview.SSTargetSlider:GetName() .. "High"):SetText(sliderVals.high)
              getglobal(ss.ConfigPreview.SSTargetSlider:GetName() .. "Low"):SetText(sliderVals.low)

              ss.ConfigPreview.SSTargetSlider:SetMinMaxValues(sliderVals.low, sliderVals.high)
              ss.ConfigPreview.SSTargetSlider:SetValueStep(sliderVals.step)

              ss.ConfigPreview.SSTargetSlider:Show()
              ss.ConfigPreview.SSTargetSlider:SetValue(targetSliderGetValue(target))
            else
              -- Run generic event handler.
              configTargetRun(arg1 .. " - " .. self:GetText())
            end

            ss.ConfigPreview.ResetButton:Show()
            ss.ConfigPreview.CommitButton:Show()
            CloseCustomDropDownMenus()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "SliderTargetLabel",
      text = ss.T["menu_label_customize"],
      location = "top",
    },
  }

  ss.ConfigPreview.SSTargetSlider, ss.ConfigPreview.SSTargetSliderEditBox = ss.ConfigTools.createSliderField({
    name = "SSTargetSlider",
    parent = ss.ConfigPreview,
    len = 275,
    heigt = 16,
    anchor = "BOTTOMLEFT",
    x = 25,
    y = 90,
    onChanged = targetSliderSetValue,
  }, {
    maxLetters = 5,
    onEnterPressed = function(self)
      local val = self:GetText()
      if tonumber(val) then
        self:GetParent():SetValue(val)
        self:SetText(self:GetParent():GetValue())
        self:ClearFocus()
      end
    end,
  });

  ss.ConfigPreview.SSTargetSlider:Hide()

  -- Add the color picker
  ss.ConfigPreview.colorFields = ss.ConfigTools.createColorPicker {
    parent = ss.ConfigPreview,
    anch = "BOTTOMRIGHT",
    x = -20,
    y = 25 + (ss.ConfigTools.itemHeight * 2),
    onColorSelect = function(self)
      local r, g, b, a = self:GetColorRGBA()
      local fillColor = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:GetFillColor()

      if ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_filling"] then
        fillColor[1] = { r = r, g = g, b = b, a = a }
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetFillColor(fillColor)
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_second_filling"] then
        fillColor[2] = { r = r, g = g, b = b, a = a }
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:SetFillColor(fillColor)
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor({ r = r, g = g, b = b, a = a })
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color1"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor({ r = r, g = g, b = b, a = a }, 1)
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color2"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor({ r = r, g = g, b = b, a = a }, 2)
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_swirl"] .. ss.T["menu_item_customize_color3"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setSwirlColor({ r = r, g = g, b = b, a = a }, 3)
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_font_1"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextColor({ r = r, g = g, b = b, a = a })
      elseif ss.ConfigPreview.colorFields.elementToChange == ss.T["menu_item_customize_font_2"] then
        ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:setTextColor2({ r = r, g = g, b = b, a = a })
      end

      ss.ConfigPreview.ResetButton:Show()
      ss.ConfigPreview.CommitButton:Show()
    end,
  }

  -- Add the reset button
  ss.ConfigPreview.ResetButton = ss.ConfigTools.createButton {
    parent = ss.ConfigPreview,
    name = "PreviewResetButton",
    anch = "BOTTOMRIGHT",
    x = -15,
    y = 15 + ss.ConfigTools.itemHeight,
    text = ss.T["btn_undo_changes"],
    onClick = function(self)
      previewSphere(ss.ConfigPreview.widgetFrame.Title:GetText(), ss.ConfigPreview.dbConfig)
      self:Hide()
      ss.ConfigPreview.CommitButton:Hide()
    end,
  }

  -- Add the save button
  ss.ConfigPreview.CommitButton = ss.ConfigTools.createButton {
    parent = ss.ConfigPreview,
    name = "PreviewCommitButton",
    anch = "BOTTOMRIGHT",
    x = -15,
    y = 15,
    text = ss.T["btn_save_changes"],
    onClick = function(self)
      ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere:UpdateDB()

      local configName = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName
      local dbConfig = ss.ConfigPreview.widgetFrame.xmlSphereDisplayFrame2.sphere.configName
      configName = (configName == "vehicle") and "health" or configName
      configName = (configName == "vehicleResource") and "mainResource" or configName

      local shouldReload

      if UnitInVehicle("player") then
        shouldReload = dbConfig == "vehicle" or dbConfig == "vehicleResource"
      else
        shouldReload = dbConfig ~= "vehicle" and dbConfig ~= "vehicleResource"
      end

      if ss.Layout.spheres[configName] and shouldReload then
        ss.Layout.spheres[configName]:setResource(ss.db[dbConfig])

        if ss.Layout:InCombat() and ss.db[dbConfig].modes[ss.profile.modeInfo[dbConfig].modeSpec] and ss.db[dbConfig].modes[ss.profile.modeInfo[dbConfig].modeSpec]["combat"] then
          if (dbConfig ~= "pet") and (dbConfig == "health" or dbConfig == "vehicle" or ss.curClass ~= "druid") then
            ss.Layout.spheres[configName]:SetMode(ss.db[dbConfig].modes[ss.profile.modeInfo[dbConfig].modeSpec]["combat"])
          end
        end
      end

      self:Hide()
      ss.ConfigPreview.ResetButton:Hide()
    end,
  }
end
