
-------------------------
-- Defaults
-------------------------
local defaults = {
    ["layerCount"] = 1,
    ["chainSpacing"] = 250,
    ["horizontalScale"] = 1.0,
    ["verticalScale"] = 2.0,
    ["connectTrails"] = false,
    ["numTrails"] = 10,
    ["trailSpacing"] = 10,
    ["trailRadius"] = 20,
    ["trailIntensity"] = 0.5,
    ["cursorSize"] = 116,
    ["glowIntensity"] = 0.800000011920929,
    ["trailColor"] = {
    ["a"] = 1,
    ["b"] = 1,
    ["g"] = 1,
    ["r"] = 1,
    },
    ["glowHollowness"] = 0,
    ["trailCount"] = 15,
    ["glowBelow"] = false,
    ["glowAboveCursor"] = false,
    ["cursorColor"] = {
    ["a"] = 1,
    ["b"] = 1,
    ["g"] = 0.9960784912109375,
    ["r"] = 0.545098066329956,
    },
    ["glowRadius"] = 0.1195038557052612,
    ["trailFrameStrata"] = "TOOLTIP",
    ["glowColor"] = {
    ["a"] = 1,
    ["b"] = 0.917647123336792,
    ["g"] = 1,
    ["r"] = 0.3568627536296845,
    },
    ["additionalEffects"] = 1,
    ["numGlows"] = 30,
    ["trailFrameStrata"] = "HIGH",
 
    ["glowPulsingIntensity"] = 0.5,
    ["cursorOffsetX"] = -1,
    ["trailSizeStart"] = 20,
    ["glowThickness"] = 0.800000011920929,
    ["trailColorEffect"] = 11,
    ["pulsingSpeed"] = 10,
    ["trailLayerSpacing"] = 0,
    ["disableGlowPulsing"] = false,
    ["trailMovementEffect"] = 9,
    ["trailTexture"] = 7,
    ["cursorOffsetY"] = 5,
    ["trailOffsetY"] = 1,
    ["trailOffsetX"] = 1,
    ["cursorColorEffect"] = 5,
    ["cursorFrameStrata"] = "BACKGROUND",
    ["selectedCursorTextureName"] = "Circle_1_Hovering",
    ["trailInitialSeparation"] = 100,
    ["cursorTexture"] = 34,
    ["enableTrails"] = true,
    ["trailSizeEnd"] = 20,
    ["minimapPosition"] = {
    ["y"] = 0,
    ["x"] = 0,
    },
    ["trailDelay"] = 0.1,
    ["menuPosition"] = {
    ["y"] = -19.49995803833008,
    ["x"] = -275.8334350585938,
    ["point"] = "TOP",
    ["relativePoint"] = "TOP",
    },
    ["selectedGlowEffect"] = 5,
    ["patternGlowCount"] = 29,
    ["trailLayerCount"] = 9,
    ["glowSize"] = 0.699999988079071,
    }

-------------------------
-- Local Variables
-------------------------
local colorIndexTrail     = 0
local pulseValueTrail     = 0.5
local pulseDirectionTrail = 1
local previousCursorX, previousCursorY = nil, nil
local cursorStopped   = false

-- Define customCursor at file scope
local customCursor = nil

-------------------------
-- Initialize the global EasyCursorTrails table
-------------------------
local EasyCursorTrails = EasyCursorTrails or {}
_G["EasyCursorTrails"] = EasyCursorTrails

-- Ensure global references:
EasyCursorTrails.trailPool       = EasyCursorTrails.trailPool or {}
EasyCursorTrails.cursorPositions = EasyCursorTrails.cursorPositions or {}

local function SaveToCurrentProfile(key, value)
    if EasyCursorTrailsDB and EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.currentProfile then
        -- Prevent saving certain keys, like 'trailTextures'
        if key ~= "trailTextures" and key ~= "trailTexture" then
            -- Save to the current profile in the database
            EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile][key] = value

            -- Save to the active profile in memory (if applicable)
            if EasyCursorTrails.currentProfile then
                EasyCursorTrails.currentProfile[key] = value
            end

        end
    else
        -- Handle cases where profile data is missing
        -- print("EasyCursorTrails: Failed to save to profile. Profile data missing.")
    end
end


-------------------------
-- GetCharacterKey Function
-------------------------
-- Function to get the current character's unique key
local function GetCharacterKey()
    local name, realm = UnitName("player"), GetRealmName()
    return name .. "-" .. realm
end

-------------------------
-- InitializeEasyCursorTrailsDB Function
-------------------------
-- Initialize Saved Variables
local function InitializeEasyCursorTrailsDB()
    if not EasyCursorTrailsDB then
        EasyCursorTrailsDB = { profiles = {}, currentProfile = "Default", lastSelectedProfile = "Default" }
        ----print("EasyCursorTrails: Created EasyCursorTrailsDB table with default profile.")
    end

    if not EasyCursorTrailsDB.profiles then
        EasyCursorTrailsDB.profiles = {}
        ----print("EasyCursorTrails: Initialized profiles table.")
    end

    -- Ensure "Default" profile exists
    if not EasyCursorTrailsDB.profiles["Default"] then
        EasyCursorTrailsDB.profiles["Default"] = {}
        for key, value in pairs(defaults) do
            if type(value) == "table" then
                EasyCursorTrailsDB.profiles["Default"][key] = {}
                for subKey, subValue in pairs(value) do
                    EasyCursorTrailsDB.profiles["Default"][key][subKey] = subValue
                end
            else
                EasyCursorTrailsDB.profiles["Default"][key] = value
            end
        end
        ----print("EasyCursorTrails: Created 'Default' profile with default settings.")
    end

    -- Load the last selected profile, if valid
    if EasyCursorTrailsDB.lastSelectedProfile and EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.lastSelectedProfile] then
        EasyCursorTrailsDB.currentProfile = EasyCursorTrailsDB.lastSelectedProfile
        ----print("EasyCursorTrails: Loaded last selected profile:", EasyCursorTrailsDB.lastSelectedProfile)
    else
        -- Fallback to default profile if the last selected profile is invalid
        EasyCursorTrailsDB.currentProfile = "Default"
        EasyCursorTrailsDB.lastSelectedProfile = "Default"
        ----print("EasyCursorTrails: Fallback to 'Default' profile.")
    end

    -- Validate the current profile and assign defaults if necessary
    local currentProfileName = EasyCursorTrailsDB.currentProfile
    local currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
    if not currentProfile then
        EasyCursorTrailsDB.profiles[currentProfileName] = {}
        currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
        for key, value in pairs(defaults) do
            if type(value) == "table" then
                currentProfile[key] = {}
                for subKey, subValue in pairs(value) do
                    currentProfile[key][subKey] = subValue
                end
            else
                currentProfile[key] = value
            end
        end
        ----print("EasyCursorTrails: Created profile with defaults for:", currentProfileName)
    else
        -- Populate missing values in the profile with defaults
        for key, value in pairs(defaults) do
            if type(value) == "table" then
                if type(currentProfile[key]) ~= "table" then
                    currentProfile[key] = {}
                end
                for subKey, subValue in pairs(value) do
                    if currentProfile[key][subKey] == nil then
                        currentProfile[key][subKey] = subValue
                    end
                end
            else
                if currentProfile[key] == nil then
                    currentProfile[key] = value
                end
            end
        end
    end

    -- Save the last selected profile to ensure persistence
    EasyCursorTrailsDB.lastSelectedProfile = EasyCursorTrailsDB.currentProfile

    -- Assign currentProfile for easy reference in global scope
    EasyCursorTrails.currentProfile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]

    -- Debug: Print the currently selected profile
    ----print("EasyCursorTrails: Current profile on initialization:", EasyCursorTrailsDB.currentProfile)
end

-- Debug Function to Print Database
local function DebugPrintDatabase()
    ----print("EasyCursorTrailsDB Contents:")
    if EasyCursorTrailsDB then
        for key, value in pairs(EasyCursorTrailsDB) do
            if type(value) == "table" then
                ----print("  " .. key .. " = {")
                for k, v in pairs(value) do
                    ----print("    " .. k .. " = " .. tostring(v))
                end
                ----print("  }")
            else
                ----print("  " .. key .. " = " .. tostring(value))
            end
        end
    else
        ----print("  EasyCursorTrailsDB is nil!")
    end
end

-- 2. Initialize Saved Variables with Defaults
if not EasyCursorTrailsDB then
    -- First-time load: Assign all default settings
    EasyCursorTrailsDB = {}
    for key, value in pairs(defaults) do
        if type(value) == "table" then
            EasyCursorTrailsDB[key] = {}
            for subKey, subValue in pairs(value) do
                EasyCursorTrailsDB[key][subKey] = subValue
            end
        else
            EasyCursorTrailsDB[key] = value
        end
    end
else
    -- Subsequent loads: Assign missing settings without overwriting existing ones
    for key, value in pairs(defaults) do
        if EasyCursorTrailsDB[key] == nil then
            if type(value) == "table" then
                EasyCursorTrailsDB[key] = {}
                for subKey, subValue in pairs(value) do
                    EasyCursorTrailsDB[key][subKey] = subValue
                end
            else
                EasyCursorTrailsDB[key] = value
            end
        elseif type(value) == "table" and type(EasyCursorTrailsDB[key]) == "table" then
            -- For nested tables, assign missing sub-keys
            for subKey, subValue in pairs(value) do
                if EasyCursorTrailsDB[key][subKey] == nil then
                    EasyCursorTrailsDB[key][subKey] = subValue
                end
            end
        end
    end
end

-------------------------
-- Custom Cursors
-------------------------
local customCursorTextures = {
    {
        name = "Pearl (Use Custom + Glow Effect)",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Pearl",
        animated = false,
    },
    {
        name = "Alien",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Alien3",
        animated = false,
    },
    {
        name = "Broom Stick",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\BroomStick1",
        animated = false,
    },
    {
        name = "Bullet",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Bullet1",
        animated = false,
    },
    {
        name = "Vibrant Sniper Scope",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\vibrant_sniper_scope",
        animated = false,
    },
    {
        name = "Sniper Scope",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\sniper_scope",
        animated = false,
    },
    {
        name = "Sniper Scope 4",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\sniper_scope4",
        animated = false,
    },
    {
        name = "Dirty Lens",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\dirty_lens",
        animated = false,
    },

    {
        name = "Circle 1",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle1",
        animated = false,
    },
    {
        name = "Circle 2",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle2",
        animated = false,
    },
    {
        name = "Circle 3",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle3",
        animated = false,
    },
    {
        name = "Circle 4",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle4",
        animated = false,
    },
    {
        name = "Circle 5",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle5",
        animated = false,
    },
    {
        name = "Circle_thin_mid",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle_thin_mid",
        animated = false,
    },
    {
        name = "Circle White",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle_White",
        animated = false,
    },
    {
        name = "2 Semi Circle 2",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\2_Semi_Circle_2",
        animated = false,
    },
    {
        name = "2 Semi Circle 5",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\2_Semi_Circle_5",
        animated = false,
    },
    {
        name = "Diamond Left",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Diamond_Left",
        animated = false,
    },
    {
        name = "Diamond Cystal",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Diamond_Crystal",
        animated = false,
    },
    {
        name = "Glass 1",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Glass1",
        animated = false,
    },
    {
        name = "Glass 2",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Glass2",
        animated = false,
    },
    {
        name = "Cursor 1",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\cursor1",
        animated = false,
    },
    {
        name = "Cursor 2",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\cursor2",
        animated = false,
    },
    {
        name = "Golden Ring",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Golden_Ring",
        animated = false,
    },
    {
        name = "Golden Heart",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Golden_Heart",
        animated = false,
    },

    {
        name = "Heart 1",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Heart_White",
        animated = false,
    },
    {
        name = "Heart 2",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Heart3",
        animated = false,
    },
    {
        name = "Heart 3",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Heart5",
        animated = false,
    },
    {
        name = "Heart 4",
        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Heart7",
        animated = false,
    },

    -- Animated Example
    {
        name = "RGB Rotate",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\RGB\\RGB_Rotate_8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.8,
    },
    {
        name = "Yin and Yang v2",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_v8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.6,
    },
    {
        name = "Yin and Yang",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Yin_Yang\\Yin_Yang_8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.6,
    },
    {
        name = "Radar",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Radar\\Radar_8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 2.5,
    },
    {
        name = "Circle",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_1_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_2_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_3_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_4_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_5_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_6_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_7_Hovering.tga",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_8_Hovering.tga",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.5,
    },
    {
        name = "Circle_focus",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\CCircle_focus_4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle\\Circle_focus_8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.5,
    },
    {
        name = "Butterfly Hovering",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_1.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_2.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_3.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_4.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_5.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_6.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_7.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Butterfly\\Butterfly_8.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.6,
    },
    {
        name = "Fairy Hovering",
        textures = {
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_1_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_2_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_3_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_4_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_5_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_6_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_7_Hovering.blp",
            "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Fairy\\Fairy_Left_8_Hovering.blp",
        },
        animated = true,
        totalFrames = 8,
        animationDuration = 0.3,
    },
}



---------------------------------------------------------------------------
-- dynamicPatterns: shape generation for glows with adjustable positioning
---------------------------------------------------------------------------
EasyCursorTrails.dynamicPatterns = EasyCursorTrails.dynamicPatterns or {}

-- Helper function to generate a single "V" shape
local function generateVShape(rotationAngle, xOffset, yOffset, length, width)
    local points = {}
    
    -- Convert rotation angle from degrees to radians
    local radians = math.rad(rotationAngle or 0)
    
    -- Define the three points of the "V"
    local baseLeft = {
        x = -width,
        y = -0
    }
    local tip = {
        x = 0,
        y = length
    }
    local baseRight = {
        x = width,
        y = 0
    }
    
    -- Function to rotate a point around the origin
    local function rotatePoint(point, radians)
        return {
            x = point.x * math.cos(radians) - point.y * math.sin(radians),
            y = point.x * math.sin(radians) + point.y * math.cos(radians)
        }
    end
    
    -- Rotate points
    local rotatedBaseLeft = rotatePoint(baseLeft, radians)
    local rotatedTip = rotatePoint(tip, radians)
    local rotatedBaseRight = rotatePoint(baseRight, radians)
    
    -- Apply offsets
    rotatedBaseLeft.x = rotatedBaseLeft.x + xOffset
    rotatedBaseLeft.y = rotatedBaseLeft.y + yOffset
    rotatedTip.x = rotatedTip.x + xOffset
    rotatedTip.y = rotatedTip.y + yOffset
    rotatedBaseRight.x = rotatedBaseRight.x + xOffset
    rotatedBaseRight.y = rotatedBaseRight.y + yOffset
    
    -- Insert points into the table
    table.insert(points, rotatedBaseLeft)
    table.insert(points, rotatedTip)
    table.insert(points, rotatedBaseRight)
    
    return points
end



-- 1. Helper function to generate points between two points
local function generateLinePoints(startPoint, endPoint, numPoints)
    local points = {}
    if numPoints < 2 then numPoints = 2 end -- Ensure at least two points
    for i = 0, numPoints - 1 do
        local ratio = i / (numPoints - 1)
        local x = startPoint.x + (endPoint.x - startPoint.x) * ratio
        local y = startPoint.y + (endPoint.y - startPoint.y) * ratio
        table.insert(points, { x = x, y = y })
    end
    return points
end

-- 2. Helper function to generate points for a single "V" shape
local function generateArrowHead(numPoints, direction, rotationAngle, xOffset, yOffset, length, width)
    local points = {}
    
    -- Convert rotation angle from degrees to radians
    local radians = math.rad(rotationAngle or 0)
    
    -- Define the three points of the "V"
    local baseLeft = { x = -width * direction.leftOrRight, y = 0 }
    local tip = { x = 0, y = length * direction.upOrDown }
    local baseRight = { x = width * direction.leftOrRight, y = 0 }
    
    -- Function to rotate a point around the origin and apply offsets
    local function rotatePoint(point, radians)
        return {
            x = point.x * math.cos(radians) - point.y * math.sin(radians) + xOffset,
            y = point.x * math.sin(radians) + point.y * math.cos(radians) + yOffset
        }
    end
    
    -- Rotate points
    local rotatedBaseLeft = rotatePoint(baseLeft, radians)
    local rotatedTip = rotatePoint(tip, radians)
    local rotatedBaseRight = rotatePoint(baseRight, radians)
    
    -- Generate points for left side of "V"
    local leftPoints = generateLinePoints(rotatedBaseLeft, rotatedTip, math.ceil(numPoints / 2))
    
    -- Generate points for right side of "V"
    local rightPoints = generateLinePoints(rotatedTip, rotatedBaseRight, math.floor(numPoints / 2))
    
    -- Combine points
    for _, point in ipairs(leftPoints) do
        table.insert(points, point)
    end
    for _, point in ipairs(rightPoints) do
        table.insert(points, point)
    end
    
    return points
end


-- 2. Helper function to generate points for a single "U" shape
local function generateUShape(numPoints, direction, rotationAngle, xOffset, yOffset, length, width)
    local points = {}
    
    -- Convert rotation angle from degrees to radians
    local radians = math.rad(rotationAngle or 0)
    
    -- Define the key points of the "U"
    local topLeft = { x = -width, y = 0 }
    local bottomLeft = { x = -width, y = -length }
    local bottomRight = { x = width, y = -length }
    local topRight = { x = width, y = 0 }
    
    -- Function to rotate a point around the origin and apply offsets
    local function rotatePoint(point, radians)
        return {
            x = point.x * math.cos(radians) - point.y * math.sin(radians) + xOffset,
            y = point.x * math.sin(radians) + point.y * math.cos(radians) + yOffset
        }
    end
    
    -- Rotate and offset points
    local rotatedTopLeft = rotatePoint(topLeft, radians)
    local rotatedBottomLeft = rotatePoint(bottomLeft, radians)
    local rotatedBottomRight = rotatePoint(bottomRight, radians)
    local rotatedTopRight = rotatePoint(topRight, radians)
    
    -- Allocate points to each segment
    -- Ensure the curved segment has a sufficient number of points for smoothness
    local minCurvePoints = 10
    local curvePoints = math.max(minCurvePoints, math.floor(numPoints * 0.6))
    local remainingPoints = numPoints - curvePoints
    local pointsPerVertical = math.floor(remainingPoints / 2)
    
    -- Ensure pointsPerVertical is at least 2 for smooth vertical lines
    pointsPerVertical = math.max(2, pointsPerVertical)
    
    -- Generate points for left vertical line
    local leftPoints = generateLinePoints(rotatedTopLeft, rotatedBottomLeft, pointsPerVertical)
    
    -- Generate points for the bottom curve (semi-circle)
    local curvePointsList = {}
    for i = 0, curvePoints - 1 do
        local angle = math.pi + (i / (curvePoints - 1)) * math.pi -- from pi to 2pi
        local x = width * math.cos(angle)
        local y = -length * math.sin(angle)
        local rotatedX = x * math.cos(radians) - y * math.sin(radians) + xOffset
        local rotatedY = x * math.sin(radians) + y * math.cos(radians) + yOffset
        table.insert(curvePointsList, {x = rotatedX, y = rotatedY})
    end
    
    -- Generate points for right vertical line
    local rightPoints = generateLinePoints(rotatedBottomRight, rotatedTopRight, pointsPerVertical)
    
    -- Combine all points
    for _, point in ipairs(leftPoints) do
        table.insert(points, point)
    end
    for _, point in ipairs(curvePointsList) do
        table.insert(points, point)
    end
    for _, point in ipairs(rightPoints) do
        table.insert(points, point)
    end
    

    return points
end



-- 2. Helper function to generate points along an ellipse
local function generateEllipsePoints(a, b, numPoints, rotationAngle, xOffset, yOffset)
    local points = {}
    local radians = math.rad(rotationAngle or 0) -- Convert rotation angle to radians
    
    for i = 0, numPoints - 1 do
        local t = (i / numPoints) * 2 * math.pi
        local x = a * math.cos(t)
        local y = b * math.sin(t)
        
        -- Apply rotation
        local rotatedX = x * math.cos(radians) - y * math.sin(radians)
        local rotatedY = x * math.sin(radians) + y * math.cos(radians)
        
        -- Apply offsets
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset
        
        table.insert(points, {x = rotatedX, y = rotatedY})
    end
    

    return points
end

-- 3. Oval Pattern Function
EasyCursorTrails.dynamicPatterns.OvalPattern = function(N)
    local points = {}
    
    -- Define parameters
    local a = 35 -- Horizontal radius; adjust for wider or narrower oval
    local b = 20 -- Vertical radius; adjust for taller or shorter oval
    local rotationAngle = 0 -- Degrees; rotate the oval if desired
    local xOffset = 0 -- Center the oval horizontally
    local yOffset = 0 -- Center the oval vertically
    
    -- Generate points along the ellipse
    points = generateEllipsePoints(a, b, N, rotationAngle, xOffset, yOffset)
    
    return points
end


    -- Helper function to determine the sign of a number
    local function sign(x)
        if x > 0 then
            return 1
        elseif x < 0 then
            return -1
        else
            return 0
        end
    end
    
EasyCursorTrails.dynamicPatterns = {
    -- Circle Pattern
    Circle_White = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the circle)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 0    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            local x = math.cos(angle) * 20 + xOffset
            local y = math.sin(angle) * 20 + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,

    -- Heart Pattern
    Heart_1 = function(N)
        local points = {}
        local tStep = (2 * math.pi) / N
        local scale = 0.7

        -- Position Offsets (Adjust these to move the heart)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 1   -- Vertical offset (e.g., moving the heart up)

        for i = 1, N do
            local t = (i - 1) * tStep
            local x = scale * (16 * math.sin(t)^3) + xOffset
            local y = scale * (
                12 * math.cos(t)
                - 5 * math.cos(2 * t)
                - 2 * math.cos(3 * t)
                - math.cos(4 * t)
            ) + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,

    -- Star Cursor Pattern
    Star_Cursor = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the star)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 0    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            local radius = (i % 2 == 1) and 30 or 15
            local x = math.cos(angle) * radius + xOffset
            local y = math.sin(angle) * radius + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,



    -- Yin and Yang Pattern
    Yin_Yang_Pattern = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the Yin-Yang)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 0    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            -- Simplified circular pattern for Yin and Yang
            local x = math.cos(angle) * 20 + xOffset
            local y = math.sin(angle) * 20 + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,

    -- Butterfly Pattern
    Butterfly_Pattern = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the butterfly)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 0    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            -- Define a butterfly-like pattern with symmetric wings
            local x = math.cos(angle) * (25 + 10 * math.sin(2 * angle)) + xOffset
            local y = math.sin(angle) * (25 + 10 * math.sin(2 * angle)) + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,


    Bullet1 = function(N)
        local points = {}
        
        -- Define parameters
        local FIXED_ROTATION_ANGLE = 42    -- Degrees: Adjust as desired
        local xOffset = 2                 -- Horizontal offset (positive moves right, negative moves left)
        local yOffset = -10                 -- Vertical offset (positive moves up, negative moves down)
        local arrowHeadLength = 20          -- Length of the arrowhead sides
        local arrowHeadWidth = 1         -- Width of the arrowhead base (positive value)
        
        -- Define manual offset parameters for each "U"
        local direction1yoffset = 5         -- Manual Y offset for first "U"
        local direction1xoffset = 2         -- Manual X offset for first "U"
        local direction2yoffset = 2         -- Manual Y offset for second "U"
        local direction2xoffset = 5         -- Manual X offset for second "U"
        
        -- Define direction multipliers for two "U" shapes
        -- First "U" pointing down and to the right
        local direction1 = {
            upOrDown = -1,       -- -1 for "Down", 1 for "Up"
            leftOrRight = 1      -- 1 for "Right", -1 for "Left"
        }
        
        -- Second "U" pointing up and to the left (mirrored)
        local direction2 = {
            upOrDown = 1,        -- 1 for "Up", -1 for "Down"
            leftOrRight = -1     -- -1 for "Left", 1 for "Right"
        }
        
        -- Ensure N is a multiple of 6 for symmetry (since each "U" has three segments)
        if N % 6 ~= 0 then
            N = math.floor(N / 6) * 6
            if N < 6 then
                N = 6
            end
        end
        
        -- Number of points per "U" shape
        local pointsPerU = math.floor(N / 2) -- Each "U" has two curves: left and right
        pointsPerU = math.max(6, pointsPerU) -- At least 6 points per "U" for smoothness
        
        -- Generate first "U" shape (pointing down and to the right) with manual offsets
        local U1Points = generateUShape(
            pointsPerU,
            direction1,
            FIXED_ROTATION_ANGLE,
            xOffset + direction1xoffset,    -- Apply manual X offset
            yOffset + direction1yoffset,    -- Apply manual Y offset
            arrowHeadLength,
            arrowHeadWidth
        )
        
        -- Generate second "U" shape (pointing up and to the left) with manual offsets and rotation
        local U2Points = generateUShape(
            pointsPerU,
            direction2,
            FIXED_ROTATION_ANGLE + 180,   -- Rotate by 180 degrees to mirror
            xOffset + direction2xoffset,    -- Apply manual X offset
            yOffset + direction2yoffset,    -- Apply manual Y offset
            arrowHeadLength,
            arrowHeadWidth
        )
        
        -- Combine points from both "U" shapes to form a diamond
        for _, point in ipairs(U1Points) do
            table.insert(points, point)
        end
        
        for _, point in ipairs(U2Points) do
            table.insert(points, point)
        end
        
        return points
    end,


    -- Cursor (Arrow) Pattern with Fixed Angle, Direction Controls, and Position Offsets
Cursor_Arrow_Pattern = function(N)
    local points = {}
 
    local arrowUpOrDown = 1          -- Positive for "Up", Negative for "Down"
    local arrowLeftOrRight = 1       -- Positive for "Right", Negative for "Left"
  
    local FIXED_ROTATION_ANGLE = 42   -- Adjust this value to rotate the cursor pattern as desired

    local xOffset = 12                -- Horizontal offset (positive moves right, negative moves left)
    local yOffset = -15               -- Vertical offset (positive moves up, negative moves down)

    local shaftLength = 10           -- Increased for visibility
    
    local shaftWidth = 10              -- Currently not directly used but can influence visual spacing
    
    local arrowHeadLength = 30        -- Increase for longer arrowhead sides; decrease for shorter sides
    
    local arrowHeadWidth = 19         -- Increase for a wider arrowhead base; decrease for a narrower base
    
    local verticalMultiplier = sign(arrowUpOrDown)

    local horizontalMultiplier = sign(arrowLeftOrRight)
    
    local radiansOffset = math.rad(FIXED_ROTATION_ANGLE or 45) -- Defaults to 45° if not defined

    local shaftPoints = math.floor(N * 0.6)
    
    local arrowHeadPoints = math.floor((N - shaftPoints) / 2)

    shaftPoints = math.max(1, shaftPoints)
    arrowHeadPoints = math.max(1, arrowHeadPoints)

    for i = 1, shaftPoints do
        -- Calculate the Y-coordinate based on the current point's position along the shaft
        local y = (i / shaftPoints) * shaftLength * verticalMultiplier
        
        -- The X-coordinate remains 0 as the shaft is centered vertically
        local x = 0
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset

        table.insert(points, { x = rotatedX, y = rotatedY })
    end

    for i = 1, arrowHeadPoints do
        -- Calculate the ratio of the current point's position within the arrowhead
        local ratio = i / arrowHeadPoints
        
        -- Calculate the X and Y coordinates for the left side of the arrowhead
        local x = -arrowHeadWidth * (1 - ratio) * horizontalMultiplier
        local y = (shaftLength + arrowHeadLength * ratio) * verticalMultiplier
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset
        
        -- Insert the rotated and offset point into the points table
        table.insert(points, { x = rotatedX, y = rotatedY })
    end
    
 
    for i = 1, arrowHeadPoints do
        -- Calculate the ratio of the current point's position within the arrowhead
        local ratio = i / arrowHeadPoints
        
        -- Calculate the X and Y coordinates for the right side of the arrowhead
        local x = arrowHeadWidth * (1 - ratio) * horizontalMultiplier
        local y = (shaftLength + arrowHeadLength * ratio) * verticalMultiplier
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset
        

        table.insert(points, { x = rotatedX, y = rotatedY })
    end
    

    return points
end,


Diamond = function(N)
    local points = {}
    
    -- Define parameters
    local FIXED_ROTATION_ANGLE = 45    -- Degrees: Adjust as desired
    local xOffset = -10                  -- Horizontal offset (positive moves right, negative moves left)
    local yOffset = -40                 -- Vertical offset (positive moves up, negative moves down)
    local arrowHeadLength = 10         -- Length of the arrowhead sides
    local arrowHeadWidth = 8          -- Width of the arrowhead base (positive value)
    
    -- Define manual offset parameters for each direction
    local direction1yoffset = 40        -- Manual Y offset for first "V"
    local direction1xoffset = 10         -- Manual X offset for first "V"
    local direction2yoffset = 30         -- Manual Y offset for second "V"
    local direction2xoffset = 10         -- Manual X offset for second "V"
    
    -- Define direction multipliers for two arrowheads
    -- First arrow pointing down and to the right
    local direction1 = {
        upOrDown = 1,       -- -1 for "Down", 1 for "Up"
        leftOrRight = 1      -- 1 for "Right", -1 for "Left"
    }
    
    -- Second arrow pointing up and to the left (mirrored)
    local direction2 = {
        upOrDown = 1,        -- 1 for "Up", -1 for "Down"
        leftOrRight = -1     -- -1 for "Left", 1 for "Right"
    }
    
    -- Ensure N is a multiple of 4 for symmetry
    if N % 4 ~= 0 then
        N = math.floor(N / 4) * 4
        if N < 4 then
            N = 4
        end
    end
    
    -- Number of points per arrowhead side
    local pointsPerArrow = math.floor(N / 4) -- Each arrow has two sides: left and right
    pointsPerArrow = math.max(1, pointsPerArrow)
    
    -- Generate first arrowhead (pointing down and to the right) with manual offsets
    local arrow1Points = generateArrowHead(
        pointsPerArrow * 2,
        direction1,
        FIXED_ROTATION_ANGLE,
        xOffset + direction1xoffset,    -- Apply manual X offset
        yOffset + direction1yoffset,    -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Compute yOffset for the second arrowhead (pointing up and to the left)
    local yOffset2 = yOffset + (arrowHeadLength * direction1.upOrDown) + direction2yoffset
    
    -- Compute xOffset for the second arrowhead
    local xOffset2 = xOffset + direction2xoffset
    
    -- Generate second arrowhead (mirrored, pointing up and to the left) with manual offsets
    local arrow2Points = generateArrowHead(
        pointsPerArrow * 2,
        direction2,
        FIXED_ROTATION_ANGLE + 180,   -- Rotate by 180 degrees to mirror
        xOffset2,                      -- Apply manual X offset
        yOffset2,                      -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Combine points from both arrowheads to form a diamond
    for _, point in ipairs(arrow1Points) do
        table.insert(points, point)
    end
    
    for _, point in ipairs(arrow2Points) do
        table.insert(points, point)
    end
    
    return points
end,


U_Shape = function(N)
    local points = {}
    
    -- Define parameters
    local FIXED_ROTATION_ANGLE = 41    -- Degrees: Adjust as desired
    local xOffset = 15                  -- Horizontal offset (positive moves right, negative moves left)
    local yOffset = -15                 -- Vertical offset (positive moves up, negative moves down)
    local arrowHeadLength = 4       -- Length of the arrowhead sides
    local arrowHeadWidth = 6           -- Width of the arrowhead base (positive value)
    
    -- Define manual offset parameters for each "U"
    local direction1yoffset = 20         -- Manual Y offset for first "U"
    local direction1xoffset = -20         -- Manual X offset for first "U"
    local direction2yoffset = 10         -- Manual Y offset for second "U"
    local direction2xoffset = -10         -- Manual X offset for second "U"
    
    -- Define direction multipliers for two "U" shapes
    -- First "U" pointing down and to the right
    local direction1 = {
        upOrDown = 1,       -- -1 for "Down", 1 for "Up"
        leftOrRight = 1      -- 1 for "Right", -1 for "Left"
    }
    
    -- Second "U" pointing up and to the left (mirrored)
    local direction2 = {
        upOrDown = 1,        -- 1 for "Up", -1 for "Down"
        leftOrRight = 1     -- -1 for "Left", 1 for "Right"
    }

        
    -- Ensure N is a multiple of 6 for symmetry (since each "U" has three segments)
    if N % 4 ~= 0 then
        N = math.floor(N / 4) * 4
        if N < 4 then
            N = 4
        end
    end

    -- Number of points per "U" shape
    local pointsPerU = math.floor(N / 2) -- Each "U" has two "U" segments (left and right)
    pointsPerU = math.max(6, pointsPerU) -- Ensure enough points for smoothness (minimum 20)
    
    -- Generate first "U" shape (pointing down and to the right) with manual offsets
    local U1Points = generateUShape(
        pointsPerU,
        direction1,
        FIXED_ROTATION_ANGLE,
        xOffset + direction1xoffset,    -- Apply manual X offset
        yOffset + direction1yoffset,    -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Generate second "U" shape (pointing up and to the left) with manual offsets and rotation
    local U2Points = generateUShape(
        pointsPerU,
        direction2,
        FIXED_ROTATION_ANGLE + 180,   -- Rotate by 180 degrees to mirror
        xOffset + direction2xoffset,    -- Apply manual X offset
        yOffset + direction2yoffset,    -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Combine points from both "U" shapes to form a diamond
    for _, point in ipairs(U1Points) do
        table.insert(points, point)
    end
    
    for _, point in ipairs(U2Points) do
        table.insert(points, point)
    end
    
    return points
end,


Diamond_Crystal = function(N)
    local points = {}
    
    -- Define parameters
    local FIXED_ROTATION_ANGLE = 32    -- Degrees: Adjust as desired
    local xOffset = -10                 -- Horizontal offset (positive moves right, negative moves left)
    local yOffset = -40                 -- Vertical offset (positive moves up, negative moves down)
    local arrowHeadLength = 10         -- Length of the arrowhead sides
    local arrowHeadWidth = 5        -- Width of the arrowhead base (positive value)
    
    -- Define manual offset parameters for each direction
    local direction1yoffset = 40        -- Manual Y offset for first "V"
    local direction1xoffset = 10         -- Manual X offset for first "V"
    local direction2yoffset = 30         -- Manual Y offset for second "V"
    local direction2xoffset = 10         -- Manual X offset for second "V"
    
    -- Define direction multipliers for two arrowheads
    -- First arrow pointing down and to the right
    local direction1 = {
        upOrDown = 1,       -- -1 for "Down", 1 for "Up"
        leftOrRight = 1      -- 1 for "Right", -1 for "Left"
    }
    
    -- Second arrow pointing up and to the left (mirrored)
    local direction2 = {
        upOrDown = 1,        -- 1 for "Up", -1 for "Down"
        leftOrRight = -1     -- -1 for "Left", 1 for "Right"
    }
    
    -- Ensure N is a multiple of 4 for symmetry
    if N % 4 ~= 0 then
        N = math.floor(N / 4) * 4
        if N < 4 then
            N = 4
        end
    end
    
    -- Number of points per arrowhead side
    local pointsPerArrow = math.floor(N / 4) -- Each arrow has two sides: left and right
    pointsPerArrow = math.max(1, pointsPerArrow)
    
    -- Generate first arrowhead (pointing down and to the right) with manual offsets
    local arrow1Points = generateArrowHead(
        pointsPerArrow * 2,
        direction1,
        FIXED_ROTATION_ANGLE,
        xOffset + direction1xoffset,    -- Apply manual X offset
        yOffset + direction1yoffset,    -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Compute yOffset for the second arrowhead (pointing up and to the left)
    local yOffset2 = yOffset + (arrowHeadLength * direction1.upOrDown) + direction2yoffset
    
    -- Compute xOffset for the second arrowhead
    local xOffset2 = xOffset + direction2xoffset
    
    -- Generate second arrowhead (mirrored, pointing up and to the left) with manual offsets
    local arrow2Points = generateArrowHead(
        pointsPerArrow * 2,
        direction2,
        FIXED_ROTATION_ANGLE + 180,   -- Rotate by 180 degrees to mirror
        xOffset2,                      -- Apply manual X offset
        yOffset2,                      -- Apply manual Y offset
        arrowHeadLength,
        arrowHeadWidth
    )
    
    -- Combine points from both arrowheads to form a diamond
    for _, point in ipairs(arrow1Points) do
        table.insert(points, point)
    end
    
    for _, point in ipairs(arrow2Points) do
        table.insert(points, point)
    end
    
    return points
end,


    -- Star Cursor Pattern
    Vibrant_Cursor = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the star)
        local xOffset = 1    -- Horizontal offset
        local yOffset = -10    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            local radius = (i % 2 == 1) and 2 or 4
            local x = math.cos(angle) * radius + xOffset
            local y = math.sin(angle) * radius + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,

    
 -- Cursor (Arrow) Pattern with Fixed Angle, Direction Controls, and Position Offsets
 Broom = function(N)
    local points = {}
 
    local arrowUpOrDown = 1          -- Positive for "Up", Negative for "Down"
    local arrowLeftOrRight = 1       -- Positive for "Right", Negative for "Left"
  
    local FIXED_ROTATION_ANGLE = 49   -- Adjust this value to rotate the cursor pattern as desired

    local xOffset = 21                -- Horizontal offset (positive moves right, negative moves left)
    local yOffset = -15               -- Vertical offset (positive moves up, negative moves down)

    local shaftLength = 20          -- Increased for visibility
    
    local shaftWidth = 10              -- Currently not directly used but can influence visual spacing
    
    local arrowHeadLength = 30        -- Increase for longer arrowhead sides; decrease for shorter sides
    
    local arrowHeadWidth = 1         -- Increase for a wider arrowhead base; decrease for a narrower base
    
    local verticalMultiplier = sign(arrowUpOrDown)

    local horizontalMultiplier = sign(arrowLeftOrRight)
    
    local radiansOffset = math.rad(FIXED_ROTATION_ANGLE or 45) -- Defaults to 45° if not defined

    local shaftPoints = math.floor(N * 0.6)
    
    local arrowHeadPoints = math.floor((N - shaftPoints) / 2)

    shaftPoints = math.max(1, shaftPoints)
    arrowHeadPoints = math.max(1, arrowHeadPoints)

    for i = 1, shaftPoints do
        -- Calculate the Y-coordinate based on the current point's position along the shaft
        local y = (i / shaftPoints) * shaftLength * verticalMultiplier
        
        -- The X-coordinate remains 0 as the shaft is centered vertically
        local x = 0
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset

        table.insert(points, { x = rotatedX, y = rotatedY })
    end

    for i = 1, arrowHeadPoints do
        -- Calculate the ratio of the current point's position within the arrowhead
        local ratio = i / arrowHeadPoints
        
        -- Calculate the X and Y coordinates for the left side of the arrowhead
        local x = -arrowHeadWidth * (1 - ratio) * horizontalMultiplier
        local y = (shaftLength + arrowHeadLength * ratio) * verticalMultiplier
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset
        
        -- Insert the rotated and offset point into the points table
        table.insert(points, { x = rotatedX, y = rotatedY })
    end
    
 
    for i = 1, arrowHeadPoints do
        -- Calculate the ratio of the current point's position within the arrowhead
        local ratio = i / arrowHeadPoints
        
        -- Calculate the X and Y coordinates for the right side of the arrowhead
        local x = arrowHeadWidth * (1 - ratio) * horizontalMultiplier
        local y = (shaftLength + arrowHeadLength * ratio) * verticalMultiplier
        
        -- Apply rotation to the (x, y) point
        local rotatedX = x * math.cos(radiansOffset) - y * math.sin(radiansOffset)
        local rotatedY = x * math.sin(radiansOffset) + y * math.cos(radiansOffset)
        
        -- Apply position offsets to shift the entire pattern
        rotatedX = rotatedX + xOffset
        rotatedY = rotatedY + yOffset
        

        table.insert(points, { x = rotatedX, y = rotatedY })
    end
    

    return points
end,


    -- Custom Star Pattern for Unique Shapes
    Custom_Star_Pattern = function(N)
        local points = {}
        local angleStep = (2 * math.pi) / N

        -- Position Offsets (Adjust these to move the custom star)
        local xOffset = 0    -- Horizontal offset
        local yOffset = 0    -- Vertical offset

        for i = 1, N do
            local angle = (i - 1) * angleStep
            local radius = (i % 2 == 1) and 30 or 15
            local x = math.cos(angle) * radius + xOffset
            local y = math.sin(angle) * radius + yOffset
            table.insert(points, { x = x, y = y })
        end
        return points
    end,
}

-- For safety, unify references:
EasyCursorTrails.glowPatterns = EasyCursorTrails.dynamicPatterns



---------------------------------------------------------------------------
-- Mapping short texture names -> pattern key
---------------------------------------------------------------------------
-- Mapping short texture names -> pattern key
EasyCursorTrails.cursorGlowMapping = {
    ["Pearl"]                 = "Diamond",
    ["Alien3"]                = "Star_Cursor",
    ["BroomStick1"]           = "Broom",
    ["Bullet1"]               = "Bullet1",
    ["vibrant_sniper_scope"]  = "Circle_White",
    ["sniper_scope"]          = "Circle_White",
    ["sniper_scope4"]        = "Circle_White",
    ["dirty_lens"]            = "Circle_White",
    ["Circle1"]              = "Circle_White",
    ["Circle2"]              = "Circle_White",
    ["Circle3"]              = "Circle_White",
    ["Circle4"]              = "Circle_White",
    ["Circle5"]              = "Circle_White",
    ["Circle_thin_mid"]       = "Circle_White",
    ["Circle_White"]          = "Circle_White",
    ["2_Semi_Circle_2"]       = "U_Shape",
    ["2_Semi_Circle_5"]       = "U_Shape",
    ["Diamond_Left"]          = "Diamond",
    ["Diamond_Crystal"]        = "Diamond_Crystal",
    ["Glass1"]               = "Circle_White",
    ["Glass2"]               = "Circle_White",
    ["cursor1"]              = "Cursor_Arrow_Pattern",
    ["cursor2"]              = "Vibrant_Cursor",
    ["Golden_Ring"]          = "Circle_White",
    ["Golden_Heart"]          = "Heart_1",
    ["Heart_White"]           = "Heart_1",
    ["Heart3"]               = "Heart_1",
    ["Heart5"]               = "Heart_1",
    ["Heart7"]               = "Heart_1",
    ["RGB_Rotate_1"]          = "Circle_White",
    ["Yin_Yang_v1"]          = "Circle_White",
    ["Yin_Yang_1"]          = "Circle_White",
    ["Radar_1"]                 = "Circle_White",
    ["Circle_1_Hovering"]     = "Circle_White",
    ["Circle_focus_1"]          = "Circle_White",
    ["Butterfly_1"]          = "Star_Cursor",
    ["Fairy_Left_1_Hovering"]       = "Star_Cursor",
}



-- Select trail “Effect” categories
local trailEffects = {
    "Star",
    "Bubble",
    "Circle",
    "Fantasy",
    "Heart",
    "Magic",
    "Nature",
    "Military",
    "Other - Trails Slider Effects can be applied.",
}


---------------------------------------------------------------------------
-- Trail Textures
---------------------------------------------------------------------------
EasyCursorTrails.trailTextures = {
    [1] = { -- Star
        { name = "Star1",   texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Star1.tga" },
        { name = "Glitter", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Glitter.tga" },
        { name = "Lines",   texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\lines_trail.tga" },
        { name = "Dust",    texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Bright_Dust.blp" },
    },
    [2] = { -- Bubble
        { name = "Bubble1", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble1.tga" },
        { name = "Bubble2", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble2.tga" },
        { name = "Bubble3", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble3.tga" },
        { name = "Bubble4", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble4.tga" },
        { name = "Bubble5", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble5.tga" },
    },
    [3] = { -- Circle
        { name = "Circle1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1_Trail.tga" },
        { name = "Circle2_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2_Trail.tga" },
        { name = "Circle3_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3_Trail.tga" },
        { name = "Seeds",         texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Seeds.tga" },
        { name = "Circle1",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1.tga" },
        { name = "Circle2",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2.tga" },
        { name = "Circle3",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3.tga" },
        { name = "Circle4",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle4.tga" },
        { name = "Circle5",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle5.tga" },
    },
    [4] = { -- Fantasy
        { name = "Fairies1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairies1_Trail.tga" },
        { name = "Fairies",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Faries1.blp" },
        { name = "Fairy",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairy_Trail.blp" },
        { name = "Fire1",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fire1.tga" },
        { name = "Ghost",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\ghost.tga" },
        { name = "Alien",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Alien3.blp" },
        { name = "Dragon_Scale",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Dragon_Scale.blp" },
    },
    [5] = { -- Heart
        { name = "Heart1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Heart\\Heart1_Trail.tga" },
        { name = "Heart4_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Heart\\Heart4_Trail.tga" },
    },
    [6] = { -- Magic
        { name = "Magic_Ball_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Magic_Ball_Trail.tga" },
        { name = "Flames",           texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Flames.tga" },
        { name = "Fire1",            texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Fire1.tga" },
        { name = "Dust",             texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Bright_Dust.blp" },
    },
    [7] = { -- Nature
        { name = "Rain",  texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Rain.tga" },
        { name = "Leaf1", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf1.tga" },
        { name = "Leaf2", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf2.tga" },
        { name = "Leaf3", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf3.tga" },
        { name = "Seeds", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Seeds.tga" },
    },
    [8] = { -- Military
        { name = "Bullet",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet_Sparks.tga" },
        { name = "Bullet Sparks", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet1.blp" },
    },
    [9] = { -- Other
    { name = "Bullet",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet_Sparks.tga" },
    { name = "Bullet Sparks", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet1.blp" },
 
    { name = "Star1",   texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Star1.tga" },
    { name = "Glitter", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Glitter.tga" },
    { name = "Lines",   texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\lines_trail.tga" },
    { name = "Dust",    texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Bright_Dust.blp" },

    { name = "Bubble1", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble1.tga" },
    { name = "Bubble2", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble2.tga" },
    { name = "Bubble3", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble3.tga" },
    { name = "Bubble4", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble4.tga" },
    { name = "Bubble5", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Bubble\\Bubble5.tga" },

    { name = "Circle1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1_Trail.tga" },
    { name = "Circle2_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2_Trail.tga" },
    { name = "Circle3_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3_Trail.tga" },
    { name = "Seeds",         texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Seeds.tga" },
    { name = "Circle1",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1.tga" },
    { name = "Circle2",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2.tga" },
    { name = "Circle3",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3.tga" },
    { name = "Circle4",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle4.tga" },
    { name = "Circle5",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle5.tga" },

    { name = "Fairies1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairies1_Trail.tga" },
    { name = "Fairies",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Faries1.blp" },
    { name = "Fairy",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairy_Trail.blp" },
    { name = "Fire1",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fire1.tga" },
    { name = "Ghost",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\ghost.tga" },
    { name = "Alien",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Alien3.blp" },
    { name = "Dragon_Scale",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Dragon_Scale.blp" },

    { name = "Heart1_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Heart\\Heart1_Trail.tga" },
    { name = "Heart4_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Heart\\Heart4_Trail.tga" },

    { name = "Magic_Ball_Trail", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Magic_Ball_Trail.tga" },
    { name = "Flames",           texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Flames.tga" },
    { name = "Fire1",            texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Fire1.tga" },
    { name = "Dust",             texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Bright_Dust.blp" },

    { name = "Rain",  texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Rain.tga" },
    { name = "Leaf1", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf1.tga" },
    { name = "Leaf2", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf2.tga" },
    { name = "Leaf3", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf3.tga" },
    { name = "Seeds", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Seeds.tga" },

    { name = "Bullet",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet_Sparks.tga" },
    { name = "Bullet Sparks", texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet1.blp" },
},

}

-- Color Effects Options (for the cursor, simplified):
local colorEffects = {
    { text = "None" },
    { text = "Rainbow" },
    { text = "Pulsing" },
    { text = "Rainbow + Pulsing" },
    { text = "Custom Color Only" },
    { text = "Custom + Pulsing" },
}

---------------------------------------------
-- 24 color effects for the trail
---------------------------------------------
local TrailcolorEffects = {
    { text = "None" },                     -- 1
    { text = "Rainbow" },                  -- 2
    { text = "Pulsing" },                  -- 3
    { text = "Glow" },                     -- 4
    { text = "Rainbow + Pulsing" },        -- 5
    { text = "Glow + Rainbow + Pulsing" }, -- 6
    { text = "Custom Color Only" },        -- 7
    { text = "Custom + Pulsing" },         -- 8
    { text = "Custom + Glow" },            -- 9
    { text = "Custom + Glow + Pulsing" },  -- 10
    { text = "Code-based Magic" },         -- 11
    { text = "Nebula Swirl" },             -- 12
    { text = "Galactic Plasma" },          -- 13
    { text = "Stardust Explosion" },       -- 14
    { text = "Dark Matter" },              -- 15
    { text = "Aurora Borealis" },          -- 16
    { text = "Crackling Electricity" },    -- 17
    { text = "Psychedelic Spiral" },       -- 18
    { text = "Inferno Pulse" },            -- 19
    { text = "Heavenly Glow" },            -- 20
    { text = "Midnight Spark" },           -- 21
    -- (and so forth)
}


local trailMovementEffectOptions = {
    { text = "No Effect" },              -- Index 1
    { text = "Linear Separation" },      -- Index 2
    { text = "Spiral Expansion" },       -- Index 3
    { text = "Zig-Zag" },                -- Index 4
    { text = "Wave Oscillation" },       -- Index 5
    { text = "Galactic Orbit" },         -- Index 6
    { text = "Firestorm" },              -- Index 7
    { text = "Wind Spiral" },            -- Index 8
    { text = "Trail Layers - Adjust the Trail Layers count, spacing and seperation, etc..." },   -- Index 26

}

--------------------------------------------------
-- Validate booleans
--------------------------------------------------
local function validateBooleanSetting(key, defaultValue)
    local val = EasyCursorTrailsDB[key]
    if type(val) ~= "boolean" then
        EasyCursorTrailsDB[key] = defaultValue
    end
end
local function InitializeSavedVariables()
    if not EasyCursorTrailsDB then
        EasyCursorTrailsDB = { profiles = {}, currentProfile = "Default" }
    end

    if not EasyCursorTrailsDB.profiles then
        EasyCursorTrailsDB.profiles = {}
    end

    if not EasyCursorTrailsDB.profiles["Default"] then
        EasyCursorTrailsDB.profiles["Default"] = {}
        for key, value in pairs(defaults) do
            EasyCursorTrailsDB.profiles["Default"][key] = value
        end
    end

    if not EasyCursorTrailsDB.currentProfile or not EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] then
        EasyCursorTrailsDB.currentProfile = "Default"
    end

    -- Ensure the current profile exists
    local currentProfileName = EasyCursorTrailsDB.currentProfile
    if not EasyCursorTrailsDB.profiles[currentProfileName] then
        EasyCursorTrailsDB.profiles[currentProfileName] = {}
        for key, value in pairs(defaults) do
            EasyCursorTrailsDB.profiles[currentProfileName][key] = value
        end
        --print("EasyCursorTrails: Created missing profile:", currentProfileName)
    end

    -- Fill missing keys in the current profile with defaults
    local currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
    for key, defaultValue in pairs(defaults) do
        if currentProfile[key] == nil then
            currentProfile[key] = defaultValue
        end
    end

    -- Helper function to validate numeric settings
    local function validateNumericSetting(profile, key, minValue, maxValue, defaultValue)
        local value = tonumber(profile[key]) or defaultValue
        if value < minValue or value > maxValue then
            profile[key] = defaultValue
        else
            profile[key] = value
        end
    end

    -- Helper function to validate boolean settings
    local function validateBooleanSetting(profile, key, defaultValue)
        if type(profile[key]) ~= "boolean" then
            profile[key] = defaultValue
        end
    end

    -- Validate settings in the current profile
    for _, setting in pairs({
        { "glowIntensity", 0, 1, defaults.glowIntensity },
        { "glowRadius", 0.1, 1, defaults.glowRadius },
        { "glowSize", 0.1, 5, defaults.glowSize },
        { "glowThickness", 0.1, 1, defaults.glowThickness },
        { "patternGlowCount", 1, 40, defaults.patternGlowCount },
        { "glowHollowness", 0.0, 1.0, defaults.glowHollowness },
        { "glowPulsingIntensity", 0, 1, defaults.glowPulsingIntensity },
        { "pulsingSpeed", 0, 10, defaults.pulsingSpeed },
        { "trailSizeStart", 1, 500, defaults.trailSizeStart },
        { "trailSizeEnd", 10, 500, defaults.trailSizeEnd },
        { "trailCount", 1, 500, defaults.trailCount },
        { "trailLayerCount", 1, 50, defaults.trailLayerCount },
        { "trailLayerSpacing", 0, 500, defaults.trailLayerSpacing },
        { "trailInitialSeparation", 0, 200, defaults.trailInitialSeparation },
        { "trailDelay", 0.1, 5.0, defaults.trailDelay },
        { "cursorSize", 10, 200, defaults.cursorSize },
        { "trailOffsetX", -100, 100, defaults.trailOffsetX },
        { "trailOffsetY", -100, 100, defaults.trailOffsetY },
        { "cursorOffsetX", -100, 100, defaults.cursorOffsetX },
        { "cursorOffsetY", -100, 100, defaults.cursorOffsetY },
    }) do
        validateNumericSetting(currentProfile, unpack(setting))
    end

    -- Validate boolean settings
    validateBooleanSetting(currentProfile, "disableGlowPulsing", defaults.disableGlowPulsing)
    validateBooleanSetting(currentProfile, "glowAboveCursor", defaults.glowAboveCursor)
    validateBooleanSetting(currentProfile, "enableTrails", defaults.enableTrails)

    -- Ensure additional settings exist in the current profile
    currentProfile.colorIndexCursor = currentProfile.colorIndexCursor or defaults.colorIndexCursor
    currentProfile.pulseDirectionCursor = currentProfile.pulseDirectionCursor or defaults.pulseDirectionCursor
    currentProfile.pulseValueCursor = currentProfile.pulseValueCursor or defaults.pulseValueCursor
    currentProfile.glowColor = currentProfile.glowColor or { r = 1, g = 1, b = 1, a = 1 }

    -- Apply the settings of the current profile to the main table
    for key, value in pairs(currentProfile) do
        EasyCursorTrailsDB[key] = value
    end

    --print("EasyCursorTrails: Initialized saved variables for profile:", currentProfileName)
end


-- Utility function to open a text input dialog
function EasyCursorTrails.OpenTextInputDialog(promptText, onAccept)
    StaticPopupDialogs["EASYCURSORTRAILS_TEXT_INPUT"] = {
        text = promptText,
        button1 = "OK",
        button2 = "Cancel",
        hasEditBox = true,
        maxLetters = 32,
        OnAccept = function(self)
            local input = self.editBox:GetText()
            onAccept(input)
        end,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
    }
    StaticPopup_Show("EASYCURSORTRAILS_TEXT_INPUT")
end


function EasyCursorTrails.SaveCurrentProfile()
    if EasyCursorTrailsDB.currentProfile then
        local profileName = EasyCursorTrailsDB.currentProfile
        if EasyCursorTrailsDB.profiles[profileName] then
            --print("EasyCursorTrails: Saving current profile:", profileName)
            EasyCursorTrailsDB.lastSelectedProfile = profileName
        else
            --print("EasyCursorTrails: Error - Attempted to save an invalid profile.")
        end
    end
end


-- Ensure the saved setting is applied during initialization
function EasyCursorTrails.InitializeProfile()
    -- Ensure profiles table exists
    if not EasyCursorTrailsDB.profiles then
        EasyCursorTrailsDB.profiles = {}
    end

    -- Create "Default" profile if it doesn't exist
    if not EasyCursorTrailsDB.profiles["Default"] then
        EasyCursorTrailsDB.profiles["Default"] = {}
        for key, value in pairs(defaults) do
            EasyCursorTrailsDB.profiles["Default"][key] = value
        end
    end

    -- Validate or fallback to last selected profile
    local lastProfile = EasyCursorTrailsDB.currentProfile
    if not (lastProfile and EasyCursorTrailsDB.profiles[lastProfile]) then
        EasyCursorTrailsDB.currentProfile = "Default"
    end

    -- Save current profile persistently
    EasyCursorTrails.SaveCurrentProfile()

    -- Load the profile settings
    LoadCurrentProfile()

    -- Ensure `glowBelow` setting is applied
    if EasyCursorTrailsDB.glowBelow == nil then
        EasyCursorTrailsDB.glowBelow = false
        SaveToCurrentProfile("glowBelow", false)
    end
    UpdateGlowBelowCursor()
end


function LoadCurrentProfile()
    local currentProfileName = EasyCursorTrailsDB.currentProfile

    -- Validate the current profile
    -- print("EasyCursorTrails: Attempting to load profile:", currentProfileName)
    if not currentProfileName or not EasyCursorTrailsDB.profiles[currentProfileName] then
        -- print("EasyCursorTrails: Invalid profile. Falling back to 'Default'.")
        currentProfileName = "Default"
        EasyCursorTrailsDB.currentProfile = currentProfileName
    end

    -- Get the profile
    local profile = EasyCursorTrailsDB.profiles[currentProfileName]
    if not profile then
        -- print("EasyCursorTrails: Profile does not exist. Creating new profile with defaults.")
        profile = {}
        EasyCursorTrailsDB.profiles[currentProfileName] = profile

        -- Populate profile with defaults
        for key, value in pairs(defaults) do
            profile[key] = value
        end
    end

    -- Apply profile settings to the EasyCursorTrailsDB
    for key, defaultValue in pairs(defaults) do
        EasyCursorTrailsDB[key] = profile[key] or defaultValue
    end

    -- Save the current profile persistently
    EasyCursorTrails.SaveCurrentProfile()

    -- Refresh UI and rebuild trails
    if RefreshSettingsUI then
        RefreshSettingsUI()  -- Refresh the settings UI if the function exists
    end
    if RebuildTrails then
        -- Ensure that the UpdateTrailTextureDropdown exists before calling
        if UpdateTrailTextureDropdown then
            UpdateTrailTextureDropdown(EasyCursorTrailsDB.trailMovementEffect or 1)  -- Update dropdown based on current trail movement effect
        else
            -- print("EasyCursorTrails: Warning - UpdateTrailTextureDropdown is not defined.")
        end
        RebuildTrails()  -- Rebuild the trails if the function exists
    end

    -- print("EasyCursorTrails: Successfully loaded profile:", currentProfileName)
end



function SaveAllSettingsToProfile()
    local profileName = EasyCursorTrailsDB.currentProfile
    if not profileName then
        -- print("EasyCursorTrails: No profile loaded. SaveAllSettingsToProfile aborted.")
        return
    end

    local profileSettings = EasyCursorTrailsDB.profiles[profileName]
    if not profileSettings then
        -- print("EasyCursorTrails: Profile settings not found for '" .. profileName .. "'. Creating new profile settings.")
        EasyCursorTrailsDB.profiles[profileName] = {}
        profileSettings = EasyCursorTrailsDB.profiles[profileName]
    end

    -- Save Sliders
    local sliders = {
        { slider = EasyCursorTrails.cursorSizeSlider, key = "cursorSize" },
        { slider = EasyCursorTrails.cursorOffsetXSlider, key = "cursorOffsetX" },
        { slider = EasyCursorTrails.cursorOffsetYSlider, key = "cursorOffsetY" },
        { slider = EasyCursorTrails.numGlowsSlider, key = "numGlows" },
        { slider = EasyCursorTrails.patternGlowCountSlider, key = "patternGlowCount" },
        { slider = EasyCursorTrails.glowIntensitySlider, key = "glowIntensity" },
        { slider = EasyCursorTrails.glowRadiusSlider, key = "glowRadius" },
        { slider = EasyCursorTrails.glowSizeSlider, key = "glowSize" },
        { slider = EasyCursorTrails.glowThicknessSlider, key = "glowThickness" },
        { slider = EasyCursorTrails.trailSizeStartSlider, key = "trailSizeStart" },
        { slider = EasyCursorTrails.trailSizeEndSlider, key = "trailSizeEnd" },
        { slider = EasyCursorTrails.trailLayerCountSlider, key = "trailLayerCount" },
        { slider = EasyCursorTrails.trailCountSlider, key = "trailCount" },
        { slider = EasyCursorTrails.trailLayerSpacingSlider, key = "trailLayerSpacing" },
        { slider = EasyCursorTrails.trailInitialSeparationSlider, key = "trailInitialSeparation" },
        { slider = EasyCursorTrails.pulsingSpeedSlider, key = "pulsingSpeed" },
        { slider = EasyCursorTrails.pulseMinSlider, key = "pulseMin" },
        { slider = EasyCursorTrails.pulseMaxSlider, key = "pulseMax" },
        { slider = EasyCursorTrails.pulseStepSlider, key = "pulseStep" },
        { slider = EasyCursorTrails.trailDelaySlider, key = "trailDelay" },
        { slider = EasyCursorTrails.glowHollownessSlider, key = "glowHollowness" },
    }

    for _, s in ipairs(sliders) do
        if s.slider then
            profileSettings[s.key] = s.slider:GetValue()
        end
    end

    -- Save Dropdowns
    local dropdowns = {
        { dropdown = EasyCursorTrails.profileDropdown, key = "currentProfile" },
        { dropdown = EasyCursorTrails.textureDropdown, key = "trailTexture" },
        { dropdown = EasyCursorTrails.trailMovementEffectDropdown, key = "trailMovementEffect" },
        { dropdown = EasyCursorTrails.cursorFrameStrataDropdown, key = "cursorFrameStrata" },
        { dropdown = EasyCursorTrails.selectedCursorTextureDropdown, key = "selectedCursorTextureName" },
        { dropdown = EasyCursorTrails.selectedGlowEffectDropdown, key = "selectedGlowEffect" },
        { dropdown = EasyCursorTrails.trailColorEffectDropdown, key = "trailColorEffect" },
    }

    for _, d in ipairs(dropdowns) do
        if d.dropdown then
            profileSettings[d.key] = UIDropDownMenu_GetSelectedID(d.dropdown)
        end
    end

    -- Save Checkboxes
    if EasyCursorTrails.enableTrailsCheckbox then
        profileSettings.enableTrails = EasyCursorTrails.enableTrailsCheckbox:GetChecked()
    end
    if EasyCursorTrails.glowBelowCheckbox then
        profileSettings.glowBelow = EasyCursorTrails.glowBelowCheckbox:GetChecked()
    end

    -- Save all settings to the profile
    -- print("EasyCursorTrails: All settings saved to profile '" .. profileName .. "'.")
end

function RefreshSettingsUI()
    local profile = EasyCursorTrailsDB.currentProfile
    if not profile then
        -- Handle error or exit if no profile is loaded
        return
    end

    local profileSettings = EasyCursorTrailsDB.profiles[profile]
    if not profileSettings then
        -- Handle error or exit if profile settings not found
        return
    end

    -- Update Checkboxes based on profile or defaults
    if EasyCursorTrails.enableTrailsCheckbox then
        EasyCursorTrails.enableTrailsCheckbox:SetChecked(profileSettings.enableTrails or defaults.enableTrails)
    end
    if EasyCursorTrails.glowBelowCheckbox then
        EasyCursorTrails.glowBelowCheckbox:SetChecked(profileSettings.glowBelow or defaults.glowBelow)
        -- Explicitly apply the glow effect after updating the checkbox
        UpdateGlowBelowCursor()
    end

    -- Update Sliders based on profile or defaults
    local sliders = {
        { slider = EasyCursorTrails.cursorSizeSlider, key = "cursorSize" },
        { slider = EasyCursorTrails.cursorOffsetXSlider, key = "cursorOffsetX" },
        { slider = EasyCursorTrails.cursorOffsetYSlider, key = "cursorOffsetY" },
        { slider = EasyCursorTrails.numGlowsSlider, key = "numGlows" },
        { slider = EasyCursorTrails.patternGlowCountSlider, key = "patternGlowCount" },
        { slider = EasyCursorTrails.glowIntensitySlider, key = "glowIntensity" },
        { slider = EasyCursorTrails.glowRadiusSlider, key = "glowRadius" },
        { slider = EasyCursorTrails.glowSizeSlider, key = "glowSize" },
        { slider = EasyCursorTrails.glowThicknessSlider, key = "glowThickness" },
        { slider = EasyCursorTrails.trailSizeStartSlider, key = "trailSizeStart" },
        { slider = EasyCursorTrails.trailSizeEndSlider, key = "trailSizeEnd" },
        { slider = EasyCursorTrails.trailLayerCountSlider, key = "trailLayerCount" },
        { slider = EasyCursorTrails.trailCountSlider, key = "trailCount" },
        { slider = EasyCursorTrails.trailLayerSpacingSlider, key = "trailLayerSpacing" },
        { slider = EasyCursorTrails.trailInitialSeparationSlider, key = "trailInitialSeparation" },
        { slider = EasyCursorTrails.pulsingSpeedSlider, key = "pulsingSpeed" },
        { slider = EasyCursorTrails.pulseMinSlider, key = "pulseMin" },
        { slider = EasyCursorTrails.pulseMaxSlider, key = "pulseMax" },
        { slider = EasyCursorTrails.pulseStepSlider, key = "pulseStep" },
        { slider = EasyCursorTrails.trailDelaySlider, key = "trailDelay" },
        { slider = EasyCursorTrails.glowHollownessSlider, key = "glowHollowness" },
    }

    for _, s in ipairs(sliders) do
        if s.slider then
            local value = profileSettings[s.key] or defaults[s.key]
            s.slider:SetValue(value)

            if s.slider.labelText then
                s.slider.labelText:SetText(string.format("%s: %s", s.slider.labelText:GetText(), tostring(value)))
            end
        end
    end

    -- Update Dropdowns based on profile or defaults
    local dropdowns = {
        { dropdown = EasyCursorTrails.profileDropdown, key = "currentProfile", defaultText = "Select Profile" },
        { dropdown = EasyCursorTrails.textureDropdown, key = "trailTexture", defaultText = "Select Texture", textPrefix = "Texture " },
        { dropdown = EasyCursorTrails.trailMovementEffectDropdown, key = "trailMovementEffect", defaultText = "Select Effect", textPrefix = "Effect " },
        { dropdown = EasyCursorTrails.cursorFrameStrataDropdown, key = "cursorFrameStrata", defaultText = "Select Frame Strata" },
        { dropdown = EasyCursorTrails.selectedCursorTextureDropdown, key = "selectedCursorTextureName", defaultText = "Select Cursor Texture" },
        { dropdown = EasyCursorTrails.selectedGlowEffectDropdown, key = "selectedGlowEffect", defaultText = "Select Glow Effect", textPrefix = "Glow Effect " },
        { dropdown = EasyCursorTrails.trailColorEffectDropdown, key = "trailColorEffect", defaultText = "Select Color Effect", textPrefix = "Color Effect " },
    }

    for _, d in ipairs(dropdowns) do
        if d.dropdown then
            local selectedValue = profileSettings[d.key] or defaults[d.key]
            if d.textPrefix then
                UIDropDownMenu_SetText(d.dropdown, (d.textPrefix .. tostring(selectedValue)) or d.defaultText)
            else
                UIDropDownMenu_SetText(d.dropdown, selectedValue or d.defaultText)
            end
            UIDropDownMenu_SetSelectedID(d.dropdown, selectedValue)
        end
    end

    -- Refresh Trails and Effects
    RebuildTrails()
    EasyCursorTrails.ApplySelectedGlowEffect()
end


-----------------------------------------------
-- CreateSlider Function
-----------------------------------------------
function CreateSlider(name, parent, label, min, max, step, initialValue, onValueChanged)
    -- Ensure initialValue is a valid number, default to min if nil
    initialValue = initialValue or min

    -- Create the slider frame using the OptionsSliderTemplate for consistent styling
    local slider = CreateFrame("Slider", name, parent, "OptionsSliderTemplate")
    slider:SetMinMaxValues(min, max)
    slider:SetValueStep(step)
    slider:SetValue(initialValue)  -- Set the initial value

    -- Customize the slider's appearance for better visibility
    slider:SetWidth(150)  -- Increased width for better interaction
    slider:SetHeight(20)  -- Increased height for easier manipulation

    -- Customize the thumb texture for better visibility
    local thumbTexture = slider:CreateTexture(nil, "ARTWORK")
    thumbTexture:SetTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
    thumbTexture:SetSize(20, 20) -- Larger thumb for easier interaction
    slider:SetThumbTexture(thumbTexture)

    -- Create the slider label above the slider
    slider.labelText = slider:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    slider.labelText:SetPoint("BOTTOM", slider, "TOP", 0, 5)
    slider.labelText:SetText(label)

    -- Create a numeric input box for precise value entry
    slider.editBox = CreateFrame("EditBox", nil, slider, "InputBoxTemplate")
    slider.editBox:SetSize(60, 20)
    slider.editBox:SetPoint("LEFT", slider, "RIGHT", 10, 0)
    slider.editBox:SetNumeric(false) -- Allows negative signs
    slider.editBox:SetAutoFocus(false)
    slider.editBox:SetText(tostring(initialValue))  -- Set the initial value in the edit box
    slider.editBox:SetJustifyH("CENTER")

    -- Function to update slider value from edit box
    local function UpdateSliderFromEditBox(self)
        local enteredValue = tonumber(self:GetText())
        if enteredValue then
            -- Ensure the value is within the allowed range
            enteredValue = math.max(min, math.min(max, enteredValue))
            slider:SetValue(enteredValue)
            self:SetText(tostring(enteredValue))
            -- Trigger the OnValueChanged callback
            if onValueChanged then
                onValueChanged(slider, enteredValue)
            end
        else
            -- Reset to the current slider value if invalid input
            self:SetText(tostring(slider:GetValue()))
        end
        self:ClearFocus()
    end

    -- Set scripts for the edit box
    slider.editBox:SetScript("OnEnterPressed", UpdateSliderFromEditBox)
    slider.editBox:SetScript("OnEscapePressed", function(self)
        self:SetText(tostring(slider:GetValue()))
        self:ClearFocus()
    end)

    -- Handle slider value changes
    slider:SetScript("OnValueChanged", function(self, newValue)
        if EasyCursorTrails.isUpdating then
            return
        end

        -- Set the flag to prevent recursive calls
        EasyCursorTrails.isUpdating = true

        -- Snap the value to the nearest step
        newValue = math.floor(newValue / step + 0.5) * step
        self:SetValue(newValue)
        self.editBox:SetText(tostring(newValue))

        -- Save to current profile and database
        if EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] then
            EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile][name] = newValue
        end
        EasyCursorTrailsDB[name] = newValue
        SaveToCurrentProfile(name, newValue)
        --print(string.format("Saved to profile: %s trailTexture = %s", EasyCursorTrailsDB.currentProfile, EasyCursorTrailsDB[name]))

        -- Invoke the callback function if provided
        if onValueChanged then
            onValueChanged(self, newValue)
        end

        -- Reset the flag
        EasyCursorTrails.isUpdating = false
    end)

    -- Add tooltip functionality for better user guidance
    slider:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText(label, 1, 1, 1)
        GameTooltip:AddLine(string.format("Value: %s", tostring(slider:GetValue())), 1, 1, 1, true)
        GameTooltip:Show()
    end)
    slider:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    return slider
end


-- Function to create a dropdown menu
local function CreateDropdown(name, parent, labelText, options, currentValue, onSelect)
    -- Create the label for the dropdown
    local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    label:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -10)
   

    -- Create the dropdown frame
    local dropdown = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate")
    dropdown:SetPoint("TOPLEFT", label, "BOTTOMLEFT", 0, -10)
    UIDropDownMenu_SetWidth(dropdown, 200)

    -- Set initial text based on the current value
    local initialText = "Select an option"
    if options and options[currentValue] and options[currentValue].text then
        initialText = options[currentValue].text
    end
    UIDropDownMenu_SetText(dropdown, initialText)

    -- Dropdown initialization
    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        if not options or #options == 0 then
            -- Handle empty options
            local info = UIDropDownMenu_CreateInfo()
            info.text = "No Options Available"
            info.disabled = true
            UIDropDownMenu_AddButton(info)
            return
        end

        for i, option in ipairs(options) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = option.text or "Option " .. i
            if option.icon then
                info.icon = option.icon
                info.iconTexCoord = { 0, 1, 0, 1 }
                info.iconWidth = 16
                info.iconHeight = 16
            end
            info.checked = (currentValue == i)
            info.func = function()
                -- Prevent callback during programmatic updates
                if EasyCursorTrails.isUpdatingDropdown then
                    return
                end

                UIDropDownMenu_SetSelectedID(dropdown, i)
                UIDropDownMenu_SetText(dropdown, option.text or "Option " .. i)
                currentValue = i -- Update the current value

                -- Save to the current profile
                if EasyCursorTrailsDB and EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.currentProfile then
                    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile][name] = i
                else
                    --print("EasyCursorTrails: Failed to save setting. Profile data is missing.")
                end

                if onSelect then
                    onSelect(i)
                end

                CloseDropDownMenus()
            end
            UIDropDownMenu_AddButton(info)
        end
    end)
   
    return dropdown
end


    EasyCursorTrails.DebugPrint = function(message)
        if EasyCursorTrailsDB.debugMode then
           -- --print("|cff00ff00EasyCursorTrails Debug:|r " .. tostring(message))
        end
    end
    
    EasyCursorTrails.HandleError = function(message)
      --  --print("|cffff0000EasyCursorTrails Error:|r " .. tostring(message))
    end

 -------------------------
-- Color Picker
-------------------------
function EasyCursorTrails.OpenColorPicker(initialColor, callback)
    local function ColorPickerCallback(restore)
        local newR, newG, newB, newA
        if restore then
            newR, newG, newB, newA = unpack(restore)
        else
            newR, newG, newB = ColorPickerFrame:GetColorRGB()
            if ColorPickerFrame.hasOpacity then
                if ColorPickerFrame.opacity then
                    newA = 1 - (ColorPickerFrame.opacity or 0)
                else
                    newA = 1
                end
            else
                newA = 1
            end
        end
        callback({ r = newR, g = newG, b = newB, a = newA })
    end

    ColorPickerFrame.func = ColorPickerCallback
    ColorPickerFrame.opacityFunc = ColorPickerCallback
    ColorPickerFrame.cancelFunc = ColorPickerCallback
    ColorPickerFrame.swatchFunc = ColorPickerCallback

    ColorPickerFrame.hasOpacity = true
    ColorPickerFrame.opacity = 1 - (initialColor.a or 1)
    ColorPickerFrame.previousValues = { initialColor.r, initialColor.g, initialColor.b, initialColor.a }

    if ColorPickerFrame.SetColorRGB then
        ColorPickerFrame:SetColorRGB(initialColor.r, initialColor.g, initialColor.b)
    else
        ColorPickerFrame.red = initialColor.r
        ColorPickerFrame.green = initialColor.g
        ColorPickerFrame.blue = initialColor.b
    end

    ColorPickerFrame:Hide()
    ColorPickerFrame:Show()
end


function EasyCursorTrails.HSVToRGB(h, s, v)
    local c = v * s
    local x = c * (1 - math.abs((h / 60) % 2 - 1))
    local m = v - c
    local r, g, b

    if h >= 0 and h < 60 then
        r, g, b = c, x, 0
    elseif h >= 60 and h < 120 then
        r, g, b = x, c, 0
    elseif h >= 120 and h < 180 then
        r, g, b = 0, c, x
    elseif h >= 180 and h < 240 then
        r, g, b = 0, x, c
    elseif h >= 240 and h < 300 then
        r, g, b = x, 0, c
    elseif h >= 300 and h < 360 then
        r, g, b = c, 0, x
    else
        r, g, b = 0, 0, 0
    end

    return r + m, g + m, b + m
end

-------------------------
-- Pulsing Logic
-------------------------
function EasyCursorTrails.UpdatePulseValue()
    EasyCursorTrails.pulseValueTrail = (EasyCursorTrails.pulseValueTrail or 0.5) + (EasyCursorTrails.pulseDirectionTrail or 1) * (EasyCursorTrailsDB.pulseStep or 0.02)
    local pulseMin = EasyCursorTrailsDB.pulseMin or 0.3
    local pulseMax = EasyCursorTrailsDB.pulseMax or 1.0

    if EasyCursorTrails.pulseValueTrail >= pulseMax then
        EasyCursorTrails.pulseValueTrail = pulseMax
        EasyCursorTrails.pulseDirectionTrail = -1
    elseif EasyCursorTrails.pulseValueTrail <= pulseMin then
        EasyCursorTrails.pulseValueTrail = pulseMin
        EasyCursorTrails.pulseDirectionTrail = 1
    end
end

-------------------------
-- Glow Animation
-------------------------
function EasyCursorTrails.AnimateGlow(glowLayer)
    if not glowLayer.animation then
        glowLayer.animation = glowLayer:CreateAnimationGroup()
        glowLayer.animation:SetLooping("BOUNCE")

        local alphaAnim = glowLayer.animation:CreateAnimation("Alpha")
        alphaAnim:SetFromAlpha((EasyCursorTrailsDB.glowIntensityFactor or 0.8) * 0.5)
        alphaAnim:SetToAlpha(EasyCursorTrailsDB.glowIntensityFactor or 0.8)
        alphaAnim:SetDuration(1)
        glowLayer.animation:AddAnimation(alphaAnim)
    end

    glowLayer.animation:Play()
end

function EasyCursorTrails.ToggleGlow(glow, show)
    if show and glow and glow.texture then
        glow.texture:SetVertexColor(EasyCursorTrailsDB.glowColor.r, EasyCursorTrailsDB.glowColor.g, EasyCursorTrailsDB.glowColor.b, EasyCursorTrailsDB.glowColor.a)
        glow:Show()
        EasyCursorTrails.AnimateGlow(glow)
    else
        if glow and glow.texture then
            glow:Hide()
        end
    end
end

-------------------------
-- Rainbow Color Update
-------------------------
function EasyCursorTrails.UpdateRainbowColor(indexOffset)
    local offset = indexOffset or 0
    local hue = (EasyCursorTrails.colorIndexTrail or 0) + 0.05 + offset

    local rr = 0.5 + 0.5 * math.sin(hue)
    local gg = 0.5 + 0.5 * math.sin(hue + 2)
    local bb = 0.5 + 0.5 * math.sin(hue + 4)

    return rr, gg, bb
end



-----------------------------------------------
-- ApplyColorEffectTrail Function
-----------------------------------------------
function EasyCursorTrails.ApplyColorEffectTrail(trail, index)
    if not (trail and trail.texture) then
        EasyCursorTrails.HandleError("ApplyColorEffectTrail: 'trail' or 'trail.texture' is nil.")
        return
    end

    -- Ensure colorIndexTrail is initialized
    EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail or 0

    -- Handle nil index by assigning a default value
    if index == nil then
        --print("ApplyColorEffectTrail: 'index' is nil for trail", trail:GetName(), ". Assigning default index 1.")
        index = 1
    end

    local glowColor = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    local intensity = EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity

    trail.texture:SetVertexColor(glowColor.r, glowColor.g, glowColor.b, glowColor.a * intensity)
    trail.texture:SetAlpha(glowColor.a * intensity)

    -- Create glow layers if they don't exist
    if not trail.glowLayers then
        trail.glowLayers = {}
        for i = 1, 2 do -- Creating two glow layers
            local glowLayer = CreateFrame("Frame", nil, trail)
            
            -- Calculate new frame level, ensuring it doesn't go below 0
            local desiredFrameLevel = trail:GetFrameLevel() - (i + 1)
            local newFrameLevel = math.max(desiredFrameLevel, 0) -- Clamps to minimum 0
            newFrameLevel = math.min(newFrameLevel, 65535) -- Clamps to maximum 65535
            
            glowLayer:SetFrameLevel(newFrameLevel)
            glowLayer:SetPoint("CENTER", trail, "CENTER")
            local multiplier = EasyCursorTrailsDB.glowSizeMultiplier or 4 -- Default multiplier
            glowLayer:SetSize(trail:GetWidth() * multiplier, trail:GetHeight() * multiplier)

            local glowTexLayer = glowLayer:CreateTexture(nil, "OVERLAY")
            local customTexture = EasyCursorTrailsDB.customGlowTexture or "Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64"
            glowTexLayer:SetTexture(customTexture)
            glowTexLayer:SetBlendMode("ADD")
            glowTexLayer:SetAllPoints()
            glowLayer.texture = glowTexLayer

            glowLayer:Hide()
            table.insert(trail.glowLayers, glowLayer)
        end
    else
        -- Update existing glow layers' size and texture based on settings
        for i, glowLayer in ipairs(trail.glowLayers) do
            local multiplier = (EasyCursorTrailsDB.glowSizeMultiplier or 0.02) + (i * 1) -- Slightly larger for each layer
            glowLayer:SetSize(trail:GetWidth() * multiplier, trail:GetHeight() * multiplier)
            glowLayer.texture:SetTexture(EasyCursorTrailsDB.customGlowTexture or "Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
        end
    end

    local effect = EasyCursorTrailsDB.trailColorEffect or 1
    local trailColor = EasyCursorTrailsDB.trailColor or { r = 1, g = 1, b = 1, a = 1 }
    local r, g, b, a = 1, 1, 1, 1
    local showGlow = false

    -- --print("Applying color effect:", effect, "for trail:", trail:GetName()) -- Optional: Remove after testing

    -- The big if-else (1..43)
    if effect == 1 then
        r, g, b, a = 1, 1, 1, 1
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 2 then
        if index ~= nil then
            r, g, b = EasyCursorTrails.UpdateRainbowColor(index * 1.2)
            -- --print("Effect 2 - Rainbow Color for trail", trail:GetName(), ":", r, g, b)
        else
            r, g, b = 1, 1, 1
            -- --print("Effect 2 - Index is nil for trail", trail:GetName(), ". Setting color to white.")
        end
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 3 then
        EasyCursorTrails.UpdatePulseValue()
        r, g, b, a = EasyCursorTrails.pulseValueTrail, EasyCursorTrails.pulseValueTrail, EasyCursorTrails.pulseValueTrail, 1
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 4 then
        r, g, b, a = 1, 1, 1, 0.9
        showGlow = true
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 5 then
        EasyCursorTrails.UpdatePulseValue()
        if index ~= nil then
            local rr, gg, bb = EasyCursorTrails.UpdateRainbowColor(index * 1.2)
            r = rr * (EasyCursorTrails.pulseValueTrail or 0.5)
            g = gg * (EasyCursorTrails.pulseValueTrail or 0.5)
            b = bb * (EasyCursorTrails.pulseValueTrail or 0.5)
        else
            r, g, b = 1, 1, 1
        end
        a = 1
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 6 then
        showGlow = true

        if index ~= nil then
            -- Base hue offset based on index to introduce variation
            local baseHueOffset = index * 1.2

            for i, glowLayer in ipairs(trail.glowLayers) do
                -- Calculate hue for each glow layer with a phase shift (e.g., 60 degrees apart)
                local hue = (EasyCursorTrails.colorIndexTrail + baseHueOffset + (i - 1) * 60) % 360
                local rr, gg, bb = EasyCursorTrails.HSVToRGB(hue, 1, 1)
                r = rr * (EasyCursorTrails.pulseValueTrail or 0.5)
                g = gg * (EasyCursorTrails.pulseValueTrail or 0.5)
                b = bb * (EasyCursorTrails.pulseValueTrail or 0.5)

                -- Set glow layer color with intensity factor
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)

                if EasyCursorTrailsDB.enableGlowAnimations then
                    EasyCursorTrails.AnimateGlow(glowLayer)
                end

                glowLayer:Show()
            end
            trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
            -- Optional: Remove or comment out debug print statements after testing
            -- --print("Rainbow glow layers shown and animated for trail", trail:GetName())
        else
            -- Default to white if index is nil
            r, g, b = 1, 1, 1
            a = 1

            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)
                glowLayer:Show()
            end

            -- --print("Rainbow glow layers shown with default color for trail", trail:GetName())
        end
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 7 then
        r, g, b, a = trailColor.r, trailColor.g, trailColor.b, trailColor.a
    elseif effect == 8 then
        EasyCursorTrails.UpdatePulseValue()
        r = trailColor.r * (EasyCursorTrails.pulseValueTrail or 0.5)
        g = trailColor.g * (EasyCursorTrails.pulseValueTrail or 0.5)
        b = trailColor.b * (EasyCursorTrails.pulseValueTrail or 0.5)
        a = trailColor.a
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 9 then
        r, g, b, a = trailColor.r, trailColor.g, trailColor.b, 0.8
        showGlow = true
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 10 then
        EasyCursorTrails.UpdatePulseValue()
        r = trailColor.r * (EasyCursorTrails.pulseValueTrail or 0.5)
        g = trailColor.g * (EasyCursorTrails.pulseValueTrail or 0.5)
        b = trailColor.b * (EasyCursorTrails.pulseValueTrail or 0.5)
        a = trailColor.a
        showGlow = true
        if EasyCursorTrailsDB.enableGlowAnimations then
            -- Animate and show all glow layers
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)
                EasyCursorTrails.AnimateGlow(glowLayer)
                glowLayer:Show()
            end
            -- --print("Glow layers shown and animated for trail", trail:GetName())
        else
            -- Show all glow layers without animation
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)
                glowLayer:Show()
            end
            -- --print("Glow layers shown for trail", trail:GetName())
        end
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 11 then
        EasyCursorTrails.UpdatePulseValue()
        if index ~= nil then
            local rr, gg, bb = EasyCursorTrails.UpdateRainbowColor(index * 1.2)
            r = rr * (EasyCursorTrails.pulseValueTrail or 0.5)
            g = gg * (EasyCursorTrails.pulseValueTrail or 0.5)
            b = bb * (EasyCursorTrails.pulseValueTrail or 0.5)
        else
            r, g, b = 1, 1, 1
        end
        a = 1
        showGlow = true
        if EasyCursorTrailsDB.enableGlowAnimations then
            -- Animate and show all glow layers
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)
                EasyCursorTrails.AnimateGlow(glowLayer)
                glowLayer:Show()
            end
            -- --print("Glow layers shown and animated for trail", trail:GetName())
        else
            -- Show all glow layers without animation
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.8)
                glowLayer:Show()
            end
            -- --print("Glow layers shown for trail", trail:GetName())
        end
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
    elseif effect == 12 then
        r, g, b, a = 0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail),
                     0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail + 1.5),
                     0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail + 3),
                     0.8
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 13 then
        r, g, b, a = 0.3 + 0.7 * math.abs(math.sin(EasyCursorTrails.colorIndexTrail)),
                     0.2 + 0.8 * math.abs(math.cos(EasyCursorTrails.colorIndexTrail)),
                     0.5 + 0.5 * math.abs(math.sin(EasyCursorTrails.colorIndexTrail * 1.5)),
                     0.9
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 14 then
        r, g, b, a = 1, 1, 1, EasyCursorTrails.pulseValueTrail or 0.5
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 15 then
        r, g, b, a = 0.2, 0.1, 0.3, 0.7
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 16 then
        r, g, b, a = 0.2 + 0.8 * math.sin(EasyCursorTrails.colorIndexTrail),
                     0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail + 2),
                     0.7 + 0.3 * math.sin(EasyCursorTrails.colorIndexTrail + 4),
                     0.85
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 17 then
        r, g, b, a = 0.8, 0.8, 1.0, EasyCursorTrails.pulseValueTrail or 0.5
        -- Adjusted scaling to prevent flat appearance
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 18 then
        r, g, b, a = 0.6 + 0.4 * math.sin(EasyCursorTrails.colorIndexTrail * 2),
                     0.6 + 0.4 * math.cos(EasyCursorTrails.colorIndexTrail * 2),
                     0.6 + 0.4 * math.sin(EasyCursorTrails.colorIndexTrail * 3),
                     0.9
       trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 19 then
        r, g, b, a = 1, 0.4, 0.2, EasyCursorTrails.pulseValueTrail or 0.5
        -- Adjusted scaling to prevent flat appearance
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 20 then
        r, g, b, a = 1, 1, 0.8, 0.9
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    elseif effect == 21 then
        r, g, b, a = 0.3, 0.3, 0.7, EasyCursorTrails.pulseValueTrail or 0.5
        -- Adjusted scaling to prevent flat appearance
        trail:SetSize(trail.originalSize * 2.0, trail.originalSize * 2.0)
        showGlow = true
    else
        r, g, b, a = 1, 1, 1, 1
        -- --print("ApplyColorEffectTrail: Unknown effect index " .. tostring(effect) .. " for trail " .. trail:GetName() .. ". Defaulting to white.")
    end

    -- Ensure colorIndexTrail is a number before using it
    if type(EasyCursorTrails.colorIndexTrail) ~= "number" then
        EasyCursorTrails.HandleError("colorIndexTrail is not a number! Resetting to 0.")
        EasyCursorTrails.colorIndexTrail = 0
    end

    a = math.max(0, math.min(a or 1, 1))
    trail.texture:SetVertexColor(r, g, b, a)
    trail.texture:SetAlpha(a)

    if showGlow then
        if EasyCursorTrailsDB.enableGlowAnimations then
            -- Animate and show all glow layers
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 3)
                EasyCursorTrails.AnimateGlow(glowLayer)
                glowLayer:Show()
            end
            -- --print("Glow layers shown and animated for trail", trail:GetName())
        else
            -- Show all glow layers without animation
            for _, glowLayer in ipairs(trail.glowLayers) do
                glowLayer.texture:SetVertexColor(r, g, b, EasyCursorTrailsDB.glowIntensityFactor or 0.9)
                glowLayer:Show()
            end
            -- --print("Glow layers shown for trail", trail:GetName())
        end
    else
        -- Hide all glow layers
        for _, glowLayer in ipairs(trail.glowLayers) do
            glowLayer:Hide()
        end
        -- --print("Glow layers hidden for trail", trail:GetName())
    end

    -- [ADDED] Apply Rotation Based on Movement Angle
    if trail.texture and trail.texture.SetRotation then
        trail.texture:SetRotation(EasyCursorTrails.currentMovementAngle or 0)
    end
end


-------------------------------------------
-- ApplyColorEffectCursor
-------------------------------------------
function EasyCursorTrails.ApplyColorEffectCursor()
    if not customCursor or not customCursor.texture then
        EasyCursorTrails.HandleError("customCursor or customCursor.texture not initialized.")
        return
    end

    local glowColor = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    local intensity = EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity
    customCursor.texture:SetVertexColor(glowColor.r, glowColor.g, glowColor.b, glowColor.a * intensity)
    customCursor.texture:SetAlpha(glowColor.a * intensity)

    local effect      = EasyCursorTrailsDB.cursorColorEffect or 1
    local cursorColor = EasyCursorTrailsDB.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
    customCursor.texture:SetBlendMode("ADD") -- default

    if effect == 1 then
        customCursor.texture:SetVertexColor(1, 1, 1, 1)
    elseif effect == 2 then
        local colorIndex = (customCursor.colorIndexCursor or 0) + 2
        customCursor.colorIndexCursor = colorIndex % 360
        local hue = customCursor.colorIndexCursor / 360
        local r,g,b =  EasyCursorTrails.HSVToRGB(hue, 1, 1)
        customCursor.texture:SetVertexColor(r, g, b, cursorColor.a)
    elseif effect == 3 then
        local pulseValue = (customCursor.pulseValueCursor or 0.5)
                         + (customCursor.pulseDirectionCursor or -1)*0.03
        if pulseValue > 1 then
            pulseValue = 1
            customCursor.pulseDirectionCursor = -1
        elseif pulseValue < 0.5 then
            pulseValue = 0.5
            customCursor.pulseDirectionCursor = 1
        end
        customCursor.pulseValueCursor = pulseValue
        local r = cursorColor.r * pulseValue
        local g = cursorColor.g * pulseValue
        local b = cursorColor.b * pulseValue
        customCursor.texture:SetVertexColor(r, g, b, cursorColor.a)
    elseif effect == 4 then
        -- Rainbow + Pulsing
        local colorIndex = (customCursor.colorIndexCursor or 0) + 3.03
        customCursor.colorIndexCursor = colorIndex % 360
        local rad = math.rad(colorIndex)
        local baseR = 0.5 + 0.5 * math.sin(rad)
        local baseG = 0.5 + 0.5 * math.sin(rad + math.rad(120))
        local baseB = 0.5 + 0.5 * math.sin(rad + math.rad(240))

        local pulseValue = (customCursor.pulseValueCursor or 0.5)
                         + (customCursor.pulseDirectionCursor or 1)*0.03
        if pulseValue > 1 then
            pulseValue = 1
            customCursor.pulseDirectionCursor = -1
        elseif pulseValue < 0.1 then
            pulseValue = 0.2
            customCursor.pulseDirectionCursor = 1
        end
        customCursor.pulseValueCursor = pulseValue

        local finalR = baseR * pulseValue
        local finalG = baseG * pulseValue
        local finalB = baseB * pulseValue
        customCursor.texture:SetVertexColor(finalR, finalG, finalB, cursorColor.a)
    elseif effect == 5 then
        customCursor.texture:SetVertexColor(cursorColor.r, cursorColor.g, cursorColor.b, cursorColor.a)
    elseif effect == 6 then
        local pulseValue = (customCursor.pulseValueCursor or 0.5)
                         + (customCursor.pulseDirectionCursor or -1)*0.03
        if pulseValue > 1 then
            pulseValue = 1
            customCursor.pulseDirectionCursor = -1
        elseif pulseValue < 0.5 then
            pulseValue = 0.5
            customCursor.pulseDirectionCursor = 1
        end
        customCursor.pulseValueCursor = pulseValue
        local r = cursorColor.r * pulseValue
        local g = cursorColor.g * pulseValue
        local b = cursorColor.b * pulseValue
        customCursor.texture:SetVertexColor(r, g, b, cursorColor.a)
    elseif effect == 7 then
        -- Glow
        customCursor.texture:SetBlendMode("ADD")
        local alpha = (customCursor.glowAlpha or 0.8)
                    + (customCursor.glowDir or 1)*0.02
        if alpha > 1 then
            alpha = 1
            customCursor.glowDir = -1
        elseif alpha < 0.8 then
            alpha = 0.8
            customCursor.glowDir = 1
        end
        customCursor.glowAlpha = alpha
        customCursor.texture:SetVertexColor(cursorColor.r, cursorColor.g, cursorColor.b, alpha)
    else
        customCursor.texture:SetVertexColor(1, 1, 1, 1)
    end
end
-- Define the UpdateTrailOffsets function within EasyCursorTrails
function EasyCursorTrails.UpdateTrailOffsets()
    -- Validate the existence of trailPool
    if not EasyCursorTrails.trailPool then
        EasyCursorTrails.HandleError("UpdateTrailOffsets: trailPool is not initialized.")
        return
    end

    -- Retrieve and validate offsets from saved variables
    local profile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then
        EasyCursorTrails.HandleError("UpdateTrailOffsets: Current profile is missing.")
        return
    end

    local offsetX = tonumber(profile.trailOffsetX) or 0
    local offsetY = tonumber(profile.trailOffsetY) or 0

    -- Iterate through each trail in each layer and update positions
    for layerIndex, layerTrails in ipairs(EasyCursorTrails.trailPool) do
        if type(layerTrails) == "table" then
            for trailIndex, trail in ipairs(layerTrails) do
                if trail and trail.texture then
                    -- Get the current position of the trail
                    local _, _, _, currentX, currentY = trail:GetPoint()
                    currentX = currentX or 0
                    currentY = currentY or 0

                    -- Calculate the new position based on offsets
                    local newX = currentX + offsetX
                    local newY = currentY + offsetY

                    -- Update the trail's position
                    trail:ClearAllPoints()
                    trail:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY)
                end
            end
        end
    end

    -- Optionally, update glow frames or other related components
    if EasyCursorTrails.UpdateGlowFrames then
        EasyCursorTrails.UpdateGlowFrames()
    else
        EasyCursorTrails.HandleError("UpdateTrailOffsets: UpdateGlowFrames function is missing.")
    end

    -- Provide feedback for successful update (optional debug message)
    --print("EasyCursorTrails: Trail offsets updated successfully.")
end



-- Function to update glow effects based on saved or selected state
function UpdateGlowBelowCursor()
    if not customCursor or not customCursor.glowEffects then
        print("EasyCursorTrails Error: customCursor or glowEffects not initialized.")
        return
    end

    -- Apply the appropriate frame strata to glow effects
    for _, glow in ipairs(customCursor.glowEffects) do
        if EasyCursorTrailsDB.glowBelow then
            glow:SetFrameStrata("LOW")
        else
            glow:SetFrameStrata("HIGH")
        end
    end
end



local function InitializeSettingsMenu()
    if EasyCursorTrails.menuInitialized then
        return
    end
    EasyCursorTrails.menuInitialized = true
 
    -- Create the settings menu frame
    local menu = CreateFrame("Frame", "EasyCursorTrailsMenu", UIParent, "BasicFrameTemplateWithInset")
    menu:SetSize(900, 830)
    menu:SetPoint("CENTER", UIParent, "CENTER")
    menu:SetMovable(true)
    menu:EnableMouse(true)
    menu:RegisterForDrag("LeftButton")
    menu:SetScript("OnDragStart", menu.StartMoving)
    menu:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        local point, _, relativePoint, x, y = self:GetPoint()
        EasyCursorTrailsDB.menuPosition = { point = point, relativePoint = relativePoint, x = x, y = y }
        SaveToCurrentProfile("menuPosition", EasyCursorTrailsDB.menuPosition)
        --print("EasyCursorTrails: Menu position saved.")
    end)
    menu:Hide()

    -- Restore saved menu position
    if EasyCursorTrailsDB.menuPosition then
        menu:ClearAllPoints()
        menu:SetPoint(
            EasyCursorTrailsDB.menuPosition.point,
            UIParent,
            EasyCursorTrailsDB.menuPosition.relativePoint,
            EasyCursorTrailsDB.menuPosition.x,
            EasyCursorTrailsDB.menuPosition.y
        )
    end

    -- Reset menu position button
    local resetPositionButton = CreateFrame("Button", "ResetMenuPositionButton", menu, "UIPanelButtonTemplate")
    resetPositionButton:SetSize(150, 25)
    resetPositionButton:SetText("Reset Menu Position")
    resetPositionButton:SetPoint("BOTTOM", menu, "BOTTOM", 300, 370)
    resetPositionButton:SetScript("OnClick", function()
        menu:ClearAllPoints()
        menu:SetPoint("CENTER", UIParent, "CENTER")
        EasyCursorTrailsDB.menuPosition = { point = "CENTER", relativePoint = "CENTER", x = 0, y = 0 }
        SaveToCurrentProfile("menuPosition", EasyCursorTrailsDB.menuPosition)
        --print("EasyCursorTrails: Menu position reset to default.")
    end)


    local menuTitle = menu:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    menuTitle:SetPoint("TOP", menu, "TOP", 0, -3)
    menuTitle:SetText("Easy Cursor Trails Settings")


    -- Enable Trails Checkbox
    local enableTrailsCheckbox = CreateFrame("CheckButton", nil, menu, "UICheckButtonTemplate")
    enableTrailsCheckbox:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", 20, -50)
    enableTrailsCheckbox.text = enableTrailsCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    enableTrailsCheckbox.text:SetPoint("LEFT", enableTrailsCheckbox, "RIGHT", 5, 0)
    enableTrailsCheckbox.text:SetText("Enable Trails")
    enableTrailsCheckbox:SetChecked(EasyCursorTrailsDB.enableTrails)

    enableTrailsCheckbox:SetScript("OnClick", function(self)
        EasyCursorTrailsDB.enableTrails = self:GetChecked()
        SaveToCurrentProfile("enableTrails", EasyCursorTrailsDB.enableTrails)
        RebuildTrails()
        --print("EasyCursorTrails: 'Enable Trails' set to", EasyCursorTrailsDB.enableTrails and "enabled" or "disabled")
    end)

    -- Cursor Settings
    local cursorHeading = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    cursorHeading:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", -330, -20)
    cursorHeading:SetText("Cursor Settings")
    
-- Glow Below Cursor Checkbox
local glowBelowCheckbox = CreateFrame("CheckButton", "GlowBelowCursorCheckbox", menu, "UICheckButtonTemplate")
glowBelowCheckbox:SetPoint("TOPLEFT", enableTrailsCheckbox, "BOTTOMLEFT", -350, 30)

-- Add label text
glowBelowCheckbox.text = glowBelowCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormal")
glowBelowCheckbox.text:SetPoint("LEFT", glowBelowCheckbox, "RIGHT", 5, 0)
glowBelowCheckbox.text:SetText("Glow Below Cursor")

-- Initialize checkbox state from the saved database or default
glowBelowCheckbox:SetChecked(EasyCursorTrailsDB.glowBelow or false)

-- OnClick event to handle user interaction
glowBelowCheckbox:SetScript("OnClick", function(self)
    -- Update the database with the new state
    EasyCursorTrailsDB.glowBelow = self:GetChecked()
    SaveToCurrentProfile("glowBelow", EasyCursorTrailsDB.glowBelow)

    -- Dynamically update the glow effect
    UpdateGlowBelowCursor()
end)

    -- Trail Settings
    local trailSettingsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    trailSettingsHeader:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", 50, -20)
    trailSettingsHeader:SetText("Trail Settings")
    
    local trailSizeStartSlider = CreateSlider("TrailSizeStartSlider", menu, "Trail Size Start", 1, 100, 1,
    EasyCursorTrailsDB.trailSizeStart or defaults.trailSizeStart,
    function(slider, value)
        EasyCursorTrailsDB.trailSizeStart = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("trailSizeStart", value) -- Save to profile
        RebuildTrails()
    end
)
trailSizeStartSlider:SetPoint("TOPLEFT", enableTrailsCheckbox, "BOTTOMLEFT", 0, -30)

local trailSizeEndSlider = CreateSlider("TrailSizeEndSlider", menu, "Trail Size End", 1, 100, 1,
    EasyCursorTrailsDB.trailSizeEnd or defaults.trailSizeEnd,
    function(slider, value)
        EasyCursorTrailsDB.trailSizeEnd = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("trailSizeEnd", value) -- Save to profile
        RebuildTrails()
    end
)
trailSizeEndSlider:SetPoint("TOPLEFT", trailSizeStartSlider, "BOTTOMLEFT", 0, -30)

    local trailCountSlider = CreateSlider("TrailCountSlider", menu, "Trail Count", 0, 100, 1,
        EasyCursorTrailsDB.trailCount or defaults.trailCount,
        function(slider, value)
            EasyCursorTrailsDB.trailCount = value
            slider:SetValue(value)
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("trailCount", value) -- Save to profile
            RebuildTrails()
        end
    )
    trailCountSlider:SetPoint("TOPLEFT", trailSizeEndSlider, "BOTTOMLEFT", 0, -30)

    local trailLayerCountSlider = CreateSlider("TrailLayerCountSlider", menu, "Trail Layer Count", 1, 50, 1,
        EasyCursorTrailsDB.trailLayerCount or defaults.trailLayerCount,
        function(slider, value)
            EasyCursorTrailsDB.trailLayerCount = value
            slider:SetValue(value)
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("trailLayerCount", value) -- Save to profile
            RebuildTrails()
        end
    )
    trailLayerCountSlider:SetPoint("TOPLEFT", trailCountSlider, "BOTTOMLEFT", 0, -30)

    local trailLayerSpacingSlider = CreateSlider("TrailLayerSpacingSlider", menu, "Trail Layer Spacing", 0, 50, 1,
        EasyCursorTrailsDB.trailLayerSpacing or defaults.trailLayerSpacing,
        function(slider, value)
            EasyCursorTrailsDB.trailLayerSpacing = value
            slider:SetValue(value)
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("trailLayerSpacing", value) -- Save to profile
            -- Any additional logic if necessary
        end
    )
    trailLayerSpacingSlider:SetPoint("TOPLEFT", trailLayerCountSlider, "BOTTOMLEFT", 0, -30)


local trailInitialSeparationSlider = CreateSlider("TrailInitialSeparationSlider", menu, "Trail Layer Seperation", 1, 500, 1, initialValue, function(slider, value)
    EasyCursorTrailsDB.trailInitialSeparation = value
    slider:SetValue(value)
    EasyCursorTrails.settingsChanged = true
    SaveToCurrentProfile("trailInitialSeparation", value) -- Save to profile
end)

trailInitialSeparationSlider:SetPoint("TOPLEFT", trailLayerSpacingSlider, "BOTTOMLEFT", 0, -30)

    local chainSpacingSlider = CreateSlider("TrailInitialSeparationSlider", menu, "Trail Texture Spacing", 1,500, 1,
    EasyCursorTrailsDB.chainSpacingSlider or defaults.chainSpacingSlider,
    function(slider, value)
        EasyCursorTrailsDB.chainSpacingSlider = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("chainSpacing", value) -- Save to profile
        
        -- Any additional logic if necessary
    end
)
chainSpacingSlider:SetPoint("TOPLEFT", trailInitialSeparationSlider, "BOTTOMLEFT", 0, -25)

-- Trail Offset X Slider
local trailOffsetXSlider = CreateSlider(
    "TrailOffsetXSlider", 
    menu, 
    "Trail Offset X", 
    -100, 
    100, 
    1,
    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailOffsetX or defaults.trailOffsetX,
    function(slider, value)
        -- Update the value in the profile and runtime memory
        SaveToCurrentProfile("trailOffsetX", value)
        
        -- Apply changes to the trail offsets
        EasyCursorTrails.UpdateTrailOffsets()
    end
)
trailOffsetXSlider:SetPoint("TOPLEFT", chainSpacingSlider, "BOTTOMLEFT", 0, -30)

-- Trail Offset Y Slider
local trailOffsetYSlider = CreateSlider(
    "TrailOffsetYSlider", 
    menu, 
    "Trail Offset Y", 
    -100, 
    100, 
    1,
    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailOffsetY or defaults.trailOffsetY,
    function(slider, value)
        -- Update the value in the profile and runtime memory
        SaveToCurrentProfile("trailOffsetY", value)
        
        -- Apply changes to the trail offsets
        EasyCursorTrails.UpdateTrailOffsets()
    end
)
trailOffsetYSlider:SetPoint("TOPLEFT", trailOffsetXSlider, "BOTTOMLEFT", 0, -30)


  -------------------------------
-- Effects Settings Section
-------------------------------
local effectsSettingsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
effectsSettingsHeader:SetPoint("TOPLEFT", trailOffsetYSlider, "BOTTOMLEFT", 0, -40)
effectsSettingsHeader:SetText("Effects Settings")

-- Dropdown: Select Trail Movement Effect
local trailMovementEffectDropdown = CreateDropdown("TrailMovementEffectDropdown", menu, "Trail Movement Effect", trailMovementEffectOptions, EasyCursorTrailsDB.trailMovementEffect or 1, function(index)
    EasyCursorTrailsDB.trailMovementEffect = index
    EasyCursorTrails.settingsChanged = true
    SaveToCurrentProfile("trailMovementEffect", index) -- Save to profile
    
    RebuildTrails()

    -- Re-apply cursor glow logic so it doesn't hide
    EasyCursorTrails.ApplySelectedGlowEffect()

    -- Debug message (optional)
    -- print(string.format("Trail Movement Effect set to: %d. Saved to profile: %s.", index, EasyCursorTrailsDB.currentProfile))
end)
trailMovementEffectDropdown:SetPoint("TOPLEFT", effectsSettingsHeader, "BOTTOMLEFT", -50, -10)

-- Trail textures Effect Options
local trailEffectsOptions = {}
for i, effectName in ipairs(trailEffects) do
    table.insert(trailEffectsOptions, { text = effectName })
end

-- Dropdown: Create and Save Functionality for Trail Texture Effect
local trailEffectsDropdown = CreateDropdown("TrailMovementEffectDropdown", menu, "Trail Movement Effect", trailEffectsOptions, EasyCursorTrailsDB.trailMovementEffect or 1, function(index)
    EasyCursorTrailsDB.trailMovementEffect = index
    EasyCursorTrails.settingsChanged = true
    SaveToCurrentProfile("trailMovementEffect", index) -- Save to profile
    EasyCursorTrailsDB.trailTexture = 1  -- Assuming the texture should be set to 1 by default, based on your previous logic
    SaveToCurrentProfile("trailTexture", 1) -- Save to profile

    UpdateTrailTextureDropdown(index)
    SaveAllSettingsToProfile()  -- Ensure all settings are saved

    RebuildTrails()

    -- Debug message (optional)
    -- print(string.format("Trail Movement Effect set to: %d. Saved to profile: %s.", index, EasyCursorTrailsDB.currentProfile))
end)
trailEffectsDropdown:SetPoint("TOPLEFT", effectsSettingsHeader, "BOTTOMLEFT", -50, -45)

-- Create Validated Dropdown Function
local function CreateValidatedDropdown(name, parent, label, options, selectedIndex, onSelect)
    local dropdown = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate")
    dropdown:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -10) -- Adjust positioning as needed

    -- Create a label for the dropdown
    local dropdownLabel = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    dropdownLabel:SetPoint("BOTTOM", dropdown, "TOP", 0, 10)
    dropdownLabel:SetText(label)

    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        for i, option in ipairs(options) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = option.text
            if option.icon then
                info.icon = option.icon
                info.iconTexCoord = { 0, 1, 0, 1 }
                info.iconWidth = 16
                info.iconHeight = 16
            end
            info.func = function()
                UIDropDownMenu_SetSelectedID(dropdown, i)
                UIDropDownMenu_SetText(dropdown, option.text)
                onSelect(i)
                CloseDropDownMenus()

                -- Debug message
                --print(string.format("%s set to: %s. Saved to profile: %s.", label, option.text, EasyCursorTrailsDB.currentProfile))
            end
            UIDropDownMenu_AddButton(info)
        end
    end)

    -- Clamp the selectedIndex to the available options
    local clampedIndex = math.max(1, math.min(selectedIndex, #options))
    if clampedIndex ~= selectedIndex then
        if name == "TrailMovementEffectDropdown" then
            EasyCursorTrailsDB.trailMovementEffect = clampedIndex
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("trailMovementEffect", clampedIndex)
        elseif name == "TrailTextureDropdown" then
            EasyCursorTrailsDB.trailTexture = clampedIndex
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("trailTexture", clampedIndex)
        end
    end

    -- Set selected ID and text
    if #options > 0 then
        UIDropDownMenu_SetSelectedID(dropdown, clampedIndex)
        UIDropDownMenu_SetText(dropdown, options[clampedIndex].text)
    else
        UIDropDownMenu_SetText(dropdown, "Select a texture")
    end

    return dropdown
end

-- Trail Texture Dropdown
local trailTextureDropdown = CreateValidatedDropdown(
    "TrailTextureDropdown",
    menu,
    "Select Specific Texture",
    {}, -- Options will be populated dynamically
    EasyCursorTrailsDB.trailTexture or 1,
    function(index)
       
        -- Save the selected texture to the profile
        EasyCursorTrailsDB.trailTexture = 1
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("trailTexture", 1)
        RebuildTrails()
        --print(string.format("Trail Texture set to index: %d. Saved to profile: %s.", index, EasyCursorTrailsDB.currentProfile))
    end
)
trailTextureDropdown:SetPoint("TOPLEFT", trailEffectsDropdown, "BOTTOMLEFT", 85, -25) -- Adjusted Y offset for better spacing

-- Ensure currentProfile is accessible here
local currentProfile = EasyCursorTrails.currentProfile

-- Enable/Disable Connect Trails Checkbox
local connectTrailsCheckbox = CreateFrame("CheckButton", nil, menu, "UICheckButtonTemplate")
connectTrailsCheckbox:SetPoint("TOPLEFT", trailTextureDropdown, "BOTTOMLEFT", -100, 30)


-- Create and position the checkbox text
connectTrailsCheckbox.text = connectTrailsCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormal")
connectTrailsCheckbox.text:SetPoint("LEFT", connectTrailsCheckbox, "RIGHT", 5, 0)
connectTrailsCheckbox.text:SetText("Connect Trails")

-- Set the initial checked state based on the profile
connectTrailsCheckbox:SetChecked(currentProfile.connectTrails or false)

-- Checkbox OnClick Script with Corrections
connectTrailsCheckbox:SetScript("OnClick", function(self)
    -- Determine the new state from the checkbox
    local isEnabled = self:GetChecked()
    
    -- Update the profile-specific connectTrails setting
    currentProfile.connectTrails = isEnabled
    
    -- Save the new state to the current profile
    EasyCursorTrails.settingsChanged = true
    SaveToCurrentProfile("connectTrails", isEnabled)
    
    -- Optionally, rebuild trails if connectTrails affects trail rendering
    RebuildTrails()
    
    -- Debug message (optional)
    print("EasyCursorTrails: 'Connect Trails' set to", isEnabled and "Enabled" or "Disabled", "and saved to the current profile.")
end)



-- Function to update the Trail Texture Dropdown based on the selected Trail Movement Effect
function UpdateTrailTextureDropdown(selectedMovementEffectIndex)
    -- Retrieve the textures for the selected movement effect
    local effectTextures = EasyCursorTrails.trailTextures[selectedMovementEffectIndex]
    
    -- Handle cases where no textures are available for the selected movement effect
    if not effectTextures or #effectTextures == 0 then
        --print(string.format("EasyCursorTrails: No textures available for Trail Movement Effect index: %d. Using default texture.", selectedMovementEffectIndex))
        effectTextures = {
            { name = "Default Texture", texture = "Interface\\CURSOR\\Arrow" }, -- Replace with actual default texture path
        }
    end
    
    -- Create texture options for the dropdown
    local textureOptions = {}
    for i, textureInfo in ipairs(effectTextures) do
        table.insert(textureOptions, { text = textureInfo.name, icon = textureInfo.texture })
        --print(string.format("EasyCursorTrails: Adding Texture: %s %s", textureInfo.name, textureInfo.texture))
    end
    
    -- Update the trailTextureOptions
    EasyCursorTrails.trailTextureOptions = textureOptions
    
    -- Reinitialize the Trail Texture Dropdown with the new options
    UIDropDownMenu_Initialize(trailTextureDropdown, function(self, level, menuList)
        for i, option in ipairs(textureOptions) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = option.text or "Texture " .. i
            if option.icon then
                info.icon = option.icon
                info.iconTexCoord = { 0, 1, 0, 1 }
                info.iconWidth = 16
                info.iconHeight = 16
            end
            info.func = function()
                -- Prevent callback during programmatic updates
                if EasyCursorTrails.isUpdatingDropdown then
                    return
                end
                
                UIDropDownMenu_SetSelectedID(trailTextureDropdown, i)
                UIDropDownMenu_SetText(trailTextureDropdown, option.text or "Texture " .. i)
                
                -- Update the database
                EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailTexture = i
                SaveSetting("trailTexture", i)
                
                -- Rebuild trails with the new texture
                RebuildTrails()
                
                -- Debug message
                --print(string.format("EasyCursorTrails: Trail Texture '%s' (index %d) saved to profile '%s'.", option.text, i, EasyCursorTrailsDB.currentProfile))
                CloseDropDownMenus()
            end
            UIDropDownMenu_AddButton(info)
        end
    end)
    
    -- Ensure the correct texture is selected in the dropdown
    local currentTextureIndex = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailTexture or 1
    if currentTextureIndex > #textureOptions then
        currentTextureIndex = 1
        EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailTexture = 1
        SaveSetting("trailTexture", 1)

       
    end
    
    -- Prevent callbacks during programmatic updates
    EasyCursorTrails.isUpdatingDropdown = true
    UIDropDownMenu_SetSelectedID(trailTextureDropdown, currentTextureIndex)
    UIDropDownMenu_SetText(trailTextureDropdown, textureOptions[currentTextureIndex].text)
    EasyCursorTrails.isUpdatingDropdown = false
    
    --print(string.format("EasyCursorTrails: Trail Texture Dropdown updated with texture index: %d.", currentTextureIndex))
end


-- Initialize the Trail Texture Dropdown with the current movement effect
local currentMovementEffectIndex = EasyCursorTrailsDB.trailMovementEffect or 1
UpdateTrailTextureDropdown(currentMovementEffectIndex)



-- Ensure saving functionality is integrated into other dropdowns and buttons
local function SaveAndApplyChanges(key, value)
    EasyCursorTrailsDB[key] = value
    EasyCursorTrails.settingsChanged = true
    SaveToCurrentProfile(key, value)
    RebuildTrails()
    --print(string.format("Saved '%s' with value '%s' to profile '%s'.", key, tostring(value), EasyCursorTrailsDB.currentProfile))
end

local effectsSettingsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
effectsSettingsHeader:SetPoint("TOPLEFT", trailTextureDropdown, "BOTTOMLEFT",  -300, 60)
effectsSettingsHeader:SetText("Select Custom Cursor")


-- Cursor Texture Dropdown
local cursorTextureOptions = {}
for i, cursorData in ipairs(customCursorTextures) do
    local displayName = cursorData.name
    if cursorData.animated then
        displayName = displayName .. " (Animated)"
    end
    table.insert(cursorTextureOptions, { text = displayName, icon = cursorData.texture })
end

local cursorTextureDropdown = CreateDropdown("CursorTextureDropdown", menu, "Cursor Textures", cursorTextureOptions,
    EasyCursorTrailsDB.cursorTexture or 1,
    function(index)
        EasyCursorTrailsDB.cursorTexture = index
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorTexture", index) -- Save to profile
        EasyCursorTrails.InitializeCustomCursor()
        --print(string.format("Cursor Texture set to: %d. Saved to profile: %s.", index, EasyCursorTrailsDB.currentProfile))
    end
)
cursorTextureDropdown:SetPoint("TOPLEFT", effectsSettingsHeader, "BOTTOMLEFT", -110, -5)

-- Cursor Color Effects Dropdown
local cursorColorEffectOptions = {}
for i, effect in ipairs(colorEffects) do
    table.insert(cursorColorEffectOptions, { text = effect.text })
end

local cursorColorEffectDropdown = CreateDropdown("CursorColorEffectDropdown", menu, "Cursor Color Effects",
    cursorColorEffectOptions,
    EasyCursorTrailsDB.cursorColorEffect or 1,
    function(index)
        EasyCursorTrailsDB.cursorColorEffect = index
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorColorEffect", index) -- Save to profile
        EasyCursorTrails.ApplyColorEffectCursor()
        --print(string.format("Cursor Color Effect set to: %d. Saved to profile: %s.", index, EasyCursorTrailsDB.currentProfile))
    end
)
cursorColorEffectDropdown:SetPoint("TOPLEFT", cursorTextureDropdown, "BOTTOMLEFT", 0, 0)

-- Select Cursor Color Button
local selectCursorColorButton = CreateFrame("Button", "SelectCursorColorButton", menu, "UIPanelButtonTemplate")
selectCursorColorButton:SetSize(150, 25)
selectCursorColorButton:SetText("Select Cursor Color")
selectCursorColorButton:SetPoint("TOPLEFT", cursorColorEffectDropdown, "BOTTOMLEFT", 20, 0)
selectCursorColorButton:SetScript("OnClick", function()
    local initialColor = EasyCursorTrailsDB.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        EasyCursorTrailsDB.cursorColor = color
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorColor", color) -- Save to profile
        EasyCursorTrails.ApplyColorEffectCursor()
        --print("Cursor Color saved to profile:", EasyCursorTrailsDB.currentProfile)
    end)
end)

-- Trail Color Effects Dropdown
local trailColorEffectDropdown = CreateDropdown("TrailColorEffectDropdown", menu, "Trail Color Effects",
    TrailcolorEffects,
    EasyCursorTrailsDB.trailColorEffect or 1,
    function(index)
        EasyCursorTrailsDB.trailColorEffect = index
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("trailColorEffect", index) -- Save to profile
       
        local selectedEffectText = TrailcolorEffects[index] and TrailcolorEffects[index].text or "Unknown"
        --print("Trail Color Effect set to:", selectedEffectText, "Saved to profile:", EasyCursorTrailsDB.currentProfile)

        if EasyCursorTrails.trailPool and next(EasyCursorTrails.trailPool) ~= nil then
            for layer, trails in pairs(EasyCursorTrails.trailPool) do
                if type(trails) == "table" then
                    for trailIndex, trail in ipairs(trails) do
                        if trail and trail.texture then
                            EasyCursorTrails.ApplyColorEffectTrail(trail, trailIndex)
                        end
                    end
                end
            end
        else
            --print("EasyCursorTrails Error: trailPool is nil or empty.")
        end
    end
)
trailColorEffectDropdown:SetPoint("TOPLEFT", trailMovementEffectDropdown, "BOTTOMLEFT", 0, -95)

-- Select Trail Color Button
local selectTrailColorButton = CreateFrame("Button", "SelectTrailColorButton", menu, "UIPanelButtonTemplate")
selectTrailColorButton:SetSize(150, 25)
selectTrailColorButton:SetText("Select Trail Color")
selectTrailColorButton:SetPoint("TOPLEFT", trailColorEffectDropdown, "BOTTOMLEFT", 20, 0)
selectTrailColorButton:SetScript("OnClick", function()
    local initialColor = EasyCursorTrailsDB.trailColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        EasyCursorTrailsDB.trailColor = color
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("trailColor", color) -- Save to profile

        if EasyCursorTrails.trailPool then
            for _, layerPool in pairs(EasyCursorTrails.trailPool) do
                for _, trail in ipairs(layerPool) do
                    if trail and trail.texture then
                        EasyCursorTrails.ApplyColorEffectTrail(trail)
                    end
                end
            end
        end
        --print("Trail Color saved to profile:", EasyCursorTrailsDB.currentProfile)
    end)
end)

-- -------------------------------
-- Profile Management Section
-- -------------------------------
local profileHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
profileHeader:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", 340, -20)
profileHeader:SetText("Profile Settings")

-- Populate Profile Dropdown
local function PopulateProfileDropdown(dropdown)
    local profileNames = {}
    for profileName, _ in pairs(EasyCursorTrailsDB.profiles) do
        table.insert(profileNames, profileName)
    end
    table.sort(profileNames)

    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        for index, profileName in ipairs(profileNames) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = profileName
            info.value = profileName
            info.func = function()
                UIDropDownMenu_SetSelectedID(dropdown, index)
                UIDropDownMenu_SetText(dropdown, profileName)
                -- Switch to the selected profile
                EasyCursorTrailsDB.currentProfile = profileName
                EasyCursorTrails.settingsChanged = true
               SaveToCurrentProfile("currentProfile", profileName) -- Save the current profile
               LoadCurrentProfile()
               RefreshSettingsUI()
               RebuildTrails()
                --print("EasyCursorTrails: Switched to profile '" .. profileName .. "'.")
            end
            UIDropDownMenu_AddButton(info)
        end
    end)

    -- Set the currently selected profile
    local currentProfile = EasyCursorTrailsDB.currentProfile
    if currentProfile then
        for index, profileName in ipairs(profileNames) do
            if profileName == currentProfile then
                UIDropDownMenu_SetSelectedID(dropdown, index)
                UIDropDownMenu_SetText(dropdown, profileName)
                return
            end
        end
    end

    -- Default to the first profile if no current profile is set
    if #profileNames > 0 then
        UIDropDownMenu_SetSelectedID(dropdown, 1)
        UIDropDownMenu_SetText(dropdown, profileNames[1])
    end
end



-- Profile Dropdown
local profileDropdown = CreateFrame("Frame", "ProfileDropdown", menu, "UIDropDownMenuTemplate")
profileDropdown:SetPoint("TOPLEFT", profileHeader, "BOTTOMLEFT", -20, -15)

-- Function to refresh the dropdown and select the current profile
local function PopulateProfileDropdownAndSelectCurrent()
    PopulateProfileDropdown(profileDropdown)
    local currentProfileName = EasyCursorTrailsDB.currentProfile or "Default"
    UIDropDownMenu_SetText(profileDropdown, currentProfileName)
end

-- Populate the dropdown initially
PopulateProfileDropdownAndSelectCurrent()

-- Handle profile selection
UIDropDownMenu_Initialize(profileDropdown, function(self, level, menuList)
    for profileName, _ in pairs(EasyCursorTrailsDB.profiles) do
        local info = UIDropDownMenu_CreateInfo()
        info.text = profileName
        info.func = function()
            EasyCursorTrailsDB.currentProfile = profileName
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("currentProfile", profileName)
            PopulateProfileDropdownAndSelectCurrent()
          LoadCurrentProfile()
          RefreshSettingsUI()
          RebuildTrails()
            --print("EasyCursorTrails: Switched to profile '" .. profileName .. "'.")
        end
        UIDropDownMenu_AddButton(info)
    end
end)

-- Create Profile Button
local createProfileButton = CreateFrame("Button", "CreateProfileButton", menu, "UIPanelButtonTemplate")
createProfileButton:SetSize(60, 25)
createProfileButton:SetText("Create")
createProfileButton:SetPoint("TOPLEFT", profileDropdown, "BOTTOMLEFT", -20, -10)
createProfileButton:SetScript("OnClick", function()
    -- Prompt for profile name
    EasyCursorTrails.OpenTextInputDialog("Enter new profile name:", function(newProfileName)
        if newProfileName and newProfileName ~= "" and not EasyCursorTrailsDB.profiles[newProfileName] then
            EasyCursorTrailsDB.profiles[newProfileName] = {}
            -- Initialize with default settings
            for k, v in pairs(defaults) do
                EasyCursorTrailsDB.profiles[newProfileName][k] = v
            end
            EasyCursorTrailsDB.currentProfile = newProfileName
            EasyCursorTrails.settingsChanged = true
            SaveToCurrentProfile("currentProfile", newProfileName) -- Save the newly created profile
            PopulateProfileDropdownAndSelectCurrent()
            LoadCurrentProfile()
            RefreshSettingsUI()
            RebuildTrails()
            --print("EasyCursorTrails: Profile '" .. newProfileName .. "' created and selected.")
        else
            --print("EasyCursorTrails: Invalid or duplicate profile name.")
        end
    end)
end)

local function PopulateProfileDropdown(dropdown)
    local profileNames = {}
    for profileName, _ in pairs(EasyCursorTrailsDB.profiles) do
        table.insert(profileNames, profileName)
    end
    table.sort(profileNames)

    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        for index, profileName in ipairs(profileNames) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = profileName
            info.value = profileName
            info.checked = (EasyCursorTrailsDB.currentProfile == profileName) -- Check if this profile is the current one
            info.func = function()
                UIDropDownMenu_SetSelectedID(dropdown, index)
                UIDropDownMenu_SetText(dropdown, profileName)
                -- Switch to the selected profile
                EasyCursorTrailsDB.currentProfile = profileName
                EasyCursorTrails.settingsChanged = true
                SaveToCurrentProfile("currentProfile", profileName) -- Save the current profile
                LoadCurrentProfile()
                RefreshSettingsUI()
                RebuildTrails()
                --print("EasyCursorTrails: Switched to profile '" .. profileName .. "'.")
            end
            UIDropDownMenu_AddButton(info)
        end
    end)

    -- Set the currently selected profile
    local currentProfile = EasyCursorTrailsDB.currentProfile
    if currentProfile then
        for index, profileName in ipairs(profileNames) do
            if profileName == currentProfile then
                UIDropDownMenu_SetSelectedID(dropdown, index)
                UIDropDownMenu_SetText(dropdown, profileName)
                return
            end
        end
    end

    -- Default to the first profile if no current profile is set
    if #profileNames > 0 then
        UIDropDownMenu_SetSelectedID(dropdown, 1)
        UIDropDownMenu_SetText(dropdown, profileNames[1])
    end
end
-- Delete Profile Button
local deleteProfileButton = CreateFrame("Button", "DeleteProfileButton", menu, "UIPanelButtonTemplate")
deleteProfileButton:SetSize(65, 25)
deleteProfileButton:SetText("Delete")
deleteProfileButton:SetPoint("LEFT", createProfileButton, "RIGHT", 10, 0)

deleteProfileButton:SetScript("OnClick", function()
    local selectedProfile = UIDropDownMenu_GetText(profileDropdown)

    if selectedProfile and EasyCursorTrailsDB.profiles[selectedProfile] and selectedProfile ~= "Default" then
        -- Define the confirmation popup
        StaticPopupDialogs["EASYCURSORTRAILS_CONFIRM_DELETE"] = {
            text = "Are you sure you want to delete the profile '" .. selectedProfile .. "'?\n\nThis action cannot be undone.",
            button1 = "Yes",
            button2 = "No",
            OnAccept = function()
                -- Remove the selected profile
                EasyCursorTrailsDB.profiles[selectedProfile] = nil
                print("EasyCursorTrails: Profile '" .. selectedProfile .. "' has been deleted.")

                -- Fallback to "Default" if the deleted profile was active
                if EasyCursorTrailsDB.currentProfile == selectedProfile then
                    EasyCursorTrailsDB.currentProfile = "Default"
                    EasyCursorTrails.settingsChanged = true
                    SaveToCurrentProfile("currentProfile", "Default") -- Save the new active profile
                    LoadCurrentProfile()
                    print("EasyCursorTrails: Current profile reset to 'Default'.")
                end

                -- Refresh the dropdown menu, settings UI, and trails
                if PopulateProfileDropdown then
                    PopulateProfileDropdown(profileDropdown)
                else
                    print("EasyCursorTrails: Error - PopulateProfileDropdown function is missing.")
                end

                if RefreshSettingsUI then
                    RefreshSettingsUI()
                else
                    print("EasyCursorTrails: Error - RefreshSettingsUI function is missing.")
                end

                if RebuildTrails then
                    RebuildTrails()
                else
                    print("EasyCursorTrails: Error - RebuildTrails function is missing.")
                end
            end,
            timeout = 0,
            whileDead = true,
            hideOnEscape = true,
            preferredIndex = 3 -- Ensure no conflicts with other popups
        }

        -- Show the confirmation popup in the center of the screen
        local popup = StaticPopup_Show("EASYCURSORTRAILS_CONFIRM_DELETE")
        if popup then
            popup:ClearAllPoints()
            popup:SetPoint("CENTER", UIParent, "CENTER")
        end
    else
        print("EasyCursorTrails: Cannot delete the 'Default' profile or an invalid profile.")
    end
end)

-- Define DeepCopyDefaults Function Globally
local function DeepCopyDefaults(source, target)
    for k, v in pairs(source) do
        if type(v) == "table" then
            if type(target[k]) ~= "table" then
                target[k] = {}
            end
            DeepCopyDefaults(v, target[k])
        else
            target[k] = v
        end
    end
end
-- Reset Settings Button
local resetButton = CreateFrame("Button", "ResetSettingsButton", menu, "UIPanelButtonTemplate")
resetButton:SetSize(60, 25)
resetButton:SetText("Reset")
resetButton:SetPoint("TOPLEFT", createProfileButton, "BOTTOMLEFT", 145, 25)

resetButton:SetScript("OnClick", function()
    -- Define the confirmation popup
    StaticPopupDialogs["EASYCURSORTRAILS_RESET_CONFIRM"] = {
        text = "Are you sure you want to reset all settings to their default values?\n\nThis will reload the user interface to apply changes.",
        button1 = "Yes",
        button2 = "No",
        OnAccept = function()
            -- Get the current profile
            local currentProfileName = EasyCursorTrailsDB.currentProfile
            local currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
            
            -- Validate the current profile and reset to defaults
            if currentProfile then
                DeepCopyDefaults(defaults, currentProfile)
                print("EasyCursorTrails: Profile '" .. currentProfileName .. "' has been reset to defaults.")
            else
                EasyCursorTrails.HandleError("ResetSettings: No valid profile found to reset.")
                print("EasyCursorTrails: No valid profile found to reset.")
                return
            end

            -- Refresh settings UI
            if EasyCursorTrails.RefreshSettingsUI and type(EasyCursorTrails.RefreshSettingsUI) == "function" then
                EasyCursorTrails.RefreshSettingsUI()
                print("EasyCursorTrails: Settings UI refreshed.")
            end

            -- Rebuild trails
            if EasyCursorTrails.RebuildTrails and type(EasyCursorTrails.RebuildTrails) == "function" then
                EasyCursorTrails.RebuildTrails()
                print("EasyCursorTrails: Trails rebuilt.")
            end

            -- Reapply effects and cursor adjustments
            if EasyCursorTrails.ApplySelectedGlowEffect and type(EasyCursorTrails.ApplySelectedGlowEffect) == "function" then
                EasyCursorTrails.ApplySelectedGlowEffect()
                print("EasyCursorTrails: Selected glow effect reapplied.")
            end

            if EasyCursorTrails.UpdateCustomCursorPosition and type(EasyCursorTrails.UpdateCustomCursorPosition) == "function" then
                EasyCursorTrails.UpdateCustomCursorPosition()
                print("EasyCursorTrails: Custom cursor position updated.")
            end

            -- Reload the UI to apply changes
            print("EasyCursorTrails: Reloading UI to apply default settings...")
            ReloadUI()
        end,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
        preferredIndex = 3 -- Prevent conflicts with other dialogs
    }

    -- Show the confirmation popup
    local popup = StaticPopup_Show("EASYCURSORTRAILS_RESET_CONFIRM")
    if popup then
        popup:ClearAllPoints()
        popup:SetPoint("CENTER", UIParent, "CENTER") -- Center the popup on the screen
    end
end)



-- Glow Settings Header
local glowSettingsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
glowSettingsHeader:SetPoint("TOPLEFT", glowEffectDropdown, "BOTTOMLEFT", 0, -20)
glowSettingsHeader:SetText("Glow Settings")

-- Number of Glows Slider
local numGlowsSlider = CreateSlider(
    "NumGlowsSlider", 
    menu, 
    "Number of Glows", 
    0, 
    30, 
    1,
    EasyCursorTrailsDB.numGlows or defaults.numGlows, -- Use defaults if EasyCursorTrailsDB is not initialized
    function(slider, value)
        value = math.floor(value)
        EasyCursorTrailsDB.numGlows = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("numGlows", value) -- Save to the current profile
        EasyCursorTrails.UpdateGlowFrames() -- Update glow frames dynamically
        --print("Saved Number of Glows: " .. value) -- Debugging information
    end
)
numGlowsSlider:SetPoint("TOPLEFT", trailCountSlider, "BOTTOMLEFT", -350, -30)

-----------------------------------------------
-- Ensure the slider updates when a profile is loaded or switched
-----------------------------------------------
local function UpdateNumGlowsSliderFromProfile()
    if EasyCursorTrailsDB and EasyCursorTrailsDB.numGlows then
        -- Set the slider's value; this will trigger the OnValueChanged script
        numGlowsSlider:SetValue(EasyCursorTrailsDB.numGlows)
        
        -- Optional: Directly update valueText and editBox if necessary
        -- Generally handled by OnValueChanged, but included for redundancy
        if numGlowsSlider.valueText then
            numGlowsSlider.valueText:SetText(tostring(EasyCursorTrailsDB.numGlows))
        else
            EasyCursorTrails.HandleError("UpdateNumGlowsSliderFromProfile: 'numGlowsSlider.valueText' is nil.")
        end
        
        if numGlowsSlider.editBox then
            numGlowsSlider.editBox:SetText(tostring(EasyCursorTrailsDB.numGlows))
        else
            EasyCursorTrails.HandleError("UpdateNumGlowsSliderFromProfile: 'numGlowsSlider.editBox' is nil.")
        end
        
        --print("Updated NumGlowsSlider from profile: " .. EasyCursorTrailsDB.numGlows)
    else
        --print("EasyCursorTrails: Failed to update NumGlowsSlider - numGlows not set in current profile.")
    end
end

-- Hook into profile loading or UI refresh to ensure slider reflects the active profile's settings
hooksecurefunc("RefreshSettingsUI", UpdateNumGlowsSliderFromProfile)

-- Pattern Glow Count Slider
local patternGlowCountSlider = CreateSlider("PatternGlowCountSlider", menu, "Pattern Glow Count", 3, 29, 1,
    EasyCursorTrailsDB.patternGlowCount or defaults.patternGlowCount,
    function(slider, value)
        value = math.floor(value)
        EasyCursorTrailsDB.patternGlowCount = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("patternGlowCount", value)
        EasyCursorTrails.UpdateGlowFrames()
        --print("Saved Pattern Glow Count: " .. value)
    end
)
patternGlowCountSlider:SetPoint("TOPLEFT", numGlowsSlider, "BOTTOMLEFT", 0, -30)

-- Glow Radius Slider
local glowRadiusSlider = CreateSlider("GlowRadiusSlider", menu, "Glow Radius", 0.1, 1.1, 0.01,
    EasyCursorTrailsDB.glowRadius or defaults.glowRadius,
    function(slider, value)
        EasyCursorTrailsDB.glowRadius = value
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("glowRadius", value)
        EasyCursorTrails.UpdateGlowFrames()
        --print("Saved Glow Radius: " .. value)
    end
)
glowRadiusSlider:SetPoint("TOPLEFT", patternGlowCountSlider, "BOTTOMLEFT", 0, -30)

-- Glow Intensity Slider
local glowIntensitySlider = CreateSlider("GlowIntensitySlider", menu, "Glow Intensity", 0.1, 1.0, 0.05,
    EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity,
    function(slider, value)
        value = math.max(0.1, math.min(1.0, value))
        EasyCursorTrailsDB.glowIntensity = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("glowIntensity", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
        --print("Saved Glow Intensity: " .. value)
    end
)
glowIntensitySlider:SetPoint("TOPLEFT", glowRadiusSlider, "BOTTOMLEFT", 0, -30)


-- Glow Size Slider
local glowSizeSlider = CreateSlider("GlowSizeSlider", menu, "Glow Size", 0.5, 1.0, 0.1,
    EasyCursorTrailsDB.glowSize or defaults.glowSize,
    function(slider, value)
        EasyCursorTrailsDB.glowSize = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("glowSize", value)
        EasyCursorTrails.UpdateGlowFrames()
        --print("Saved Glow Size: " .. value)
    end
)
glowSizeSlider:SetPoint("TOPLEFT", glowIntensitySlider, "BOTTOMLEFT", 0, -30)

-- Glow Thickness Slider
local glowThicknessSlider = CreateSlider("GlowThicknessSlider", menu, "Glow Thickness", 0.1, 2.0, 0.1,
    EasyCursorTrailsDB.glowThickness or defaults.glowThickness,
    function(slider, value)
        EasyCursorTrailsDB.glowThickness = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("glowThickness", value)
        EasyCursorTrails.UpdateGlowFrames()
        --print("Saved Glow Thickness: " .. value)
    end
)
glowThicknessSlider:SetPoint("TOPLEFT", glowSizeSlider, "BOTTOMLEFT", 0, -30)

local cursorSizeSlider = CreateSlider("CursorSizeSlider", menu, "Cursor Size", 10, 200, 1,
    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].cursorSize or defaults.cursorSize,
    function(slider, value)
        -- Update the cursor size in the current profile
        if EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] then
            EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].cursorSize = value
        end

        -- Update the global database for current session consistency
        EasyCursorTrailsDB.cursorSize = value

        -- Update the slider text
        slider:SetValue(value)
     
        EasyCursorTrails.settingsChanged = true
        -- Save the new value to the current profile
        SaveToCurrentProfile("cursorSize", value)

        -- Apply the new cursor size
        EasyCursorTrails.UpdateCustomCursorSize(value)

        -- Rebuild trails with updated settings
        RebuildTrails()

        -- Debugging log
        --print("Saved Cursor Size for profile '" .. EasyCursorTrailsDB.currentProfile .. "': " .. value)
    end
)
cursorSizeSlider:SetPoint("TOPLEFT", glowBelowCheckbox, "BOTTOMLEFT", 0, -30)

-- Cursor Offset X Slider
local cursorOffsetXSlider = CreateSlider("CursorOffsetXSlider", menu, "Cursor Offset X", -100, 100, 1,
    EasyCursorTrailsDB.cursorOffsetX or defaults.cursorOffsetX,
    function(slider, value)
        EasyCursorTrailsDB.cursorOffsetX = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorOffsetX", value)
        EasyCursorTrails.UpdateCustomCursorPosition()
        --print("Saved Cursor Offset X: " .. value)
    end
)
cursorOffsetXSlider:SetPoint("TOPLEFT", cursorSizeSlider, "BOTTOMLEFT", 0, -30)

-- Cursor Offset Y Slider
local cursorOffsetYSlider = CreateSlider("CursorOffsetYSlider", menu, "Cursor Offset Y", -100, 100, 1,
    EasyCursorTrailsDB.cursorOffsetY or defaults.cursorOffsetY,
    function(slider, value)
        EasyCursorTrailsDB.cursorOffsetY = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorOffsetY", value)
        EasyCursorTrails.UpdateCustomCursorPosition()
        --print("Saved Cursor Offset Y: " .. value)
    end
)
cursorOffsetYSlider:SetPoint("TOPLEFT", cursorOffsetXSlider, "BOTTOMLEFT", 0, -30)

-- Select Glow Color Button
local selectGlowColorButton = CreateFrame("Button", "SelectGlowColorButton", menu, "UIPanelButtonTemplate")
selectGlowColorButton:SetSize(150, 25)
selectGlowColorButton:SetText("Select Glow Color")
selectGlowColorButton:SetPoint("TOPLEFT", glowThicknessSlider, "BOTTOMLEFT", 0, -60)
selectGlowColorButton:SetScript("OnClick", function()
    local initialColor = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        -- Save the selected glow color to the profile
        EasyCursorTrailsDB.glowColor = color
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("glowColor", color)
        -- Debugging message
        --print(string.format("Saved Glow Color: R=%.2f, G=%.2f, B=%.2f, A=%.2f", color.r, color.g, color.b, color.a))
        -- Apply the new glow effect
        EasyCursorTrails.ApplySelectedGlowEffect()
    end)
end)

-- Glow Effect Options
EasyCursorTrails.glowEffectOptions = {
    { text = "Custom Color - Click Select Glow Color button" },
    { text = "Custom + Normal Pulse" },
    { text = "Custom + Pulse like a star in the sky" },
    { text = "Custom + Pulse in clockwise direction" },
    { text = "Different random color in clockwise direction" },
    { text = "Custom + Pulse in anticlockwise direction" },
    { text = "Different random color in anticlockwise direction" },
    { text = "Disco light" },
    { text = "Custom + Wave pattern" },
    { text = "Custom + Airport lights" },
    { text = "Custom + Fast pulsing" },
    { text = "Custom + Slow pulsing" },
    { text = "Custom + Stretch Segments" },
    { text = "Burning" },
    { text = "Custom + Lightning Pulse" },
    { text = "Tinker Bell" },
    { text = "Random - Keep selecting for random effects" },
}

-- Glow Effect Dropdown
local glowEffectDropdown = CreateDropdown(
    "GlowEffectDropdown",
    menu,
    "Glow Effects",
    EasyCursorTrails.glowEffectOptions,
    EasyCursorTrailsDB.selectedGlowEffect or 1,
    function(index)
        -- Save the selected glow effect to the profile
        EasyCursorTrailsDB.selectedGlowEffect = index
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("selectedGlowEffect", index)
        -- Debugging message
        --print("Saved Glow Effect:", EasyCursorTrails.glowEffectOptions[index].text)
        -- Apply the selected glow effect
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
glowEffectDropdown:SetPoint("TOPLEFT", selectGlowColorButton, "BOTTOMLEFT", -20, 60)


-- Frame Strata Options
local frameStrataOptions = {
    { text = "BACKGROUND" },
    { text = "LOW" },
    { text = "MEDIUM" },
    { text = "HIGH" },
    { text = "DIALOG" },
}

local function GetStrataIndex(strata)
    for i, v in ipairs(frameStrataOptions) do
        if v.text == strata then
            return i
        end
    end
    return 4 -- Default to "HIGH"
end

-- Get the initial frame strata index
local initialFrameStrataIndex = GetStrataIndex(EasyCursorTrailsDB.cursorFrameStrata or "HIGH")

-- Cursor Frame Strata Dropdown
local cursorFrameStrataDropdown = CreateDropdown(
    "CursorFrameStrataDropdown",
    menu,
    "Cursor Frame Strata",
    frameStrataOptions,
    initialFrameStrataIndex,
    function(selectedIndex)
        local selectedStrata = frameStrataOptions[selectedIndex].text

        -- Save the selected frame strata to the database
        EasyCursorTrailsDB.cursorFrameStrata = selectedStrata
        EasyCursorTrails.settingsChanged = true
        SaveToCurrentProfile("cursorFrameStrata", selectedStrata)

        -- Apply the frame strata to the custom cursor if it exists
        if customCursor then
            customCursor:SetFrameStrata(selectedStrata)
        end

    end
)

-- Position the dropdown below the glowEffectDropdown
cursorFrameStrataDropdown:SetPoint("TOPLEFT", glowEffectDropdown, "BOTTOMLEFT", 0, -35)

-- OK Button
local SaveButton = CreateFrame("Button", "SaveButton", menu, "UIPanelButtonTemplate")
SaveButton:SetSize(100, 25)
SaveButton:SetText("Save")
SaveButton:SetPoint("TOPLEFT", selectTrailColorButton, "BOTTOMLEFT", 280, 20)

SaveButton:SetScript("OnClick", function()
    -- Define the confirmation dialog
    StaticPopupDialogs["RELOAD_WARNING"] = {
        text = "Are you sure you want to save and reload the UI to apply the changes?",
        button1 = "Yes",
        button2 = "No",
        OnAccept = function()
            -- Save all settings to the profile
            SaveAllSettingsToProfile()

            -- Save the connectTrails state specifically
            if connectTrailsCheckbox then
                local connectTrailsState = connectTrailsCheckbox:GetChecked()
                SaveToCurrentProfile("connectTrails", connectTrailsState)
            end

            -- Reload the UI to apply changes
            ReloadUI()

            -- Optional message to confirm changes
            print("EasyCursorTrails: Settings saved and applied. The UI has been reloaded.")
        end,
        OnCancel = function()
            -- Optional message for cancellation
            print("EasyCursorTrails: UI reload canceled. Settings were saved.")
        end,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
        preferredIndex = 3 -- Avoids conflicts with other popups
    }

    -- Display the confirmation dialog
    local popup = StaticPopup_Show("RELOAD_WARNING")
    if popup then
        popup:ClearAllPoints()
        popup:SetPoint("CENTER", UIParent, "CENTER") -- Position the popup at the screen's center
    end
end)


-- Close Button
local closeButton = CreateFrame("Button", "CloseButton", menu, "UIPanelButtonTemplate")
closeButton:SetSize(100, 25)
closeButton:SetText("Close")
closeButton:SetPoint("LEFT", SaveButton, "RIGHT", 50, 0)

closeButton:SetScript("OnClick", function()
    -- Save all settings to the current profile
    SaveAllSettingsToProfile()

    -- Hide the menu
    menu:Hide()

    -- Check if settings have changed
    if EasyCursorTrails.settingsChanged then
        EasyCursorTrails.settingsChanged = false  -- Reset the flag

        -- Define the popup dialog
        StaticPopupDialogs["EASYCURSORTRAILS_RELOAD_UI"] = {
            text = "Configuration changes saved. Reload UI to apply changes?",
            button1 = "Reload",
            button2 = "Later",
            OnAccept = function()
                ReloadUI()
            end,
            timeout = 0,
            whileDead = true,
            hideOnEscape = true,
            preferredIndex = 3, -- Avoids conflict with other StaticPopupDialogs
        }

        -- Show the popup and position it at the center of the screen
        local popup = StaticPopup_Show("EASYCURSORTRAILS_RELOAD_UI")
        if popup then
            popup:ClearAllPoints()
            popup:SetPoint("CENTER", UIParent, "CENTER")
        end

        -- Debug message (optional)
        print("EasyCursorTrails: Settings saved. Reload recommended.")
    else
        -- Debug message for no changes
        print("EasyCursorTrails: No changes detected. Settings menu closed.")
    end
end)


-- Minimap Button
local minimapButton = CreateFrame("Button", "EasyCursorTrailsMinimapButton", Minimap)
minimapButton:SetSize(32, 32)
minimapButton:SetNormalTexture("Interface\\AddOns\\EasyCursorTrails\\Textures\\icon.tga")
minimapButton:SetHighlightTexture("Interface\\Buttons\\UI-Minimap-ZoomButton-Highlight.blp")
minimapButton:SetPoint("TOPLEFT", Minimap, "TOPLEFT", -10, -10)
minimapButton:SetScript("OnClick", function()
    menu:SetShown(not menu:IsShown())
end)

minimapButton:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:AddLine("Easy Cursor Trails")
    GameTooltip:AddLine("Click to open the settings menu.", 1, 1, 1)
    GameTooltip:Show()
end)

minimapButton:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)


-- Function to Save All Settings to Profile
function SaveAllSettingsToProfile()
    -- Check that the current profile exists
    if EasyCursorTrailsDB and EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.currentProfile then
        local profile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if profile then
            for key, value in pairs(profile) do
                -- Save each setting to the current profile
                SaveToCurrentProfile(key, value)
            end
        else
            -- Initialize profile if missing
            EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] = {}
            print("EasyCursorTrails: Initialized missing profile during SaveAllSettingsToProfile.")
        end
    else
        print("EasyCursorTrails: Cannot save settings. Profile data missing.")
    end

    -- Rebuild trails after saving all settings
    RebuildTrails()

    -- Debug message (optional)
    print("EasyCursorTrails: All settings saved to the current profile.")
end


end


--------------------------------------------------------
-- Animations for Glow
--------------------------------------------------------
local function CreatePulsingAnimation(animationGroup, color, intensity, duration, startDelay)
    if not animationGroup or not animationGroup.CreateAnimation then
       -- --print("EasyCursorTrails: Invalid AnimationGroup in CreatePulsingAnimation.")
        return
    end
    startDelay = startDelay or 0

    local alphaAnim1 = animationGroup:CreateAnimation("Alpha")
    alphaAnim1:SetFromAlpha(color.a * intensity)
    alphaAnim1:SetToAlpha(color.a * intensity * 9.5)
    alphaAnim1:SetDuration(duration / 2)
    alphaAnim1:SetStartDelay(startDelay)
    alphaAnim1:SetOrder(1)

    local alphaAnim2 = animationGroup:CreateAnimation("Alpha")
    alphaAnim2:SetFromAlpha(color.a * intensity * 0.1)
    alphaAnim2:SetToAlpha(color.a * intensity)
    alphaAnim2:SetDuration(duration / 2)
    alphaAnim2:SetOrder(2)

    animationGroup:SetLooping("REPEAT")
    animationGroup:Play()
end

function EasyCursorTrails.ApplyDefaultCircularGlow()
  --  --print("EasyCursorTrails: Applying default circular glow.")

    local NUM_GLOWS = #customCursor.glowEffects
    if NUM_GLOWS < 1 then return end

    local angleStep = 360 / NUM_GLOWS
    local cursorRadius = customCursor:GetWidth() / 1.5
    local rad = EasyCursorTrailsDB.glowRadius or defaults.glowRadius
    local offsetDistance = cursorRadius * rad

    for i, glow in ipairs(customCursor.glowEffects) do
        if glow and glow.texture then
            local angle = math.rad((i - 1) * angleStep)
            local offsetX = math.cos(angle) * offsetDistance
            local offsetY = math.sin(angle) * offsetDistance

            glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
            local size = (customCursor:GetWidth() * (EasyCursorTrailsDB.glowSize or defaults.glowSize))
                        * (EasyCursorTrailsDB.glowThickness or defaults.glowThickness)
            glow:SetSize(size, size)
            glow.texture:SetVertexColor(EasyCursorTrailsDB.glowColor.r,
                                        EasyCursorTrailsDB.glowColor.g,
                                        EasyCursorTrailsDB.glowColor.b)
            glow.texture:SetAlpha(EasyCursorTrailsDB.glowIntensity * EasyCursorTrailsDB.glowColor.a)
            glow:Show()
        end
    end
end

-- Updated ApplySelectedGlowEffect function
function EasyCursorTrails.ApplySelectedGlowEffect()
    -- 1) Basic safety checks
    if not customCursor or not customCursor.glowEffects then
        -- --print("EasyCursorTrails: customCursor or glowEffects not initialized.")
        return
    end

    local glowEffectOptions = EasyCursorTrails.glowEffectOptions
    if not glowEffectOptions then
        -- --print("EasyCursorTrails: glowEffectOptions is missing or nil.")
        return
    end

    -- 2) Determine which effect is selected
    local selectedEffect = EasyCursorTrailsDB.selectedGlowEffect or 1
    local totalEffects = #glowEffectOptions

    -- 3) If "Random" => pick a random effect
    if glowEffectOptions[selectedEffect] and glowEffectOptions[selectedEffect].text == "Random - Keep selecting for random effects" then
        selectedEffect = math.random(1, totalEffects - 1)
        EasyCursorTrailsDB.selectedGlowEffect = selectedEffect
    end

    -- 4) Obtain the short name for the current cursor
    local currentCursorTexture = EasyCursorTrailsDB.selectedCursorTextureName
    if not currentCursorTexture or currentCursorTexture == "" then
        -- --print("EasyCursorTrails: No currentCursorTexture => fallback to default circle.")
        EasyCursorTrails.ApplyDefaultCircularGlow()
        return
    end

    -- 5) Check if we have a pattern for that short name
    local patternName = EasyCursorTrails.cursorGlowMapping[currentCursorTexture]
    if not patternName then
        -- --print("EasyCursorTrails: No pattern mapping for", currentCursorTexture, "=> fallback to default circle.")
        EasyCursorTrails.ApplyDefaultCircularGlow()
        return
    end

    local glowPattern = EasyCursorTrails.glowPatterns[patternName]
    if not glowPattern then
        -- --print("EasyCursorTrails: Glow pattern '"..patternName.."' not defined => fallback to default circle.")
        EasyCursorTrails.ApplyDefaultCircularGlow()
        return
    end

    -- 6) Grab color & user-chosen radius
    local glowColor = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    local intensity = EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity
    local glowRadius = tonumber(EasyCursorTrailsDB.glowRadius) or defaults.glowRadius -- Ensure it's a number
    -- --print("Debug: glowRadius type:", type(glowRadius), "value:", glowRadius)
    local cursorWidth = customCursor:GetWidth() or 64
    local radiusScale = glowRadius * (cursorWidth / 5.5)

    -- 7) Generate coordinates based on the pattern
    local coords = nil
    if type(glowPattern) == "function" then
        local count = EasyCursorTrailsDB.patternGlowCount or 8
        coords = glowPattern(count)
    elseif type(glowPattern) == "table" then
        coords = glowPattern
    end

    -- 8) Retrieve the current movement pattern ID
    local movementPatternID = tonumber(EasyCursorTrailsDB.movementPatternID) or 1

    -- 9) Position and color each glow frame
    for i, glow in ipairs(customCursor.glowEffects) do
        if glow and glow.texture then
            -- STOP & DISCARD the old AnimationGroup
            if glow.animationGroup then
                glow.animationGroup:Stop()
                -- Discard the old group by creating a new one
                glow.animationGroup = glow:CreateAnimationGroup()
            else
                -- If no animationGroup exists, create one
                glow.animationGroup = glow:CreateAnimationGroup()
            end

            glow.texture:SetBlendMode("ADD")

            -- Initialize color variables
            local r, g, b = glowColor.r, glowColor.g, glowColor.b
            local a = glowColor.a * intensity

            -- Check if the Rainbow movement pattern is selected
            if movementPatternID == 43 then
                -- Calculate hue based on index and elapsed time for dynamic coloring
                local hue = (i * 30 + GetTime() * 50) % 360 -- Adjust multipliers as needed for color distribution and speed

                -- Convert hue to RGB
                r, g, b =  EasyCursorTrails.HSVToRGB(hue, 1, 1) -- Full saturation and brightness for vibrant colors
                a = 0.6 -- Set a consistent alpha for the glow
            end

            -- Apply the calculated color to the glow texture
            glow.texture:SetVertexColor(r, g, b, a)

            if movementPatternID == 43 then
                -- Rainbow Movement Pattern: Arrange glows in a circular rainbow arch
                if coords and coords[i] then
                    local x = coords[i].x
                    local y = coords[i].y
                    local offsetX = x * radiusScale
                    local offsetY = y * radiusScale
                    glow:ClearAllPoints()
                    glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
                    glow:Show()
                else
                    glow:Hide()
                end
            else
                -- Non-Rainbow Movement Patterns: Position based on pattern coordinates
                if coords and coords[i] then
                    local x = coords[i].x
                    local y = coords[i].y
                    local offsetX = x * radiusScale
                    local offsetY = y * radiusScale
                    glow:ClearAllPoints()
                    glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
                    glow:Show()
                else
                    glow:Hide()
                end
            end

            -- Scale the glow frame
            local size = (cursorWidth * (EasyCursorTrailsDB.glowSize or defaults.glowSize)) *
                         (EasyCursorTrailsDB.glowThickness or defaults.glowThickness)
            glow:SetSize(size, size)

            -- 9) Apply the selected glow effect
            if movementPatternID ~= 43 then
                -- Existing glow effect logic for non-Rainbow patterns
                if selectedEffect == 1 then
                    -- None
                    glow.texture:SetVertexColor(glowColor.r, glowColor.g, glowColor.b, glowColor.a * 0.2)
                    glow.texture:SetAlpha(glowColor.a * 0.2)

                elseif selectedEffect == 2 then
                    -- Normal Pulse
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 1.0)

                elseif selectedEffect == 3 then
                    -- Pulse like a star
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 0.8)

                elseif selectedEffect == 4 then
                    -- Pulse clockwise w/ staggered start
                    local delay = (i - 1) * 0.05
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 1.0, delay)

                elseif selectedEffect == 5 then
                    -- Different random color, clockwise
                    local r_rand, g_rand, b_rand = math.random(), math.random(), math.random()
                    glow.texture:SetVertexColor(r_rand, g_rand, b_rand, glowColor.a * intensity)
                    local delay = (i - 1) * 0.05
                    CreatePulsingAnimation(
                        glow.animationGroup,
                        { r = r_rand, g = g_rand, b = b_rand, a = glowColor.a },
                        intensity,
                        1.0,
                        delay
                    )

                elseif selectedEffect == 6 then
                    -- Pulse anticlockwise
                    local delay = (#customCursor.glowEffects - i) * 0.05
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 1.0, delay)

                elseif selectedEffect == 7 then
                    -- Different random color, anticlockwise
                    local r_rand, g_rand, b_rand = math.random(), math.random(), math.random()
                    glow.texture:SetVertexColor(r_rand, g_rand, b_rand, glowColor.a * intensity)
                    local delay = (#customCursor.glowEffects - i) * 0.05
                    CreatePulsingAnimation(
                        glow.animationGroup,
                        { r = r_rand, g = g_rand, b = b_rand, a = glowColor.a },
                        intensity,
                        1.0,
                        delay
                    )

                elseif selectedEffect == 8 then
                    -- Disco light
                    local r_rand, g_rand, b_rand = math.random(), math.random(), math.random()
                    glow.texture:SetVertexColor(r_rand, g_rand, b_rand, glowColor.a * intensity)
                    CreatePulsingAnimation(
                        glow.animationGroup,
                        { r = r_rand, g = g_rand, b = b_rand, a = glowColor.a },
                        intensity,
                        0.3
                    )

                elseif selectedEffect == 9 then
                    -- Wave pattern
                    local delay = (i - 1) * 0.1
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 1.0, delay)

                elseif selectedEffect == 10 then
                    -- Airport trailing lights
                    if i % 2 == 0 then
                        CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 0.2)
                    else
                        CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 0.2, 0.1)
                    end

                elseif selectedEffect == 11 then
                    -- Fast pulsing
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 0.1)

                elseif selectedEffect == 12 then
                    -- Slow pulsing
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, 2.0)

                elseif selectedEffect == 13 then
                    -- Stretch Segments
                    local stretchAnim = glow.animationGroup:CreateAnimation("Scale")
                    stretchAnim:SetScale(1.2, 1.2)
                    stretchAnim:SetDuration(0.3)
                    stretchAnim:SetOrder(1)

                    local contractAnim = glow.animationGroup:CreateAnimation("Scale")
                    contractAnim:SetScale(0.8, 0.8)
                    contractAnim:SetDuration(0.3)
                    contractAnim:SetOrder(2)

                    glow.animationGroup:SetLooping("REPEAT")
                    glow.animationGroup:Play()

                elseif selectedEffect == 14 then
                    -- Burning Flicker
                    glow.texture:SetVertexColor(1, 0.5, 0, glowColor.a * intensity)
                    CreatePulsingAnimation(
                        glow.animationGroup,
                        { r = 1, g = 0.5, b = 0, a = glowColor.a },
                        intensity,
                        0.5,
                        0.1
                    )

                elseif selectedEffect == 15 then
                    -- Lightning
                    local lightningAnim = glow.animationGroup:CreateAnimation("Alpha")
                    lightningAnim:SetFromAlpha(0)
                    lightningAnim:SetToAlpha(glowColor.a * intensity)
                    lightningAnim:SetDuration(0.1)
                    lightningAnim:SetStartDelay(0.2)
                    lightningAnim:SetOrder(1)

                    local fadeOutAnim = glow.animationGroup:CreateAnimation("Alpha")
                    fadeOutAnim:SetFromAlpha(glowColor.a * intensity)
                    fadeOutAnim:SetToAlpha(0)
                    fadeOutAnim:SetDuration(0.2)
                    fadeOutAnim:SetOrder(2)

                    local scaleAnim = glow.animationGroup:CreateAnimation("Scale")
                    scaleAnim:SetScale(1.0, 2.0)
                    scaleAnim:SetDuration(0.3)
                    scaleAnim:SetOrder(3)

                    glow.animationGroup:SetLooping("REPEAT")
                    glow.animationGroup:Play()

                elseif selectedEffect == 16 then
                    -- Tinker Bell
                    glow.texture:SetVertexColor(1, 0.84, 0, glowColor.a * intensity)
                    local pulseDuration = 0.4 + math.random() * 0.2
                    CreatePulsingAnimation(glow.animationGroup, glowColor, intensity, pulseDuration)

                else
                    -- Default / fallback
                    glow.texture:SetVertexColor(glowColor.r, glowColor.g, glowColor.b, glowColor.a * intensity)
                    glow.texture:SetAlpha(glowColor.a * intensity)
                end
            end
        end
    end
end

function EasyCursorTrails.InitializeGlowFrames()
    -- Safety check: Ensure customCursor and its texture exist
    if not customCursor or not customCursor.texture then return end

    -- Initialize glowEffects table if it doesn't exist
    if not customCursor.glowEffects then
        customCursor.glowEffects = {}
    else
        -- Clear existing glows
        for _, glow in ipairs(customCursor.glowEffects) do
            glow:Hide()
            glow:ClearAllPoints()
            glow:SetParent(nil)
        end
        customCursor.glowEffects = {}
    end

    -- Retrieve settings or use default values
    local NUM_GLOWS = EasyCursorTrailsDB.numGlows or 20 -- Number of glow segments
    local cursorWidth  = customCursor:GetWidth()
    local userRadius   = EasyCursorTrailsDB.glowRadius or defaults.glowRadius -- Radius multiplier
    local cursorRadius = cursorWidth / 1.5 -- Base radius from cursor

    -- Retrieve scaling factors from DB (set via sliders)
    local horizontalScale = EasyCursorTrailsDB.horizontalScale or 1.0 -- Width scaling
    local verticalScale = EasyCursorTrailsDB.verticalScale or 2.0 -- Height scaling
    local enableRotation = EasyCursorTrailsDB.enableRotation or false -- Rotation toggle

    -- Loop to create each glow segment
    for i = 1, NUM_GLOWS do
        -- Create a new frame for the glow
        local glow = CreateFrame("Frame", nil, customCursor)
        glow:SetSize(8 * horizontalScale, 16 * verticalScale) -- Apply scaling for pointiness
        glow:SetFrameStrata("HIGH")
        glow:SetFrameLevel(customCursor:GetFrameLevel() + 3)

        -- Create and configure the texture for the glow
        glow.texture = glow:CreateTexture(nil, "OVERLAY")
        glow.texture:SetAllPoints(true)
        glow.texture:SetBlendMode("ADD")
        glow.texture:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64") -- Replace with custom texture if desired
        glow.texture:SetVertexColor(1, 1, 1, EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity)

        -- Calculate the angle for the current glow segment
        local angle = math.rad((i - 1) * (360 / NUM_GLOWS)) -- Evenly spaced angles
        local offsetX = math.cos(angle) * cursorRadius * userRadius -- X offset from cursor
        local offsetY = math.sin(angle) * cursorRadius * userRadius -- Y offset from cursor
        glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY) -- Position the glow

        -- Apply rotation to the texture if enabled
        if enableRotation and glow.texture.SetRotation then
            glow.texture:SetRotation(angle)
        elseif enableRotation then
            -- Fallback message if SetRotation isn't available
            --print("EasyCursorTrails: SetRotation method is not available for Texture objects.")
        end

        -- Show the glow segment
        glow:Show()

        -- Add the glow segment to the glowEffects table
        table.insert(customCursor.glowEffects, glow)
    end
end

-- Can create connected chain-like trails or independent trails based on settings
function EasyCursorTrails.InitializeTrailFrames()
    -- Safety check: Ensure customCursor and its texture exist
    if not customCursor or not customCursor.texture then return end

    -- Initialize trailEffects table if it doesn't exist
    if not customCursor.trailEffects then
        customCursor.trailEffects = {}
    else
        -- Clear existing trails
        for _, trail in ipairs(customCursor.trailEffects) do
            trail:Hide()
            trail:ClearAllPoints()
            trail:SetParent(nil)
        end
        customCursor.trailEffects = {}
    end

    -- Retrieve trail settings or use default values
    local NUM_TRAILS = EasyCursorTrailsDB.numTrails or 10 -- Number of trail segments
    local trailSpacing = EasyCursorTrailsDB.trailSpacing or 10 -- Distance between connected trail segments
    local trailRadius = EasyCursorTrailsDB.trailRadius or 20 -- Radius from cursor for independent trails

    -- Variable to keep track of the previous trail segment
    local previousTrail = nil

    -- Loop to create each trail segment
    for i = 1, NUM_TRAILS do
        -- Create a new frame for the trail
        local trail = CreateFrame("Frame", nil, customCursor)
        trail:SetSize(8, 8) -- Adjust size as needed
        trail:SetFrameStrata("LOW")
        trail:SetFrameLevel(customCursor:GetFrameLevel() + 2)

        -- Create and configure the texture for the trail
        trail.texture = trail:CreateTexture(nil, "OVERLAY")
        trail.texture:SetAllPoints(true)
        trail.texture:SetBlendMode("ADD")
        trail.texture:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64") -- Replace with trail texture if different
        trail.texture:SetVertexColor(1, 1, 1, EasyCursorTrailsDB.trailIntensity or defaults.trailIntensity)

        if EasyCursorTrailsDB.connectTrails then
            if previousTrail then
                -- Position current trail relative to the previous trail to form a chain
                trail:SetPoint("CENTER", previousTrail, "CENTER", trailSpacing, 0)
            else
                -- Position the first trail relative to the custom cursor
                trail:SetPoint("CENTER", customCursor, "CENTER", 0, 0)
            end
        else
            -- Position trails independently around the cursor in a circular pattern
            local angle = math.rad((i - 1) * (360 / NUM_TRAILS))
            local offsetX = math.cos(angle) * trailRadius
            local offsetY = math.sin(angle) * trailRadius
            trail:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
        end

        -- Show the trail segment
        trail:Show()
        table.insert(customCursor.trailEffects, trail)

        -- Update previousTrail for the next iteration if connecting trails
        if EasyCursorTrailsDB.connectTrails then
            previousTrail = trail
        end
    end
end



function EasyCursorTrails.UpdateGlowFrames()
    if not customCursor or not customCursor.texture then
        ----print("EasyCursorTrails: customCursor or its texture is not initialized.")
        return
    end
    EasyCursorTrails.InitializeGlowFrames()


    local cursorWidth   = customCursor:GetWidth() or 64
    local glowRadius    = tonumber(EasyCursorTrailsDB.glowRadius)    or defaults.glowRadius
    local glowSize      = tonumber(EasyCursorTrailsDB.glowSize)      or defaults.glowSize
    local glowThickness = tonumber(EasyCursorTrailsDB.glowThickness) or defaults.glowThickness
    local numGlows      = math.max(0, math.min(tonumber(EasyCursorTrailsDB.numGlows) or 20, 30))

    local currentGlows = #customCursor.glowEffects
    if currentGlows > numGlows then
        for i = currentGlows, numGlows + 1, -1 do
            local glow = table.remove(customCursor.glowEffects, i)
            if glow then
                glow:Hide()
                glow:SetParent(nil)
                if glow.texture then
                    glow.texture:SetTexture(nil)
                end
            end
        end
    elseif currentGlows < numGlows then
        for i = currentGlows+1, numGlows do
            local glow = CreateFrame("Frame", nil, customCursor)
            glow:SetSize(16, 16)
            glow:SetFrameStrata("HIGH")
            glow:SetFrameLevel(customCursor:GetFrameLevel()+3)
            local tex = glow:CreateTexture(nil, "OVERLAY")
            tex:SetAllPoints(true)
            tex:SetBlendMode("ADD")
            tex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
            tex:SetVertexColor(1,1,1)
            glow.texture = tex
            glow:Hide()
            table.insert(customCursor.glowEffects, glow)
        end
    end

    local shortName  = EasyCursorTrailsDB.selectedCursorTextureName
    local patternKey = shortName and EasyCursorTrails.cursorGlowMapping[shortName] or nil
    local patternFunction = patternKey and EasyCursorTrails.dynamicPatterns[patternKey] or nil

    local cursorRadius = cursorWidth / 5.5
    local usedCoordsCount = 0
    local coords = nil

    if patternFunction then
        local patternCount = EasyCursorTrailsDB.patternGlowCount or defaults.patternGlowCount
        coords = patternFunction(patternCount)
        usedCoordsCount = coords and #coords or 0
    end

    if coords then
        for i, glow in ipairs(customCursor.glowEffects) do
            if coords[i] and i <= numGlows then
                local x = coords[i].x
                local y = coords[i].y
                local scaleFactor = (glowRadius * cursorRadius) / 20
                local offsetX = x * scaleFactor
                local offsetY = y * scaleFactor
                glow:ClearAllPoints()
                glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
                local size = (cursorWidth * glowSize) * glowThickness
                glow:SetSize(size, size)
                local alpha = EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity
                glow.texture:SetAlpha(alpha)
                glow:Show()
            else
                glow:Hide()
            end
        end
    else
        -- fallback circle
        local angleStep = (numGlows>0) and (360/numGlows) or 0
        for i, glow in ipairs(customCursor.glowEffects) do
            if i<=numGlows and glow and glow.texture then
                local angle = math.rad((i - 1)*angleStep)
                local offsetDist = cursorRadius * glowRadius
                local offsetX = offsetDist * math.cos(angle)
                local offsetY = offsetDist * math.sin(angle)
                glow:ClearAllPoints()
                glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
                local size = (cursorWidth * glowSize)*glowThickness
                glow:SetSize(size, size)
                local alpha = EasyCursorTrailsDB.glowIntensity or defaults.glowIntensity
                glow.texture:SetAlpha(alpha)
                glow:Show()
            else
                glow:Hide()
            end
        end
    end

    EasyCursorTrails.ApplySelectedGlowEffect()

end
function EasyCursorTrails.InitializeCustomCursor()
    -- Create the custom cursor frame if it doesn't exist
    if not customCursor then
        customCursor = CreateFrame("Frame", "EasyCursorCustomCursor", UIParent, "BackdropTemplate")
        customCursor:SetPoint("CENTER", UIParent, "CENTER")
        customCursor:EnableMouse(false)
    end

    -- Apply the saved frame strata
    local frameStrata = EasyCursorTrailsDB.cursorFrameStrata or "MEDIUM"
    customCursor:SetFrameStrata(frameStrata)

    -- Set cursor size
    local cursorSize = EasyCursorTrailsDB.cursorSize or 32
    customCursor:SetSize(cursorSize, cursorSize)

    -- Create or update the texture
    if not customCursor.texture then
        customCursor.texture = customCursor:CreateTexture(nil, "OVERLAY")
        customCursor.texture:SetAllPoints()
        customCursor.texture:SetBlendMode("ADD")
    end

    -- Retrieve the cursor data
    local cursorIndex = EasyCursorTrailsDB.cursorTexture or 1
    local cursorData = customCursorTextures[cursorIndex]

    if not cursorData then
        -- Fallback to default arrow cursor if data is invalid
        customCursor.texture:SetTexture("Interface\\CURSOR\\Arrow")
        customCursor:SetScript("OnUpdate", nil)
        EasyCursorTrailsDB.selectedCursorTextureName = "Default"
    else
        -- Save the selected cursor texture name
        local function extractFilename(path)
            local filename = path:match("([^/\\]+)$") or ""
            return filename:gsub("%.tga", ""):gsub("%.blp", "")
        end

        if cursorData.texture then
            EasyCursorTrailsDB.selectedCursorTextureName = extractFilename(cursorData.texture)
        elseif cursorData.textures and #cursorData.textures > 0 then
            EasyCursorTrailsDB.selectedCursorTextureName = extractFilename(cursorData.textures[1])
        else
            EasyCursorTrailsDB.selectedCursorTextureName = "Unknown"
        end

        -- Handle animated or static cursors
        if cursorData.animated and cursorData.textures then
            local totalFrames = #cursorData.textures
            local animationDuration = cursorData.animationDuration or 1
            customCursor.texture:SetTexture(cursorData.textures[1])
            customCursor:SetScript("OnUpdate", function(self, elapsed)
                self.elapsedTime = (self.elapsedTime or 0) + elapsed
                local frameIndex = math.floor(
                    (self.elapsedTime % animationDuration) / animationDuration * totalFrames
                ) + 1
                self.texture:SetTexture(cursorData.textures[frameIndex] or "Interface\\CURSOR\\Arrow")
            end)
        else
            customCursor.texture:SetTexture(cursorData.texture or "Interface\\CURSOR\\Arrow")
            customCursor:SetScript("OnUpdate", nil)
        end
    end

    -- Initialize and apply glow effects
    if not customCursor.glowEffects or #customCursor.glowEffects == 0 then
        EasyCursorTrails.InitializeGlowFrames()
    end
    EasyCursorTrails.UpdateGlowFrames()
    EasyCursorTrails.ApplySelectedGlowEffect()

    -- Show the custom cursor
    customCursor:Show()
end


function EasyCursorTrails.UpdateCustomCursorPosition()
    if not customCursor then
        ----print("EasyCursorTrails: customCursor not initialized.")
        return
    end

    local xOffset = EasyCursorTrailsDB.cursorOffsetX or 0
    local yOffset = EasyCursorTrailsDB.cursorOffsetY or 0
    local x, y = GetCursorPosition()
    local scale = UIParent:GetEffectiveScale()
    x = x/scale + xOffset
    y = y/scale + yOffset
    customCursor:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x, y)
end

function EasyCursorTrails.UpdateCustomCursorSize(size)
    if type(size) ~= "number" then
        EasyCursorTrails.HandleError("UpdateCustomCursorSize: 'size' is not a number. Received: " .. tostring(size))
        ----print("Debug: 'size' is of type " .. type(size))
        return
    end

    if customCursor then
        ----print(string.format("Debug: Setting customCursor size to %d", size))
        customCursor:SetSize(size, size)
        EasyCursorTrails.UpdateGlowFrames()
    end
end

-- Helper function to save settings to the profile
function SaveSetting(key, value)
    if EasyCursorTrailsDB and EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.currentProfile then
        EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile][key] = value
        --print(string.format("EasyCursorTrails: '%s' set to index %d. Saved to profile '%s'.", key, value, EasyCursorTrailsDB.currentProfile))
    else
        --print("EasyCursorTrails: Failed to save setting. Profile data is missing.")
    end
end

function RebuildTrails()
    -- Validate and save settings with fallback to defaults
    local settingsToValidate = {
        { key = "cursorSize", type = "number" },
        { key = "cursorOffsetX", type = "number" },
        { key = "cursorOffsetY", type = "number" },
        { key = "numGlows", type = "number" },
        { key = "patternGlowCount", type = "number" },
        { key = "glowIntensity", type = "number" },
        { key = "glowRadius", type = "number" },
        { key = "glowSize", type = "number" },
        { key = "glowThickness", type = "number" },
        { key = "cursorFrameStrata", type = "string" },
        { key = "trailFrameStrata", type = "string" },
        { key = "trailMovementEffect", type = "number" },
        { key = "trailTexture", type = "number" },
        { key = "trailSizeStart", type = "number" },
        { key = "trailSizeEnd", type = "number" },
        { key = "trailLayerCount", type = "number" },
        { key = "trailCount", type = "number" },
    }

    local currentProfile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    for _, setting in ipairs(settingsToValidate) do
        local key = setting.key
        local value = currentProfile[key]
        local defaultValue = defaults[key]

        if type(value) ~= setting.type then
            EasyCursorTrails.HandleError("Invalid type for key '" .. key .. "'. Resetting to default.")
            currentProfile[key] = defaultValue
            SaveSetting(key, defaultValue)
        end
    end

    -- Apply the default cursor texture if not set
    if not currentProfile.selectedCursorTextureName then
        currentProfile.selectedCursorTextureName = defaults.selectedCursorTextureName
        SaveSetting("selectedCursorTextureName", defaults.selectedCursorTextureName)
    end

    -- Ensure the custom cursor texture is applied
    if EasyCursorTrails.InitializeCustomCursor then
        EasyCursorTrails.InitializeCustomCursor()
    else
        EasyCursorTrails.HandleError("InitializeCustomCursor function is missing.")
    end

    if EasyCursorTrails.UpdateCustomCursorSize then
        EasyCursorTrails.UpdateCustomCursorSize(currentProfile.cursorSize or defaults.cursorSize)
    else
        EasyCursorTrails.HandleError("UpdateCustomCursorSize function is missing.")
    end

    -- Clean up existing trails
    EasyCursorTrails.trailPool = EasyCursorTrails.trailPool or {}
    for _, layerPool in pairs(EasyCursorTrails.trailPool) do
        for _, trail in ipairs(layerPool) do
            trail:Hide()
            trail:ClearAllPoints()
            trail:SetParent(nil)
        end
    end
    EasyCursorTrails.trailPool = {}

    -- Determine the frame strata for the trails
    local trailStrata = currentProfile.trailFrameStrata or "TOOLTIP"

    -- Recreate trail frames
    for layer = 1, currentProfile.trailLayerCount do
        EasyCursorTrails.trailPool[layer] = {}
        for i = 1, currentProfile.trailCount do
            local size = currentProfile.trailSizeStart
            if currentProfile.trailCount > 1 then
                size = currentProfile.trailSizeStart +
                    ((currentProfile.trailSizeEnd - currentProfile.trailSizeStart) * ((i - 1) / (currentProfile.trailCount - 1)))
            end

            local trail = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
            trail:SetSize(size, size)
            trail.originalSize = size
            trail:SetFrameStrata(trailStrata)
            trail:SetAlpha(1)
            trail:Hide()

            -- Create and set up the trail's texture
            trail.texture = trail:CreateTexture(nil, "BACKGROUND")
            trail.texture:SetAllPoints(true)

            -- Apply movement effects and textures
            local currentTrailEffect = currentProfile.trailMovementEffect or 1
            local currentTrailTexture = currentProfile.trailTexture or 1

            if EasyCursorTrails.trailTextures[currentTrailEffect] and EasyCursorTrails.trailTextures[currentTrailEffect][currentTrailTexture] then
                local textureData = EasyCursorTrails.trailTextures[currentTrailEffect][currentTrailTexture]
                trail.texture:SetTexture(textureData.texture)
            else
                trail.texture:SetTexture("Interface\\CURSOR\\Arrow") -- Default texture
            end

            -- Apply color effects
            if EasyCursorTrails.ApplyColorEffectTrail then
                EasyCursorTrails.ApplyColorEffectTrail(trail, i)
            else
                EasyCursorTrails.HandleError("ApplyColorEffectTrail function is missing.")
            end

            table.insert(EasyCursorTrails.trailPool[layer], trail)
        end
    end

    -- Apply glow effects if necessary
    if EasyCursorTrails.UpdateGlowBelowCursor then
        EasyCursorTrails.UpdateGlowBelowCursor()
    end

    -- Update trail offsets
    if EasyCursorTrails.UpdateTrailOffsets then
        EasyCursorTrails.UpdateTrailOffsets()
    else
        EasyCursorTrails.HandleError("UpdateTrailOffsets function is missing.")
    end

    -- Apply selected glow effects
    if EasyCursorTrails.ApplySelectedGlowEffect then
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
end


EasyCursorTrails.movementEffects = {
    -- 1: No Effect
    [1] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        print("No Effect applied.")
        return {0, 0}
    end,

    -- 2: Linear Separation
    [2] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local offsetX = offsetDistance * math.cos(movementAngle)
        local offsetY = offsetDistance * math.sin(movementAngle)
        print(string.format("Linear Separation | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 3: Spiral Expansion
    [3] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local spiralSpeed = 2 * math.pi * separationFactor
        local radius = offsetDistance * separationFactor
        local offsetX = radius * math.cos(spiralSpeed + movementAngle)
        local offsetY = radius * math.sin(spiralSpeed + movementAngle)
        print(string.format("Spiral Expansion | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 4: Zig-Zag
    [4] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local zigzagFactor = 20 * math.sin(separationFactor * 10 * math.pi)
        local offsetX = offsetDistance * math.cos(movementAngle) + zigzagFactor
        local offsetY = offsetDistance * math.sin(movementAngle)
        print(string.format("Zig-Zag | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 5: Wave Oscillation
    [5] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local waveAmplitude = 30 * math.sin(2 * math.pi * separationFactor)
        local offsetX = offsetDistance * math.cos(movementAngle)
        local offsetY = offsetDistance * math.sin(movementAngle) + waveAmplitude
        print(string.format("Wave Oscillation | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 6: Galactic Orbit
    [6] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local orbitRadius = 15 * separationFactor
        local orbitSpeed = 3 * math.pi * separationFactor
        local offsetX = orbitRadius * math.cos(orbitSpeed + movementAngle)
        local offsetY = orbitRadius * math.sin(orbitSpeed + movementAngle)
        print(string.format("Galactic Orbit | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 7: Firestorm
    [7] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local fireJitter = 10 * math.random(-1, 1)
        local offsetX = offsetDistance * math.cos(movementAngle) + fireJitter
        local offsetY = offsetDistance * math.sin(movementAngle) + fireJitter
        print(string.format("Firestorm | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    -- 8: Wind Spiral
    [8] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local windShift = 20 * math.cos(separationFactor * 6 * math.pi)
        local offsetX = offsetDistance * math.cos(movementAngle) + windShift
        local offsetY = offsetDistance * math.sin(movementAngle)
        print(string.format("Wind Spiral | OffsetX: %.2f, OffsetY: %.2f", offsetX, offsetY))
        return {offsetX, offsetY}
    end,

    }
    

-- ============================
-- EasyCursorTrails Addon Code
-- ============================

-- Initialize essential variables
EasyCursorTrails.previousCursorX = nil
EasyCursorTrails.previousCursorY = nil
EasyCursorTrails.cursorPositions = {}
EasyCursorTrails.cursorStopped   = false

----------------------------------------------
-- Initialize Ring Buffer for connectTrails
----------------------------------------------
-- Configuration Parameters
EasyCursorTrails.cursorHistory = {}
EasyCursorTrails.headIndex     = 0
EasyCursorTrails.bufferSize    = 200     -- Adjust based on trailCount * desired history depth
EasyCursorTrails.skipSpacing   = 1       -- Frames to skip per trail segment (adjust for smoother trails)

-- Initialize cursorHistory and define skipSpacing
if not EasyCursorTrails.cursorHistory then
    EasyCursorTrails.cursorHistory = {}
    for i = 1, EasyCursorTrails.bufferSize do
        EasyCursorTrails.cursorHistory[i] = { x = 0, y = 0 }
    end
end


-- Initialize headIndex and bufferSize if not already set
EasyCursorTrails.headIndex = EasyCursorTrails.headIndex or 0
EasyCursorTrails.bufferSize = EasyCursorTrails.bufferSize or 200 -- Ensure bufferSize is set


function EasyCursorTrails.HandleTrailMovement(elapsed)
    -- Retrieve the current profile
    local profile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then
        EasyCursorTrails.HandleError("HandleTrailMovement: Current profile not found.")
        return
    end

    -- Retrieve configuration parameters from profile
    local maximumOffset = tonumber(profile.trailLayerSpacing) or 30
    local initialSeparation = tonumber(profile.trailInitialSeparation) or 0

    -- Grab Current Cursor Position
    local cursorX, cursorY = GetCursorPosition()
    local scale = UIParent:GetEffectiveScale()
    cursorX, cursorY = cursorX / scale, cursorY / scale

    -- Update Custom Cursor Position and Color Effects (if any)
    if EasyCursorTrails.UpdateCustomCursorPosition then
        EasyCursorTrails.UpdateCustomCursorPosition()
    end

    -- If trails are disabled, hide all trails and exit early
    if not profile.enableTrails then
        for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, f in ipairs(layerPool) do
                f:Hide()
            end
        end
        return
    end

    -- Determine if connectTrails is enabled
    local connectTrails = profile.connectTrails
    local layerCount = profile.trailLayerCount or 1
    local trailCount = profile.trailCount or 10

    -- Track cursor movement
    local cursorMoved = false
    EasyCursorTrails.cursorHistory = EasyCursorTrails.cursorHistory or {}
    EasyCursorTrails.headIndex = (EasyCursorTrails.headIndex or 0) + 1
    if EasyCursorTrails.headIndex > EasyCursorTrails.bufferSize then
        EasyCursorTrails.headIndex = 1
    end

    if EasyCursorTrails.previousCursorX and EasyCursorTrails.previousCursorY then
        local dx = cursorX - EasyCursorTrails.previousCursorX
        local dy = cursorY - EasyCursorTrails.previousCursorY
        local distance = math.sqrt(dx^2 + dy^2)

        if distance >= 0.1 then
            cursorMoved = true
        end
    end

    EasyCursorTrails.previousCursorX, EasyCursorTrails.previousCursorY = cursorX, cursorY

    -- Update trail history
    if connectTrails or cursorMoved then
        EasyCursorTrails.cursorHistory[EasyCursorTrails.headIndex] = { x = cursorX, y = cursorY }
    else
        EasyCursorTrails.cursorHistory = {}
    end

    -- Rebuild and position the trails
    for layer = 1, layerCount do
        local layerTrails = EasyCursorTrails.trailPool and EasyCursorTrails.trailPool[layer]
        if layerTrails then
            -- Define layerDirection per layer (if applicable)
            local layerDirection = 0
            if layerCount > 1 then
                layerDirection = ((layer - 1) / (layerCount - 1)) * math.pi * 2
            end

            for i = 1, trailCount do
                local f = layerTrails[i]
                if f then
                    local posIndex = EasyCursorTrails.headIndex - (i * EasyCursorTrails.skipSpacing)
                    if posIndex < 1 then
                        posIndex = posIndex + EasyCursorTrails.bufferSize
                    end
                    local pos = EasyCursorTrails.cursorHistory[posIndex]

                    if pos and (connectTrails or cursorMoved) then
                        -- Calculate rotation and position
                        local dx = pos.x - cursorX
                        local dy = pos.y - cursorY
                        local distance = math.sqrt(dx^2 + dy^2)
                        local angle = math.atan2(dy, dx) + math.pi

                        -- Compute movementEffect-based offset
                        local separationFactor = (i - 1) / math.max(trailCount - 1, 1)
                        local offsetDistance = initialSeparation + separationFactor * (maximumOffset - initialSeparation)
                        local movementEffect = profile.trailMovementEffect or 1

                        local offsetX, offsetY = 0, 0
                        if EasyCursorTrails.movementEffects and EasyCursorTrails.movementEffects[movementEffect] then
                            local effectOffsets = EasyCursorTrails.movementEffects[movementEffect](
                                layerDirection,
                                separationFactor,
                                offsetDistance,
                                profile,
                                f,
                                angle,
                                maximumOffset
                            )
                            if type(effectOffsets) == "table" and #effectOffsets == 2 then
                                offsetX, offsetY = unpack(effectOffsets)
                            else
                                EasyCursorTrails.HandleError("Invalid effectOffsets returned for movementEffect " .. movementEffect)
                                offsetX, offsetY = 0, 0
                            end
                        else
                            -- Default to Linear Separation if effect not defined
                            offsetX = offsetDistance * math.cos(layerDirection)
                            offsetY = offsetDistance * math.sin(layerDirection)
                        end

                        -- Apply trailOffsetX and Y from profile
                        local finalOffsetX = (profile.trailOffsetX or 0) + offsetX
                        local finalOffsetY = (profile.trailOffsetY or 0) + offsetY

                        -- Hide trails if they reach the cursor
                        if connectTrails and distance < 10 then
                            f:Hide()
                        else
                            -- Position and display trails
                            f:ClearAllPoints()
                            f:SetPoint("CENTER", UIParent, "BOTTOMLEFT", pos.x + finalOffsetX, pos.y + finalOffsetY)
                            f.texture:SetRotation(angle)
                            f:Show()
                        end

                        -- Apply color effects (if any)
                        if EasyCursorTrails.ApplyColorEffectTrail then
                            EasyCursorTrails.ApplyColorEffectTrail(f, i)
                        end
                    else
                        f:Hide()
                    end
                end
            end
        end
    end

    -- Hide trails immediately when `connectTrails` is unchecked, and the cursor stops
    if not connectTrails and not cursorMoved then
        for layer = 1, layerCount do
            local layerTrails = EasyCursorTrails.trailPool and EasyCursorTrails.trailPool[layer]
            if layerTrails then
                for _, f in ipairs(layerTrails) do
                    f:Hide()
                end
            end
        end
    end
end

function InitializeAddon()
    -- Ensure the database and profiles are initialized
    InitializeEasyCursorTrailsDB()
    EasyCursorTrails.settingsChanged = false

    -- Validate the last used profile or fallback to 'Default'
    local lastProfile = EasyCursorTrailsDB.currentProfile
    if not lastProfile or not EasyCursorTrailsDB.profiles[lastProfile] then
        EasyCursorTrailsDB.currentProfile = "Default"

        -- Create 'Default' profile if it doesn't exist
        if not EasyCursorTrailsDB.profiles["Default"] then
            EasyCursorTrailsDB.profiles["Default"] = {}
            for key, value in pairs(defaults) do
                EasyCursorTrailsDB.profiles["Default"][key] = value
            end
        end
    end

    -- Initialize the current profile
    EasyCursorTrails.InitializeProfile()

    -- Apply default settings if necessary
    local currentProfile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    for key, defaultValue in pairs(defaults) do
        if currentProfile[key] == nil then
            currentProfile[key] = defaultValue
        end
    end

    -- Load the current profile settings
    LoadCurrentProfile()

    -- Initialize saved variables and settings menu
    InitializeSavedVariables()
    InitializeSettingsMenu()

    -- Initialize trails, glow effects, and the custom cursor
    if EasyCursorTrails.InitializeCustomCursor then
        EasyCursorTrails.InitializeCustomCursor()
    else
        EasyCursorTrails.HandleError("InitializeCustomCursor function is missing.")
    end

    -- Ensure glow effects respect the "glowBelow" setting
    if EasyCursorTrails.UpdateGlowBelowCursor then
        EasyCursorTrails.UpdateGlowBelowCursor()
    else
        EasyCursorTrails.HandleError("UpdateGlowBelowCursor function is missing.")
    end

    -- Refresh settings UI to reflect the loaded profile
    if RefreshSettingsUI then
        RefreshSettingsUI()
    else
        EasyCursorTrails.HandleError("RefreshSettingsUI function is missing.")
    end

    -- Rebuild trails to ensure they match the current profile
    if RebuildTrails then
        RebuildTrails()
    else
        EasyCursorTrails.HandleError("RebuildTrails function is missing.")
    end

    -- Initialize pulse variables
    EasyCursorTrails.pulseValueTrail = 0.5
    EasyCursorTrails.pulseDirectionTrail = 1

    -- Ensure pulse settings are initialized
    EasyCursorTrailsDB.pulseStep = EasyCursorTrailsDB.pulseStep or defaults.pulseStep
    EasyCursorTrailsDB.pulseMin = EasyCursorTrailsDB.pulseMin or defaults.pulseMin
    EasyCursorTrailsDB.pulseMax = EasyCursorTrailsDB.pulseMax or defaults.pulseMax

    -- Create an update frame for animations
    local updateFrame = CreateFrame("Frame")
    updateFrame:SetScript("OnUpdate", function(_, elapsed)
        EasyCursorTrails.colorIndexTrail = (EasyCursorTrails.colorIndexTrail or 0) + (elapsed * 300)
        if EasyCursorTrails.colorIndexTrail >= 360 then
            EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail - 360
        end

        EasyCursorTrails.UpdatePulseValue()

        if EasyCursorTrails.trailPool and type(EasyCursorTrails.trailPool) == "table" then
            for _, trailLayer in pairs(EasyCursorTrails.trailPool) do
                for _, trail in ipairs(trailLayer) do
                    if trail and trail.index then
                        EasyCursorTrails.ApplyColorEffectTrail(trail, trail.index)
                    end
                end
            end
        end
    end)

    -- Confirm successful initialization
    --print("EasyCursorTrails: Addon initialized successfully with profile '" .. EasyCursorTrailsDB.currentProfile .. "'.")
end
-- Event Frame for ADDON_LOADED
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:SetScript("OnEvent", function(self, event, addonName)
    if event == "ADDON_LOADED" and addonName == "EasyCursorTrails" then
        InitializeAddon() -- Ensure all settings and UI are properly initialized
    end
end)

-- Update Frame for Animations and Trail Updates
local updateFrame = CreateFrame("Frame")
updateFrame:SetScript("OnUpdate", function(self, elapsed)
    -- Increment colorIndexTrail for smooth cycling
    EasyCursorTrails.colorIndexTrail = (EasyCursorTrails.colorIndexTrail or 0) + (elapsed * 60)
    
    -- Keep colorIndexTrail within bounds (0-360 degrees)
    if EasyCursorTrails.colorIndexTrail >= 360 then
        EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail - 360
    end

    -- Update pulse value for pulsating effect
    if EasyCursorTrails.UpdatePulseValue then
        EasyCursorTrails.UpdatePulseValue()
    else
        EasyCursorTrails.HandleError("UpdatePulseValue function is missing.")
    end

    -- Handle trail movement and animations
    if EasyCursorTrails.HandleTrailMovement then
        EasyCursorTrails.HandleTrailMovement(elapsed)
    else
        EasyCursorTrails.HandleError("HandleTrailMovement function is missing.")
    end

    -- Iterate through all active trails and update their glow colors
    if EasyCursorTrails.trailPool and type(EasyCursorTrails.trailPool) == "table" then
        for _, trailLayer in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(trailLayer) do
                if trail and trail.index then
                    if EasyCursorTrails.ApplyColorEffectTrail then
                        EasyCursorTrails.ApplyColorEffectTrail(trail, trail.index)
                    else
                        EasyCursorTrails.HandleError("ApplyColorEffectTrail function is missing.")
                    end
                end
            end
        end
    else
        EasyCursorTrails.HandleError("trailPool is missing or invalid.")
    end
end)

-- Slash Command to Toggle Settings Menu
SLASH_EASYCURSORMENU1 = "/easymenu"
SlashCmdList["EASYCURSORMENU"] = function()
    local menu = _G["EasyCursorTrailsMenu"]
    if menu then
        menu:SetShown(not menu:IsShown())
    else
        print("EasyCursorTrails Error: Settings menu frame not found. Ensure the menu is initialized.")
    end
end
