local AddOnName, nsVars = ...
local ss = nsVars.SS

local CreateFrame, getglobal, InterfaceOptions_AddCategory = CreateFrame, 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 mtEdit = {
    parent = UIParent,
    width = 150,
    height = 25,
    anch = "TOPLEFT",
    x = 0,
    y = 0,
    letters = 0,
    text = "",
    autofocus = false,
}
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 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 mtColorSelect = {
    parent = UIParent,
    width = 160,
    height = 175,
    anch = "TOPLEFT",
    x = 0,
    y = 0,
    onTextChanged = function() end,
}

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 = -55,
    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", 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", 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",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", check.name, check.parent, "UICheckButtonTemplate")
        checkbox:SetPoint(check.anch, check.x, check.y)
        checkbox:SetChecked(check.checked)
        getglobal(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", 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", "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",name,parent, "UICheckButtonTemplate")
        parent[name]:SetPoint(getItemPos())
        parent[name]:SetChecked(checked)
        getglobal(name.."Text"):SetText(text)
        parent[name]:SetScript("OnClick", onClick)
    end,
    getWidgetContainer = function(parent, name)
        -- Add the widget container
        local widgetFrame = CreateFrame("Frame", 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 });
