--- Micro Sphere Configuration Panel
--
local AddOnName, nsVars = ...
local ss = nsVars.SS

local UIDropDownMenu_GetText = ss.APIUtils.UIDropDownMenu_GetText
local pairs, CloseCustomDropDownMenus, CustomDropDownMenu_SetText = pairs, CloseCustomDropDownMenus, CustomDropDownMenu_SetText
local table, GetSpellCharges, strlower, next = table, GetSpellCharges, strlower, next
local select, string, tonumber, type, tostring = select, string, tonumber, type, tostring
local CreateFrame = ss.CreateFrame

--- Updates the "preview" list of selected resources.
--
local updatePreview = function()
  local text = ""

  if ss.ConfigMicroSpheres.resources and (ss.ConfigMicroSpheres.resources[1] or ss.ConfigMicroSpheres.resources.buffGroup) then
    for _, v in pairs(ss.ConfigMicroSpheres.resources.buffGroup or { ss.ConfigMicroSpheres.resources }) do
      text = text .. ((v.ssClass == "BuffData" or v.ssClass == "DebuffData") and v[1] or v.name) .. "\n"
    end
  end

  ss.ConfigMicroSpheres.previewList:SetText(text)
end

--- Displays the ColorSelect panel.
--
local showColorSelect = function()
  local r, g, b, a = ss.ConfigMicroSpheres.colorDisplayText:GetVertexColor()

  ss.ConfigMicroSpheres.colorFields:SetColorRGBA(r, g, b, a)
  ss.ConfigMicroSpheres.colorFields:Show()
end

--- Shows or hides the custom resource frames.
-- @param show Flag to show or hide.
--
local toggleCustomResourceFields = function(show)
  if show then
    ss.ConfigMicroSpheres.newResourceEditBox:Show()

    if ss.ConfigMicroSpheres.resourceOptionList ~= "SpellChargeData" then
      -- Uses stacks from API.
      ss.ConfigMicroSpheres.newResourceIsStackingCheckBox:Show()
    end

    ss.ConfigMicroSpheres.newResourceCreateButton:Show()
    ss.ConfigMicroSpheres.colorDisplay:Show()
    showColorSelect()

    ss.ConfigMicroSpheres.ResourceRemoveDropDown:Hide()
    ss.ConfigMicroSpheres.ResourceRemoveDropDown.label:Hide()
    ss.ConfigMicroSpheres.ResourceDeleteDropDown:Hide()
    ss.ConfigMicroSpheres.ResourceDeleteDropDown.label:Hide()
    ss.ConfigMicroSpheres.backgroundDropDown:Hide()
    ss.ConfigMicroSpheres.backgroundDropDown.label:Hide()
    ss.ConfigMicroSpheres.previewList:Hide()
  else
    ss.ConfigMicroSpheres.newResourceEditBox:SetText("")
    ss.ConfigMicroSpheres.newResourceIsStackingCheckBox:SetChecked(false)
    ss.ConfigMicroSpheres.newResourceEditBox:Hide()
    ss.ConfigMicroSpheres.newResourceIsStackingCheckBox:Hide()
    ss.ConfigMicroSpheres.newResourceStacksEditBox:Hide()
    ss.ConfigMicroSpheres.colorDisplay:Hide()
    ss.ConfigMicroSpheres.colorFields:Hide()
    ss.ConfigMicroSpheres.newResourceCreateButton:Hide()

    ss.ConfigMicroSpheres.ResourceRemoveDropDown:Show()
    ss.ConfigMicroSpheres.ResourceRemoveDropDown.label:Show()

    if ss.ConfigMicroSpheres.resourceOptionList ~= "ClassResourceData" then
      ss.ConfigMicroSpheres.ResourceDeleteDropDown:Show()
      ss.ConfigMicroSpheres.ResourceDeleteDropDown.label:Show()
    else
      ss.ConfigMicroSpheres.ResourceDeleteDropDown:Hide()
      ss.ConfigMicroSpheres.ResourceDeleteDropDown.label:Hide()
    end

    ss.ConfigMicroSpheres.backgroundDropDown:Show()
    ss.ConfigMicroSpheres.backgroundDropDown.label:Show()
    ss.ConfigMicroSpheres.previewList:Show()
  end
end

--- Updates layout values according to the target resource.
-- @param group The selected resource group.
-- @param microResource The selected micro resource values.
-- @param region The selected region.
--
local configureMicroSphereGroup = function(group, microResource, region)
  local groupIndex = (group == "Group 1") and 1 or 2
  local regionLabel = region and region == "secondary" and "secondary_" or ""
  local regionIndex = (region and region == "secondary") and 2 or 1

  ss.ConfigMicroSpheres.widgetFrame.Title:SetText(ss.T["config_title_micro_spheres_" .. regionLabel .. "group_" .. groupIndex])
  ss.ConfigMicroSpheres.selectedTexture = ss.profile.microResourceFillTextures[regionIndex]
  ss.ConfigMicroSpheres.selectedTextureGroup = ss.profile.microResourceFillTextureGroups[regionIndex]

  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceRemoveDropDown, ss.T["menu_item_select_resource"])
  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceDeleteDropDown, ss.T["menu_item_select_resource"])
  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceAddDropDown, ss.T["menu_item_select_resource"])
  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceTypeDropDown, ss.T["menu_item_resource_type_select"])
  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.backgroundDropDown, ss.ConfigMicroSpheres.selectedTexture)

  ss.ConfigMicroSpheres.resourceOptionList = nil
  ss.ConfigMicroSpheres.region = region

  if microResource and not microResource.getMinMax and not microResource.buffGroup then
    microResource = (microResource[groupIndex] and (microResource[groupIndex].buffGroup or microResource[groupIndex].getMinMax)) and microResource[groupIndex] or {}
  elseif microResource then
    microResource = (groupIndex == 1) and microResource or {}
  end

  ss.ConfigMicroSpheres.resources = ss.Utils.tcopy(microResource, true)
  ss.ConfigMicroSpheres.MicroSphereSaveButton:Hide()
  toggleCustomResourceFields(false)
  updatePreview()
end

--- Deletes a custom resource from storage.
-- @param ssClass The resource type.
-- @param name The resource index.
-- @param tbl The storage table.
-- @return Flag to refresh layouts.
--
local deleteCustomResource = function(ssClass, name, tbl)
  tbl = tbl or "microResources"
  local shouldRefresh

  if ss.curClass == "druid" then
    if ss.profile[tbl][strlower(ss.curSpecName)] then
      for shapeshift, vals in pairs(ss.profile[tbl][strlower(ss.curSpecName)]) do
        for k, v in pairs(vals) do
          if v.buffGroup then
            for kk, vv in pairs(v.buffGroup) do
              if vv.ssClass == ssClass and vv[1] == name then
                table.remove(ss.profile[tbl][strlower(ss.curSpecName)][shapeshift][k].buffGroup, kk)
                shouldRefresh = true
              end
            end
            if shouldRefresh and next(ss.profile[tbl][strlower(ss.curSpecName)][shapeshift][k].buffGroup) == nil then
              ss.profile[tbl][strlower(ss.curSpecName)][shapeshift][k] = {}
            end
          elseif v.ssClass == ssClass and v[1] == name then
            ss.profile[tbl][strlower(ss.curSpecName)][shapeshift][k] = {}
            shouldRefresh = true
          end
        end
      end
    end
  else
    if ss.profile[tbl][strlower(ss.curSpecName)] then
      for k, v in pairs(ss.profile[tbl][strlower(ss.curSpecName)]) do
        if v.buffGroup then
          for kk, vv in pairs(v.buffGroup) do
            if vv.ssClass == ssClass and vv[1] == name then
              table.remove(ss.profile[tbl][strlower(ss.curSpecName)][k].buffGroup, kk)
              shouldRefresh = true
            end
          end
          if shouldRefresh and next(ss.profile[tbl][strlower(ss.curSpecName)][k].buffGroup) == nil then
            ss.profile[tbl][strlower(ss.curSpecName)][k] = {}
          end
        elseif v.ssClass == ssClass and v[1] == name then
          ss.profile[tbl][strlower(ss.curSpecName)][k] = {}
          shouldRefresh = true
        end
      end
    end
  end

  return shouldRefresh
end

--- Sets default layout values.
--
local initMicroSphereGroupOption = function()
  local microResource = ss.Utils.tcopy(ss.profile.microResources or {}, true)

  if ss.curClass == "druid" then
    CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown, ss.T["menu_item_default_group_1"])
    CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown, ss.T["menu_item_select_group"])
    ss.ConfigMicroSpheres.selectedMicroGroup = { "Group 1", strlower("Default") }

    microResource = microResource[strlower(ss.curSpecName)]
    microResource = microResource and microResource[strlower("Default")] or {}
  else
    CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown, ss.T["lbl_group_1"])
    CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown, ss.T["menu_item_select_group"])
    ss.ConfigMicroSpheres.selectedMicroGroup = { "Group 1" }

    microResource = microResource[strlower(ss.curSpecName)] or {}
  end

  configureMicroSphereGroup("Group 1", microResource)
  CloseCustomDropDownMenus()
end

--- Adds a custom resource to storage.
--
local createCustomResource = function()
  local name = ss.ConfigMicroSpheres.newResourceEditBox:GetText()
  local r, g, b, a = ss.ConfigMicroSpheres.colorDisplayText:GetVertexColor()
  local funcName = "getMinMax"
  local stackNum = 1

  if ss.ConfigMicroSpheres.newResourceIsStackingCheckBox:GetChecked() then
    stackNum = tonumber(ss.ConfigMicroSpheres.newResourceStacksEditBox:GetText())
    funcName = "getStackingMinMax"
  end

  for i = 1, stackNum, 1 do
    local stackName = name .. ((i > 1) and tostring(i) or "")

    local new = {
      [1] = stackName,
      [2] = { r = r, g = g, b = b, a = a },
      getMinMax = funcName,
      name = name,
      ssClass = ss.ConfigMicroSpheres.resourceOptionList,
    }

    local index = strlower(string.gsub(stackName, "[ :'%(%),]", ""))
    ss.global.customResources[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass][index] = new
  end

  ss.MicroSphereData.loadCustomResources(ss.ConfigMicroSpheres.resourceOptionList)
  toggleCustomResourceFields(false)
  CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceAddDropDown, ss.T["menu_item_select_resource"])
end

--- Initializes the custom resource frames.
--
local initCreateResourcePanel = function()
  -- Add Name field.
  ss.ConfigMicroSpheres.newResourceEditBox = ss.ConfigTools.createEditBox {
    parent = ss.ConfigMicroSpheres,
    name = "NewResourceEditBox",
    width = 175,
    height = 25,
    anch = "TOPLEFT",
    x = 120,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 6) - 15),
    letters = 50,
    onEnterPressed = function(self)
      self:ClearFocus()
    end,
    onTextChanged = function()
    end,
    label = {
      name = "NewResourceEditBoxLabel",
      text = ss.T["txt_label_name"],
      leftLabelMargin = 60,
    },
  }

  local showLabel = function(self)
    self.label:Show()
  end

  local hideLabel = function(self)
    self.label:Hide()
  end

  ss.ConfigMicroSpheres.newResourceEditBox:HookScript("OnShow", showLabel)
  ss.ConfigMicroSpheres.newResourceEditBox:HookScript("OnHide", hideLabel)

  -- Add the stacking resource checkbox.
  ss.ConfigTools.addWidget {
    type = "Checkbox",
    name = "newResourceIsStackingCheckBox",
    parent = ss.ConfigMicroSpheres,
    anch = "TOPLEFT",
    x = 55,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 7) - 15),
    width = 100,
    justifyH = "LEFT",
    text = ss.T["chk_stacking"],
    onClick = function(self)
      if self:GetChecked() then
        ss.ConfigMicroSpheres.newResourceStacksEditBox:Show()
      else
        ss.ConfigMicroSpheres.newResourceStacksEditBox:Hide()
      end
    end,
  }

  ss.ConfigMicroSpheres.newResourceStacksEditBox = ss.ConfigTools.createEditBox {
    parent = ss.ConfigMicroSpheres,
    name = "newResourceStacksEditBox",
    width = 50,
    height = 25,
    anch = "TOPLEFT",
    x = 205,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 8) - 30),
    letters = 1,
    onEnterPressed = function(self)
      self:ClearFocus()
    end,
    onTextChanged = function(self)
      local val = self:GetText()
      if not tonumber(val) and val ~= "" then
        self:SetText("1")
      end
    end,
    OnEditFocusLost = function(self)
      local val = self:GetText()
      if not tonumber(val) or val == "0" then
        self:SetText("1")
      end
    end,
    label = {
      name = "newResourceStacksEditBoxLabel",
      text = ss.T["txt_label_stack_limit"],
      leftLabelMargin = 100,
    },
  }

  ss.ConfigMicroSpheres.newResourceStacksEditBox:HookScript("OnShow", showLabel)
  ss.ConfigMicroSpheres.newResourceStacksEditBox:HookScript("OnHide", hideLabel)

  -- Add the color picker
  ss.ConfigMicroSpheres.colorFields = ss.ConfigTools.createColorPicker {
    parent = ss.ConfigMicroSpheres,
    name = "ConfigMicroSpheresColorPicker",
    anch = "TOPLEFT",
    x = 375,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 5) - 15),
    onColorSelect = function(self)
      ss.ConfigMicroSpheres.colorDisplayText:SetVertexColor(self:GetColorRGBA())
    end,
  }

  ss.ConfigMicroSpheres.colorDisplay = CreateFrame("Frame", "CustomResourceColorDisplay", ss.ConfigMicroSpheres)
  ss.ConfigMicroSpheres.colorDisplay:SetWidth(20)
  ss.ConfigMicroSpheres.colorDisplay:SetHeight(20)
  ss.ConfigMicroSpheres.colorDisplay:SetPoint("TOPLEFT", 350, (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 8) - 15))

  ss.ConfigMicroSpheres.colorDisplayText = ss.ConfigMicroSpheres.colorDisplay:CreateTexture(nil, "BACKGROUND")
  ss.ConfigMicroSpheres.colorDisplayText:SetColorTexture(1, 1, 1, 1)
  ss.ConfigMicroSpheres.colorDisplayText:SetAllPoints(ss.ConfigMicroSpheres.colorDisplay)
  ss.ConfigMicroSpheres.colorDisplayText:SetVertexColor(ss.Utils:GetRGBAValues(ss.ClassResourceData.classColor(ss.curClass)))

  -- Add the create button.
  ss.ConfigMicroSpheres.newResourceCreateButton = ss.ConfigTools.createButton {
    parent = ss.ConfigMicroSpheres,
    name = "newResourceCreateButton",
    anch = "TOPLEFT",
    x = 113,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 10) - 40),
    text = ss.T["btn_create"],
    onClick = createCustomResource,
  }

  ss.ConfigMicroSpheres.newResourceEditBox:Hide()
  ss.ConfigMicroSpheres.newResourceEditBox.label:Hide()
  ss.ConfigMicroSpheres.newResourceIsStackingCheckBox:Hide()
  ss.ConfigMicroSpheres.newResourceStacksEditBox:Hide()
  ss.ConfigMicroSpheres.newResourceStacksEditBox.label:Hide()
  ss.ConfigMicroSpheres.colorDisplay:Hide()
  ss.ConfigMicroSpheres.colorFields:Hide()
  ss.ConfigMicroSpheres.newResourceCreateButton:Hide()
end

local microGroups

if ss.curClass == "druid" then
  microGroups = {
    Default = {
      group1 = "Group 1",
      group2 = "Group 2",
    },
    Bear = {
      group1 = "Group 1",
      group2 = "Group 2",
    },
    Cat = {
      group1 = "Group 1",
      group2 = "Group 2",
    },
    Moonkin = {
      group1 = "Group 1",
      group2 = "Group 2",
    },
  }
else
  microGroups = {
    group1 = "Group 1",
    group2 = "Group 2",
  }
end

ss["ConfigMicroSpheres"] = {}

--- Initializes the micro sphere config panel.
--
function ss:InitializeConfigMicroSpheresPanel()
  -- Create the config preview frame.
  ss.ConfigMicroSpheres = ss.Config:AddTab(ss._f .. "Config_MicroSpheres", ss.T["tab_label_micro_spheres"], initMicroSphereGroupOption)
  ss.ConfigMicroSpheres:HookScript("OnHide", function()
    ss.Notification:CloseConfirm()
  end)

  ss.ConfigMicroSpheres.selectedMicroGroup = ""
  ss.ConfigMicroSpheres.resources = {}
  ss.ConfigMicroSpheres.group1 = {}
  ss.ConfigMicroSpheres.group2 = {}

  -- Add the widget container.
  ss.ConfigMicroSpheres.widgetFrame = ss.ConfigTools.getWidgetContainer(ss.ConfigMicroSpheres, "ConfigMicroSpheresWidgetFrame")

  -- Add micro sphere group select dropdown.
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "MicroSphereSettingsDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = 125,
    height = 50,
    anchor = "TOPLEFT",
    x = ss.ConfigTools.itemPadCorner + ss.ConfigTools.leftLabelMargin,
    y = 5 - ss.ConfigTools.itemPadCorner,
    init = function(_, level, menuList)
      if level == 1 then
        for k, v in ss.Utils.pairsByKeys(microGroups) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          if type(v) == "table" then
            stuff.text = ss.T["menu_item_" .. strlower(k)]
            stuff.menuList = k
            stuff.checked = (ss.ConfigMicroSpheres.selectedMicroGroup[2] == strlower(k)) and not ss.ConfigMicroSpheres.region
            stuff.hasArrow = true
          else
            local groupIndex = (v == "Group 1") and 1 or 2

            stuff.text = ss.T["lbl_group_" .. groupIndex]
            stuff.checked = ss.ConfigMicroSpheres.selectedMicroGroup[1] == v and not ss.ConfigMicroSpheres.region
            stuff.func = function(self)
              if self:GetText() ~= ss.T["menu_item_select_group"] then
                CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown, self:GetText())
                CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown, ss.T["menu_item_select_group"])
                ss.ConfigMicroSpheres.selectedMicroGroup = { v }

                local microResource = ss.Utils.tcopy(ss.profile.microResources or {}, true)
                microResource = microResource[strlower(ss.curSpecName)] or {}

                configureMicroSphereGroup(v, microResource)
                CloseCustomDropDownMenus()
              end
            end
          end

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

          local groupIndex = (v == "Group 1") and 1 or 2

          stuff.text = ss.T["lbl_group_" .. groupIndex]
          stuff.value = k
          stuff.checked = (ss.ConfigMicroSpheres.selectedMicroGroup[1] == v)
              and (ss.ConfigMicroSpheres.selectedMicroGroup[2] == strlower(menuList))
              and not ss.ConfigMicroSpheres.region

          stuff.func = function(self)
            if self:GetText() ~= ss.T["menu_item_select_group"] then
              CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown,
                  ss.T["menu_item_" .. strlower(menuList) .. "_group_" .. groupIndex])
              CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown,
                  ss.T["menu_item_select_group"])
              ss.ConfigMicroSpheres.selectedMicroGroup = { v, strlower(menuList) }

              local microResource = ss.Utils.tcopy(ss.profile.microResources or {}, true)
              microResource = microResource[strlower(ss.curSpecName)]
              microResource = microResource and microResource[strlower(menuList)] or {}

              configureMicroSphereGroup(v, microResource)
              CloseCustomDropDownMenus()
            end
          end

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

  -- Add secondary micro sphere group select dropdown.
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "SecondaryMicroSphereSettingsDropDown",
    parent = ss.ConfigMicroSpheres,
    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, menuList)
      if level == 1 then
        for k, v in ss.Utils.pairsByKeys(microGroups) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          if type(v) == "table" then
            stuff.text = ss.T["menu_item_" .. strlower(k)]
            stuff.menuList = k
            stuff.checked = (ss.ConfigMicroSpheres.selectedMicroGroup[2] == strlower(k)) and (ss.ConfigMicroSpheres.region == "secondary")
            stuff.hasArrow = true
          else
            local groupIndex = (v == "Group 1") and 1 or 2

            stuff.text = ss.T["lbl_group_" .. groupIndex]
            stuff.checked = (ss.ConfigMicroSpheres.selectedMicroGroup[1] == v) and (ss.ConfigMicroSpheres.region == "secondary")
            stuff.func = function(self)
              if self:GetText() ~= ss.T["menu_item_select_group"] then
                CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown, ss.T["menu_item_select_group"])
                CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown, self:GetText())
                ss.ConfigMicroSpheres.selectedMicroGroup = { v }

                local microResource = ss.Utils.tcopy(ss.profile.microResourcesSecondary or {}, true)
                microResource = microResource[strlower(ss.curSpecName)] or {}

                configureMicroSphereGroup(v, microResource, "secondary")
                CloseCustomDropDownMenus()
              end
            end
          end

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

          local groupIndex = (v == "Group 1") and 1 or 2

          stuff.text = ss.T["lbl_group_" .. groupIndex]
          stuff.value = k
          stuff.checked = (ss.ConfigMicroSpheres.selectedMicroGroup[1] == v)
              and (ss.ConfigMicroSpheres.selectedMicroGroup[2] == strlower(menuList))
              and (ss.ConfigMicroSpheres.region == "secondary")

          stuff.func = function(self)
            if self:GetText() ~= ss.T["menu_item_select_group"] then
              CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.MicroSphereSettingsDropDown, ss.T["menu_item_select_group"])
              CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.SecondaryMicroSphereSettingsDropDown,
                  ss.T["menu_item_" .. strlower(menuList) .. "_group_" .. groupIndex])
              ss.ConfigMicroSpheres.selectedMicroGroup = { v, strlower(menuList) }

              local microResource = ss.Utils.tcopy(ss.profile.microResourcesSecondary or {}, true)
              microResource = microResource[strlower(ss.curSpecName)]
              microResource = microResource and microResource[strlower(menuList)] or {}

              configureMicroSphereGroup(v, microResource, "secondary")
              CloseCustomDropDownMenus()
            end
          end

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

  -- Add title.
  ss.ConfigMicroSpheres.widgetFrame.Title = ss.ConfigTools.createTitle(ss.T["config_title_micro_spheres_group_1"], ss.ConfigMicroSpheres.widgetFrame)

  local leftLabelMargin = 195
  local width = 150
  local dropdownXPos = (leftLabelMargin - width) * 2
  local anchor = "TOP"

  -- Add resource type select dropdown.
  ss.ConfigMicroSpheres.resourceGroups = {
    debuff = ss.T["menu_item_resource_type_debuff"],
    buff = ss.T["menu_item_resource_type_buff"],
    spellCharges = ss.T["menu_item_resource_type_spell_charges"],
    classResource = ss.T["menu_item_resource_type_class_resource"],
  }

  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "ResourceTypeDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = width,
    height = 50,
    anchor = anchor,
    x = dropdownXPos,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 2) - 15),
    init = function(_, level)
      for k, v in ss.Utils.pairsByKeys(ss.ConfigMicroSpheres.resourceGroups) do
        if k ~= "classResource" or ss.MicroSphereData.hasClassResource() then
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.text = v
          stuff.value = k
          stuff.notCheckable = true

          stuff.func = function(self)
            CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceTypeDropDown, self:GetText())

            if k == "debuff" then
              ss.ConfigMicroSpheres.resourceOptionList = "DebuffData"
            elseif k == "buff" then
              ss.ConfigMicroSpheres.resourceOptionList = "BuffData"
            elseif k == "spellCharges" then
              ss.ConfigMicroSpheres.resourceOptionList = "SpellChargeData"
            elseif k == "classResource" then
              ss.ConfigMicroSpheres.resourceOptionList = "ClassResourceData"
            else
              ss.ConfigMicroSpheres.resourceOptions = nil
            end

            CloseCustomDropDownMenus()
            toggleCustomResourceFields(false)
            CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceAddDropDown, ss.T["menu_item_select_resource"])
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "ResourceTypeLabel",
      text = ss.T["menu_label_resource_type"],
      leftLabelMargin = leftLabelMargin,
    },
  }

  -- Add resource add select dropdown.
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "ResourceAddDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = width,
    height = 50,
    anchor = anchor,
    x = dropdownXPos,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 3) - 15),
    init = function(_, level)
      if ss.ConfigMicroSpheres.resourceOptionList and ss[ss.ConfigMicroSpheres.resourceOptionList] then
        for k, v in ss.Utils.pairsByKeys(ss[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass] or {}) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          if (ss.ConfigMicroSpheres.resourceOptionList == "SpellChargeData" and GetSpellCharges(v.name))
              or (ss.ConfigMicroSpheres.resourceOptionList == "ClassResourceData" and ss.MicroSphereData.hasClassResource(v.name))
              or (ss.ConfigMicroSpheres.resourceOptionList ~= "SpellChargeData" and ss.ConfigMicroSpheres.resourceOptionList ~= "ClassResourceData") then
            stuff.notCheckable = true
            stuff.text = (ss.ConfigMicroSpheres.resourceOptionList == "BuffData" or ss.ConfigMicroSpheres.resourceOptionList == "DebuffData")
                and v[1] or v.name
            stuff.value = k

            stuff.func = function()
              v.ssClass = v.ssClass or ss.ConfigMicroSpheres.resourceOptionList

              if ss.ConfigMicroSpheres.resourceOptionList == "BuffData" or ss.ConfigMicroSpheres.resourceOptionList == "DebuffData" then
                ss.ConfigMicroSpheres.resources = ss.ConfigMicroSpheres.resources.buffGroup
                    and ss.ConfigMicroSpheres.resources or { buffGroup = {}, }

                if table.getn(ss.ConfigMicroSpheres.resources.buffGroup) < 10 then
                  table.insert(ss.ConfigMicroSpheres.resources.buffGroup, v)
                end
              else
                ss.ConfigMicroSpheres.resources = v
              end

              updatePreview()
              CloseCustomDropDownMenus()
              toggleCustomResourceFields(false)
              CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceAddDropDown, ss.T["menu_item_select_resource"])
              ss.ConfigMicroSpheres.MicroSphereSaveButton:Show()
            end

            securecall("CustomDropDownMenu_AddButton", stuff, level)
          end
        end

        if ss.ConfigMicroSpheres.resourceOptionList ~= "ClassResourceData" then
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          -- Add "Custom" button.
          stuff.notCheckable = true
          stuff.text = ss.T["menu_item_add_resource_custom"]
          stuff.value = "custom"

          stuff.func = function(self)
            -- Toggle create resource layout.
            CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.ResourceAddDropDown, self:GetText())
            toggleCustomResourceFields(true)
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end

      end
    end,
    label = {
      name = "ResourceAddLabel",
      text = ss.T["menu_label_add_resource"],
      leftLabelMargin = leftLabelMargin,
    },
  }

  -- Add resource remove select dropdown.
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "ResourceRemoveDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = width,
    height = 50,
    anchor = anchor,
    x = dropdownXPos,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 4) - 15),
    init = function(_, level)
      if ss.ConfigMicroSpheres.resources and (ss.ConfigMicroSpheres.resources[1] or ss.ConfigMicroSpheres.resources.buffGroup) then
        for k, v in pairs(ss.ConfigMicroSpheres.resources.buffGroup or { ss.ConfigMicroSpheres.resources }) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.notCheckable = true
          stuff.text = ss.ConfigMicroSpheres.resources.buffGroup and v[1] or v.name
          stuff.value = k

          stuff.func = function(_)
            if ss.ConfigMicroSpheres.resources.buffGroup and ss.ConfigMicroSpheres.resources.buffGroup[2] then
              table.remove(ss.ConfigMicroSpheres.resources.buffGroup, k)
            else
              ss.ConfigMicroSpheres.resources = {}
            end

            updatePreview()
            CloseCustomDropDownMenus()
            ss.ConfigMicroSpheres.MicroSphereSaveButton:Show()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "ResourceRemoveLabel",
      text = ss.T["menu_label_remove_resource"],
      leftLabelMargin = leftLabelMargin,
    },
  }

  -- Add resource delete select dropdown.
  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "ResourceDeleteDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = width,
    height = 50,
    anchor = anchor,
    x = dropdownXPos,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 5) - 15),
    init = function(_, level)
      if ss.ConfigMicroSpheres.resourceOptionList and ss.global.customResources[ss.ConfigMicroSpheres.resourceOptionList] then
        for k, v in ss.Utils.pairsByKeys(ss.global.customResources[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass]) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.notCheckable = true
          stuff.text = (ss.ConfigMicroSpheres.resourceOptionList == "BuffData" or ss.ConfigMicroSpheres.resourceOptionList == "DebuffData")
              and v[1] or v.name
          stuff.value = k

          stuff.func = function()
            ss.Notification:Confirm(function()
              -- Remove resource if currently in use.
              local shouldRefresh = deleteCustomResource(ss.ConfigMicroSpheres.resourceOptionList, v[1])
              shouldRefresh = deleteCustomResource(ss.ConfigMicroSpheres.resourceOptionList, v[1], "microResourcesSecondary") or shouldRefresh

              ss.global.customResources[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass][k] = nil
              if ss[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass] then
                ss[ss.ConfigMicroSpheres.resourceOptionList][ss.curClass][k] = nil
              end

              if shouldRefresh then
                ss.Layout:AddMicroSpheres()
                ss.Layout:AddMicroSpheres("mainResource")
              end

              updatePreview()
              initMicroSphereGroupOption()
            end)

            CloseCustomDropDownMenus()
          end

          securecall("CustomDropDownMenu_AddButton", stuff, level)
        end
      end
    end,
    label = {
      name = "ResourceDeleteLabel",
      text = ss.T["menu_label_delete_custom"],
      leftLabelMargin = leftLabelMargin,
    },
  }

  -- Add Backgrounds.
  local textureNameTable = ss.FillTextures.listAll()

  ss.ConfigTools.addWidget {
    type = "DropDown",
    name = "backgroundDropDown",
    parent = ss.ConfigMicroSpheres,
    tAlign = "LEFT",
    width = width,
    height = 50,
    anchor = anchor,
    x = dropdownXPos,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 6) - 15),
    init = function(_, level, menuList)
      if level == 1 then
        for k in ss.Utils.pairsByKeys(textureNameTable) do
          local stuff = {
            fontObject = "Exo2Medium12",
          }

          stuff.text = k
          stuff.menuList = k
          stuff.hasArrow = true
          stuff.checked = (ss.ConfigMicroSpheres.selectedTextureGroup == k)

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

          stuff.text = k
          stuff.value = k
          stuff.checked = (ss.ConfigMicroSpheres.selectedTexture == k)
          stuff.func = function(self)
            CustomDropDownMenu_SetText(ss.ConfigMicroSpheres.backgroundDropDown, self:GetText())
            ss.ConfigMicroSpheres.selectedTexture = self:GetText()
            ss.ConfigMicroSpheres.selectedTextureGroup = menuList
            ss.ConfigMicroSpheres.MicroSphereSaveButton:Show()
            CloseCustomDropDownMenus()
          end

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

  -- Add the list of current micro resources.
  ss.ConfigMicroSpheres.previewList = ss.ConfigTools.createLabel {
    parent = ss.ConfigMicroSpheres,
    name = "ss.ConfigMicroSpheresPreviewList",
    width = 200,
    height = 200,
    anch = "TOP",
    x = 0,
    y = (ss.ConfigTools.topMargin - (ss.ConfigTools.itemHeight * 8) - 15),
    color = ss.ConfigTools.headerItemColor,
    justifyV = "TOP",
  }

  initCreateResourcePanel()

  -- Add the save button.
  ss.ConfigMicroSpheres.MicroSphereSaveButton = ss.ConfigTools.createButton {
    parent = ss.ConfigMicroSpheres,
    name = "MicroSphereCommitButton",
    anch = "BOTTOMRIGHT",
    x = -15,
    y = 15,
    text = ss.T["btn_save_changes"],
    onClick = function(self)
      local index = select(2, string.split(" ", ss.ConfigMicroSpheres.selectedMicroGroup[1]))
      local fillTexture = UIDropDownMenu_GetText(ss.ConfigMicroSpheres.backgroundDropDown)
      if ss.ConfigMicroSpheres.region and ss.ConfigMicroSpheres.region == "secondary" then
        ss.profile.microResourceFillTextures[2] = fillTexture and fillTexture
        ss.profile.microResourceFillTextureGroups[2] = ss.ConfigMicroSpheres.selectedTextureGroup
        ss.Layout:UpdateMicroSphereTextures(ss.ConfigMicroSpheres.selectedTextureGroup, fillTexture, "mainResource")
        ss.MicroSphereData.setSecondary(ss.ConfigMicroSpheres.resources, tonumber(index), ss.ConfigMicroSpheres.selectedMicroGroup[2])
      else
        ss.profile.microResourceFillTextures[1] = fillTexture and fillTexture
        ss.profile.microResourceFillTextureGroups[1] = ss.ConfigMicroSpheres.selectedTextureGroup
        ss.Layout:UpdateMicroSphereTextures(ss.ConfigMicroSpheres.selectedTextureGroup, fillTexture)
        ss.MicroSphereData.set(ss.ConfigMicroSpheres.resources, tonumber(index), ss.ConfigMicroSpheres.selectedMicroGroup[2])
      end
      self:Hide()
    end,
  }
end
