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

local CreateFrame, UIParent, getglobal, InterfaceOptions_AddCategory = CreateFrame, UIParent, getglobal, InterfaceOptions_AddCategory
local select, strlower, setmetatable = select, strlower, setmetatable
local UIDropDownMenu_Initialize, UIDropDownMenu_JustifyText = UIDropDownMenu_Initialize, UIDropDownMenu_JustifyText

local itemCol = 1
local itemRow = 1

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         = 160,
    height        = 175,
    anch          = "TOPLEFT",
    x             = 0,
    y             = 0,
    onTextChanged = function() end,
}
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,},
}

local getItemPos = function()
    if itemCol == 1 then
        itemCol = itemCol + 1

        if itemRow == 1 then
            return "TOPLEFT", 26, -181
        elseif itemRow == 2 then
            return "TOPLEFT", 26, -219
        elseif itemRow == 3 then
            return "TOPLEFT", 26, -257
        elseif itemRow == 4 then
            return "TOPLEFT", 26, -295
        elseif itemRow == 5 then
            return "TOPLEFT", 26, -335
        end
    elseif itemCol == 2 then
        local row = itemRow
        itemCol = itemCol - 1
        itemRow = itemRow + 1

        if row == 1 then
            return "TOPLEFT", 200, -181
        elseif row == 2 then
            return "TOPLEFT", 200, -219
        elseif row == 3 then
            return "TOPLEFT", 200, -257
        elseif row == 4 then
            return "TOPLEFT", 200, -295
        elseif row == 5 then
            return "TOPLEFT", 200, -335
        end
    end

    return "CENTER", 0, 0
end

local mtConfigTools = {
    itemHeight       = 30,
    itemPadLeft      = 50,
    itemPadCorner    = 10,
    itemPadTitle     = 15,
    topMargin        = -60,
    leftLabelMargin  = 145,
    bannerColor      = ss.ClassResourceData.classColor(ss.curClass),
    titleColor       = {r=0.5,g=1,b=0.3,a=1},
    headerItemColor  = {r=1.0,g=0.7,b=0.5,a=1},
    itemColor        = {r=0,g=0.5,b=1,a=1},
    createButton     = function(btn)
        btn = setmetatable(btn, { __index = mtButton });

        local button = CreateFrame("Button", ss._f..btn.name, btn.parent, "GameMenuButtonTemplate")
        button:SetSize  (btn.width, btn.height)
        button:SetPoint (btn.anch, btn.x, btn.y)
        button:SetText  (btn.text)
        button:SetScript("OnClick", btn.onClick)

        return button
    end,
    createInterfaceOption = function(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,
    createDropdown = function(menu)
        local dropdown = CreateFrame("Button", ss._f..menu.name, menu.parent, "UIDropDownMenuTemplate")
        dropdown:SetSize (menu.width, menu.height)
        dropdown:SetPoint(menu.anchor, menu.x, menu.y)
        UIDropDownMenu_Initialize (dropdown, menu.init)
        UIDropDownMenu_JustifyText(dropdown, menu.tAlign)

        if menu.label then
            dropdown.label = ss.ConfigTools.addItemLabel(menu.label.name, dropdown, menu.label.text, menu.label.location, menu.label.color)
        end

        return dropdown
    end,
    createSliderField = function(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.width)
        slider:SetScript("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,
    createCheckbox = function(check)
        check = setmetatable(check, { __index = mtCheck });

        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"):SetText(check.text)
        checkbox:SetScript("OnClick", check.onClick)

        return checkbox
    end,
    createEditBox = function(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:SetScript("OnEnterPressed", edit.onEnterPressed)
        end

        if (edit.onTextChanged) then
            editBox:SetScript("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,
    createColorPicker = function(colorSelect)
        colorSelect = setmetatable(colorSelect, { __index = mtColorSelect });

        -- Create the ColorSelect frame
        local colorFields = CreateFrame("ColorSelect", ss._f.."ColorFieldContainer", colorSelect.parent)
        colorFields:SetPoint(colorSelect.anch, colorSelect.x, colorSelect.y)
        colorFields:SetSize (160, 175)

        -- create the colorpicker wheel
        colorFields.cWheelTexture = colorFields:CreateTexture()
        colorFields.cWheelTexture:SetWidth (120)
        colorFields.cWheelTexture:SetHeight(120)
        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   (10)
        colorFields.cWheelThumbTexture:SetHeight  (10)
        colorFields.cWheelThumbTexture:SetTexCoord(0,0.15625, 0, 0.625)
        colorFields:SetColorWheelThumbTexture     (colorFields.cWheelThumbTexture)

        -- create the colorpicker slider
        colorFields.valueTexture = colorFields:CreateTexture()
        colorFields.valueTexture:SetWidth (30)
        colorFields.valueTexture:SetHeight(120)
        colorFields.valueTexture:SetPoint ("TOPRIGHT",0,0)
        colorFields:SetColorValueTexture  (colorFields.valueTexture)

        colorFields.valueThumbTexture = colorFields:CreateTexture()
        colorFields.valueThumbTexture:SetTexture ("Interface\\Buttons\\UI-ColorPicker-Buttons")
        colorFields.valueThumbTexture:SetWidth   (30)
        colorFields.valueThumbTexture:SetHeight  (14)
        colorFields.valueThumbTexture:SetTexCoord(0.25, 1, 0.875, 0)
        colorFields:SetColorValueThumbTexture    (colorFields.valueThumbTexture)

        -- 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 = colorSelect.onTextChanged,
        }

        -- 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 = colorSelect.onTextChanged,
        }

        -- 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 = colorSelect.onTextChanged,
        }

        -- 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 = colorSelect.onTextChanged,
        }

        -- 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 reset button
        colorFields.classButton = ss.ConfigTools.createButton{
            parent  = colorFields,
            name    = "ColorFieldClassButton",
            width   = 40,
            height  = height,
            anch    = "BOTTOMLEFT",
            x       = -40,
            y       = 0,
            text    = "Class",
            onClick = function()
                colorFields.colorFieldR:SetText    (ss.ConfigTools.bannerColor.r * 255)
                colorFields.colorFieldG:SetText    (ss.ConfigTools.bannerColor.g * 255)
                colorFields.colorFieldB:SetText    (ss.ConfigTools.bannerColor.b * 255)
                colorFields.colorFieldA:SetText    (100 - (100 * ss.ConfigTools.bannerColor.a))
                colorFields            :SetColorRGB(ss.ConfigTools.bannerColor.r, ss.ConfigTools.bannerColor.g, ss.ConfigTools.bannerColor.b)
            end,
        }

        return colorFields
    end,
    createLabel = function(label)
        label = setmetatable(label, { __index = mtLabel });

        local fontString = label.parent:CreateFontString(label.name)
        fontString:SetFont     (ss.private.font["general"], 19)
        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,
    createTitle = function(text, parent)
        local title = parent:CreateFontString(nil, "BossEmoteNormalHuge")
        title:SetFont     (ss.private.font["general"], 26)
        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,
    addItemLabel = function(name, target, text, location, color)
        location = location or "left"
        color    = color    or ss.ConfigTools.itemColor

        -- Determine relative location
        local anch, x, y = select(3, target:GetPoint())
        x                = (strlower(location) == "left") and (x - ss.ConfigTools.leftLabelMargin) or ((strlower(location) == "top") and (x + 20) or x)
        y                = (strlower(location) == "left") and (y - 5) or ((strlower(location) == "top")                              and (y + 15) or y)

        local fontString = target:GetParent():CreateFontString(name)
        fontString:SetFont     (ss.private.font["general"], 19)
        fontString:SetPoint    (anch,x,y)
        fontString:SetSize     (181, 39)
        fontString:SetTextColor(color.r, color.g, color.b, color.a)
        fontString:SetText     (text)
        fontString:SetJustifyV ("TOP")
        fontString:SetJustifyH ("Left")

        return fontString
    end,
    getCheckbox = function(name, text, parent, checked, onClick)
        parent[name] = CreateFrame("CheckButton",ss._f..name,parent, "UICheckButtonTemplate")
        parent[name]:SetPoint  (getItemPos())
        parent[name]:SetChecked(checked)

        getglobal(ss._f..name.."Text"):SetText(text)
        parent[name]:SetScript("OnClick", onClick)
    end,
    getWidgetContainer = function(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"], 42)
        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["ConfigTools"] = setmetatable({}, { __index = mtConfigTools });
