---  Configuration UI Tools
--
local mtConfigTools = {}
local AddOnName, nsVars = ...
local ss = nsVars.SS

local CreateFrame, UIParent, getglobal, InterfaceOptions_AddCategory = ss.CreateFrame, UIParent, getglobal, InterfaceOptions_AddCategory
local select, strlower, setmetatable, tonumber = select, strlower, setmetatable, tonumber
local UIDropDownMenu_SetInitializeFunction = UIDropDownMenu_SetInitializeFunction
local UIDropDownMenu_JustifyText, UIDropDownMenu_SetText = UIDropDownMenu_JustifyText, UIDropDownMenu_SetText
local GetCursorPosition, UIDropDownMenu_SetWidth = GetCursorPosition, UIDropDownMenu_SetWidth

local function createBackdrop(frame)
  local backdrop = frame:CreateTexture(nil, "BACKGROUND")
  backdrop:SetColorTexture(1,1,1,1)
  backdrop:SetVertexColor(0.15, 0.15, 0.15, 1)
  backdrop:SetAllPoints(frame)
  
  frame:SetBackdrop({
    bgFile = backdrop,
    edgeFile = backdrop,
    insets = {
      left = 0,
      top = 0,
      right = 0,
      bottom = 0,
    },
  })
  
  frame:SetBackdropBorderColor(0.175, 0.175, 0.175, 1)
end

local function createButton(parent, name)
  local button = CreateFrame("Button", nil, parent)
  
  -- Crreate the standard texture.
  button._tNorm = button:CreateTexture(nil, "BACKGROUND")
  button._tNorm:SetColorTexture(1,1,1,1)
  button._tNorm:SetAllPoints   (button)
  button._tNorm:SetVertexColor (0.15, 0.15, 0.15, 1)
  button:SetNormalTexture(button._tNorm)
  
  -- Crreate the pushed texture.
  button._tPushed = button:CreateTexture(nil, "BACKGROUND")
  button._tPushed:SetColorTexture(1,1,1,1)
  button._tPushed:SetAllPoints   (button)
  button._tPushed:SetVertexColor (0.175, 0.175, 0.175, 1)
  button:SetPushedTexture(button._tPushed)
  
  -- Crreate the highlighted texture.
  button._tHighlight = button:CreateTexture(nil, "BACKGROUND")
  button._tHighlight:SetColorTexture(1,1,1,1)
  button._tHighlight:SetVertexColor (0.05, 0.05, 0.05, 1)
  button._tHighlight:SetAllPoints   (button)
  button:SetHighlightTexture(button._tHighlight)
  
  -- Crreate the font string.
  button._fontStr = button:CreateFontString()
  button._fontStr:SetAllPoints(button)
  button._fontStr:SetTextColor(0.5, 0.5, 0.5, 1)
  button:SetFontString(button._fontStr)
  
  -- Set the fonts.
  button:SetNormalFontObject("FontExo2SemiBold")
  
  return button
end

local itemCol = 1
local itemRow = 1

--- Local metatables.
-----------------------
local mtButton = {
  parent  = UIParent,
  width   = 135,
  height  = 25,
  anch    = "TOPLEFT",
  x       = 0,
  y       = 0,
  text    = "",
  onClick = function() end,
}

local mtCheck = {
  parent  = UIParent,
  anch    = "TOPLEFT",
  x       = 0,
  y       = 0,
  text    = "Show Value",
  checked = false,
  onClick = function() end,
}

local mtColorSelect = {
  parent        = UIParent,
  width         = 185,
  height        = 175,
  wheelWidth    = 120,
  barWidth      = 20,
  thumbWidth    = 14,
  anch          = "TOPLEFT",
  x             = 0,
  y             = 0,
}

local mtEdit = {
  parent    = UIParent,
  width     = 150,
  height    = 25,
  anch      = "TOPLEFT",
  x         = 0,
  y         = 0,
  letters   = 0,
  text      = "",
  autofocus = false,
}

local mtLabel = {
  parent   = UIParent,
  width    = 150,
  height   = 50,
  anch     = "TOPLEFT",
  x        = 0,
  y        = 0,
  text     = "",
  justifyV = "CENTER",
  justifyH = "CENTER",
  font     = ss.SharedMedia.fontChoices[1],
  fontSize = 19,
  color    = {r=1,g=1,b=1,a=1,},
}

--- Returns the next element position for the main config panel.
--
local function getItemPos()
  if itemCol == 1 then
    itemCol = itemCol + 1
    
    if itemRow == 1 then
      return "TOPLEFT", 25, -131
    elseif itemRow == 2 then
      return "TOPLEFT", 25, -179
    elseif itemRow == 3 then
      return "TOPLEFT", 25, -227
    elseif itemRow == 4 then
      return "TOPLEFT", 25, -275
    elseif itemRow == 5 then
      return "TOPLEFT", 25, -325
    end
  elseif itemCol == 2 then
    local row = itemRow
    itemCol   = itemCol - 1
    itemRow   = itemRow + 1
    
    if row == 1 then
      return "TOP", 0, -131
    elseif row == 2 then
      return "TOP", 0, -179
    elseif row == 3 then
      return "TOP", 0, -227
    elseif row == 4 then
      return "TOP", 0, -275
    elseif row == 5 then
      return "TOP", 0, -325
    end
  end
  
  return "CENTER", 0, 0
end

--- Creates a checkbox frame.
-- @param name The name.
-- @param text The text to display.
-- @param parent The parent container.
-- @param checked Default checked state.
-- @param onClick The click handler.
--
local function getCheckbox(name, text, parent, checked, onClick)
  parent[name] = CreateFrame("CheckButton",ss._f..name,parent, "UICheckButtonTemplate")
  parent[name]:SetPoint  (getItemPos())
  parent[name]:SetChecked(checked)
  local col = ss.ConfigTools.itemColor
  
  getglobal(ss._f..name.."Text"):SetFont(ss.private.font["general"], 23)
  getglobal(ss._f..name.."Text"):SetTextColor(col.r, col.g, col.b, col.a)
  getglobal(ss._f..name.."Text"):SetText(text)
  getglobal(ss._f..name.."Text"):SetWordWrap(true)
  getglobal(ss._f..name.."Text"):SetWidth(250)
  getglobal(ss._f..name.."Text"):SetJustifyH("LEFT")
  parent[name]:HookScript("OnClick", onClick)
end

--- Creates a dropdown menu frame.
-- @param menu The values to use.
-- @return The dropdown menu.
--
local function getDropdown(menu)
  local dropdown   = CreateFrame("Frame", ss._f..menu.name, menu.parent, "UIDropDownMenuTemplate")
  local anch, x, y

  if not menu.anchor then
    anch, x, y = getItemPos()
    x = x + 24
  else
    anch, x, y = menu.anchor, menu.x or 0, menu.y or 0
  end

  dropdown:SetPoint(anch, x, y)
  UIDropDownMenu_SetInitializeFunction(dropdown, menu.init)
  UIDropDownMenu_SetWidth   (dropdown, menu.width or 55)
  UIDropDownMenu_JustifyText(dropdown, menu.tAlign or "LEFT")
  UIDropDownMenu_SetText(dropdown, menu.defaultText or "")
  
  if menu.label then
    dropdown.label = ss.ConfigTools.addItemLabel(menu.label.name, dropdown, menu.label.text, menu.label.location, menu.label.color, menu.label.leftLabelMargin)
  elseif menu.text then
    local col = ss.ConfigTools.itemColor
    dropdown.label = dropdown:GetParent():CreateFontString(ss._f..menu.name.."Label")
    dropdown.label:SetFont     (ss.private.font["general"], 23)
    dropdown.label:SetPoint    (anch,x + 105,y)
    dropdown.label:SetHeight   (dropdown:GetHeight())
    dropdown.label:SetTextColor(col.r, col.g, col.b, col.a)
    dropdown.label:SetText     (menu.text)
    dropdown.label:SetJustifyV ("CENTER")
    dropdown.label:SetJustifyH ("LEFT")
  end
  
  return dropdown
end

mtConfigTools.itemHeight       = 30
mtConfigTools.itemPadLeft      = 50
mtConfigTools.itemPadCorner    = 10
mtConfigTools.itemPadTitle     = 15
mtConfigTools.topMargin        = -60
mtConfigTools.leftLabelMargin  = 165
mtConfigTools.bannerColor      = ss.ClassResourceData.classColor(ss.curClass)
mtConfigTools.titleColor       = {r=0.5,g=1,b=0.3,a=1}
mtConfigTools.headerItemColor  = {r=1.0,g=0.7,b=0.5,a=1}
mtConfigTools.itemColor        = {r=0,g=0.5,b=1,a=1}

function mtConfigTools.createButton(btn)
  btn = setmetatable(btn, { __index = mtButton });
  
  local button = CreateFrame("Button", ss._f..btn.name, btn.parent, "GameMenuButtonTemplate")
  --    local button = createButton(btn.parent, ss._f..btn.name)
  button:SetSize  (btn.width, btn.height)
  button:SetPoint (btn.anch, btn.x, btn.y)
  button:SetText  (btn.text)
  button:HookScript("OnClick", btn.onClick)
  
  return button
end

function mtConfigTools.createInterfaceOption(opt)
  local option   = CreateFrame("Frame", AddOnName .. (opt.name or "") .. "InterfaceOption")
  option.name    = opt.name and opt.name or AddOnName
  option.parent  = opt.parent
  option.refresh = opt.refresh
  InterfaceOptions_AddCategory(option)
  
  return option
end

function mtConfigTools.createSliderField(sliderConf, sliderEditBoxConf)
  local slider = CreateFrame("Slider",ss._f..sliderConf.name,sliderConf.parent, "OptionsSliderTemplate")
  slider:SetPoint (sliderConf.anchor, sliderConf.x, sliderConf.y)
  slider:SetSize  (sliderConf.len, sliderConf.heigt)
  slider:HookScript("OnValueChanged", sliderConf.onChanged)
  
  if sliderConf.values then
    getglobal(slider:GetName().."Text"):SetText(sliderConf.values.label)
    getglobal(slider:GetName().."High"):SetText(sliderConf.values.high)
    getglobal(slider:GetName().."Low") :SetText(sliderConf.values.low)
    
    slider:SetMinMaxValues(sliderConf.values.low, sliderConf.values.high)
    slider:SetValueStep   (sliderConf.values.step)
    slider:SetValue       (sliderConf.values.value)
  end
  
  -- Add the glow scale slider edit box
  local sliderEditBox = ss.ConfigTools.createEditBox{
    parent         = slider,
    name           = sliderConf.name.."EditBox",
    width          = 50,
    height         = 10,
    anch           = "BOTTOMRIGHT",
    x              = 0,
    y              = 35,
    letters        = sliderEditBoxConf.maxLetters,
    text           = slider:GetValue(),
    onEnterPressed = sliderEditBoxConf.onEnterPressed,
  }
  
  return slider, sliderEditBox
end

function mtConfigTools.createCheckbox(check)
  check = setmetatable(check, { __index = mtCheck });
  local col = ss.ConfigTools.itemColor
  
  local checkbox  = CreateFrame("CheckButton", ss._f..check.name, check.parent, "UICheckButtonTemplate")
  checkbox:SetPoint  (check.anch, check.x, check.y)
  checkbox:SetChecked(check.checked)
  
  getglobal(ss._f..check.name.."Text"):SetFont(ss.private.font["general"], 23)
  getglobal(ss._f..check.name.."Text"):SetTextColor(col.r, col.g, col.b, col.a)
  getglobal(ss._f..check.name.."Text"):SetText(check.text)
  getglobal(ss._f..check.name.."Text"):SetWordWrap(check.wordWrap or false)
  getglobal(ss._f..check.name.."Text"):SetJustifyH(check.justifyH or "CENTER")
  
  if check.width then
    getglobal(ss._f..check.name.."Text"):SetWidth(check.width)
  end
  
  checkbox:HookScript("OnClick", check.onClick)
  
  return checkbox
end

function mtConfigTools.createEditBox(edit)
  edit = setmetatable(edit, { __index = mtEdit });
  
  local editBox = CreateFrame("EditBox", ss._f..edit.name, edit.parent, "InputBoxTemplate")
  editBox:SetSize      (edit.width, edit.height)
  editBox:SetPoint     (edit.anch,edit.x,edit.y)
  editBox:SetMaxLetters(edit.letters)
  editBox:SetText      (edit.text or "")
  editBox:SetAutoFocus (edit.autofocus or false)
  
  if (edit.onEnterPressed) then
    editBox:HookScript("OnEnterPressed", edit.onEnterPressed)
  else
    editBox:HookScript("OnEnterPressed", function(self)
      self:ClearFocus()
    end)
  end
  
  if (edit.onTabPressed) then
    editBox:HookScript("OnTabPressed", edit.onTabPressed)
  end
  
  if (edit.OnEditFocusLost) then
    editBox:HookScript("OnEditFocusLost", edit.OnEditFocusLost)
  end
  
  if (edit.onTextChanged) then
    editBox:HookScript("OnTextChanged", edit.onTextChanged)
  end
  
  if edit.label then
    editBox.label = ss.ConfigTools.addItemLabel(
      edit.label.name,
      editBox,
      edit.label.text,
      edit.label.location,
      edit.label.color
    )
  end
  
  return editBox
end

function mtConfigTools.createColorPicker(colorSelect)
  colorSelect = setmetatable(colorSelect, { __index = mtColorSelect });
  
  -- Create the ColorSelect frame.
  local colorFields = CreateFrame("ColorSelect", colorSelect.name or ss._f.."ColorFieldContainer", colorSelect.parent)
  colorFields:SetPoint(colorSelect.anch, colorSelect.x, colorSelect.y)
  colorFields:SetSize (colorSelect.width, colorSelect.height)
  
  -- Create colorpicker wheel.
  colorFields.cWheelTexture = colorFields:CreateTexture()
  colorFields.cWheelTexture:SetWidth (colorSelect.wheelWidth)
  colorFields.cWheelTexture:SetHeight(colorSelect.wheelWidth)
  colorFields.cWheelTexture:SetPoint ("TOPLEFT",0,0)
  colorFields:SetColorWheelTexture   (colorFields.cWheelTexture)
  
  colorFields.cWheelThumbTexture = colorFields:CreateTexture()
  colorFields.cWheelThumbTexture:SetTexture ("Interface\\Buttons\\UI-ColorPicker-Buttons")
  colorFields.cWheelThumbTexture:SetWidth   (colorSelect.thumbWidth)
  colorFields.cWheelThumbTexture:SetHeight  (colorSelect.thumbWidth)
  colorFields.cWheelThumbTexture:SetTexCoord(0,0.15625, 0, 0.625)
  colorFields:SetColorWheelThumbTexture     (colorFields.cWheelThumbTexture)
  
  -- Create the colorpicker slider.
  colorFields.valueTexture = colorFields:CreateTexture()
  colorFields.valueTexture:SetWidth (colorSelect.barWidth)
  colorFields.valueTexture:SetHeight(colorSelect.wheelWidth)
  colorFields.valueTexture:SetPoint ("TOPRIGHT", (colorSelect.barWidth * -1) - 10,0)
  colorFields:SetColorValueTexture  (colorFields.valueTexture)
  
  colorFields.valueThumbTexture = colorFields:CreateTexture()
  colorFields.valueThumbTexture:SetTexture ("Interface\\Buttons\\UI-ColorPicker-Buttons")
  colorFields.valueThumbTexture:SetWidth   (colorSelect.barWidth)
  colorFields.valueThumbTexture:SetHeight  (colorSelect.thumbWidth)
  colorFields.valueThumbTexture:SetTexCoord(0.25, 1, 0.875, 0)
  colorFields:SetColorValueThumbTexture    (colorFields.valueThumbTexture)
  
  -- Create the alpha widget.
  colorFields.alphaTextureContainer = CreateFrame("Frame", ss._f.."ColorFieldAlphaContainer", colorFields)
  colorFields.alphaTextureContainer:SetHeight      (colorSelect.wheelWidth)
  colorFields.alphaTextureContainer:SetWidth       (colorSelect.barWidth)
  colorFields.alphaTextureContainer:SetPoint       ("TOPRIGHT",0,0)
  colorFields.alphaTextureContainer:RegisterForDrag("LeftButton")
  colorFields.alphaTextureContainer:EnableMouse    (true)
  
  -- TODO: Set a background that is visible for transparent colors.
  -- Set the default hook for the text fields.
  ss.Extentions:Hook(colorFields, "OnColorSelect", function(self)
    -- Ensure custom fields are updated.
    local r, g, b, a = self:GetColorRGBA()
    self.colorFieldA :SetText(100 * a)
    self.colorFieldR :SetText(r * 255)
    self.colorFieldG :SetText(g * 255)
    self.colorFieldB :SetText(b * 255)
    self.alphaTexture:SetGradientAlpha("VERTICAL",0,0,0,1,r,g,b,1)
  end, "__")
  
  ss.Extentions:Hook(colorFields, "OnColorSelect", colorSelect.onColorSelect)
  
  function colorFields:SetColorRGBA(r, g, b, a)
    self:SetColorAlpha(a)
    self:SetColorRGB(r,g,b)
  end
  
  function colorFields:GetColorRGBA()
    local r, g, b = self:GetColorRGB()
    return r, g, b, self:GetColorAlpha()
  end
  
  function colorFields:SetColorAlpha(a)
    a = a < 0 and 0 or a
    a = a > 1 and 1 or a
    
    -- Update Alpha slider and trigger OnColorSelect.
    self.alphaThumbTexture:SetPoint("TOP",0,7 - (120 - 120 * a))
    self.colorFieldA:SetText(100 * a)
    self:SetColorRGB(self:GetColorRGB())
  end
  
  function colorFields:GetColorAlpha()
    local a = tonumber(self.colorFieldA:GetText()) or 100
    return a/100
  end
  
  colorFields.alphaTextureContainer:HookScript("OnDragStart", function(self)
    colorFields.alphaThumbContainer.minY = self:GetBottom()
  end)
  
  colorFields.alphaTextureContainer:HookScript("OnDragStop", function(self)
    colorFields.alphaThumbContainer.minY = nil
  end)
  
  -- I broke this with new tabs
  colorFields.alphaThumbTexture = colorFields.alphaTextureContainer:CreateTexture()
  colorFields.alphaThumbTexture:SetTexture ("Interface\\Buttons\\UI-ColorPicker-Buttons")
  colorFields.alphaThumbTexture:SetWidth   (colorSelect.barWidth)
  colorFields.alphaThumbTexture:SetHeight  (colorSelect.thumbWidth)
  colorFields.alphaThumbTexture:SetPoint   ("TOP",0,colorSelect.thumbWidth/2)
  colorFields.alphaThumbTexture:SetTexCoord(0.25, 1, 0.875, 0)
  
  colorFields.alphaTexture = colorFields.alphaTextureContainer:CreateTexture()
  colorFields.alphaTexture:SetAllPoints    (colorFields.alphaTextureContainer)
  colorFields.alphaTexture:SetColorTexture (1,1,1,1)
  colorFields.alphaTexture:SetGradientAlpha("VERTICAL",0,0,0,0,1,1,1,1)
  
  -- Add the alpha slider.
  colorFields.alphaThumbContainer = CreateFrame("Frame", ss._f.."AlphaDragFrame", colorFields)
  
  colorFields.alphaThumbContainer:HookScript("OnUpdate", function(self)
    if self.minY then
      -- Calculate yPos relative to container bottom.
      local _, yPos = GetCursorPosition()
      yPos = yPos/UIParent:GetScale() - self.minY
      
      -- Ensure movement is within the container boundaries.
      yPos = (yPos < 0)   and 0   or yPos
      yPos = (yPos > 120) and 120 or yPos
      yPos = yPos + colorSelect.thumbWidth/2
      
      -- Drag the slider.
      -- TODO: Review positioning during drag with different scaling.
      colorFields.alphaThumbTexture:SetPoint("TOP",0,yPos - colorSelect.wheelWidth)
      
      -- Update the alpha value.
      yPos = (yPos - colorSelect.thumbWidth/2) / 120
      colorFields:SetColorAlpha(yPos)
    end
  end)
  
  -- Create the edit fields
  local height = 25
  local width  = 30
  local xPos   = -width - 10
  local yPos   = height - 5
  
  -- Create the R color field
  colorFields.colorFieldR = ss.ConfigTools.createEditBox{
    parent        = colorFields,
    name          = "ColorFieldR",
    width         = width,
    height        = height,
    anch          = "BOTTOMRIGHT",
    x             = (xPos*3),
    y             = 0,
    letters       = 3,
    onTextChanged = function(self)
      local val = self:GetText()
      if tonumber(val) then
        local r,g,b = colorFields:GetColorRGB()
        colorFields:SetColorRGB(val/255,g,b)
      end
      
      if colorSelect.onTextChanged then
        colorSelect.onTextChanged(self)
      end
    end,
    onTabPressed = function(self)
      if colorFields.colorFieldG then
        colorFields.colorFieldG:SetFocus()
      else
        self:ClearFocus()
      end
    end,
  }
  
  -- Create the R color label
  colorFields.colorFieldR.label = ss.ConfigTools.createLabel{
    parent = colorFields,
    name   = "ColorFieldRLabel",
    width  = width,
    height = height,
    anch   = "BOTTOMRIGHT",
    x      = (xPos*3) - 10,
    y      = yPos,
    color  = ss.ConfigTools.itemColor,
    text   = "R",
  }
  
  -- Create the G color field
  colorFields.colorFieldG = ss.ConfigTools.createEditBox{
    parent        = colorFields,
    name          = "ColorFieldG",
    width         = width,
    height        = height,
    anch          = "BOTTOMRIGHT",
    x             = (xPos*2),
    y             = 0,
    letters       = 3,
    onTextChanged = function(self)
      local val = self:GetText()
      if tonumber(val) then
        local r,g,b = colorFields:GetColorRGB()
        colorFields:SetColorRGB(r,val/255,b)
      end
      
      if colorSelect.onTextChanged then
        colorSelect.onTextChanged(self)
      end
    end,
    onTabPressed = function(self)
      if colorFields.colorFieldB then
        colorFields.colorFieldB:SetFocus()
      else
        self:ClearFocus()
      end
    end,
  }
  
  -- Create the G color label
  colorFields.colorFieldG.label = ss.ConfigTools.createLabel{
    parent = colorFields,
    name   = "ColorFieldGLabel",
    width  = width,
    height = height,
    anch   = "BOTTOMRIGHT",
    x      = (xPos*2) - 10,
    y      = yPos,
    color  = ss.ConfigTools.itemColor,
    text   = "G",
  }
  
  -- Create the B color field
  colorFields.colorFieldB = ss.ConfigTools.createEditBox{
    parent        = colorFields,
    name          = "ColorFieldB",
    width         = width,
    height        = height,
    anch          = "BOTTOMRIGHT",
    x             = xPos,
    y             = 0,
    letters       = 3,
    onTextChanged = function(self)
      local val = self:GetText()
      if tonumber(val) then
        local r,g,b = colorFields:GetColorRGB()
        colorFields:SetColorRGB(r,g,val/255)
      end
      
      if colorSelect.onTextChanged then
        colorSelect.onTextChanged(self)
      end
    end,
    onTabPressed = function(self)
      if colorFields.colorFieldA then
        colorFields.colorFieldA:SetFocus()
      else
        self:ClearFocus()
      end
    end,
  }
  
  -- Create the B color label
  colorFields.colorFieldB.label = ss.ConfigTools.createLabel{
    parent = colorFields,
    name   = "ColorFieldBLabel",
    width  = width,
    height = height,
    anch   = "BOTTOMRIGHT",
    x      = xPos - 10,
    y      = yPos,
    color  = ss.ConfigTools.itemColor,
    text   = "B",
  }
  
  -- Create the Alpha field
  colorFields.colorFieldA = ss.ConfigTools.createEditBox{
    parent        = colorFields,
    name          = "ColorFieldA",
    width         = width,
    height        = height,
    anch          = "BOTTOMRIGHT",
    x             = 0,
    y             = 0,
    letters       = 3,
    onTextChanged = function(self)
      local val = self:GetText()
      if tonumber(val) then
        colorFields:SetColorAlpha(val/100)
      end
      
      if colorSelect.onTextChanged then
        colorSelect.onTextChanged(self)
      end
    end,
    onTabPressed = function(self)
      self:ClearFocus()
    end,
  }
  
  -- Create the Alpha label
  colorFields.colorFieldA.label = ss.ConfigTools.createLabel{
    parent = colorFields,
    name   = "ColorFieldALabel",
    width  = width,
    height = height,
    anch   = "BOTTOMRIGHT",
    x      = -10,
    y      = yPos,
    color  = ss.ConfigTools.itemColor,
    text   = "A",
  }
  
  -- Add the class button
  colorFields.classButton = ss.ConfigTools.createButton{
    parent  = colorFields,
    name    = "ColorFieldClassButton",
    width   = 45,
    height  = height,
    anch    = "BOTTOMLEFT",
    x       = -20,
    y       = 0,
    text    = ss.T["btn_class"],
    onClick = function()
      colorFields:SetColorRGBA(ss.ConfigTools.bannerColor.r, ss.ConfigTools.bannerColor.g, ss.ConfigTools.bannerColor.b, ss.ConfigTools.bannerColor.a)
    end,
  }
  
  return colorFields
end

function mtConfigTools.createLabel(label)
  label = setmetatable(label, { __index = mtLabel });
  
  local fontString = label.parent:CreateFontString(label.name)
  fontString:SetFont     (ss.private.font["general"], 23)
  fontString:SetPoint    (label.anch, label.x, label.y)
  fontString:SetSize     (label.width, label.height)
  fontString:SetTextColor(label.color.r, label.color.g, label.color.b, label.color.a)
  fontString:SetText     (label.text)
  fontString:SetJustifyV (label.justifyV)
  fontString:SetJustifyH (label.justifyH)
  
  return fontString
end

function mtConfigTools.createTitle(text, parent)
  local title = parent:CreateFontString(nil, "BossEmoteNormalHuge")
  title:SetFont     (ss.private.font["general"], 32)
  title:SetPoint    ("TOPRIGHT", -ss.ConfigTools.itemPadTitle, (ss.ConfigTools.topMargin - 3))
  title:SetSize     (400, 39)
  title:SetTextColor(ss.ConfigTools.titleColor.r, ss.ConfigTools.titleColor.g, ss.ConfigTools.titleColor.b, ss.ConfigTools.titleColor.a)
  title:SetText     (text)
  title:SetJustifyV ("TOP")
  title:SetJustifyH ("RIGHT")
  
  return title
end

function mtConfigTools.addItemLabel(name, target, text, location, color, leftLabelMargin)
  leftLabelMargin = leftLabelMargin or ss.ConfigTools.leftLabelMargin
  location        = location or "left"
  color           = color    or ss.ConfigTools.itemColor
  
  -- Determine relative location
  local anch, x, y = select(3, target:GetPoint())
  local topAdjustY = string.match(strlower(anch), "top") and 22 or 17
  
  x = (strlower(location) == "left") and (x - leftLabelMargin) or ((strlower(location) == "top") and (x + 20) or x)
  y = (strlower(location) == "left") and (y - 3)               or ((strlower(location) == "top") and (y + topAdjustY) or y)
  
  
  local fontString = target:GetParent():CreateFontString(name)
  fontString:SetFont     (ss.private.font["general"], 23)
  fontString:SetPoint    (anch,x,y)
  fontString:SetSize     (leftLabelMargin, 39)
  fontString:SetTextColor(color.r, color.g, color.b, color.a)
  fontString:SetText     (text)
  fontString:SetJustifyV ("TOP")
  fontString:SetJustifyH ("Left")
  
  return fontString
end

function mtConfigTools.addWidget(widget)
  if widget.type == "Checkbox" then
    getCheckbox(widget.name, widget.text, widget.parent, widget.checked, widget.onClick)
  elseif widget.type == "Dropdown" then
    widget.parent[widget.name] = getDropdown(widget)
  end
end

function mtConfigTools.getWidgetContainer(parent, name)
  -- Add the widget container
  local widgetFrame = CreateFrame("Frame", ss._f..name, parent)
  widgetFrame:SetAllPoints(parent)
  
  -- Add the banner.
  widgetFrame.banner = widgetFrame:CreateFontString(name.."Banner", "ARTWORK", "NumberFontNormalHuge")
  widgetFrame.banner:SetFont     (ss.private.font["general"], 50)
  widgetFrame.banner:SetPoint    ("TOPRIGHT", ss.ConfigTools.itemPadTitle, -ss.ConfigTools.itemPadTitle)
  widgetFrame.banner:SetSize     (262, 57)
  widgetFrame.banner:SetTextColor(ss.ConfigTools.bannerColor.r, ss.ConfigTools.bannerColor.g, ss.ConfigTools.bannerColor.b, ss.ConfigTools.bannerColor.a)
  widgetFrame.banner:SetText     ("Seamore Spheres")
  widgetFrame.banner:SetJustifyV ("TOP")
  
  return widgetFrame
end

ss.Utils.addModule("ConfigTools", mtConfigTools)
