local _, addonTable = ...

local Options = CreateFrame("Frame", "ScritchPopOptions", UIParent, "ScritchPopOptions")
addonTable.Options = Options
Options.steps = {1, 3, 5, 10, 25}
Options.Select = {}
Options.Button = {}

function addonTable.InitOptions()
    ---------------------------------------------------------------
    -- Options Left List
    ---------------------------------------------------------------
    function SetupCheckbox(check, key, onChange)
        check:SetChecked(ScritchPopConfig[key])
        check:SetScript("OnClick", function(self)
            ScritchPopConfig[key] = self:GetChecked()
            if onChange then onChange(ScritchPopConfig[key]) end
            addonTable.Options:UpdatePreview()
            addonTable.cp_frame:ApplyLayout()
        end)
    end

    function SetupSlider(slider, key, min, max, step, onChange)
        slider:SetMinMaxValues(min, max)
        slider:SetValue(ScritchPopConfig[key] or min)
        slider:SetValueStep(step or 0.01)
        if slider.Low then slider.Low:SetText(min) end
        if slider.High then slider.High:SetText(max) end
        if slider.Text then slider.Text:SetText(ScritchPopConfig[key]) end

        slider:SetScript("OnValueChanged", function(self, value)
            local roundedValue = math.floor(value * 100 + 0.5) / 100
            ScritchPopConfig[key] = roundedValue
            if onChange then onChange(roundedValue) end
            addonTable.Options:UpdatePreview()
            addonTable.cp_frame:ApplyLayout()
            addonTable.EnergyBar:updateLayout()
            if slider.Text then slider.Text:SetText(roundedValue) end
        end)
    end

    function SetupDropdown(dropdown, key, options, onChange)
        UIDropDownMenu_SetWidth(dropdown, 140)

        local function Initialize()
            UIDropDownMenu_Initialize(dropdown, function(self, level)
                for _, option in ipairs(options) do
                    local info = UIDropDownMenu_CreateInfo()
                    info.text = option
                    info.value = option
                    info.func = function(btn)
                        ScritchPopConfig[key] = btn.value
                        UIDropDownMenu_SetSelectedValue(dropdown, btn.value)
                        if onChange then onChange(btn.value) end
                        addonTable.Options:UpdatePreview()
                        addonTable.cp_frame:ApplyLayout()
                    end
                    UIDropDownMenu_AddButton(info, level)
                end
            end)
        end

        Initialize()
        UIDropDownMenu_SetSelectedValue(dropdown, ScritchPopConfig[key])

        return function(newOptions, newValue)
            options = newOptions
            Initialize()
            UIDropDownMenu_SetSelectedValue(dropdown, newValue)
        end
    end

    local offset = 0
    function AddRow(offset, template, label, key, type, options, onChange)
        local row = CreateFrame("Frame", nil, Options, template)
        row.Label:SetText(label)
        if (offset < 0) then
            row:SetPoint("TOPRIGHT", Options, "TOPRIGHT", 48, offset*(64))
        else
            row:SetPoint("TOPLEFT", Options, "TOPLEFT", 12, offset*(-64))
        end
        offset = offset + 1

        if type == "dropdown" then
            SetupDropdown(row.Dropdown, key, options, onChange)
        elseif type == "checkbox" then
            SetupCheckbox(row.Checkbox, key, onChange)
        elseif type == "slider" then
            SetupSlider(row.Slider, key, options[1], options[2], 0.01, onChange)
        end
        return row
    end

    Options.Select.Energy = AddRow(-1, "ScritchPopOptionsCheckbox", "Energy Bar:", "energy_bar", "checkbox", nil, function(value)
        if value then
            addonTable.EnergyBar:createEnergyBar()
        else
            addonTable.EnergyBar:destroyEnergyBar()
        end
    end)

    Options.Select.Lock = AddRow(1, "ScritchPopOptionsCheckbox", "Move frame:", "movable", "checkbox", nil, function(value)
        addonTable.cp_frame:SetMovable(value)
        addonTable.cp_frame:EnableMouse(value)
    end)

    Options.Select.Scale = AddRow(2, "ScritchPopOptionsSlider", "Scale:", "scale", "slider", {0.15, 3}, function(value)
        addonTable.cp_frame:SetScale(value)
        addonTable.EnergyBar:updateLayout()
    end)

    Options.Select.Gap = AddRow(3, "ScritchPopOptionsSlider", "Gap:", "gap", "slider", {-20, 20})

    Options.Select.Pop = AddRow(4, "ScritchPopOptionsCheckbox", "Toggle popping:", "popping", "checkbox", nil, function(value)
        if not value then
            addonTable.blinkState = false
        end
    end)

    Options.Select.PopSpeed = AddRow(5, "ScritchPopOptionsSlider", "Pop speed:", "popSpeed", "slider", {0.10, 2})

    Options.Select.Color = AddRow(6, "ScritchPopOptionsDropdown", "Color:", "color", "dropdown", {"Red", "Blue", "Green", "Purple", "Yellow"})
    local refreshColorDropdown = SetupDropdown(Options.Select.Color.Dropdown, "color", {"Red", "Blue", "Green", "Purple", "Yellow"})

    Options.Select.Shape = AddRow(7, "ScritchPopOptionsDropdown", "Shape:", "shape", "dropdown", {"scritchPop", "kitchPop"}, function(value)
        if value == "scritchPop" then
            refreshColorDropdown({"Red", "Blue", "Green", "Purple", "Yellow"}, ScritchPopConfig.color)
        else
            if ScritchPopConfig.color == "Yellow" then
                ScritchPopConfig.color = "Red"
            end
            refreshColorDropdown({"Red", "Blue", "Green", "Purple"}, ScritchPopConfig.color)
        end
    end)

    Options.Select.Opacity = AddRow(8, "ScritchPopOptionsSlider", "General opacity:", "opacity", "slider", {0, 1}, function(value) addonTable.cp_frame:UpdateOpacity() end)
    Options.Select.Combat_Opacity = AddRow(9, "ScritchPopOptionsSlider", "Combat opacity:", "combat_opacity", "slider", {0, 1}, function(value) addonTable.cp_frame:UpdateOpacity() end)

    ---------------------------------------------------------------
    -- Options Incremental Movement Buttons
    ---------------------------------------------------------------
    local config = addonTable.getConfig()
    function moveFrame(direction)
        local frame = addonTable.cp_frame:GetFrame()
        local config = addonTable.getConfig()
        local step = Options.steps[config.step_index]

        local ux, uy = UIParent:GetCenter()
        local fx, fy = frame:GetCenter()

        local x = fx - ux
        local y = fy - uy

        if direction == "TOP" then
            y = y + step
        elseif direction == "BOTTOM" then
            y = y - step
        elseif direction == "LEFT" then
            x = x - step
        elseif direction == "RIGHT" then
            x = x + step
        end

        config.point = "CENTER"
        config.relativePoint = "CENTER"
        config.position_x = x
        config.position_y = y

        frame:ClearAllPoints()
        frame:SetPoint(config.point, UIParent, config.relativePoint, config.position_x, config.position_y)
    end
    function createIncremental(dir, text, step)
        local btn = CreateFrame("Button", nil, Options.Button.Incremental, "UIPanelButtonTemplate")
        btn:SetSize(32, 32)
        btn:SetPoint(dir)
        btn:SetText(text)
        if step then
            btn:SetScript("OnClick", step)
            return btn
        else
            btn:SetScript("OnClick", function() moveFrame(dir) end)
        end
        return btn
    end

    Options.Button.Incremental = CreateFrame("Frame", nil, Options, "BackdropTemplate")
    Options.Button.Incremental:SetSize(96, 96)
    Options.Button.Incremental:SetPoint("RIGHT", Options, "RIGHT", -15-64, -64)
    Options.Button.Incremental.TOP = createIncremental("TOP", "+")
    Options.Button.Incremental.BOTTOM = createIncremental("BOTTOM", "-")
    Options.Button.Incremental.LEFT = createIncremental("LEFT", "<")
    Options.Button.Incremental.RIGHT = createIncremental("RIGHT", ">")
    Options.Button.Incremental.Step = createIncremental("CENTER", Options.steps[config.step_index].."x", function(self) 
        local config = addonTable.getConfig()
        config.step_index = config.step_index % #Options.steps + 1
        self:SetText(Options.steps[config.step_index].."x")
    end)


    ---------------------------------------------------------------
    -- Options Centering Buttons
    ---------------------------------------------------------------
    function centerFrame(zeroX, zeroY)
        local frame = addonTable.cp_frame:GetFrame()
        local config = addonTable.getConfig()
        local ux, uy = UIParent:GetCenter()
        local fx, fy = frame:GetCenter()

        config.point = "CENTER"
        config.relativePoint = "CENTER"

        if zeroX then
            config.position_x = 0
        else
            config.position_x = fx - ux
        end

        if zeroY then
            config.position_y = 0
        else
            config.position_y = fy - uy
        end

        frame:ClearAllPoints()
        frame:SetPoint(config.point, UIParent, config.relativePoint, config.position_x, config.position_y)
    end

    Options.Button.Center = CreateFrame("Button", nil, Options, "UIPanelButtonTemplate")
    Options.Button.Center:SetSize(160, 24)
    Options.Button.Center:SetPoint("RIGHT", Options, "RIGHT", -15-32, -32-96)
    Options.Button.Center:SetText("Center")
    Options.Button.Center:SetScript("OnClick", function() centerFrame(true, true) end)

    Options.Button.CenterVertical = CreateFrame("Button", nil, Options, "UIPanelButtonTemplate")
    Options.Button.CenterVertical:SetSize(160, 24)
    Options.Button.CenterVertical:SetPoint("RIGHT", Options, "RIGHT", -15-32, -64-96)
    Options.Button.CenterVertical:SetText("Center Vertically")
    Options.Button.CenterVertical:SetScript("OnClick", function() centerFrame(false, true) end)

    Options.Button.CenterHorizontal = CreateFrame("Button", nil, Options, "UIPanelButtonTemplate")
    Options.Button.CenterHorizontal:SetSize(160, 24)
    Options.Button.CenterHorizontal:SetPoint("RIGHT", Options, "RIGHT", -15-32, -96-96)
    Options.Button.CenterHorizontal:SetText("Center Horizontally")
    Options.Button.CenterHorizontal:SetScript("OnClick", function() centerFrame(true, false) end)

    if not Options.Preview then
        Options.Preview = Options:CreateTexture(nil, "BACKGROUND")
        Options.Preview:SetSize(128, 128)
        Options.Preview:SetPoint("RIGHT", Options, "RIGHT", -15-48, 96)
    end
    Options.Preview:SetTexture(getPop())

    function Options:UpdatePreview()
        Options.Preview:SetTexture(getPop())
    end



    Options:Hide()
end


SLASH_SCRITCHPOP1 = "/scritchpop"
SLASH_SCRITCHPOP2 = "/scritch"
SLASH_SCRITCHPOP3 = "/spcp"
SLASH_RL1 = "/rl"

SlashCmdList["RL"] = function(msg)
    ReloadUI()
end

SlashCmdList["SCRITCHPOP"] = function(msg)
    local cmd, arg = msg:match("^(%S*)%s*(.-)$")
    local config = addonTable.getConfig()

    if cmd == "default" or cmd == "reset" then
        for _, frame in pairs(Options.Select or {}) do
            frame:Hide()
            frame:SetParent(nil)
        end
        for _, frame in ipairs({ Options.Button.Incremental:GetChildren() }) do
            frame:Hide()
            frame:SetParent(nil)
        end
        Options.Button.Incremental:Hide()
        Options.Button.Incremental = nil
        restoreDefaults()
        addonTable.cp_frame:Cleanup()
        addonTable.cp_frame:Init()
        addonTable.InitOptions()
    else 
        addonTable.Options:Show()
    end
end