-- 🔧 Initialize main table
EasyCursorTrails = EasyCursorTrails or {}
EasyCursorTrails.previewMode = true
EasyCursorTrails.debugMode = false
EasyCursorTrails.liveEffects = EasyCursorTrails.liveEffects or {}
EasyCursorTrails.rotationTimers = EasyCursorTrails.rotationTimers or {}
EasyCursorTrails.lastArcTime = {}


-- 🔧 Fallback CopyTable if not provided by WoW API
local function CopyTable(tbl)
    local copy = {}
    for k, v in pairs(tbl) do
        copy[k] = type(v) == "table" and CopyTable(v) or v
    end
    return copy
end

-- 🔧 Default profile settings
EasyCursorTrails.defaults = {
    enableTrails = true,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 6,
    connectTrails = true,
    horizontalScale = 1,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1599999964237213,
    randomStarEmberColor = false,
    glowColor = { a = 1, r = 1, g = 0.5058823529411764, b = 0.7294117647058823 },
    splitLayoutEnabled = false,
    sweepSpeed = 29,
    trailRadius = 20,
    cursorOffsetX = 0,
    enableTrailShadows = true,
    rainbowSpeed = 4.937482357025147,
    trailDelay = 0,
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    selectedGlowTexture = 2,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    rippleScale = 1.2,
    randomFireTrailColor = false,
    cursorTexture = 35,
    enableRotation = false,
    trailLayerCount = 1,
    driftEnabled = false,
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    randomLightningSparkColor = false,
    enableTwinkleStars = false,
    cursorFrameStrata = "HIGH",
    enableSmokeEffect = true,
    enableSpringSeasonTrails = false,
    patternGlowCount = 30,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    trailTexture = 1,
    rainbowEnabled = true,
    cursorSize = 30,
    shadowTrailColor = { a = 1, r = 0, g = 0, b = 0 },
    randomSmokeColor = true,
    glowIntensity = 1,
    twinkleEnabled = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    twinkleSpeed = 5,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 35,
    trailSpacing = 10,
    counterClockwiseSpeed = 30,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = false,
    randomSpringSeasonColor = false,
    cursorColor = { a = 1, r = 1, g = 0.09803921568627451, b = 0 },
    trailTextureOpacity = 1,
    enableSmokeEffectTrails = true,
    shimmerEnabled = false,
    trailSizeEnd = 1,
    trailMovementEffect = 1,
    randomStarDustColor = true,
    trailInitialSeparation = 30,
    enableStarDust = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 11,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 18,
    glowIntensityFactor = 0.2999999821186066,
    menuPosition = {
        x = 250.1666412,
        y = -87.3333206,
        point = "TOP",
        relativePoint = "TOP",
    },
    trailLayerSpacing = 0,
    splitEffectEnabled = false,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = true,
    trailColor = { a = 1, r = 1, g = 1, b = 1 },
    enableFire = false,
    enableStarEmbers = true,
    cursorOffsetY = 0,
    trailOffsetY = -20,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    splitLayoutHeight = 50,
    glowBelow = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    randomShadowColor = false,
    arcEmitterCooldown = 2.24,
    enableFireTrails = false,
    verticalScale = 2,
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    trailUpdateMultiplier = 100,
    clockwiseSpeed = 30,
    randomSpringSeasonTrailColor = false,
    glowSize = 0.5

}


-- 🔧 Merge defaults into target profile
function EasyCursorTrails:MergeDefaults(target, defaults)
    for key, value in pairs(defaults) do
        if type(value) == "table" then
            if type(target[key]) ~= "table" or next(target[key]) == nil then
                target[key] = CopyTable(value)
            else
                self:MergeDefaults(target[key], value)
            end
        elseif target[key] == nil then
            target[key] = value
        end
    end
end


------------------------------------------------------------------------------
-- Initialize or fix up EasyCursorTrailsDB
------------------------------------------------------------------------------
function EasyCursorTrails.InitializeEasyCursorTrailsDB()
    if not EasyCursorTrails.defaults then
        --EasyCursorTrails.HandleError"InitializeEasyCursorTrailsDB: Defaults not defined.")
        return
    end

    -- Ensure the global saved variable
    if not EasyCursorTrailsDB then
        EasyCursorTrailsDB = { profiles = {} }
        ----print("EasyCursorTrails: Created a fresh EasyCursorTrailsDB.")
    else
        EasyCursorTrailsDB.profiles = EasyCursorTrailsDB.profiles or {}
    end

    -- Ensure 'Default' profile exists
    if not EasyCursorTrailsDB.profiles["Default"] then
        EasyCursorTrailsDB.profiles["Default"] = {}
        for key, val in pairs(EasyCursorTrails.defaults) do
            EasyCursorTrailsDB.profiles["Default"][key] = val
        end

        ----print("EasyCursorTrails: 'Default' profile created with defaults.")
    end

    -- Pick a valid currentProfile if needed
    local cp = EasyCursorTrailsDB.currentProfile
    if not cp or not EasyCursorTrailsDB.profiles[cp] then
        cp = "Default"
        EasyCursorTrailsDB.currentProfile = "Default"
        ----print("EasyCursorTrails: Using 'Default' profile since current was invalid.")
    end

    -- Also ensure lastSelectedProfile is valid
    local lsp = EasyCursorTrailsDB.lastSelectedProfile
    if not lsp or not EasyCursorTrailsDB.profiles[lsp] then
        EasyCursorTrailsDB.lastSelectedProfile = "Default"
    end
    -- We do NOT call Load/Refresh/Rebuild here to avoid double merges
end


------------------------------------------------------------------------------
-- InitializeProfile
-----------------------
function EasyCursorTrails.InitializeProfile()
    local cp = EasyCursorTrailsDB.currentProfile or "Default"
    local prof = EasyCursorTrailsDB.profiles[cp]
    if not prof then
        cp = "Default"
        EasyCursorTrailsDB.currentProfile = cp
        prof = EasyCursorTrailsDB.profiles[cp]
        if not prof then
            --EasyCursorTrails.HandleError"InitializeProfile: Missing 'Default' profile.")
            return
        end
    end
  
    EasyCursorTrails.currentProfileTable = prof
   
end

------------------------------------------------------------------------------
-- LoadCurrentProfile
--
-- Usually called after switching profile or reset. 
-- Ensures currentProfileTable is valid and merges defaults if needed.
------------------------------------------------------------------------------


function EasyCursorTrails.LoadCurrentProfile()
    local cp = EasyCursorTrailsDB.currentProfile or "Default"
    local profiles = EasyCursorTrailsDB.profiles or {}
    local prof = profiles[cp]

    -- 🛡️ Fallback to Default profile if missing
    if not prof then
        cp = "Default"
        EasyCursorTrailsDB.currentProfile = cp
        prof = profiles[cp]
        if not prof then
            if EasyCursorTrails.debugSave then
                print("[EasyCursorTrails] Error: No valid profile found.")
            end
            return
        end
    end

    -- 🧱 Merge defaults without overwriting saved values
    if EasyCursorTrails.defaults then
        prof = EasyCursorTrails.DeepCopyDefaults(EasyCursorTrails.defaults, prof)
        profiles[cp] = prof
    end

    -- 🔗 Assign profile references
    EasyCursorTrails.currentProfileTable = prof
    EasyCursorTrails.profile = prof

    -- 🔄 Sync UI controls with profile
    if EasyCursorTrails.SyncGlobalSettingsUI then
        EasyCursorTrails.SyncGlobalSettingsUI()
    end
    if EasyCursorTrails.SyncEffectSettingsUI then
        EasyCursorTrails.SyncEffectSettingsUI(prof.selectedGlowEffect or 1)
    end

    -- ✅ Validate profile structure
    if EasyCursorTrails.ValidateProfile then
        EasyCursorTrails.ValidateProfile(prof)
    end

    -- 🧭 Normalize frame strata
    local strataMap = {
        "BACKGROUND", "LOW", "MEDIUM", "HIGH", "DIALOG",
        "FULLSCREEN", "FULLSCREEN_DIALOG", "TOOLTIP"
    }
    local storedStrata = prof.cursorFrameStrata
    if type(storedStrata) ~= "string" then
        prof.cursorFrameStrata = strataMap[tonumber(storedStrata)] or "MEDIUM"
    end

    -- 🧮 Normalize trail layer count
    local storedLayerCount = tonumber(prof.trailLayerCount)
    if not storedLayerCount or storedLayerCount < 1 then
        storedLayerCount = tonumber(EasyCursorTrails.defaults.trailLayerCount) or 14
    end
    prof.trailLayerCount = math.floor(storedLayerCount)

    -- 🧼 Clear active glows
    if EasyCursorTrails.ClearActiveGlows then
        EasyCursorTrails.ClearActiveGlows()
    end

    -- 🔁 Initialize trail pool and arc timers
    EasyCursorTrails.trailPool = EasyCursorTrails.trailPool or {}
    EasyCursorTrails.lastArcTime = EasyCursorTrails.lastArcTime or {}

    -- 🖱️ Initialize cursor
    if EasyCursorTrails.InitializeCustomCursor then
        EasyCursorTrails.InitializeCustomCursor()
    end

    -- 🔄 Rebuild trails
    if EasyCursorTrails.RebuildTrails then
        EasyCursorTrails.RebuildTrails()
    end

    -- 🎛️ Refresh UI
    if EasyCursorTrails.RefreshSettingsUI then
        EasyCursorTrails.RefreshSettingsUI()
    end

    -- ✅ Sync Twinkle Stars color picker swatch
    local color = prof.twinkleStarsColor or EasyCursorTrails.GetDefaultColor("twinkleStarsColor")
    if EasyCursorTrails.twinkleStarsColorPicker and color then
        if EasyCursorTrails.twinkleStarsColorPicker.SetColorRGBA then
            EasyCursorTrails.twinkleStarsColorPicker:SetColorRGBA(color.r, color.g, color.b, color.a)
        end
    end

    -- 🌟 Reapply Twinkle Stars color after trail rebuild
    C_Timer.After(0.6, function()
        local profile = EasyCursorTrails.GetCurrentProfile()
        if profile and profile.enableTwinkleStars then
            if type(EasyCursorTrails.UpdateTwinkleTrailColors) == "function" then
                EasyCursorTrails.UpdateTwinkleTrailColors()
            elseif EasyCursorTrails.debugSave then
                -- print("[EasyCursorTrails] Warning: UpdateTwinkleTrailColors is not defined.")
            end
        end
    end)

    _G.currentProfile = EasyCursorTrails.profile
    
local glowEffectID = EasyCursorTrails.profile and EasyCursorTrails.profile.selectedGlowEffect or 1
EasyCursorTrails.SyncEffectSettingsUI(glowEffectID)

end


function EasyCursorTrails.SaveToCurrentProfile(key, value)
    if type(key) ~= "string" then return end

    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profiles = EasyCursorTrailsDB.profiles or {}
    local profile = EasyCursorTrails.currentProfileTable

    if not profile or not profiles[profileName] then return end

    -- 🛡️ Prevent accidental shared references
    if type(value) == "table" then
        value = CopyTable(value)
    end

    -- 🔐 Save to both in-memory and persistent DB
    profile[key] = value
    profiles[profileName][key] = value

    if EasyCursorTrails.debugSave then
        -- print(("[EasyCursorTrails] Saved '%s' → %s"):format(key, type(value) == "table" and "table" or tostring(value)))
    end
end



function EasyCursorTrails.SaveLastSelectedProfile(profileName)
    if type(profileName) ~= "string" then return end

    local profiles = EasyCursorTrailsDB and EasyCursorTrailsDB.profiles
    if not profiles or not profiles[profileName] then return end

    EasyCursorTrailsDB.lastSelectedProfile = profileName

    -- 🧠 Optional debug log
    if EasyCursorTrails.debugSave then
        -- print(("[EasyCursorTrails] Last selected profile set to '%s'"):format(profileName))
    end
end

function EasyCursorTrails.DeepCopyDefaults(defaults, overrides, seen)
    -- Prevent infinite loops from recursive tables
    if type(defaults) ~= "table" then
        return defaults
    end

    seen = seen or {}
    if seen[defaults] then
        return seen[defaults]
    end

    local copy = {}
    seen[defaults] = copy

    -- Copy defaults first
    for key, value in pairs(defaults) do
        if type(value) == "table" then
            local subOverride = (type(overrides) == "table") and overrides[key]
            copy[key] = EasyCursorTrails.DeepCopyDefaults(value, subOverride, seen)
        else
            copy[key] = value
        end
    end

    -- Apply overrides (non-table or new keys)
    if type(overrides) == "table" then
        for key, value in pairs(overrides) do
            if type(value) ~= "table" or type(copy[key]) ~= "table" then
                copy[key] = value
            end
        end
    end

    return copy
end



if not EasyCursorTrails.GetDefaultColor then
    function EasyCursorTrails.GetDefaultColor(effectKey)
        local defaults = {
            shadowTrailColor = { r = 0, g = 0, b = 0, a = 0.4 },
            fireColor = { r = 1, g = 0.3, b = 0, a = 1 },
            emberColor = { r = 1, g = 0.6, b = 0.2, a = 1 },
            smokeColor = { r = 0.4, g = 0.4, b = 0.4, a = 0.4 },
            lightningSparkColor = { r = 0.8, g = 0.8, b = 1, a = 1 },
            starColor = { r = 1, g = 1, b = 1, a = 1 },
            twinkleStarsColor = { r = 1, g = 1, b = 1, a = 1 },
            springSeasonColor = { r = 0.5, g = 1, b = 0.5, a = 1 },
            staticArcColor = { r = 0.6, g = 0.6, b = 1, a = 1 },
            lightningEmberColor = { r = 1, g = 1, b = 0.3, a = 1 },
        }
        return defaults[effectKey]
    end
end

-------------------------
-- Custom Cursors
-------------------------
EasyCursorTrails.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"]                 = "",
    ["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",
    "Shapes",
    "Bubble",
    "Circle",
    "Fantasy",
    "Heart",
    "Magic",
    "Nature",
    "Military",
    "ALL",
}


---------------------------------------------------------------------------
-- Trail Textures
---------------------------------------------------------------------------
EasyCursorTrails.trailTextures = {
    { name = "Dragon_Scale",         texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Dragon_Scale.blp" },
    { name = "Alien",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Alien3.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 = "Bullet Sparks",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet_Sparks.tga" },
    { name = "Bullet",               texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet1.blp" },
    { name = "Circle1",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1.tga" },
    { name = "Circle1_Trail",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle1_Trail.tga" },
    { name = "Circle2",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2.tga" },
    { name = "Circle2_Trail",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle2_Trail.tga" },
    { name = "Circle3",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3.tga" },
    { name = "Circle3_Trail",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle3_Trail.tga" },
    { name = "Circle4",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle4.tga" },
    { name = "Circle5",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Circle5.tga" },
    { name = "Dragon_Scale",         texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Dragon_Scale.blp" },
    { name = "Dust_Magic",           texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Bright_Dust.blp" },
    { name = "Fairies",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Faries1.blp" },
    { name = "Fairies1_Trail",       texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairies1_Trail.tga" },
    { name = "Fairy",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fairy_Trail.blp" },
    { name = "Fire1_Fantasy",        texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Fire1.tga" },
    { name = "Fire1_Magic",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Fire1.tga" },
    { name = "Flames",               texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Flames.tga" },
    { name = "Glitter",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Glitter.tga" },
    { name = "Ghost",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\ghost.tga" },
    { 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 = "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 = "Lines",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\lines_trail.tga" },
    { name = "Magic_Ball_Trail",     texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Magic_Ball_Trail.tga" },
    { name = "Rain",                 texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Rain.tga" },
    { name = "Seeds_Circle",         texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Seeds.tga" },
    { name = "Star1",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Star1.tga" },
    { name = "Rigth_Arrow",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\White_Arrow.blp" },
    { name = "Hexagon",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Hexagon.blp" },
    { name = "Capsule",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Capsule.blp" },
    { name = "Diamond",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Diamond.blp" },
    { name = "Star",                 texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Star.blp" },
    { name = "Cross",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Cross.blp" },
    { name = "Arrow",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Arrow.blp" },
    { name = "snake_scale",          texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\snake_scale.blp" },
    { name = "Chain",                texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Chain_800_500.blp" },
    { name = "Smiley",               texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\Smiley.blp" },
    { name = "DNA",                  texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\DNA_800_500.blp" },
    { name = "feather",              texture = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Fantasy\\feather.blp" },
   
}

local function OnTrailTextureSelected(newIndex)
    -- Save the selected texture index to the active profile
    EasyCursorTrails.SaveToCurrentProfile("trailTexture", newIndex)

    -- Rebuild trails to apply the new texture
    if EasyCursorTrails.RebuildTrails then
        EasyCursorTrails.RebuildTrails()
    end
end

function EasyCursorTrails.PopulateTrailTextureDropdown()
    local MAX_PER_LEVEL = 30

    -- Ensure trailTextures exist before proceeding
    if not EasyCursorTrails.trailTextures or #EasyCursorTrails.trailTextures == 0 then
        EasyCursorTrails.trailTextures = {
            { name = "Default Texture", texture = "Interface\\CURSOR\\Arrow" }
        }
    end

    -- Retrieve active profile
    
    
    local defaults = EasyCursorTrails.defaults or {}

    -- Get saved trail texture index
    local storedIndex = currentProfile.trailTexture or defaults.trailTexture or 1

    -- Validate stored index before applying
    if storedIndex < 1 or storedIndex > #EasyCursorTrails.trailTextures then
        storedIndex = 1
        EasyCursorTrailsDB.trailTexture = 1
        EasyCursorTrails.SaveToCurrentProfile("trailTexture", 1)
    end

    -- Create dropdown options
    local textureOptions = {}
    for i, textureInfo in ipairs(EasyCursorTrails.trailTextures) do
        table.insert(textureOptions, {
            text = textureInfo.name,
            icon = textureInfo.texture
        })
    end

    -- Initialize dropdown
    UIDropDownMenu_Initialize(EasyCursorTrails.trailTextureDropdown, function(self, level, menuList)
        if not level then return end

        if level == 1 then
            -- Populate main level dropdown
            for i, option in ipairs(textureOptions) do
                if i > MAX_PER_LEVEL then break end

                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(EasyCursorTrails.profileDropdown, name)
                    UIDropDownMenu_SetText(EasyCursorTrails.profileDropdown, name)
                
                    -- Apply selection
                    EasyCursorTrailsDB.currentProfile = name
                    EasyCursorTrails.settingsChanged = true
                    EasyCursorTrails.SaveToCurrentProfile("currentProfile", name)
                
                    -- Refresh settings
                    if EasyCursorTrails.RefreshSettingsUI then
                        EasyCursorTrails.RefreshSettingsUI()
                    end
                
                    CloseDropDownMenus()
                end
                
                
                UIDropDownMenu_AddButton(info, level)
            end

            -- Add "More..." submenu if options exceed MAX_PER_LEVEL
            if #textureOptions > MAX_PER_LEVEL then
                local info = UIDropDownMenu_CreateInfo()
                info.text = "More..."
                info.hasArrow = true
                info.notCheckable = true
                info.menuList = "TrailTextureDropdown_EXTRA_OPTIONS"
                UIDropDownMenu_AddButton(info, level)
            end

        elseif level == 2 and menuList == "TrailTextureDropdown_EXTRA_OPTIONS" then
            -- Populate second-level menu
            for i, option in ipairs(textureOptions) do
                if i > MAX_PER_LEVEL then
                    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()
                        -- Save selected trail texture
                        OnTrailTextureSelected(i)

                        -- Update dropdown UI
                        UIDropDownMenu_SetSelectedID(EasyCursorTrails.trailTextureDropdown, i)
                        UIDropDownMenu_SetText(EasyCursorTrails.trailTextureDropdown, option.text)

                        CloseDropDownMenus()
                    end
                    UIDropDownMenu_AddButton(info, level)
                end
            end
        end
    end)

    -- Ensure dropdown loads saved texture selection
    UIDropDownMenu_SetSelectedID(EasyCursorTrails.trailTextureDropdown, storedIndex)
    UIDropDownMenu_SetText(EasyCursorTrails.trailTextureDropdown, textureOptions[storedIndex].text or "Unknown")
  
end

function EasyCursorTrails.GetRandomTwinkleColor()
    local hue = math.random()
    local saturation = 0.7 + math.random() * 0.3
    local value = 0.8 + math.random() * 0.2

    -- HSV to RGB conversion
    local i = math.floor(hue * 6)
    local f = hue * 6 - i
    local p = value * (1 - saturation)
    local q = value * (1 - f * saturation)
    local t = value * (1 - (1 - f) * saturation)

    local r, g, b
    if i % 6 == 0 then r, g, b = value, t, p
    elseif i == 1 then r, g, b = q, value, p
    elseif i == 2 then r, g, b = p, value, t
    elseif i == 3 then r, g, b = p, q, value
    elseif i == 4 then r, g, b = t, p, value
    elseif i == 5 then r, g, b = value, p, q end

    return { r = r, g = g, b = b, a = 1 }
end


function EasyCursorTrails.GetTwinkleStarsColor(profile)
    if not profile then
        return { r = 1, g = 1, b = 1, a = 1 } -- default white sparkle
    end

    if profile.randomTwinkleStarsColor then
        return {
            r = math.random(),
            g = math.random(),
            b = math.random(),
            a = profile.twinkleStarsAlpha or 1
        }
    else
        return profile.twinkleStarsColor or { r = 1, g = 1, b = 1, a = 1 }
    end
end

function EasyCursorTrails.ApplyTwinkleStarsEffect(trail, index, intensity)
    if not trail or not trail:IsVisible() then return end

    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableTwinkleStars then return end

    -- 🕒 Throttle sparkle spawn per trail
    trail.lastTwinkleTime = trail.lastTwinkleTime or 0
    local now = GetTime()
    local minDelay = (profile.twinkleSpawnDelayMin or 120) / 1000
    if now - trail.lastTwinkleTime < minDelay then return end
    trail.lastTwinkleTime = now

    -- 🧩 Create or reuse sparkle frame
    if not trail.twinkleSpark then
        trail.twinkleSpark = CreateFrame("Frame", nil, trail)
        trail.twinkleSpark:SetFrameStrata("HIGH")

        local tex = trail.twinkleSpark:CreateTexture(nil, "OVERLAY")
        trail.twinkleSpark.texture = tex
        tex:SetTexture("Interface\\Cooldown\\star4")
        tex:SetBlendMode("ADD")
        tex:SetAllPoints()
        tex:SetTexCoord(0.2, 0.8, 0.2, 0.8)

        -- ✨ Optional glow halo layer
        trail.twinkleSpark.glowLayer = trail.twinkleSpark:CreateTexture(nil, "BACKGROUND")
        trail.twinkleSpark.glowLayer:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
        trail.twinkleSpark.glowLayer:SetBlendMode("ADD")
        trail.twinkleSpark.glowLayer:SetPoint("CENTER")
    end

    local sparkle = trail.twinkleSpark
    local tex = sparkle.texture
    local glowLayer = sparkle.glowLayer

    local trailW, trailH = trail:GetWidth(), trail:GetHeight()
    local offsetX = (math.random() - 0.5) * trailW * 0.6
    local offsetY = (math.random() - 0.5) * trailH * 0.6

    sparkle:SetSize(trailW, trailH)
    sparkle:ClearAllPoints()
    sparkle:SetPoint("CENTER", trail, "CENTER", offsetX, offsetY)
    sparkle:Show()

    local defaultColor = EasyCursorTrails.defaults and EasyCursorTrails.defaults.twinkleStarsColor or { r = 0.9, g = 0.95, b = 1, a = 1 }
    local color = profile.twinkleStarsRandomColor and EasyCursorTrails.GetRandomTwinkleColor()
        or profile.twinkleStarsColor
        or defaultColor

    -- 🎨 Boost sparkle brightness
    tex:SetVertexColor(
        math.min(color.r * 1.75, 1),
        math.min(color.g * 1.75, 1),
        math.min(color.b * 1.75, 1),
        math.min(color.a * 1.25, 1)
    )
    tex:SetRotation(math.random() * 2 * math.pi)

    -- ✨ Randomize sparkle scale
    local scale = 1.0 + math.random() * 0.4
    sparkle:SetScale(scale)

    -- 🌟 Glow halo layer
    glowLayer:SetSize(trailW * 1.5, trailH * 1.5)
    glowLayer:SetVertexColor(1, 1, 1, 0.3)
    glowLayer:Show()

    -- 🌀 Reuse or create animation group
    local ag = sparkle.ag
    if not ag then
        ag = sparkle:CreateAnimationGroup()
        sparkle.ag = ag

        ag.translation = ag:CreateAnimation("Translation")
        ag.translation:SetDuration(0.10)
        ag.translation:SetOrder(1)

        ag.alpha = ag:CreateAnimation("Alpha")
        ag.alpha:SetDuration(0.10)
        ag.alpha:SetOrder(1)

        ag:SetScript("OnFinished", function()
            sparkle:Hide()
            tex:SetAlpha(0)
            glowLayer:Hide()
        end)
    end

    -- ✨ Update animation offsets
    local angle = math.random() * 360
    local dist = (6 + math.random() * 16) * (intensity or 1)
    local dx = math.cos(math.rad(angle)) * dist
    local dy = math.sin(math.rad(angle)) * dist

    ag.translation:SetOffset(dx, dy)
    ag.alpha:SetFromAlpha(0.9)
    ag.alpha:SetToAlpha(0)

    ag:Stop()
    ag:SetLooping("NONE")
    ag:Play()
end



--==========================================================================================
function EasyCursorTrails.StartStaticArcTicker()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableStaticArc or not profile.enableTrails then return end

    if EasyCursorTrails.staticArcTicker then
        EasyCursorTrails.staticArcTicker:Cancel()
        EasyCursorTrails.staticArcTicker = nil
    end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for i, trail in ipairs(pool) do
            EasyCursorTrails.ApplyStaticArcEffect(trail, i, nil, true)
        end
    end

    -- 🔁 Reduced ticker frequency
    EasyCursorTrails.staticArcTicker = C_Timer.NewTicker(0.3, function()
        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for i, trail in ipairs(pool) do
                local emitter = trail.arcEmitter
                local visible = trail:IsVisible() and trail.texture and trail.texture:GetAlpha() > 0.01

                if visible then
                    -- 🕒 Respect emitter cooldown
                    local now = GetTime()
                    trail.lastArcSpawn = trail.lastArcSpawn or 0
                    if now - trail.lastArcSpawn >= 0.5 then
                        trail.lastArcSpawn = now
                        if emitter and emitter.ag and not emitter.ag:IsPlaying() then
                            emitter:Show()
                            emitter.ag:Play()
                        end
                    end
                elseif emitter then
                    emitter:Hide()
                    if emitter.ag then emitter.ag:Stop() end
                end

                if profile.randomStaticArcColor then
                    EasyCursorTrails.ApplyStaticArcEffect(trail, i, nil, true)
                end
            end
        end
    end)
end



function EasyCursorTrails.StopStaticArcTicker()
    if EasyCursorTrails.staticArcTicker then
        EasyCursorTrails.staticArcTicker:Cancel()
        EasyCursorTrails.staticArcTicker = nil
    end

    -- 🧹 Hide and detach visuals
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            local emitter = trail.arcEmitter
            if emitter then
                if emitter.ag then emitter.ag:Stop() end
                emitter:Hide()
                emitter:SetParent(nil)
                if emitter.texture then
                    emitter.texture:SetVertexColor(0, 0, 0, 0)
                    emitter.texture:SetTexture(nil)
                end
                trail.arcEmitter = nil
            end
        end
    end
end


function EasyCursorTrails.ApplyStaticArcEffect(trail, index, color, forceColorRefresh)
    if not trail then return end

    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        or {}

    local defaultColor = EasyCursorTrails.defaults and EasyCursorTrails.defaults.staticArcColor
        or { r = 1, g = 1, b = 1, a = 0.8 }

    local useRandom = profile.randomStaticArcColor
    local finalColor = useRandom and EasyCursorTrails.GetRandomTwinkleColor()
        or color
        or profile.staticArcColor
        or defaultColor


    -- 🧱 Create or reuse emitter
    if not trail.arcEmitter or not trail.arcEmitter.texture then
        local emitter = EasyCursorTrails.CreateArcEmitter(trail)
        if emitter then
            trail.arcEmitter = emitter
        else
            return -- 🛑 Abort if emitter couldn't be created due to cooldown
        end
    end

    -- 🎨 Apply color if forced or not yet set
    if forceColorRefresh or not trail.arcEmitter._lastColor then
        if trail.arcEmitter.texture then
            trail.arcEmitter.texture:SetVertexColor(
                finalColor.r or 1,
                finalColor.g or 1,
                finalColor.b or 1,
                finalColor.a or 0.8
            )
        end
        trail.arcEmitter._lastColor = finalColor
    end

    -- 🚀 Show and animate
    trail.arcEmitter:Show()
    if trail.arcEmitter.ag then
        trail.arcEmitter.ag:Play()
    end
end


function EasyCursorTrails.ClearStaticArcEffect(trail)
    if not trail or not trail.arcEmitter then return end

    local emitter = trail.arcEmitter

    -- 🛑 Stop animation
    if emitter.ag then emitter.ag:Stop() end

    -- 🧽 Hide and detach
    emitter:Hide()
    emitter:SetParent(nil)

    -- 🎨 Clear texture
    if emitter.texture then
        emitter.texture:SetVertexColor(0, 0, 0, 0)
        emitter.texture:SetTexture(nil)
    end

    -- 🧹 Remove reference
    trail.arcEmitter = nil
end


function EasyCursorTrails.CreateArcEmitter(trail)
    if not trail then return end

    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        or {}

    -- 🕒 Throttle spawn rate (default: 2.24s)
    local now = GetTime()
    local cooldown = math.clamp(profile.arcEmitterCooldown or 2.24, 0.2, 5.0)
    trail.lastArcSpawn = trail.lastArcSpawn or 0
    if now - trail.lastArcSpawn < cooldown then return end
    trail.lastArcSpawn = now

    -- ✨ Create emitter
    local emitter = CreateFrame("Frame", nil, trail)
    emitter:SetSize(trail:GetWidth() * 2.0, trail:GetHeight() * 2.0)
    emitter:SetPoint("CENTER", trail)
    emitter:Show()

    local tex = emitter:CreateTexture(nil, "OVERLAY")
    emitter.texture = tex
    tex:SetTexture("Interface\\Cooldown\\star4")
    tex:SetBlendMode("ADD")
    tex:SetAllPoints()
    tex:SetVertexColor(1, 1, 1, 1.0)
    tex:SetRotation(math.random() * 6.28)

    local ag = emitter:CreateAnimationGroup()
    emitter.ag = ag

    local flick = ag:CreateAnimation("Alpha")
    flick:SetFromAlpha(0.3)
    flick:SetToAlpha(1.0)
    flick:SetDuration(0.05)
    flick:SetSmoothing("IN_OUT")
    flick:SetOrder(1)

    local scale = ag:CreateAnimation("Scale")
    scale:SetScale(1.2 + math.random() * 0.3, 1.3)
    scale:SetOrigin("CENTER", 0, 0)
    scale:SetDuration(0.05)
    scale:SetSmoothing("OUT")
    scale:SetOrder(1)

    local drift = ag:CreateAnimation("Translation")
    drift:SetOffset(math.random(-5, 5), math.random(-10, 10))
    drift:SetDuration(0.08)
    drift:SetSmoothing("IN_OUT")
    drift:SetOrder(3)

    local fade = ag:CreateAnimation("Alpha")
    fade:SetFromAlpha(0.9)
    fade:SetToAlpha(0.2)
    fade:SetDuration(0.06)
    fade:SetOrder(3)

    ag:SetLooping("REPEAT")
    ag:Play()

    return emitter
end



function EasyCursorTrails.IsStaticArcEnabled()
    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    return profile and profile.enableStaticArc
end


if not math.clamp then
    function math.clamp(val, min, max)
        return math.max(min, math.min(max, val))
    end
end
if not EasyCursorTrails.arcOverlay then
    EasyCursorTrails.arcOverlay = CreateFrame("Frame", nil, UIParent)
    EasyCursorTrails.arcOverlay:SetAllPoints(UIParent)
    EasyCursorTrails.arcOverlay:SetFrameStrata("TOOLTIP")
end



--===================================================================================================
-- Initialize pools
EasyCursorTrails.sparkGlowPool = EasyCursorTrails.sparkGlowPool or {}
EasyCursorTrails.sparkBranchPool = EasyCursorTrails.sparkBranchPool or {}
EasyCursorTrails.sparkRipplePool = EasyCursorTrails.sparkRipplePool or {}

function EasyCursorTrails.StartLightningSparkEffect()
    EasyCursorTrails.StopLightningSparkEffect()

    EasyCursorTrails.lightningSparkTicker = C_Timer.NewTicker(0.05, function()
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not (profile and profile.enableLightningSparks) then return end

        local pool = EasyCursorTrails.trailPool
        if not pool or #pool == 0 then return end

        local mode = math.random(1, 4)

        local function getTrailByMode()
            -- ✅ Pick a random layer safely
            local layerIndex = math.random(1, #pool)
            local layer = pool[layerIndex]
            if not layer or #layer == 0 then return nil end

            local count = #layer

            -- ✅ Mode 1: pick from second half
            if mode == 1 and count >= 2 then
                local startIndex = math.max(1, math.floor(count / 2))
                return layer[math.random(startIndex, count)]

            -- ✅ Mode 2: pick from first half
            elseif mode == 2 and count >= 2 then
                local endIndex = math.max(1, math.floor(count / 2))
                return layer[math.random(1, endIndex)]

            -- ✅ Mode 3: pick topmost visible trail with decent size
            elseif mode == 3 then
                local sortedLayer = {}
                for _, trail in ipairs(layer) do
                    if trail:IsVisible() and trail.texture then
                        local w, h = trail.texture:GetSize()
                        if w > 4 and h > 4 then
                            table.insert(sortedLayer, trail)
                        end
                    end
                end

                table.sort(sortedLayer, function(a, b)
                    return (a:GetTop() or 0) > (b:GetTop() or 0)
                end)

                return sortedLayer[1] -- topmost valid trail or nil

            -- ✅ Mode 4 (fallback): pick any
            else
                return layer[math.random(1, count)]
            end
        end

        local trail = getTrailByMode()
        if trail and trail:IsVisible() then
            EasyCursorTrails.ApplyLightningSparkEffect(trail)
        end
    end)
end


function EasyCursorTrails.StopLightningSparkEffect()
    if EasyCursorTrails.lightningSparkTicker then
        EasyCursorTrails.lightningSparkTicker:Cancel()
        EasyCursorTrails.lightningSparkTicker = nil
    end

    if EasyCursorTrails.trailPool then
        for _, layer in ipairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(layer) do
                EasyCursorTrails.ClearLightningSparkEffect(trail)
            end
        end
    end
end


function EasyCursorTrails.ResetTrailTexture(trail)
    if not trail or not trail.texture then return end

    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    local startSize = tonumber(profile and profile.trailSizeStart) or EasyCursorTrails.defaults.trailSizeStart or 32

    local nativeW = trail.texture:GetWidth()
    local nativeH = trail.texture:GetHeight()

    -- 🛡️ Skip malformed or uninitialized textures
    if nativeW < 4 or nativeH < 4 then return end

    local scaleFactor = startSize / math.max(nativeW, nativeH)
    scaleFactor = math.min(math.max(scaleFactor, 0.5), 2.0) -- optional clamping

    trail.texture:SetTexCoord(0, 1, 0, 1)
    trail.texture:SetSize(nativeW, nativeH)

    -- 🧠 Only apply scale if it changed
    if trail._lastResetScale ~= scaleFactor then
        trail.texture:SetScale(scaleFactor)
        trail._lastResetScale = scaleFactor
    end

    trail.texture:ClearAllPoints()
    trail.texture:SetPoint("CENTER", trail, "CENTER")
end


function EasyCursorTrails.ClearLightningSparkEffect(trail)
    if not trail or not trail.lightningSpark then return end

    if trail.lightningSpark.ag then
        trail.lightningSpark.ag:Stop()
    end

    trail.lightningSpark:Hide()
    trail.lightningSpark:SetParent(nil)
    trail.lightningSpark = nil
end

function EasyCursorTrails.ApplyLightningSparkEffect(trail)
    if not trail or not trail.texture or not trail:IsVisible() then return end

    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    local startSize = tonumber(profile.trailSizeStart) or EasyCursorTrails.defaults.trailSizeStart or 32
    local endSize = tonumber(profile.trailSizeEnd) or EasyCursorTrails.defaults.trailSizeEnd or 48

    trail.texture:SetTexCoord(0, 1, 0, 1)
    local nativeW, nativeH = trail.texture:GetWidth(), trail.texture:GetHeight()
    local scaleFactor = startSize / math.max(nativeW, nativeH)

    trail.texture:SetSize(nativeW, nativeH)
    trail.texture:SetScale(scaleFactor)
    trail.texture:ClearAllPoints()
    trail.texture:SetPoint("CENTER", trail, "CENTER")

    local rawColor = profile.randomLightningSparkColor and EasyCursorTrails.GetRandomVibrantColor()
        or profile.lightningSparkColor or { r = 0.8, g = 0.9, b = 1, a = 1 }

    local color = {
        r = tonumber(rawColor.r) or 1,
        g = tonumber(rawColor.g) or 1,
        b = tonumber(rawColor.b) or 1,
        a = tonumber(rawColor.a) or 0.8
    }

    trail._nextSparkDelay = trail._nextSparkDelay or 0
    if GetTime() < (trail.lastSparkTime or 0) + trail._nextSparkDelay then return end
    trail.lastSparkTime = GetTime()
    trail._nextSparkDelay = math.random(10, 50) / 100

    local baseScale = endSize * 0.50
    local segmentLength = baseScale * 0.40
    local segmentCount = 10
    local angleSpread = 0.15
    local rootAngle = math.random() * 2 * math.pi

    for i = 1, segmentCount do
        local t = i / segmentCount
        local theta = rootAngle + (math.random() - 0.5) * angleSpread
        local dist = segmentLength * i
        local x, y = math.cos(theta) * dist, math.sin(theta) * dist
        local alpha = math.max(color.a * (1.0 - math.abs(t - 0.5) * 1.4), 0.6)
        local duration = math.random(15, 60) / 100

        local glow = tremove(EasyCursorTrails.sparkGlowPool) or CreateFrame("Frame", nil, trail)
        glow:SetSize(baseScale, baseScale)
        glow:SetPoint("CENTER", trail, "CENTER", x, y)
        glow:SetFrameStrata("HIGH")
        glow:SetFrameLevel(trail:GetFrameLevel() + 6)
        glow:SetParent(trail)
        glow:Show()

        local tex = glow.texture or glow:CreateTexture(nil, "OVERLAY")
        glow.texture = tex
        tex:ClearAllPoints()
        tex:SetAllPoints()
        tex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
        tex:SetBlendMode("ADD")
        tex:SetRotation(theta)
        tex:SetTexCoord(0, 1, 0, 1)
        tex:SetVertexColor(color.r, color.g, color.b, alpha)

        local ag = glow.animGroup or glow:CreateAnimationGroup()
        glow.animGroup = ag
        ag:Stop()
        ag:SetLooping("NONE")
        ag:SetScript("OnFinished", function()
            tex:SetTexture(nil)
            glow:SetParent(nil)
            glow:Hide()
            tinsert(EasyCursorTrails.sparkGlowPool, glow)
        end)

        local fade = ag.fade or ag:CreateAnimation("Alpha")
        ag.fade = fade
        fade:SetFromAlpha(1)
        fade:SetToAlpha(0)
        fade:SetDuration(duration)
        fade:SetOrder(1)
        ag:Play()

        -- Branch logic
        if math.random() < 0.10 then
            local branchAngle = theta + ((math.random() - 0.5) * math.pi)
            local branchCount = math.random(2, 3)
            local branchFactor = math.random(1.0, 1.4)

            for j = 1, branchCount do
                local bDist = segmentLength * j * branchFactor
                local bx, by = x + math.cos(branchAngle) * bDist, y + math.sin(branchAngle) * bDist
                local bAlpha = alpha * (1 - j / branchCount) ^ 1.3
                local branchDuration = duration + j * 0.08

                local branch = tremove(EasyCursorTrails.sparkBranchPool) or CreateFrame("Frame", nil, trail)
                branch:SetSize(baseScale * 0.15, baseScale * 0.15)
                branch:SetPoint("CENTER", trail, "CENTER", bx, by)
                branch:SetFrameStrata("HIGH")
                branch:SetFrameLevel(trail:GetFrameLevel() + 5)
                branch:SetParent(trail)
                branch:Show()

                local branchTex = branch.texture or branch:CreateTexture(nil, "OVERLAY")
                branch.texture = branchTex
                branchTex:ClearAllPoints()
                branchTex:SetAllPoints()
                branchTex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
                branchTex:SetBlendMode("ADD")
                branchTex:SetRotation(branchAngle)
                branchTex:SetTexCoord(0, 1, 0, 1)
                branchTex:SetVertexColor(color.r, color.g, color.b, bAlpha)

                local bag = branch.animGroup or branch:CreateAnimationGroup()
                branch.animGroup = bag
                bag:Stop()
                bag:SetLooping("NONE")
                bag:SetScript("OnFinished", function()
                    branchTex:SetTexture(nil)
                    branch:SetParent(nil)
                    branch:Hide()
                    tinsert(EasyCursorTrails.sparkBranchPool, branch)
                end)

                local bfade = bag.fade or bag:CreateAnimation("Alpha")
                bag.fade = bfade
                bfade:SetFromAlpha(1)
                bfade:SetToAlpha(0)
                bfade:SetDuration(branchDuration)
                bfade:SetOrder(1)
                bag:Play()
            end

            -- Ripple logic
            if math.random() < 0.6 then
                local ripple = tremove(EasyCursorTrails.sparkRipplePool) or CreateFrame("Frame", nil, trail)
                ripple:SetSize(32, 32)
                ripple:SetPoint("CENTER", trail, "CENTER", 0, 0)
                ripple:SetFrameStrata("HIGH")
                ripple:SetFrameLevel(trail:GetFrameLevel() + 7)
                ripple:SetParent(trail)
                ripple:Show()

                local tex = ripple.texture or ripple:CreateTexture(nil, "OVERLAY")
                ripple.texture = tex
                tex:ClearAllPoints()
                tex:SetAllPoints()
                tex:SetTexture("Interface\\Cooldown\\ping4")
                tex:SetBlendMode("ADD")
                tex:SetTexCoord(0, 1, 0, 1)
                tex:SetVertexColor(color.r, color.g, color.b, color.a)

                local ag = ripple.animGroup or ripple:CreateAnimationGroup()
                ripple.animGroup = ag
                ag:Stop()
                ag:SetLooping("NONE")
                ag:SetScript("OnFinished", function()
                    tex:SetTexture(nil)
                    ripple:SetParent(nil)
                    ripple:Hide()
                    tinsert(EasyCursorTrails.sparkRipplePool, ripple)
                end)

                local scale = ag.scale or ag:CreateAnimation("Scale")
                ag.scale = scale
                scale:SetScaleFrom(1, 1)
                scale:SetScaleTo(2.0, 2.0)
                scale:SetDuration(0.5)
                scale:SetOrder(1)

                local fade = ag.fade or ag:CreateAnimation("Alpha")
                ag.fade = fade
                fade:SetFromAlpha(1)
                fade:SetToAlpha(0)
                fade:SetDuration(0.4)
                fade:SetOrder(2)

                ag:Play()
            end
        end
    end
end




--=========================================================================================================
function EasyCursorTrails.GetRandomVibrantColor()
    local colors = {
        { r = 1, g = 0.5, b = 0.5, a = 0.6 }, -- soft red
        { r = 0.5, g = 1, b = 0.5, a = 0.6 }, -- soft green
        { r = 0.5, g = 0.5, b = 1, a = 0.6 }, -- soft blue
        { r = 1, g = 1, b = 0.5, a = 0.6 }, -- yellowish
        { r = 0.8, g = 0.5, b = 1, a = 0.6 }, -- purple
    }
    return colors[math.random(#colors)]
end





function EasyCursorTrails.HSVtoRGB(h, s, v, a)
    local r, g, b
    local i = math.floor(h * 6)
    local f = h * 6 - i
    local p = v * (1 - s)
    local q = v * (1 - f * s)
    local t = v * (1 - (1 - f) * s)
    i = i % 6
    if i == 0 then r, g, b = v, t, p
    elseif i == 1 then r, g, b = q, v, p
    elseif i == 2 then r, g, b = p, v, t
    elseif i == 3 then r, g, b = p, q, v
    elseif i == 4 then r, g, b = t, p, v
    elseif i == 5 then r, g, b = v, p, q end
    return { r = r, g = g, b = b, a = a or 1 }
end

--==========================================================================================



function EasyCursorTrails.ClearStarEmbersEffect(trail)
    if not trail or not trail.starEmber then return end

    if trail.starEmber.ag then
        trail.starEmber.ag:Stop()
    end

    trail.starEmber:Hide()
    trail.starEmber:SetParent(nil)
    trail.starEmber = nil
end


function EasyCursorTrails.StarDustTicker()
    EasyCursorTrails.StopDustTicker()

    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    EasyCursorTrails.SaveToCurrentProfile("enableStarEmbers", true)

    -- 🕒 Use profile-driven spawn rate
    local min = profile.starDustSpawnRateMin or 100
    local max = profile.starDustSpawnRateMax or 100

    EasyCursorTrails.starTicker = C_Timer.NewTicker(math.random(min, max) / 100, function()
        if not profile.enableStarEmbers then return end

        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    EasyCursorTrails.SpawnSparkles(trail)
                end
            end
        end
    end)
end



function EasyCursorTrails.StopDustTicker()
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if profile then
        EasyCursorTrails.SaveToCurrentProfile("enableStarEmbers", false)
    end

    if EasyCursorTrails.starTicker then
        EasyCursorTrails.starTicker:Cancel()
        EasyCursorTrails.starTicker = nil
    end
end


-- Initialize sparkle system
EasyCursorTrails.sparklePool = EasyCursorTrails.sparklePool or {}
EasyCursorTrails.activeSparkles = EasyCursorTrails.activeSparkles or {}
EasyCursorTrails.maxSparkles = 60

-- Track cursor velocity
local lastX, lastY = GetCursorPosition()
local function UpdateCursorVelocity()
    local x, y = GetCursorPosition()
    local dx, dy = x - lastX, y - lastY
    EasyCursorTrails.cursorVelocity = { x = dx, y = dy }
    lastX, lastY = x, y
end

-- Frame-based sparkle spawner
if not EasyCursorTrails.sparkleSpawner then
    EasyCursorTrails.sparkleSpawner = CreateFrame("Frame")
end

EasyCursorTrails.sparkleSpawner = EasyCursorTrails.sparkleSpawner or CreateFrame("Frame")

local lastX, lastY = GetCursorPosition()
EasyCursorTrails.sparkleSpawner:SetScript("OnUpdate", function()
    local x, y = GetCursorPosition()
    local dx, dy = x - lastX, y - lastY
    EasyCursorTrails.cursorVelocity = { x = dx, y = dy }
    lastX, lastY = x, y

    local speed = math.sqrt(dx * dx + dy * dy)
    if speed > 0.5 then
        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    EasyCursorTrails.SpawnSparkles(trail)
                end
            end
        end
    end
end)

-- Spawn sparkle with flicker and fade
function EasyCursorTrails.SpawnSparkles(trail)
    if not trail or not trail:IsVisible() then return end
    local profile = EasyCursorTrails.currentProfileTable
    if not profile or not profile.enableStarDust then return end
    if #EasyCursorTrails.activeSparkles >= EasyCursorTrails.maxSparkles then return end

    local trailSize = trail:GetWidth() or 15
    local baseScale = trailSize * 0.65
    local trailX, trailY = trail:GetCenter()
    if not trailX or not trailY then return end

    local sparkle = tremove(EasyCursorTrails.sparklePool) or CreateFrame("Frame", nil, UIParent)
    local tex = sparkle.texture or sparkle:CreateTexture(nil, "OVERLAY")
    sparkle.texture = tex

    local offsetX = (math.random() - 0.5) * trailSize
    local offsetY = (math.random() - 0.5) * trailSize
    local sparkleX = trailX + offsetX
    local sparkleY = trailY + offsetY

    local scaleMult = math.random(20, 60) / 100
    local sparkleSize = baseScale * scaleMult
    local alpha = math.min(0.6 + scaleMult * 0.4, 1)

    sparkle:SetPoint("CENTER", UIParent, "BOTTOMLEFT", sparkleX, sparkleY)
    sparkle:SetSize(sparkleSize, sparkleSize)
    sparkle:SetFrameStrata("LOW")
    sparkle:SetFrameLevel((trail:GetFrameLevel() or 2) + 1)
    sparkle:Show()

    tex:SetAllPoints()
    tex:SetBlendMode("ADD")
    tex:SetTexture("Interface\\Cooldown\\star4")
    tex:SetTexCoord(0.2, 0.8, 0.2, 0.8)
    tex:SetRotation(math.random() * 0.25)

    local color = profile.randomStarDustColor and EasyCursorTrails.GetRandomVibrantColor()
        or profile.starDustColor
        or EasyCursorTrails.GetDefaultColor("starDustColor") or { r = 1, g = 1, b = 1, a = 0.8 }

    tex:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha)
    tex:SetAlpha(alpha)

    -- Directional trailing drift
    local velocity = EasyCursorTrails.cursorVelocity or { x = 0, y = 0 }
    local magnitude = math.max(math.sqrt(velocity.x^2 + velocity.y^2), 1)
    local normX = -velocity.x / magnitude
    local normY = -velocity.y / magnitude

    local driftDist = math.random(1, 3)
    local driftX = normX * driftDist
    local driftY = normY * driftDist
    local driftDur = 0.6 + math.random() * 0.2

    -- Animation group
    local ag = sparkle.animationGroup or sparkle:CreateAnimationGroup()
    sparkle.animationGroup = ag
    ag:Stop()
    ag:SetLooping("NONE")
    ag:SetScript("OnFinished", function()
        sparkle:Hide()
        tex:SetAlpha(0)
        tinsert(EasyCursorTrails.sparklePool, sparkle)
        EasyCursorTrails.activeSparkles[sparkle] = nil
    end)

    for _, anim in ipairs(ag:GetAnimations() or {}) do anim:Stop() end

    local drift = ag:CreateAnimation("Translation")
    drift:SetOffset(driftX, driftY)
    drift:SetDuration(driftDur)
    drift:SetOrder(1)
    drift:SetSmoothing("IN_OUT")

    local rotate = ag:CreateAnimation("Rotation")
    rotate:SetDegrees(math.random(-15, 15))
    rotate:SetDuration(driftDur)
    rotate:SetOrder(2)
    rotate:SetSmoothing("IN_OUT")

    local fade = ag:CreateAnimation("Alpha")
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0)
    fade:SetDuration(0.3)
    fade:SetStartDelay(driftDur - 0.3)
    fade:SetOrder(3)
    fade:SetSmoothing("OUT")

    -- Flicker while fading
    local twinkleAg = tex.twinkleAg or tex:CreateAnimationGroup()
    tex.twinkleAg = twinkleAg
    twinkleAg:Stop()
    twinkleAg:SetLooping("NONE")

    for _, anim in ipairs(twinkleAg:GetAnimations() or {}) do anim:Stop() end

    local flickerCount = math.floor(driftDur / 0.13)
    for i = 1, flickerCount do
        local flickerIn = twinkleAg:CreateAnimation("Alpha")
        flickerIn:SetFromAlpha(alpha * 0.6)
        flickerIn:SetToAlpha(alpha)
        flickerIn:SetDuration(0.05)
        flickerIn:SetOrder(i * 2 - 1)

        local flickerOut = twinkleAg:CreateAnimation("Alpha")
        flickerOut:SetFromAlpha(alpha)
        flickerOut:SetToAlpha(alpha * 0.2)
        flickerOut:SetDuration(0.08)
        flickerOut:SetOrder(i * 2)
    end

    twinkleAg:SetScript("OnFinished", function()
        tex:SetAlpha(0)
    end)

    twinkleAg:Play()
    ag:Play()
    EasyCursorTrails.activeSparkles[sparkle] = true
end




--==========================================================================================
function EasyCursorTrails.ClearNatureEmbersEffect(trail)
    if not trail or not trail.natureEmbers then return end

    for _, ember in ipairs(trail.natureEmbers) do
        if ember.ag then ember.ag:Stop() end
        ember:Hide()
        ember:SetParent(nil)
    end

    trail.natureEmbers = nil
end



function EasyCursorTrails.StartNatureTicker()
   --test")
    if EasyCursorTrails.lightningTicker then
      
        EasyCursorTrails.lightningTicker:Cancel()
    end

    EasyCursorTrails.lightningTicker = C_Timer.NewTicker(0.25, function()
        local profile = EasyCursorTrails.currentProfileTable 
                     or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile or not profile.enableSpringSeasonTrails then return end


        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    local nowX, nowY = trail:GetCenter()
                    local last = trail._lastPos or { x = nowX, y = nowY }

                    if nowX and nowY and (math.abs(nowX - last.x) > 0.5 or math.abs(nowY - last.y) > 0.5) then
                        
                        EasyCursorTrails.SpawnNatureEmbersAt(last.x, last.y, trail:GetWidth(), trail)

                    end

                    trail._lastPos = { x = nowX, y = nowY }
                end
            end
        end
    end)
end


function EasyCursorTrails.SpawnNatureEmbersAt(centerX, centerY, baseScale, trail)
    EasyCursorTrails.SpawnNatureEmbers(
        baseScale,
        centerX,
        centerY,
        0,    -- offsetX
        0,    -- offsetY
        trail -- pass trail for tracking
    )
end



function EasyCursorTrails.StopNatureTicker()
  
    if EasyCursorTrails.lightningTicker then
        EasyCursorTrails.lightningTicker:Cancel()
        EasyCursorTrails.lightningTicker = nil
    end
end

function EasyCursorTrails.SpawnNatureEmbers(baseScale, baseX, baseY, offsetX, offsetY, trail)
    local profile = EasyCursorTrails.currentProfileTable
                 or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    local color = profile.randomLightningColor and EasyCursorTrails.GetRandomVibrantColor()
               or profile.lightningEmberColor or { r = 0.8, g = 0.9, b = 1, a = 0.8 }

    local emberX = baseX + offsetX + (math.random() - 0.5) * 10
    local emberY = baseY + offsetY + (math.random() - 0.5) * 8

    for _ = 1, math.random(1, 2) do
        if math.random() < 0.3 then
            local sizeMult = math.random(30, 60) / 100
            local emberLength = baseScale * sizeMult * 2.5
            local emberWidth  = baseScale * sizeMult * 2.5
            local alpha = math.min(0.7 + sizeMult * 0.6, 1.0)

            local spark = CreateFrame("Frame", nil, UIParent)
            spark:SetPoint("CENTER", UIParent, "BOTTOMLEFT", emberX, emberY)
            spark:SetSize(emberLength, emberWidth)
            spark:SetFrameStrata("TOOLTIP")
            spark:SetFrameLevel(20)
            spark:Show()

            local tex = spark:CreateTexture(nil, "OVERLAY")
            tex:SetAllPoints()
            local leafTextures = {
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Petal.blp",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Petal2.blp",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Red_Rose.blp",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf1.tga",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Leaf3.tga",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Dandelion.blp",
                "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\flower1.blp"
            }
            tex:SetTexture(leafTextures[math.random(#leafTextures)])
            tex:SetBlendMode("ADD")
            tex:SetVertexColor(color.r * 1.2, color.g * 1.2, color.b * 1.2, alpha)
            tex:SetRotation(math.random() * 2 * math.pi)

            local ag = spark:CreateAnimationGroup()
            spark.ag = ag -- ✅ store for cleanup
            ag:SetLooping("NONE")
            ag:SetScript("OnFinished", function()
                spark:Hide()
                tex:SetTexture(nil)
                tex:SetParent(nil)
                spark:SetParent(nil)
            end)

            local driftAngle = math.random() * 2 * math.pi
            local driftDist = math.random(24, 56)
            local driftX = math.cos(driftAngle) * driftDist
            local driftY = math.sin(driftAngle) * driftDist

            local drift = ag:CreateAnimation("Translation")
            drift:SetOffset(driftX, driftY)
            drift:SetDuration(2.0)
            drift:SetOrder(1)
            drift:SetSmoothing("IN_OUT")

            local fade = ag:CreateAnimation("Alpha")
            fade:SetFromAlpha(alpha)
            fade:SetToAlpha(0)
            fade:SetDuration(2.0)
            fade:SetOrder(1)
            fade:SetSmoothing("IN_OUT")

            local rotate = ag:CreateAnimation("Rotation")
            rotate:SetDegrees((math.random() - 0.5) * 80)
            rotate:SetDuration(2.0)
            rotate:SetOrder(1)
            rotate:SetSmoothing("IN_OUT")

            local pulse = ag:CreateAnimation("Scale")
            pulse:SetScaleFrom(1.0, 1.0)
            pulse:SetScaleTo(1.05, 0.95)
            pulse:SetDuration(0.4)
            pulse:SetOrder(1)
            pulse:SetSmoothing("IN_OUT")

            ag:Play()

            -- ✅ Register ember to trail
            if trail then
                trail.natureEmbers = trail.natureEmbers or {}
                table.insert(trail.natureEmbers, spark)
            end
        end
    end
end




--==========================================================================================


--==========================================================================================

function EasyCursorTrails.ClearTrailShadowEffect(trail)
    if not trail or not trail.shadowFrame then return end

    local frame = trail.shadowFrame

    -- Hide and clear offset texture
    if frame.offsetTex then
        frame.offsetTex:Hide()
        frame.offsetTex:SetTexture(nil)
        frame.offsetTex:SetParent(nil)
        frame.offsetTex = nil
    end

    -- Hide and clear glow texture
    if frame.glowTex then
        frame.glowTex:Hide()
        frame.glowTex:SetTexture(nil)
        frame.glowTex:SetParent(nil)
        frame.glowTex = nil
    end

    frame:Hide()
    frame:SetParent(nil)
    trail.shadowFrame = nil

    -- Clear metadata
    trail._lastShadowPos = nil
    trail._shadowIdleTime = nil
    trail._lastShadowScale = nil
end


function EasyCursorTrails.SpawnTrailShadow(trail)
    if not trail or not trail.texture then return end

    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableTrailShadows then return end

    if not trail.shadowFrame then
        local frame = CreateFrame("Frame", nil, UIParent)
        frame:SetSize(trail:GetWidth(), trail:GetHeight())
        frame:SetFrameStrata("BACKGROUND")
        frame:SetFrameLevel(0)

        local offsetTex = frame:CreateTexture(nil, "BACKGROUND")
        offsetTex:SetPoint("CENTER", frame, "CENTER")
        offsetTex:SetTexture(trail.texture:GetTexture())
        offsetTex:SetBlendMode("BLEND")

        local glowTex = frame:CreateTexture(nil, "BACKGROUND")
        glowTex:SetPoint("CENTER", frame, "CENTER")
        glowTex:SetTexture(trail.texture:GetTexture())
        glowTex:SetBlendMode("ADD")

        frame.offsetTex = offsetTex
        frame.glowTex = glowTex

        trail.shadowFrame = frame
        trail._lastShadowPos = { x = 0, y = 0 }
        trail._shadowIdleTime = 0
        trail._lastShadowScale = trail:GetScale()
    end

    trail:SetScript("OnUpdate", function(self, elapsed)
        local shadow = self.shadowFrame
        if not shadow or not shadow.offsetTex or not shadow.glowTex then return end

        local profile = EasyCursorTrails.currentProfileTable
            or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile or not profile.enableTrailShadows then
            shadow:Hide()
            return
        end

        if not self:IsVisible() or (self.texture:GetAlpha() or 0) <= 0.01 then
            shadow:Hide()
            return
        end

        local trailX, trailY = self:GetCenter()
        if not trailX or not trailY then return end

        local last = self._lastShadowPos or { x = trailX, y = trailY }
        self._shadowIdleTime = (self._shadowIdleTime or 0) + elapsed

        local dx = trailX - last.x
        local dy = trailY - last.y
        local moved = math.abs(dx) > 0.5 or math.abs(dy) > 0.5
        local idleFadeFactor = moved and 1 or math.max(0, 1 - self._shadowIdleTime * 1.8)

        if moved then
            self._lastShadowPos = { x = trailX, y = trailY }
            self._shadowIdleTime = 0
        end

        local angle = math.atan2(dy, dx)
        shadow.offsetTex:SetRotation(angle)
        shadow.glowTex:SetRotation(angle)

        local screenHeight = UIParent:GetHeight()
        local trailYRatio = math.max(0, math.min(1, trailY / screenHeight))
        local dropOffset = math.max(0, math.min(350, trailYRatio * 350))
        local baseOffset = 5

        local isTilting = IsMouseButtonDown("RightButton")
        local tiltFade = isTilting and 0.5 or 1.0
        local shadowDarknessFactor = 1 - trailYRatio
        local alphaBoost = 1.0 + shadowDarknessFactor * 0.5
        local offsetAlpha = 0.13 * idleFadeFactor * tiltFade * alphaBoost
        local glowAlpha   = 0.18 * idleFadeFactor * tiltFade * alphaBoost

        -- Smooth interpolation helper
        local function Lerp(a, b, t)
            return a + (b - a) * t
        end

        local trailScale = self:GetScale() or 1
        local shrinkFactor = 1 - (1 - idleFadeFactor) * 0.3
        local upwardBoost = (dy > 1) and (1 + 0.6 * trailYRatio) or 1.0
        local targetScale = trailScale * shrinkFactor

        if dy < -1 then
            -- Smoothly shrink when descending
            self._lastShadowScale = Lerp(self._lastShadowScale or trailScale, targetScale, math.min(1, elapsed * 6))
        else
            -- Snap or expand upward
            self._lastShadowScale = trailScale * shrinkFactor * upwardBoost
        end

        local maxShadowScale = self._lastShadowScale or trailScale

        local w, h = trail:GetWidth(), trail:GetHeight()
        shadow.offsetTex:SetSize(w * maxShadowScale, h * maxShadowScale)
        shadow.glowTex:SetSize(w * maxShadowScale, h * maxShadowScale)

        local color = profile.randomShadowColor and EasyCursorTrails.GetRandomVibrantColor()
            or profile.shadowTrailColor or { r = 0, g = 0, b = 0, a = 0.4 }
        shadow.offsetTex:SetVertexColor(color.r * 0.5, color.g * 0.5, color.b * 0.5, offsetAlpha)
        shadow.glowTex:SetVertexColor(color.r * 1.1, color.g * 1.1, color.b * 1.1, glowAlpha)

        shadow:SetPoint("CENTER", UIParent, "BOTTOMLEFT", trailX - baseOffset, trailY - (baseOffset + dropOffset))

        shadow:Show()
    end)
end

--==========================================================================================

function EasyCursorTrails.ClearEmberEffect(trail)
    if not trail or not trail.ember then return end

    if trail.ember.ag then
        trail.ember.ag:Stop()
    end

    trail.ember:Hide()
    trail.ember:SetParent(nil)
    trail.ember = nil
end

function EasyCursorTrails.StartEmberTicker()
    if EasyCursorTrails.emberTicker then
        EasyCursorTrails.emberTicker:Cancel()
    end

    EasyCursorTrails.emberTicker = C_Timer.NewTicker(0.25, function()
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile or not profile.enableEmbers then return end

        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    EasyCursorTrails.SpawnEmberEffect(trail)
                end
            end
        end
    end)
end


function EasyCursorTrails.StopEmberTicker()
    if EasyCursorTrails.emberTicker then
        EasyCursorTrails.emberTicker:Cancel()
        EasyCursorTrails.emberTicker = nil
    end
end


function EasyCursorTrails.SpawnEmberEffect(trail)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    -- 🧯 Stop early if embers are disabled or trail isn't visible enough
    if not profile.enableEmbers or not trail:IsVisible() or trail:GetAlpha() < 0.1 then return end

    -- 🎯 Gather trail dimensions and position
    local trailSize = trail:GetWidth() or 15
    local baseScale = trailSize * 0.9

    local trailX, trailY = trail:GetCenter()
    if not trailX or not trailY then return end -- 🛡️ Prevent nil crash

    -- 🌠 Randomized ember offset
    local offsetX = (math.random() - 0.5) * trailSize * 0.4
    local offsetY = (math.random() - 0.5) * trailSize * 0.4

    local baseX = trailX
    local baseY = trailY

    -- 🧪 Optional debugging: Log spawn origin
    -- --print("Spawning Ember at:", baseX + offsetX, baseY + offsetY)

    EasyCursorTrails.SpawnEmbers(trail, baseScale, baseX, baseY, offsetX, offsetY)
end


function EasyCursorTrails.SpawnEmbers(trail, baseScale, baseX, baseY, offsetX, offsetY)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    local color = profile.randomEmberColor and EasyCursorTrails.GetRandomVibrantColor()
        or profile.emberColor
        or { r = 1, g = 0.4, b = 0.1, a = 0.8 }

    local emberX = baseX + offsetX + (math.random() - 0.5) * 16
    local emberY = baseY + offsetY + (math.random() - 0.5) * 12


    for _ = 1, math.random(1, 2) do
        if math.random() < 0.3 then
            local sizeMult = math.random(20, 50) / 100
            local emberSize = baseScale * sizeMult
            local alpha = math.min(0.9 + sizeMult * 0.5, 0.8)

            local ember = CreateFrame("Frame", nil, UIParent)
            ember:SetPoint("CENTER", UIParent, "BOTTOMLEFT", emberX, emberY)
            ember:SetSize(emberSize, emberSize)
            ember:SetFrameStrata("BACKGROUND")
            ember:SetFrameLevel(1)

            local tex = ember:CreateTexture(nil, "OVERLAY")
            tex:SetAllPoints()
            tex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
            tex:SetBlendMode("ADD")
            tex:SetVertexColor(color.r, color.g, color.b, alpha)

            local ag = ember:CreateAnimationGroup()
            ag:SetLooping("NONE")
            ag:SetScript("OnFinished", function()
                ember:Hide()
                tex:SetTexture(nil)
                tex:SetParent(nil)
                ember:SetParent(nil)
            end)

            local driftAngle = math.random() * 2 * math.pi
            local driftDistance = math.random(8, 50)
            local driftX = math.cos(driftAngle) * driftDistance
            local driftY = math.sin(driftAngle) * driftDistance

            local drift = ag:CreateAnimation("Translation")
            drift:SetOffset(driftX, driftY)
            drift:SetDuration(2.0)
            drift:SetOrder(1)
            drift:SetSmoothing("OUT")

            local fade = ag:CreateAnimation("Alpha")
            fade:SetFromAlpha(alpha)
            fade:SetToAlpha(0)
            fade:SetDuration(0.3)
            fade:SetOrder(2)
            fade:SetSmoothing("IN")

            local rotate = ag:CreateAnimation("Rotation")
            rotate:SetDegrees((math.random() - 0.5) * 90)
            rotate:SetDuration(0.3)
            rotate:SetOrder(3)
            rotate:SetSmoothing("OUT")

            ag:Play()
        end
    end
end


--===============================================================================================
EasyCursorTrails.fireFlamePool = EasyCursorTrails.fireFlamePool or {}

-- 🔥 Cleanup Fire Glow
function EasyCursorTrails.ClearFireGlow(trail)
    if not trail then return end
    for _, region in pairs({ trail:GetChildren() }) do
        local tex = region:GetRegions()
        if tex and tex:GetTexture() == "Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64" then
            region:Hide()
            tex:SetTexture(nil)
            tex:SetParent(nil)
            region:SetParent(nil)
        end
    end
end

-- 🔥 Check if Fire is enabled
function EasyCursorTrails.IsFireEnabled()
    local profile = EasyCursorTrails.GetCurrentProfile()
    return profile and profile.enableFire == true
end


-- 🔥 Start Fire Ticker
function EasyCursorTrails.StartFireTicker()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableFire then return end

    -- 🧼 Cancel any existing ticker
    if EasyCursorTrails.fireEffectTicker then
        EasyCursorTrails.fireEffectTicker:Cancel()
        EasyCursorTrails.fireEffectTicker = nil
    end

    -- 🧹 Clear lingering fire visuals before starting
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            EasyCursorTrails.ClearFireGlow(trail)
        end
    end

    -- 🔥 Start new ticker
    EasyCursorTrails.fireEffectTicker = C_Timer.NewTicker(0.2, function()
        for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(layerPool) do
                if trail:IsVisible() then
                    local color = profile.randomFireColor and EasyCursorTrails.GetRandomVibrantColor()
                                or profile.fireColor or { r = 1, g = 0.5, b = 0.1, a = 0.8 }
                    EasyCursorTrails.SpawnFireGlow(trail, color)
                end
            end
        end
    end)
end

-- 🔥 Stop Fire Ticker and Clear Visuals
function EasyCursorTrails.StopFireTicker()
    -- 🧼 Cancel active ticker
    if EasyCursorTrails.fireEffectTicker then
        EasyCursorTrails.fireEffectTicker:Cancel()
        EasyCursorTrails.fireEffectTicker = nil
    end

    -- 🧹 Clear fire glow from all visible trails
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            if trail and trail:IsVisible() then
                EasyCursorTrails.ClearFireGlow(trail)
            end
        end
    end
end


-- 🔥 Spawn Fire Glow
function EasyCursorTrails.SpawnFireGlow(trail, color)
    if not trail or not trail.texture or not trail:IsVisible() then return end

    local trailX, trailY = trail:GetCenter()
    if not trailX or not trailY then return end

    local dx = trail:GetLeft() - (trail.lastX or trail:GetLeft())
    local dy = trail:GetTop() - (trail.lastY or trail:GetTop())
    trail.lastX, trail.lastY = trail:GetLeft(), trail:GetTop()
    local angle = math.atan2(dy, dx)

    local trailSize = math.max(trail:GetWidth() or 0, 1)
    local baseScale = trailSize * 0.9
    local offsetX = -math.cos(angle) * trailSize * 0.1 + (math.random() - 0.5) * trailSize * 0.2
    local offsetY = -math.sin(angle) * trailSize * 0.2 + (math.random() - 0.5) * trailSize * 0.3

    EasyCursorTrails.SpawnFireBurst(trail, baseScale, offsetX, offsetY, color)
end

-- 🔥 Spawn Fire Burst Layers
function EasyCursorTrails.SpawnFireBurst(trail, baseScale, offsetX, offsetY, color)
    for i = 1, 3 do -- 🔽 Reduced from 3 to 2 layers
        local flame = tremove(EasyCursorTrails.fireFlamePool) or CreateFrame("Frame", nil, trail)

        local scaleFactor = baseScale * (0.2 + i * 0.3) -- 🔽 Smaller flame sizes
        flame:SetSize(scaleFactor, scaleFactor)
        flame:SetPoint("CENTER", trail, "CENTER", offsetX, offsetY + (i - 1.5) * baseScale * 0.08)
        flame:SetFrameStrata("HIGH") -- 🔽 Lowered from HIGH
        flame:SetFrameLevel(trail:GetFrameLevel() + 1 + i)

        local tex = flame:CreateTexture(nil, "OVERLAY")
        tex:SetAllPoints()
        tex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
        tex:SetBlendMode("ADD")
        tex:SetVertexColor(color.r, color.g, color.b, color.a * (0.6 - (i - 1) * 0.15)) -- 🔽 Lower alpha
        tex:SetTexCoord(0.35, 0.65, 0.1, 0.9)

        local group = flame:CreateAnimationGroup()
        group:SetLooping("NONE")
        group:SetScript("OnFinished", function()
            tex:SetTexture(nil)
            tex:SetParent(nil)
            flame:SetParent(nil)
            tinsert(EasyCursorTrails.fireFlamePool, flame)
        end)

        local drift = group:CreateAnimation("Translation")
        drift:SetOffset((math.random() - 0.5) * 6, math.random(6, 10)) -- 🔽 Softer drift
        drift:SetDuration(0.3 + i * 0.05) -- 🔽 Shorter duration
        drift:SetOrder(1)

        local fade = group:CreateAnimation("Alpha")
        fade:SetFromAlpha(1)
        fade:SetToAlpha(0)
        fade:SetDuration(0.4 + i * 0.05) -- 🔽 Faster fade
        fade:SetOrder(2)

        group:Play()
    end
end


--===============================================================================================

--=======================================================================================================


function EasyCursorTrails.ClearSmokeEffect(trail)
    if not trail or not trail.smokeEffects then return end

    for _, smoke in ipairs(trail.smokeEffects) do
        if smoke.ag then
            smoke.ag:Stop()
        end
        smoke:Hide()
        smoke:SetParent(nil)
    end

    trail.smokeEffects = nil
end

EasyCursorTrails.smokeTickerRunning = false


function EasyCursorTrails.StartSmokeTicker()
    if EasyCursorTrails.smokeTickerRunning or EasyCursorTrails.isPreviewing then return end

    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableSmokeEffect then return end

    EasyCursorTrails.smokeTickerRunning = true  -- ✅ Only set if we're actually starting

    EasyCursorTrails.smokeTicker = C_Timer.NewTicker(0.18, function()
        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    EasyCursorTrails.SpawnSmokeTrail(trail)
                end
            end
        end
    end)
end


function EasyCursorTrails.StopSmokeTicker()
    if EasyCursorTrails.smokeTicker then
        EasyCursorTrails.smokeTicker:Cancel()
        EasyCursorTrails.smokeTicker = nil
        EasyCursorTrails.smokeTickerRunning = false
    end
end


function EasyCursorTrails.SpawnSmokeTrail(trail)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableSmokeEffect or not trail:IsVisible() then return end
    if EasyCursorTrails.isPreviewing then return end -- 🚫 Skip during preview

    local trailSize = trail:GetWidth() or 15
    local baseScale = trailSize * 0.70
    local trailX, trailY = trail:GetCenter()
    if not trailX or not trailY then return end

    local offsetX = (math.random() - 0.5) * trailSize * 0.2
    local offsetY = (math.random() - 0.5) * trailSize * 0.2

    EasyCursorTrails.SpawnSmokeEffect(trail, baseScale, trailX, trailY, offsetX, offsetY)
end



function EasyCursorTrails.SpawnSmokeEffect(trail, baseScale, baseX, baseY, offsetX, offsetY)
    local profile = EasyCursorTrails.currentProfileTable or (EasyCursorTrailsDB and EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile])
    if not profile then return end

    local color = profile.randomSmokeColor and EasyCursorTrails.GetRandomVibrantColor()
        or profile.smokeColor or { r = 0.129, g = 0.121, b = 0.117, a = 0.45 }

    if not (color.r and color.g and color.b and color.a) then
        --EasyCursorTrails.HandleError"SmokeEffect: Invalid color format.")
        return
    end

    local puffCount = math.random(3, 5)
    for layer = 1, 2 do
        for i = 1, puffCount do
            local smokeX = baseX + offsetX + (math.random() - 0.5) * 10 + (layer - 1) * 4
            local smokeY = baseY + offsetY + (math.random() - 0.5) * 10 + (layer - 1) * 4
            local puffSize = baseScale * math.random(1.4, 2.4) * (1 + layer * 0.1)

            local puff = CreateFrame("Frame", nil, UIParent)
            puff:SetPoint("CENTER", UIParent, "BOTTOMLEFT", smokeX, smokeY)
            puff:SetSize(puffSize, puffSize)
            puff:SetFrameStrata("MEDIUM")
            puff:SetFrameLevel(2)

            local tex = puff:CreateTexture(nil, "OVERLAY")
            tex:SetAllPoints()
            tex:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
            tex:SetBlendMode("BLEND")
            tex:SetVertexColor(color.r, color.g, color.b, color.a)
            tex:SetRotation(math.rad(math.random(0, 360)))
            tex:SetTexCoord(0, 1, 0, 1)

            local ag = puff:CreateAnimationGroup()
            ag:SetLooping("NONE")
            ag:SetScript("OnFinished", function()
                puff:Hide()
                tex:SetTexture(nil)
            end)

            -- 🎯 Velocity-based drift blending
            local velocity = EasyCursorTrails.cursorVelocity or { x = 0, y = 0 }
            local magnitude = math.sqrt(velocity.x^2 + velocity.y^2)
            if magnitude == 0 then magnitude = 1 end

            local normX = velocity.x / magnitude
            local normY = velocity.y / magnitude

            local randomAngle = math.random() * 2 * math.pi
            local randX = math.cos(randomAngle)
            local randY = math.sin(randomAngle)

            local blendFactor = 0.4 -- 0 = pure random, 1 = pure velocity
            local finalX = (1 - blendFactor) * randX + blendFactor * normX
            local finalY = (1 - blendFactor) * randY + blendFactor * normY + 0.5 -- upward lift

            local driftDistance = math.random(8, 24)
            local driftX = finalX * driftDistance
            local driftY = finalY * driftDistance

            local duration = math.random(1.1, 1.4)

            local move = ag:CreateAnimation("Translation")
            move:SetOffset(driftX, driftY)
            move:SetDuration(duration)
            move:SetOrder(1)

            local fade = ag:CreateAnimation("Alpha")
            fade:SetFromAlpha(color.a)
            fade:SetToAlpha(0)
            fade:SetDuration(duration)
            fade:SetOrder(1)

            local rotate = ag:CreateAnimation("Rotation")
            rotate:SetDegrees((math.random() - 0.5) * 30)
            rotate:SetDuration(duration)
            rotate:SetOrder(1)

            local grow = ag:CreateAnimation("Scale")
            grow:SetScale(1.3, 1.3)
            grow:SetDuration(duration)
            grow:SetOrder(1)

            ag:Play()
        end
    end
end



--=================================================================================================

-- 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
}


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 = "Spiral" },                 -- Index 9
    { text = "Radial Burst" },                 -- Index 10
    { text = "Vortex Spiral" },                 -- Index 11
    { text = "Oscillating Swirl" },                 -- Index 12
    { text = "Drifting Fog" },                 -- Index 13
    { text = "Counter Wave" },                 -- Index 14
    { text = "Chaotic Jab" },                 -- Index 15
    { text = "Heartbeat Pulse" },                 -- Index 16
    { text = "Pendulum Swing" },                 -- Index 17
    { text = "Elliptical Orbit" },                 -- Index 18
    { text = "Rising Spiral" },                 -- Index 19
    { text = "Cosmic Ripple" },                 -- Index 20
   
}

StaticPopupDialogs["EASYCURSORTRAILS_TEXT_INPUT"] = {
    text = "Enter new profile name:",
    button1 = "OK",
    button2 = "Cancel",
    hasEditBox = true,
    maxLetters = 100,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,

    OnAccept = function(self)
        local popupName = self:GetName()  -- e.g., "StaticPopup1"
        local editBox = _G[popupName .. "EditBox"]
        local text = editBox and editBox:GetText() or ""

        if EasyCursorTrails._onTextInputAccept then
            EasyCursorTrails._onTextInputAccept(text)
            EasyCursorTrails._onTextInputAccept = nil
        end
    end,

    EditBoxOnEnterPressed = function(self)
        local parent = self:GetParent()
        local text = self:GetText()

        if EasyCursorTrails._onTextInputAccept then
            EasyCursorTrails._onTextInputAccept(text)
            EasyCursorTrails._onTextInputAccept = nil
        end

        parent:Hide()
    end,

    EditBoxOnEscapePressed = function(self)
        self:GetParent():Hide()
    end,
}


-- A small helper to get a profile value or default
local function getValueOrDefault(profileTable, key, defaultsTable)
    local val = profileTable[key]
    if val == nil then
        val = defaultsTable[key]
        --print(("EasyCursorTrails: '%s' not found in profile. Using default value."):format(key))
    end
    return val
end

function EasyCursorTrails.ValidateProfile(profile)
    if type(profile) ~= "table" then return end

    -- 🔍 All expected profile keys (toggles + random flags)
    local expectedFlags = {
        "connectTrails",

        "enableEmbers",               "randomEmberColor",
        "enableFire",                 "randomFireColor",
        "enableLightningEmbers",     "randomLightningColor",
        "enableLightningSparks",     "randomLightningSparkColor",
        "enableSmokeEffect",         "randomSmokeColor",
        "enableSmokeEffectTrails",   "randomSmokeTrailColor",
        "enableSpringSeason",        "randomSpringSeasonColor",
        "enableSpringSeasonTrails",  "randomSpringSeasonTrailColor",
        "enableStarDust",            "randomStarDustColor",
        "enableStarEmbers",          "randomStarEmberColor",
        "enableStaticArc",           "randomStaticArcColor",
        "enableTrailShadows",        "randomShadowColor",
        "enableTwinkleStars",        "randomTwinkleStarsColor",
    }

    local missing = {}

    for _, key in ipairs(expectedFlags) do
        if profile[key] == nil then
            table.insert(missing, key)
            -- Optional auto-correction:
            -- profile[key] = false
        end
    end

    if #missing > 0 then
        -- print("🛑 Missing profile flags:")
        for _, key in ipairs(missing) do
            -- print("  •", key)
        end
    else
        -- print("✅ Profile validation passed. All expected flags are present.")
    end
end



-- 🔄 Trail Shadows
function EasyCursorTrails.RefreshAllTrailShadows()
    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableTrailShadows then return end

    if not EasyCursorTrails.trailPool then return end

    for _, layerPool in pairs(EasyCursorTrails.trailPool) do
        for _, trail in ipairs(layerPool) do
            -- Force rebuild: remove old shadow frame
            if trail.shadowFrame then
                trail.shadowFrame:Hide()
                trail.shadowFrame:SetParent(nil)
                trail.shadowFrame = nil
            end

            -- Reapply shadow logic
            EasyCursorTrails.SpawnTrailShadow(trail)
        end
    end
end


-- 🔥 Fire Trails
function EasyCursorTrails.RefreshAllFireEffects()
    EasyCursorTrails.StopFireTicker()
    EasyCursorTrails.StartFireTicker()
end

-- 🌸 Spring Season Trails
function EasyCursorTrails.RefreshSpringSeasonEffects()
    EasyCursorTrails.StopNatureTicker()

    -- Reset trail position tracking for fresh ember spawning
    if EasyCursorTrails.trailPool then
        for _, pool in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(pool) do
                trail._lastPos = nil
            end
        end
    end

    EasyCursorTrails.StartNatureTicker()
end

--- ⚡ Lightning Sparks
function EasyCursorTrails.RefreshLightningVisuals()
  for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
    for _, trail in ipairs(pool) do
      if trail:IsVisible() then
        EasyCursorTrails.ClearLightningSparkEffect(trail)
        EasyCursorTrails.ApplyLightningSparkEffect(trail)
      end
    end
  end
end

--- 💨 Smoke Trails
function EasyCursorTrails.RefreshSmokeTrails()
    EasyCursorTrails.StopSmokeTicker()
    EasyCursorTrails.StartSmokeTicker()
    
end

function EasyCursorTrails.RefreshStaticArcTrails()
    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableStaticArcTrails then return end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for index, trail in ipairs(pool) do
            if trail:IsVisible() then
                -- 🧼 Clear old arc visuals
                EasyCursorTrails.ClearStaticArcEffect(trail)

                -- ⚡ Apply static arc effect
                EasyCursorTrails.ApplyStaticArcEffect(trail, index, profile.staticArcColor)

                -- ✨ Optional: Apply twinkle stars
                if profile.enableTwinkleStars then
                    EasyCursorTrails.ApplyTwinkleStarsEffect(trail, index, profile.twinkleIntensity or 1.0)
                end
            end
        end
    end
end


--- 🔥 Ember Trails
function EasyCursorTrails.RefreshEmberTrails()
    EasyCursorTrails.StopEmberTicker()
    EasyCursorTrails.StartEmberTicker()
    
end


-- ✨ Twinkle Stars
function EasyCursorTrails.RefreshTwinkleStarsEffects()
    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for i, trail in ipairs(pool) do
            if trail:IsVisible() then
                if not profile.enableTwinkleStars then
                    -- Clear twinkle visuals
                    if trail.twinkleSpark then
                        if trail.twinkleSpark.ag then trail.twinkleSpark.ag:Stop() end
                        trail.twinkleSpark:Hide()
                    end
                    trail.twinkleSpark = nil
                else
                    -- Reapply twinkle visuals
                    EasyCursorTrails.ApplyColorEffectTrail(trail, i)
                end
            end
        end
    end
end

function EasyCursorTrails.CleanupStarSparkles()
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            if trail.starSparkle then
                if trail.starSparkle.ag then trail.starSparkle.ag:Stop() end
                trail.starSparkle:Hide()
            end
            trail.starSparkle = nil
        end
    end
end

function EasyCursorTrails.RefreshStarTrails()
    EasyCursorTrails.StopDustTicker()
    EasyCursorTrails.CleanupStarSparkles()

    local profile = EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile or not profile.enableStarEmbers then return end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            if trail:IsVisible() then
                EasyCursorTrails.SpawnSparkles(trail)
            end
        end
    end

    EasyCursorTrails.StarDustTicker()
end

function EasyCursorTrails.ApplyActiveEffectsFromProfile(profileSettings)
    if not profileSettings then return end

    -- 🔗 Connect Trails
    if profileSettings.connectTrails then
        if type(EasyCursorTrails.RebuildTrails) == "function" then
            EasyCursorTrails.RebuildTrails()
        end
    end

    -- 🔥 Ember Effects
    if profileSettings.enableEmbers then
        if type(EasyCursorTrails.StartEmberTicker) == "function" then
            EasyCursorTrails.StartEmberTicker()
        end
    else
        if type(EasyCursorTrails.StopEmberTicker) == "function" then
            EasyCursorTrails.StopEmberTicker()
        end
    end

    -- 🔥 Fire Effects
    if profileSettings.enableFire then
        if type(EasyCursorTrails.StartFireTicker) == "function" then
            EasyCursorTrails.StartFireTicker()
        end
    else
        if type(EasyCursorTrails.StopFireTicker) == "function" then
            EasyCursorTrails.StopFireTicker()
        end
    end

    -- 🌟 Glow Effects
    if profileSettings.enableGlowFrames then
        if type(EasyCursorTrails.UpdateGlowFrames) == "function" then
            EasyCursorTrails.UpdateGlowFrames()
        end
    end

    if profileSettings.enableSelectedGlowEffect then
        if type(EasyCursorTrails.ApplySelectedGlowEffect) == "function" then
            EasyCursorTrails.ApplySelectedGlowEffect()
        end
    end

    -- ⚡ Lightning Embers
    if profileSettings.enableLightningEmbers then
        if type(EasyCursorTrails.StartLightningEmberTicker) == "function" then
            EasyCursorTrails.StartLightningEmberTicker()
        end
    else
        if type(EasyCursorTrails.StopLightningEmberTicker) == "function" then
            EasyCursorTrails.StopLightningEmberTicker()
        end
    end

    -- ⚡ Lightning Sparks
    if profileSettings.enableLightningSparks then
        if type(EasyCursorTrails.StartLightningSparkEffect) == "function" then
            EasyCursorTrails.StartLightningSparkEffect()
        end
    else
        if type(EasyCursorTrails.StopLightningSparkEffect) == "function" then
            EasyCursorTrails.StopLightningSparkEffect()
        end
    end

    -- 🌸 Spring Season Trails
    if profileSettings.enableSpringSeasonTrails then
        if type(EasyCursorTrails.StartNatureTicker) == "function" then
            EasyCursorTrails.StartNatureTicker()
        end
    else
        if type(EasyCursorTrails.StopNatureTicker) == "function" then
            EasyCursorTrails.StopNatureTicker()
        end
    end

    -- 💨 Smoke Effects
    if profileSettings.enableSmokeEffect then
        if type(EasyCursorTrails.StartSmokeTicker) == "function" then
            EasyCursorTrails.StartSmokeTicker()
        end
    else
        if type(EasyCursorTrails.StopSmokeTicker) == "function" then
            EasyCursorTrails.StopSmokeTicker()
        end
    end

    -- 💨 Smoke Trails
    if profileSettings.enableSmokeEffectTrails then
        if type(EasyCursorTrails.RefreshSmokeTrails) == "function" then
            EasyCursorTrails.RefreshSmokeTrails()
        end
    end

    -- 🌟 Star Dust
    if profileSettings.enableStarDust then
        if type(EasyCursorTrails.StarDustTicker) == "function" then
            EasyCursorTrails.StarDustTicker()
        end
    else
        if type(EasyCursorTrails.StopDustTicker) == "function" then
            EasyCursorTrails.StopDustTicker()
        end
    end

    -- 🌟 Star Embers
    if profileSettings.enableStarEmbers then
        if type(EasyCursorTrails.StartStarEmberTicker) == "function" then
            EasyCursorTrails.StartStarEmberTicker()
        end
    else
        if type(EasyCursorTrails.StopStarEmberTicker) == "function" then
            EasyCursorTrails.StopStarEmberTicker()
        end
    end

    -- 🔗 Static Arc
    if profileSettings.enableStaticArc then
        if type(EasyCursorTrails.RefreshStaticArcTrails) == "function" then
            EasyCursorTrails.RefreshStaticArcTrails()
        end
    end

    -- 🌒 Trail Shadows
    if profileSettings.enableTrailShadows then
        if type(EasyCursorTrails.RefreshAllTrailShadows) == "function" then
            EasyCursorTrails.RefreshAllTrailShadows()
        end
    end

    -- ✨ Twinkle Stars
    if profileSettings.enableTwinkleStars then
        if type(EasyCursorTrails.RefreshTwinkleStarsEffects) == "function" then
            EasyCursorTrails.RefreshTwinkleStarsEffects()
        end
    end

    -- 🐛 Debug Logging
    if profileSettings.debugMode then
        ----print("✓ Effects applied from profile:", EasyCursorTrailsDB.currentProfile)
        for k, v in pairs(profileSettings) do
            ----print("  •", k, "=", tostring(v))
        end
    end
end




function EasyCursorTrails.SanitizeProfileState(profile)
    if not profile or type(profile) ~= "table" then return end

    local defaults = EasyCursorTrails.defaults or {}
    local missingKeys = {}

    for key, defaultValue in pairs(defaults) do
        if profile[key] == nil then
            profile[key] = defaultValue
            table.insert(missingKeys, key)
        end
    end

    if #missingKeys > 0 then
        --SanitizeProfileState: Initialized missing keys →", table.concat(missingKeys, ", "))
    end
end


function EasyCursorTrails.ResetAllEffectCheckboxes()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    -- 🧰 Effect toggles and checkboxes
    local effectCheckboxMap = {
        enableTwinkleStars           = EasyCursorTrails.twinkleStarsCheckbox,
        randomTwinkleStarsColor      = EasyCursorTrails.twinkleStarsRandomColorCheckbox,
        enableStarDust               = EasyCursorTrails.starDustCheckbox,
        randomStarDustColor          = EasyCursorTrails.starDustRandomColorCheckbox,
        enableEmbers                 = EasyCursorTrails.emberCheckbox,
        randomEmberColor             = EasyCursorTrails.emberRandomColorCheckbox,
        enableSmokeEffect            = EasyCursorTrails.smokeEffectCheckbox,
        randomSmokeColor             = EasyCursorTrails.smokeRandomColorCheckbox,
        enableFire                   = EasyCursorTrails.fireEffectCheckbox,
        randomFireColor              = EasyCursorTrails.fireRandomColorCheckbox,
        enableLightningSparks        = EasyCursorTrails.lightningSparkCheckbox,
        randomLightningSparkColor    = EasyCursorTrails.lightningSparkRandomColorCheckbox,
        enableLightningEmbers        = EasyCursorTrails.lightningEmberCheckbox,
        randomLightningColor         = EasyCursorTrails.lightningEmberRandomColorCheckbox,
        enableSpringSeason           = EasyCursorTrails.springSeasonCheckbox,
        randomSpringSeasonColor      = EasyCursorTrails.springSeasonRandomColorCheckbox,
        enableSmokeEffectTrails      = EasyCursorTrails.smokeTrailCheckbox,
        randomSmokeTrailColor        = EasyCursorTrails.randomSmokeTrailColorCheckbox,
        enableFireTrails             = EasyCursorTrails.fireTrailCheckbox,
        randomFireTrailColor         = EasyCursorTrails.randomFireTrailColorCheckbox,
        enableStarEmbers             = EasyCursorTrails.starEmberCheckbox,
        randomStarEmberColor         = EasyCursorTrails.randomStarEmberColorCheckbox,
        enableStaticArc              = EasyCursorTrails.staticArcEffectCheckbox,
        randomStaticArcColor         = EasyCursorTrails.staticArcRandomColorCheckbox,
        enableTrailShadows           = EasyCursorTrails.shadowEffectCheckbox,
        randomShadowColor            = EasyCursorTrails.shadowRandomColorCheckbox,
        connectTrails                = EasyCursorTrails.connectTrailsCheckbox,
    }

    for key, checkbox in pairs(effectCheckboxMap) do
        profile[key] = false
        EasyCursorTrails.SaveToCurrentProfile(key, false)
        if checkbox and checkbox.SetChecked then
            checkbox:SetChecked(false)
        end
    end

    -- 🎨 Reset color pickers to default
    local colorKeys = {
        "twinkleStarsColor", "staticArcColor", "trailColor", "cursorColor", "glowColor",
        "shadowTrailColor", "emberColor", "fireColor", "smokeColor", "lightningSparkColor",
        "lightningEmberColor", "springSeasonColor", "starColor", "starEmberColor",
        "starDustColor", "fireTrailColor", "smokeTrailColor"
    }

    for _, key in ipairs(colorKeys) do
        local defaultColor = EasyCursorTrails.GetDefaultColor(key)
        if defaultColor then
            profile[key] = CopyTable(defaultColor)
            EasyCursorTrails.SaveToCurrentProfile(key, profile[key])

            local picker = EasyCursorTrails[key .. "Picker"]
            if picker then
                if picker.SetColorRGBA then
                    picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
                elseif picker.swatch then
                    picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
                end
            end
        end
    end

    -- 🧹 Clear lingering visuals
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            if trail.twinkleSpark then
                if trail.twinkleSpark.ag then trail.twinkleSpark.ag:Stop() end
                trail.twinkleSpark:Hide()
                trail.twinkleSpark = nil
            end
            if trail.staticArc then
                if trail.staticArc.ag then trail.staticArc.ag:Stop() end
                trail.staticArc:Hide()
                trail.staticArc = nil
            end
        end
    end

    -- 🔄 Rebuild trails with clean state
    EasyCursorTrails.RebuildTrails()
end


function EasyCursorTrails.ApplyCheckboxStates(profileSettings)
    if type(profileSettings) ~= "table" then return end

    local checkboxMap = {
        -- 🌟 Core trail toggles
        enableTrails                     = "enableTrailsCheckbox",
        connectTrails                    = "connectTrailsCheckbox",

        -- 🔥 Effect toggles
        enableEmbers                     = "emberCheckbox",
        enableFire                       = "fireEffectCheckbox",
        enableSmokeEffect                = "smokeEffectCheckbox",
        enableLightningSparks            = "lightningSparkCheckbox",
        enableLightningEmbers            = "lightningEmberCheckbox",
        enableStaticArc                  = "staticArcEffectCheckbox",
        enableTrailShadows               = "shadowEffectCheckbox",
        enableTwinkleStars               = "twinkleStarsCheckbox",
        enableStarEmbers                 = "starEmberCheckbox",
        enableStarDust                   = "starDustCheckbox",
        enableSpringSeason               = "springSeasonCheckbox",
        enableSpringSeasonTrails         = "springSeasonTrailCheckbox",
        enableFireTrails                 = "fireTrailCheckbox",
        enableSmokeEffectTrails          = "smokeTrailCheckbox",

        -- 🎨 Random color toggles
        randomEmberColor                 = "emberRandomColorCheckbox",
        randomFireColor                  = "fireRandomColorCheckbox",
        randomSmokeColor                 = "smokeRandomColorCheckbox",
        randomLightningSparkColor        = "lightningSparkRandomColorCheckbox",
        randomLightningColor             = "lightningEmberRandomColorCheckbox",
        randomStaticArcColor             = "staticArcRandomColorCheckbox",
        randomShadowColor                = "shadowRandomColorCheckbox",
        randomTwinkleStarsColor          = "twinkleStarsRandomColorCheckbox",
        randomStarDustColor              = "starDustRandomColorCheckbox",
        randomSpringSeasonColor          = "springSeasonRandomColorCheckbox",
        randomSmokeTrailColor            = "randomSmokeTrailColorCheckbox",
        randomFireTrailColor             = "randomFireTrailColorCheckbox",
        randomStarEmberColor             = "randomStarEmberColorCheckbox",

        -- ✨ Visual customization toggles
        enableSparkles                   = "sparkleCheckbox",
        enableGlowTrail                  = "glowEffectCheckbox",
        enableTrailDistortion            = "trailDistortionCheckbox",
        enableCursorPulse                = "cursorPulseCheckbox",
        enableTrailFade                  = "trailFadeCheckbox",
        enableTrailBlend                 = "trailBlendCheckbox",
        enableTrailRotation              = "trailRotationCheckbox",
        enableTrailStretch               = "trailStretchCheckbox",
        enableCursorShadow               = "cursorShadowCheckbox",
        enableCursorGlow                 = "cursorGlowCheckbox",
        enableCursorDistortion           = "cursorDistortionCheckbox",
    }

    for profileKey, checkboxVar in pairs(checkboxMap) do
        local checkbox = EasyCursorTrails[checkboxVar]
        if checkbox and checkbox.SetChecked then
            checkbox:SetChecked(profileSettings[profileKey] == true)
        end
    end
end

function EasyCursorTrails.RefreshSettingsUI()
    if not EasyCursorTrails.menuInitialized then return end

    EasyCursorTrails.isSyncingUI = true

    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profileSettings = EasyCursorTrailsDB.profiles[profileName]
    local defaults = EasyCursorTrails.defaults

    if not profileSettings then
        profileSettings = CopyTable(defaults)
        EasyCursorTrailsDB.profiles[profileName] = profileSettings
    end

    -- 🧼 Sanitize and apply profile
    EasyCursorTrails.SanitizeProfileState(profileSettings)
    EasyCursorTrails.currentProfileTable = profileSettings
    EasyCursorTrails.profile = profileSettings

    -- 🔽 Sync profile dropdown label
    if EasyCursorTrails.profileDropdown then
        UIDropDownMenu_SetText(EasyCursorTrails.profileDropdown, profileName)
    end

    -- 🎚️ Sync sliders from profile
    local sliders = {
        { ref = EasyCursorTrails.opacitySlider, key = "trailOpacity" },
        { ref = EasyCursorTrails.trailFollowSpeedSlider, key = "trailUpdateMultiplier" },
        { ref = EasyCursorTrails.chainSegmentSlider, key = "chainSegment" },
        { ref = EasyCursorTrails.cursorSizeSlider, key = "cursorSize" },
        { ref = EasyCursorTrails.trailSizeStartSlider, key = "trailSizeStart" },
        { ref = EasyCursorTrails.trailSizeEndSlider, key = "trailSizeEnd" },
        { ref = EasyCursorTrails.trailCountSlider, key = "trailCount" },
        { ref = EasyCursorTrails.trailLengthSlider, key = "trailLayerCount", roundToInt = true },
        { ref = EasyCursorTrails.trailLayerSpacingSlider, key = "trailLayerSpacing" },
        { ref = EasyCursorTrails.trailInitialSeparationSlider, key = "trailInitialSeparation" },
        { ref = EasyCursorTrails.glowIntensitySlider, key = "glowIntensity" },
        { ref = EasyCursorTrails.trailIntensitySlider, key = "trailIntensity" },
        { ref = EasyCursorTrails.trailSpacingSlider, key = "trailSpacing" },
        { ref = EasyCursorTrails.trailOffsetXSlider, key = "trailOffsetX" },
        { ref = EasyCursorTrails.trailOffsetYSlider, key = "trailOffsetY" },
        { ref = EasyCursorTrails.trailOffsetMagnitudeSlider, key = "trailOffsetMagnitude" },
        { ref = EasyCursorTrails.trailTextureOpacitySlider, key = "trailTextureOpacity" },
        { ref = EasyCursorTrails.glowFactorSlider, key = "glowIntensityFactor" },
        { ref = EasyCursorTrails.numGlowsSlider, key = "numGlows", roundToInt = true },
        { ref = EasyCursorTrails.patternGlowCountSlider, key = "patternGlowCount", roundToInt = true },
        { ref = EasyCursorTrails.glowRadiusSlider, key = "glowRadius" },
        { ref = EasyCursorTrails.glowSizeSlider, key = "glowSize" },
        { ref = EasyCursorTrails.glowThicknessSlider, key = "glowThickness" },
        { ref = EasyCursorTrails.cursorOffsetXSlider, key = "cursorOffsetX" },
        { ref = EasyCursorTrails.cursorOffsetYSlider, key = "cursorOffsetY" },
    }

    for _, info in ipairs(sliders) do
        local slider, key = info.ref, info.key
        if slider and slider.SetValue then
            local value = profileSettings[key]
            if value == nil then value = defaults[key] end
            if value == nil then value = 1 end

            local displayValue = info.roundToInt and math.floor(value) or value
            slider:SetValue(displayValue)

            if slider.editBox then
                slider.editBox:SetText(info.roundToInt and tostring(displayValue) or string.format("%.2f", displayValue))
            elseif slider.valueText then
                slider.valueText:SetText(tostring(displayValue))
            end
        end
    end

    -- ✅ Sync checkboxes
    EasyCursorTrails.ApplyCheckboxStates(profileSettings)

    -- 🔽 Dropdown sync utility
    local function SyncDropdown(dropdown, options, index, defaultText)
        if not dropdown or type(options) ~= "table" then return end
        index = options[index] and index or 1
        UIDropDownMenu_SetSelectedID(dropdown, index)
        UIDropDownMenu_SetText(dropdown, options[index].text or defaultText)
    end

    -- 🎨 Build dropdown option lists
    EasyCursorTrails.trailColorEffectOptions = {}
    for _, effect in ipairs(TrailcolorEffects or {}) do
        table.insert(EasyCursorTrails.trailColorEffectOptions, {
            text = effect.text or "Unnamed Effect",
            value = effect.value
        })
    end

    EasyCursorTrails.cursorColorEffectOptions = {}
    for _, effect in ipairs(colorEffects or {}) do
        table.insert(EasyCursorTrails.cursorColorEffectOptions, {
            text = effect.text or "Unnamed Effect",
            value = effect.value
        })
    end

    EasyCursorTrails.trailMovementEffectOptions = {}
    for _, effect in ipairs(trailMovementEffectOptions or {}) do
        table.insert(EasyCursorTrails.trailMovementEffectOptions, {
            text = effect.text or "Unnamed Movement",
            value = effect.value
        })
    end

    -- 🎛️ Sync effect-specific UI
    local effectID = tonumber(profileSettings.selectedGlowEffect) or 1
    if type(EasyCursorTrails.SyncEffectSettingsUI) == "function" then
        EasyCursorTrails.SyncEffectSettingsUI(effectID)
    end

    -- 🌟 Sync glow texture dropdown
    local glowTextureID = tonumber(profileSettings.selectedGlowTexture) or 1
    for index, option in ipairs(EasyCursorTrails.glowTextureOptions or {}) do
        if option.id == glowTextureID then
            C_Timer.After(0.1, function()
                if EasyCursorTrails.glowTextureDropdown and type(EasyCursorTrails.glowTextureDropdown.SetSelectedIndex) == "function" then
                    EasyCursorTrails.glowTextureDropdown:SetSelectedIndex(index)
                end
            end)
            break
        end
    end

    -- 🖼️ Sync cursor texture dropdown
    if EasyCursorTrails.cursorTextureDropdown and profileSettings.selectedCursorTextureName then
        UIDropDownMenu_SetSelectedName(EasyCursorTrails.cursorTextureDropdown, profileSettings.selectedCursorTextureName)
    end

    -- 🔄 Reapply visuals
    EasyCursorTrails.ApplySelectedGlowEffect()
    EasyCursorTrails.UpdateGlowFrames()

    -- ✅ Sync dropdown selections from profile
    SyncDropdown(EasyCursorTrails.trailColorEffectDropdown, EasyCursorTrails.trailColorEffectOptions, tonumber(profileSettings.trailColorEffect) or 1, "Custom Effect")
    SyncDropdown(EasyCursorTrails.cursorColorEffectDropdown, EasyCursorTrails.cursorColorEffectOptions, tonumber(profileSettings.cursorColorEffect) or 1, "Default")
    SyncDropdown(EasyCursorTrails.glowEffectDropdown, EasyCursorTrails.glowEffectOptions, tonumber(profileSettings.selectedGlowEffect) or 1, "Custom Glow")
    SyncDropdown(EasyCursorTrails.trailMovementEffectDropdown, EasyCursorTrails.trailMovementEffectOptions, tonumber(profileSettings.trailMovementEffect) or 1, "No Effect")

    if EasyCursorTrails.cursorFrameStrataDropdown then
        local index = EasyCursorTrails.GetStrataIndex(profileSettings.cursorFrameStrata or "HIGH")
        SyncDropdown(EasyCursorTrails.cursorFrameStrataDropdown, EasyCursorTrails.frameStrataOptions, index, "HIGH")
    end

    -- 🎨 Sync cursor texture dropdown options
    EasyCursorTrails.cursorTextureOptions = {}
    if EasyCursorTrails.customCursorTextures then
        for _, data in ipairs(EasyCursorTrails.customCursorTextures) do
            local name = data.name or "Unknown"
            if data.animated then name = name .. " (Animated)" end
            table.insert(EasyCursorTrails.cursorTextureOptions, {
                text = name,
                icon = data.texture
            })
        end
    end

    C_Timer.After(0.1, function()
        local index = tonumber(profileSettings.cursorTexture) or 1
        if index > #EasyCursorTrails.cursorTextureOptions then index = 1 end
        SyncDropdown(EasyCursorTrails.cursorTextureDropdown, EasyCursorTrails.cursorTextureOptions, index, "Default")
    end)

    local trailIndex = tonumber(profileSettings.trailTexture) or 1
    C_Timer.After(0.1, function()
        if EasyCursorTrails.trailTextureDropdown and type(EasyCursorTrails.trailTextureDropdown.SetSelectedIndex) == "function" then
                    EasyCursorTrails.trailTextureDropdown:SetSelectedIndex(trailIndex)
    end
end)

EasyCursorTrails.isSyncingUI = false


----------------------------------------------------------------
-- 🎨 Sync Color Pickers
----------------------------------------------------------------
local function SetColor(editBox, color)
    if editBox and color and type(RGBToHex) == "function" then
        editBox:SetText(RGBToHex(color.r, color.g, color.b))
    end
end

SetColor(EasyCursorTrails.cursorColorEditBox, profileSettings.cursorColor or defaults.cursorColor)
SetColor(EasyCursorTrails.glowColorEditBox, profileSettings.glowColor or defaults.glowColor)

-- ✅ Sync trail color edit box
local trailColor = profileSettings.trailColor or defaults.trailColor or { r = 1, g = 1, b = 1, a = 1 }
local colorText = RGBToHex(trailColor.r, trailColor.g, trailColor.b, trailColor.a)
EasyCursorTrails.trailColorEditBox:SetText(colorText)

-- ✅ Apply trail color visually
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

-- ✅ Sync shadow color picker
if EasyCursorTrails.shadowColorPicker and type(EasyCursorTrails.shadowColorPicker.SetColorRGBA) == "function" then
    local shadowColor = profileSettings.shadowTrailColor or defaults.shadowTrailColor or { r = 0, g = 0, b = 0, a = 0.4 }
    EasyCursorTrails.shadowColorPicker:SetColorRGBA(shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a)
end



----------------------------------------------------------------
-- ✨ Apply Active Effects
----------------------------------------------------------------
EasyCursorTrails.ApplyActiveEffectsFromProfile(profileSettings)

----------------------------------------------------------------
-- 🔁 Sync toggle states with tickers
----------------------------------------------------------------

-- 🌐 Core trail logic
EasyCursorTrails.SyncToggleState(
    "connectTrails",
    EasyCursorTrails.connectTrailsCheckbox,
    EasyCursorTrails.StartConnectTrailsTicker,
    EasyCursorTrails.StopConnectTrailsTicker
)

-- ✨ Sparkles and embers
EasyCursorTrails.SyncToggleState(
    "enableEmbers",
    EasyCursorTrails.emberCheckbox,
    EasyCursorTrails.StartEmberTicker,
    EasyCursorTrails.StopEmberTicker
)

EasyCursorTrails.SyncToggleState(
    "enableFire",
    EasyCursorTrails.fireEffectCheckbox,
    EasyCursorTrails.StartFireTicker,
    EasyCursorTrails.StopFireTicker
)

EasyCursorTrails.SyncToggleState(
    "enableLightningEmbers",
    EasyCursorTrails.lightningEmberCheckbox,
    EasyCursorTrails.StartLightningEmberTicker,
    EasyCursorTrails.StopLightningEmberTicker
)

EasyCursorTrails.SyncToggleState(
    "enableLightningSparks",
    EasyCursorTrails.lightningSparkCheckbox,
    EasyCursorTrails.StartLightningSparkEffect,
    EasyCursorTrails.StopLightningSparkEffect
)

EasyCursorTrails.SyncToggleState(
    "enableSmokeEffect",
    EasyCursorTrails.smokeEffectCheckbox,
    EasyCursorTrails.StartSmokeTicker,
    EasyCursorTrails.StopSmokeTicker
)

EasyCursorTrails.SyncToggleState(
    "enableSmokeEffectTrails",
    EasyCursorTrails.smokeTrailCheckbox,
    EasyCursorTrails.StartSmokeTrailTicker,
    EasyCursorTrails.StopSmokeTrailTicker
)

EasyCursorTrails.SyncToggleState(
    "enableSpringSeasonTrails",
    EasyCursorTrails.springSeasonCheckbox,
    EasyCursorTrails.StartNatureTicker,
    EasyCursorTrails.StopNatureTicker
)

EasyCursorTrails.SyncToggleState(
    "enableStarDust",
    EasyCursorTrails.starDustCheckbox,
    EasyCursorTrails.StarDustTicker,
    EasyCursorTrails.StopDustTicker
)

EasyCursorTrails.SyncToggleState(
    "enableStarEmbers",
    EasyCursorTrails.starEmberCheckbox,
    EasyCursorTrails.StartStarEmberTicker,
    EasyCursorTrails.StopStarEmberTicker
)

EasyCursorTrails.SyncToggleState(
    "enableStaticArc",
    EasyCursorTrails.staticArcEffectCheckbox,
    EasyCursorTrails.StartStaticArcTicker,
    EasyCursorTrails.StopStaticArcTicker
)

EasyCursorTrails.SyncToggleState(
    "enableTrailShadows",
    EasyCursorTrails.shadowEffectCheckbox,
    EasyCursorTrails.StartTrailShadowTicker,
    EasyCursorTrails.StopTrailShadowTicker
)

EasyCursorTrails.SyncToggleState(
    "enableTwinkleStars",
    EasyCursorTrails.twinkleStarsCheckbox,
    EasyCursorTrails.StartTwinkleStarsTicker,
    EasyCursorTrails.StopTwinkleStarsTicker
)

----------------------------------------------------------------
-- 🌟 Final visual updates
----------------------------------------------------------------
if EasyCursorTrails.UpdateGlowFrames then
    EasyCursorTrails.UpdateGlowFrames()
end

if EasyCursorTrails.ApplySelectedGlowEffect then
    EasyCursorTrails.ApplySelectedGlowEffect()
end

-- ✅ Sync Twinkle Stars color picker swatch
if EasyCursorTrails.twinkleStarsColorPicker and type(EasyCursorTrails.twinkleStarsColorPicker.SetColorRGBA) == "function" then
    local twinkleColor = profileSettings.twinkleStarsColor or defaults.twinkleStarsColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.twinkleStarsColorPicker:SetColorRGBA(twinkleColor.r, twinkleColor.g, twinkleColor.b, twinkleColor.a)
end

-- ✅ Reapply live effect toggles
if EasyCursorTrails.liveEffects.enableLightningSpark then
    EasyCursorTrails.lightningSparkCheckbox:SetChecked(true)
    EasyCursorTrails.RestartLightningSparkTicker()
end

----------------------------------------------------------------
-- 🔄 Rebuild trails safely
----------------------------------------------------------------
if EasyCursorTrails.RebuildTrails then
    local success, err = pcall(EasyCursorTrails.RebuildTrails)
    if not success and EasyCursorTrails.debugSave then
        -- print("[EasyCursorTrails] Error rebuilding trails:", tostring(err))
    end
end

-- ✅ Reapply Twinkle Stars color after trails are rebuilt
C_Timer.After(0.6, function()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if profile and profile.enableTwinkleStars then
        if type(EasyCursorTrails.UpdateTwinkleTrailColors) == "function" then
            EasyCursorTrails.UpdateTwinkleTrailColors()
        elseif EasyCursorTrails.debugSave then
            -- print("[EasyCursorTrails] Warning: UpdateTwinkleTrailColors is not defined.")
        end
    end
end)

-- ✅ Finalize sync state
EasyCursorTrails.isSyncingUI = false

end


function EasyCursorTrails.SyncToggleState(profileKey, checkbox, startFunc, stopFunc)
    local profile = EasyCursorTrails.currentProfileTable
    if not profile then return end

    local state = profile[profileKey]
    if type(state) ~= "boolean" then return end

    if checkbox and checkbox.SetChecked then
        checkbox:SetChecked(state)
    end

    if state then
        if type(startFunc) == "function" then startFunc() end
    elseif type(stopFunc) == "function" then
        stopFunc()
    end
end


function EasyCursorTrails.SaveCurrentProfile()
    local profileName = EasyCursorTrailsDB.currentProfile
    if not profileName then return end

    local profileSettings = EasyCursorTrailsDB.profiles[profileName]
    if not profileSettings then return end

    -- 🧭 Save sliders
    local sliders = {
        { EasyCursorTrails.cursorSizeSlider,        "cursorSize" },
        { EasyCursorTrails.trailSizeStartSlider,    "trailSizeStart" },
        { EasyCursorTrails.trailSizeEndSlider,      "trailSizeEnd" },
        { EasyCursorTrails.trailCountSlider,        "trailCount" },
        { EasyCursorTrails.trailLengthSlider,       "trailLayerCount", true },
        { EasyCursorTrails.glowIntensitySlider,     "glowIntensity" },
        { EasyCursorTrails.glowRadiusSlider,        "glowRadius" },
        { EasyCursorTrails.trailIntensitySlider,    "trailGlowIntensity" },
        { EasyCursorTrails.trailSpacingSlider,      "trailSpacing" },
        { EasyCursorTrails.horizontalScaleSlider,   "horizontalScale" },
        { EasyCursorTrails.verticalScaleSlider,     "verticalScale" },
        { EasyCursorTrails.cursorOffsetXSlider,     "cursorOffsetX" },
        { EasyCursorTrails.cursorOffsetYSlider,     "cursorOffsetY" },
        { EasyCursorTrails.trailOffsetXSlider,      "trailOffsetX" },
        { EasyCursorTrails.trailOffsetYSlider,      "trailOffsetY" },
    }

    for _, slider in ipairs(sliders) do
        EasyCursorTrails.SaveSliderValue(slider[1], slider[2], slider[3])
    end

    -- 🎛️ Save dropdowns
    local dropdowns = {
        { EasyCursorTrails.trailTextureDropdown, "trailTexture" },
        -- Add more dropdowns here if needed
    }

    for _, dropdown in ipairs(dropdowns) do
        EasyCursorTrails.SaveDropdownValue(dropdown[1], dropdown[2])
    end

    -- ✅ Save effect toggles
    local effectCheckboxes = {
        { EasyCursorTrails.connectTrailsCheckbox,       "connectTrails" },
        { EasyCursorTrails.emberCheckbox,               "enableEmbers" },
        { EasyCursorTrails.enableTrailsCheckbox,        "enableTrails" },
        { EasyCursorTrails.fireEffectCheckbox,          "enableFire" },
        { EasyCursorTrails.lightningEmberCheckbox,      "enableLightningEmbers" },
        { EasyCursorTrails.lightningSparkCheckbox,      "enableLightningSparks" },
        { EasyCursorTrails.shadowEffectCheckbox,        "enableTrailShadows" },
        { EasyCursorTrails.smokeEffectCheckbox,         "enableSmokeEffect" },
        { EasyCursorTrails.smokeTrailCheckbox,          "enableSmokeEffectTrails" },
        { EasyCursorTrails.springSeasonCheckbox,        "enableSpringSeasonTrails" },
        { EasyCursorTrails.starDustCheckbox,            "enableStarDust" },
        { EasyCursorTrails.starEmberCheckbox,           "enableStarEmbers" },
        { EasyCursorTrails.staticArcEffectCheckbox,     "enableStaticArc" },
        { EasyCursorTrails.twinkleStarsCheckbox,        "enableTwinkleStars" },
    }

    for _, checkbox in ipairs(effectCheckboxes) do
        EasyCursorTrails.SaveCheckboxValue(checkbox[1], checkbox[2])
    end

    -- 🌈 Save random color toggles
    local randomColorCheckboxes = {
        { EasyCursorTrails.emberRandomColorCheckbox,            "randomEmberColor" },
        { EasyCursorTrails.fireRandomColorCheckbox,             "randomFireColor" },
        { EasyCursorTrails.lightningEmberRandomColorCheckbox,   "randomLightningColor" },
        { EasyCursorTrails.lightningSparkRandomColorCheckbox,   "randomLightningSparkColor" },
        { EasyCursorTrails.randomSmokeTrailColorCheckbox,       "randomSmokeTrailColor" },
        { EasyCursorTrails.shadowRandomColorCheckbox,           "randomShadowColor" },
        { EasyCursorTrails.smokeRandomColorCheckbox,            "randomSmokeColor" },
        { EasyCursorTrails.springSeasonRandomColorCheckbox,     "randomSpringSeasonTrailColor" },
        { EasyCursorTrails.starDustRandomColorCheckbox,         "randomStarDustColor" },
        { EasyCursorTrails.randomStarEmberColorCheckbox,        "randomStarEmberColor" },
        { EasyCursorTrails.staticArcRandomColorCheckbox,        "randomStaticArcColor" },
        { EasyCursorTrails.randomTwinkleStarsColorCheckbox,     "randomTwinkleStarsColor" },
    }

    for _, checkbox in ipairs(randomColorCheckboxes) do
        EasyCursorTrails.SaveCheckboxValue(checkbox[1], checkbox[2])
    end
end



function EasyCursorTrails.SaveSliderValue(slider, key, roundToInt)
    if EasyCursorTrails.isSyncingUI then return end
    if not slider or type(slider.GetValue) ~= "function" then return end

    local value = tonumber(slider:GetValue())
    if not value then return end

    if roundToInt then value = math.floor(value) end
    EasyCursorTrails.currentProfileTable[key] = value
end

function EasyCursorTrails.SaveDropdownValue(dropdown, key)
    if EasyCursorTrails.isSyncingUI then return end
    if not dropdown or type(UIDropDownMenu_GetSelectedID) ~= "function" then return end

    local selectedID = UIDropDownMenu_GetSelectedID(dropdown)
    if type(selectedID) == "number" then
        EasyCursorTrails.currentProfileTable[key] = selectedID
    end
end

function EasyCursorTrails.SaveCheckboxValue(checkbox, key)
    if EasyCursorTrails.isSyncingUI then return end
    if not checkbox or type(checkbox.GetChecked) ~= "function" then return end

    local checked = checkbox:GetChecked()
    EasyCursorTrails.currentProfileTable[key] = checked == true
end

function EasyCursorTrails.PopulateProfileDropdownAndSelectCurrent()
    local dropdown = EasyCursorTrails.profileDropdown
    local profiles = EasyCursorTrailsDB and EasyCursorTrailsDB.profiles
    if not dropdown or not profiles then return end

    -- 🧭 Ensure current profile is valid
    local currentProfile = EasyCursorTrailsDB.currentProfile or "Default"
    if not profiles[currentProfile] then
        currentProfile = "Default"
        EasyCursorTrailsDB.currentProfile = currentProfile
    end

    -- 🔽 Initialize dropdown menu
    UIDropDownMenu_Initialize(dropdown, function(self, level)
        if level ~= 1 then return end

        -- 📋 Collect and sort profile names
        local profileNames = {}
        for name in pairs(profiles) do
            table.insert(profileNames, name)
        end
        table.sort(profileNames)

        -- 🧩 Add each profile to dropdown
        for _, name in ipairs(profileNames) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = name
            info.checked = (name == currentProfile)
            info.func = function()
                -- 🔄 Switch profile
                EasyCursorTrailsDB.currentProfile = name
                EasyCursorTrails.SaveLastSelectedProfile(name)

                -- 🧼 Reset UI controls before applying new profile
                if type(EasyCursorTrails.ResetEffectControls) == "function" then
                    EasyCursorTrails.ResetEffectControls()
                end

                -- 🔁 Load profile
                EasyCursorTrails.LoadCurrentProfile()

                -- ⏳ Delay UI sync to ensure dropdowns and controls are initialized
                C_Timer.After(0.1, function()
                    -- 🎛️ Sync effect settings and UI
                    local glowEffectID = EasyCursorTrails.profile and EasyCursorTrails.profile.selectedGlowEffect or 1
                    if type(EasyCursorTrails.SyncEffectSettingsUI) == "function" then
                        EasyCursorTrails.SyncEffectSettingsUI(glowEffectID, EasyCursorTrails.profile)
                    end
                    if type(EasyCursorTrails.RefreshSettingsUI) == "function" then
                        EasyCursorTrails.RefreshSettingsUI()
                    end

                    -- 🔄 Reapply visuals
                    EasyCursorTrails.ApplySelectedGlowEffect()
                    EasyCursorTrails.UpdateGlowFrames()

                    -- 🏷️ Update dropdown label
                    UIDropDownMenu_SetText(dropdown, name)
                end)
            end
            UIDropDownMenu_AddButton(info, level)
        end
    end)

    -- ✅ Set dropdown text to current profile
    UIDropDownMenu_SetText(dropdown, currentProfile)
end


function EasyCursorTrails.SaveAllSettingsToProfile()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    if not profileName then return end

    -- 🧱 Ensure profile table exists
    EasyCursorTrailsDB.profiles[profileName] = EasyCursorTrailsDB.profiles[profileName] or {}
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    ----------------------------------------------------------------------
    -- 🔧 Save slider values
    ----------------------------------------------------------------------
    local sliders = {
        { EasyCursorTrails.cursorSizeSlider,            "cursorSize" },
        { EasyCursorTrails.trailSizeStartSlider,        "trailSizeStart" },
        { EasyCursorTrails.trailSizeEndSlider,          "trailSizeEnd" },
        { EasyCursorTrails.trailCountSlider,            "trailCount" },
        { EasyCursorTrails.trailLengthSlider,           "trailLayerCount", true },
        { EasyCursorTrails.glowIntensitySlider,         "glowIntensity" },
        { EasyCursorTrails.glowRadiusSlider,            "glowRadius" },
        { EasyCursorTrails.trailIntensitySlider,        "trailIntensity" },
        { EasyCursorTrails.trailSpacingSlider,          "trailSpacing" },
        { EasyCursorTrails.horizontalScaleSlider,       "horizontalScale" },
        { EasyCursorTrails.verticalScaleSlider,         "verticalScale" },
        { EasyCursorTrails.cursorOffsetXSlider,         "cursorOffsetX" },
        { EasyCursorTrails.cursorOffsetYSlider,         "cursorOffsetY" },
        { EasyCursorTrails.trailOffsetXSlider,          "trailOffsetX" },
        { EasyCursorTrails.trailOffsetYSlider,          "trailOffsetY" },
    }

    for _, sliderInfo in ipairs(sliders) do
        local slider, key, round = unpack(sliderInfo)
        if slider and key and type(slider.GetValue) == "function" then
            local val = tonumber(slider:GetValue())
            if val then profile[key] = round and math.floor(val) or val end
        end
    end

    ----------------------------------------------------------------------
    -- 🎛️ Save dropdown selections
    ----------------------------------------------------------------------
    local dropdowns = {
        { EasyCursorTrails.trailTextureDropdown,       "trailTexture" },
        { EasyCursorTrails.trailColorEffectDropdown,   "trailColorEffect" },
        { EasyCursorTrails.cursorFrameStrataDropdown,  "cursorFrameStrata" },
        { EasyCursorTrails.glowEffectDropdown,         "selectedGlowEffect" },
        { EasyCursorTrails.cursorTextureDropdown,      "cursorTexture" },
    }

    for _, dropdownInfo in ipairs(dropdowns) do
        local dropdown, key = unpack(dropdownInfo)
        if dropdown and key and type(UIDropDownMenu_GetSelectedID) == "function" then
            local selectedID = UIDropDownMenu_GetSelectedID(dropdown)
            if selectedID then profile[key] = selectedID end
        end
    end

    ----------------------------------------------------------------------
    -- ☑ Save effect checkboxes
    ----------------------------------------------------------------------
    local effectCheckboxes = {
        -- 🌟 Core trail toggles
        { EasyCursorTrails.enableTrailsCheckbox,       "enableTrails" },
        { EasyCursorTrails.connectTrailsCheckbox,      "connectTrails" },

        -- ✨ Visual effects
        { EasyCursorTrails.twinkleStarsCheckbox,       "enableTwinkleStars" },
        { EasyCursorTrails.starDustCheckbox,           "enableStarDust" },
        { EasyCursorTrails.starEmberCheckbox,          "enableStarEmbers" },
        { EasyCursorTrails.emberCheckbox,              "enableEmbers" },
        { EasyCursorTrails.fireEffectCheckbox,         "enableFire" },
        { EasyCursorTrails.smokeEffectCheckbox,        "enableSmokeEffect" },
        { EasyCursorTrails.lightningSparkCheckbox,     "enableLightningSparks" },
        { EasyCursorTrails.lightningEmberCheckbox,     "enableLightningEmbers" },
        { EasyCursorTrails.staticArcEffectCheckbox,    "enableStaticArc" },
        { EasyCursorTrails.shadowEffectCheckbox,       "enableTrailShadows" },

        -- 🌸 Seasonal effects
        { EasyCursorTrails.springSeasonCheckbox,       "enableSpringSeasonTrails" },

        -- 💨 Trail variants
        { EasyCursorTrails.smokeTrailCheckbox,         "enableSmokeEffectTrails" },
    }

    for _, checkboxInfo in ipairs(effectCheckboxes) do
        local checkbox, key = unpack(checkboxInfo)
        if checkbox and key and type(checkbox.GetChecked) == "function" then
            profile[key] = checkbox:GetChecked() == true
        end
    end

    ----------------------------------------------------------------------
    -- 🌈 Save random color toggles
    ----------------------------------------------------------------------
    local randomCheckboxes = {
        { EasyCursorTrails.emberRandomColorCheckbox,          "randomEmberColor" },
        { EasyCursorTrails.fireRandomColorCheckbox,           "randomFireColor" },
        { EasyCursorTrails.lightningEmberRandomColorCheckbox, "randomLightningColor" },
        { EasyCursorTrails.lightningSparkRandomColorCheckbox, "randomLightningSparkColor" },
        { EasyCursorTrails.randomSmokeTrailColorCheckbox,     "randomSmokeTrailColor" },
        { EasyCursorTrails.shadowRandomColorCheckbox,         "randomShadowColor" },
        { EasyCursorTrails.smokeRandomColorCheckbox,          "randomSmokeColor" },
        { EasyCursorTrails.springSeasonRandomColorCheckbox,   "randomSpringSeasonTrailColor" },
        { EasyCursorTrails.starDustRandomColorCheckbox,       "randomStarDustColor" },
        { EasyCursorTrails.randomStarEmberColorCheckbox,      "randomStarEmberColor" },
        { EasyCursorTrails.staticArcRandomColorCheckbox,      "randomStaticArcColor" },
        { EasyCursorTrails.twinkleStarsRandomColorCheckbox,   "randomTwinkleStarsColor" },
    }

    for _, checkboxInfo in ipairs(randomCheckboxes) do
        local checkbox, key = unpack(checkboxInfo)
        if checkbox and key and type(checkbox.GetChecked) == "function" then
            profile[key] = checkbox:GetChecked() == true
        end
    end

    ----------------------------------------------------------------------
    -- 🎨 Save color pickers and edit boxes
    ----------------------------------------------------------------------
    if EasyCursorTrails.cursorColorEditBox and type(HexToRGB) == "function" then
        local r, g, b, a = HexToRGB(EasyCursorTrails.cursorColorEditBox:GetText())
        profile.cursorColor = { r = r, g = g, b = b, a = a }
    end

    if EasyCursorTrails.glowColorEditBox and type(HexToRGB) == "function" then
        local r, g, b, a = HexToRGB(EasyCursorTrails.glowColorEditBox:GetText())
        profile.glowColor = { r = r, g = g, b = b, a = a }
    end

    if EasyCursorTrails.shadowColorPicker and type(EasyCursorTrails.shadowColorPicker.GetColorRGBA) == "function" then
        local r, g, b, a = EasyCursorTrails.shadowColorPicker:GetColorRGBA()
        profile.shadowTrailColor = { r = r, g = g, b = b, a = a }
    end

    -- ❌ Do NOT overwrite twinkleStarsColor here — it's already saved via picker callback

    ----------------------------------------------------------------------
    -- 🔁 Update in-memory reference
    ----------------------------------------------------------------------
    EasyCursorTrails.currentProfileName = profileName
    EasyCursorTrails.currentProfileTable = profile
end

function EasyCursorTrails.CreateSlider(name, parent, label, min, max, step, initialValue, onValueChanged, numDecimals, tooltipText)
    local slider = CreateFrame("Slider", name, parent, "OptionsSliderTemplate")
    slider:SetMinMaxValues(min, max)
    slider:SetValueStep(step)
    slider:SetWidth(150)
    slider:SetHeight(20)

    local decimals = numDecimals or 2

    -- 🏷️ Label
    slider.labelText = slider:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    slider.labelText:SetPoint("BOTTOM", slider, "TOP", 0, 0)
    slider.labelText:SetText(label)
    slider.labelText:SetTextColor(1, 0.85, 0.1)

    -- 🧮 Value formatting
    local function formatValue(val)
        local fmt = "%." .. decimals .. "f"
        return string.format(fmt, val)
    end

    -- 🔁 Sync helper
    local function UpdateEditBox(val)
        slider.editBox:SetText(formatValue(val))
    end

    -- 📝 EditBox for precise input
    slider.editBox = CreateFrame("EditBox", nil, slider, "InputBoxTemplate")
    slider.editBox:SetSize(45, 20)
    slider.editBox:SetPoint("LEFT", slider, "RIGHT", 10, 0)
    slider.editBox:SetAutoFocus(false)
    slider.editBox:SetFontObject("GameFontHighlight")
    slider.editBox:SetTextColor(1, 1, 1)

    -- 🎨 Background for visibility
    local bg = slider.editBox:CreateTexture(nil, "BACKGROUND")
    bg:SetColorTexture(0, 0, 0, 0.6)
    bg:SetAllPoints(slider.editBox)
    slider.editBox.bg = bg

    -- 🧼 Apply initial value
    local initial = tonumber(initialValue) or min
    slider:SetValue(initial)
    UpdateEditBox(initial)

    -- 🧠 EditBox input handler
    slider.editBox:SetScript("OnEnterPressed", function(self)
        local entered = tonumber(self:GetText())
        if entered then
            local clamped = math.max(min, math.min(max, entered))
            slider:SetValue(clamped)
            UpdateEditBox(clamped)
        else
            UpdateEditBox(slider:GetValue())
        end
        self:ClearFocus()
    end)

    -- 🔄 Slider movement handler
    slider:SetScript("OnValueChanged", function(self, newValue)
        local val = tonumber(newValue)
        UpdateEditBox(val)

        if onValueChanged then
            onValueChanged(self, val)
        end

        if EasyCursorTrails.UpdateGlowFrames then
            EasyCursorTrails.UpdateGlowFrames()
        end
        if EasyCursorTrails.ApplySelectedGlowEffect then
            EasyCursorTrails.ApplySelectedGlowEffect()
        end
    end)

    -- 🧩 Optional tooltip
    if tooltipText then
        slider:SetScript("OnEnter", function()
            GameTooltip:SetOwner(slider, "ANCHOR_RIGHT")
            GameTooltip:SetText(tooltipText, nil, nil, nil, nil, true)
            GameTooltip:Show()
        end)
        slider:SetScript("OnLeave", function()
            GameTooltip:Hide()
        end)
    end

    return slider
end


local function AutoAdjustDropdownWidth(dropdown, options)
    if not dropdown or type(options) ~= "table" then return end

    local fontString = dropdown:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    local maxWidth = 0

    for i, option in ipairs(options) do
        local text = type(option) == "table" and option.text
                  or type(option) == "string" and option
                  or ("Option " .. i)

        fontString:SetText(text or "")
        local width = fontString:GetStringWidth()
        if width > maxWidth then
            maxWidth = width
        end
    end

    local padding = 30  -- Extra space for arrow, icon, and margin
    local finalWidth = math.max(100, maxWidth + padding)

    UIDropDownMenu_SetWidth(dropdown, finalWidth)

    local dropdownText = _G[dropdown:GetName() .. "Text"]
    if dropdownText then
        dropdownText:SetWidth(finalWidth - 10)
    end

    fontString:Hide()
end

function EasyCursorTrails.CreateDropdown(name, parent, label, options, selectedIndex, onSelect)
    if not parent or not name then return nil end

    if type(options) ~= "table" or #options == 0 then
        options = { { text = "Default Option" } }
    end

    local dropdown = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate")
    dropdown:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -10)

    local dropdownLabel = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    dropdownLabel:SetPoint("BOTTOM", dropdown, "TOP", 0, 0)
    dropdownLabel:SetText(label or "Dropdown")

    UIDropDownMenu_Initialize(dropdown, function(self, level)
        if level ~= 1 then return end

        for i, option in ipairs(options) do
            local text = type(option) == "table" and option.text
                      or type(option) == "string" and option
                      or ("Option " .. i)

            local info = UIDropDownMenu_CreateInfo()
            info.text = text
            info.checked = (UIDropDownMenu_GetSelectedID(dropdown) == i)

            if type(option) == "table" and option.icon then
                info.icon = option.icon
                info.iconTexCoord = {0, 1, 0, 1}
                info.iconWidth = 20
                info.iconHeight = 20
            end

            info.func = function()
                -- ✅ Reset UI controls before applying new selection
                if type(EasyCursorTrails.ResetEffectControls) == "function" then
                    EasyCursorTrails.ResetEffectControls()
                end

                UIDropDownMenu_SetSelectedID(dropdown, i)
                UIDropDownMenu_SetText(dropdown, text)

                if type(onSelect) == "function" then
                    onSelect(i)
                end

                CloseDropDownMenus()
            end

            UIDropDownMenu_AddButton(info, level)
        end
    end)

    -- 🧮 Clamp and apply initial selection
    local clampedIndex = math.max(1, math.min(selectedIndex or 1, #options))
    UIDropDownMenu_SetSelectedID(dropdown, clampedIndex)

    local initialOption = options[clampedIndex]
    local initialText = type(initialOption) == "table" and initialOption.text
                      or type(initialOption) == "string" and initialOption
                      or "Default Option"
    UIDropDownMenu_SetText(dropdown, initialText)

    if type(AutoAdjustDropdownWidth) == "function" then
        AutoAdjustDropdownWidth(dropdown, options)
    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()
    -- Retrieve the number of trails (fallback to 70 if missing)
    local numTrails = EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.trailCount 
                      or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailCount 
                      or 70

    -- Base pulse step, adjust dynamically based on trail count.
    local basePulseStep = EasyCursorTrailsDB.pulseStep or 0.02
    local adjustedPulseStep = basePulseStep * (70 / math.max(numTrails, 70))

    EasyCursorTrails.pulseValueTrail = (EasyCursorTrails.pulseValueTrail or 0.5) 
                                        + (EasyCursorTrails.pulseDirectionTrail or 1) * adjustedPulseStep

    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

   -- ----print("DEBUG: Pulse updated with adjustedPulseStep:", adjustedPulseStep, "NumTrails:", numTrails)
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


local function SanitizeColor(c)
    if type(c) ~= "table" or type(c.r) ~= "number" or type(c.g) ~= "number" or type(c.b) ~= "number" then
        return { r = 1, g = 1, b = 1, a = 1 }
    end
    c.a = type(c.a) == "number" and c.a or 1
    return c
end

function EasyCursorTrails.DisableTrailEffects(trail)
    -- Hide glow layers
    if trail.glowLayers then
        for _, glowFrame in ipairs(trail.glowLayers) do
            if glowFrame.texture then glowFrame.texture:Hide() end
        end
    end

    -- Cleanup particle effects
    if EasyCursorTrails.effectCleanupRegistry then
        for effectKey, cleanupFunc in pairs(EasyCursorTrails.effectCleanupRegistry) do
            if type(cleanupFunc) == "function" then
                cleanupFunc(trail)
            else
                --EasyCursorTrails.HandleError"Cleanup function missing for effect: " .. tostring(effectKey))
            end
        end
    end
end



function EasyCursorTrails.ApplyColorEffectTrail(trail, index, profile, effectsEnabled, defaults)
    if not trail or not trail.texture then
        --EasyCursorTrails.HandleError"ApplyColorEffectTrail: trail or texture missing.")
        return
    end

    ---------------------------------------------------------------
    -- 0) Respect trailEffectsEnabled toggle
    ---------------------------------------------------------------
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    local effectsEnabled = profile and profile.trailEffectsEnabled ~= false

    -- Always show trail texture
    trail.texture:Show()

    -- If effects are disabled, hide glow layers and exit
    if not effectsEnabled then
        if trail.glowLayers then
            for _, glowFrame in ipairs(trail.glowLayers) do
                if glowFrame.texture then glowFrame.texture:Hide() end
            end
        end
        return
    end

    ---------------------------------------------------------------
    -- 1) Gather config values from profile (or defaults)
    ---------------------------------------------------------------
    local defaults = EasyCursorTrails.defaults or {}

    local function getVal(key)
        return profile[key] ~= nil and profile[key] or defaults[key]
    end

    ---------------------------------------------------------------
    -- 2) Retrieve values
    ---------------------------------------------------------------
    local glowColor           = getVal("glowColor")         or { r=1, g=1, b=1, a=1 }
    local glowIntensity       = getVal("glowIntensity")     or 1
    local customGlowTex       = getVal("customGlowTexture") or "Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64"
    local textureOpacity      = getVal("trailTextureOpacity") or 1
    local glowIntensityFactor = getVal("glowIntensityFactor") or 0.8
    local effect              = getVal("trailColorEffect") or 1
    local trailColor          = getVal("trailColor") or { r=1, g=1, b=1, a=1 }

    ---------------------------------------------------------------
    -- 4) Initialize dynamic values
    ---------------------------------------------------------------
    EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail or 0
    EasyCursorTrails.pulseValueTrail = EasyCursorTrails.pulseValueTrail or 0.5
    index = index or 1

    local r, g, b, a = 1, 1, 1, 1
    local showGlow = false

    local function UpdatePulse()
        if EasyCursorTrails.UpdatePulseValue then
            EasyCursorTrails.UpdatePulseValue()
        else
            --EasyCursorTrails.HandleError"ApplyColorEffectTrail: Missing UpdatePulseValue function.")
        end
    end

    local function GetRainbowHue(offset)
        offset = offset or 0
        local hue = (EasyCursorTrails.colorIndexTrail + (index * 15) + offset) % 360
        return EasyCursorTrails.HSVToRGB(hue, 1, 1)
    end

        -- Always show trail texture
    trail.texture:Show()

    -- If effects are disabled, hide glow layers and clean up particles
    if not effectsEnabled then
        EasyCursorTrails.DisableTrailEffects(trail)
        return
    end


    ---------------------------------------------------------------
    -- 5) Color effect logic
    ---------------------------------------------------------------
    local pv = EasyCursorTrails.pulseValueTrail
    local hueOffset = EasyCursorTrails.colorIndexTrail * 3

    local effectMap = {
        [1]  = function() r, g, b, a = 1, 1, 1, 1 end,
        [2]  = function() r, g, b = GetRainbowHue(); a = 1 end,
        [3]  = function() UpdatePulse(); r, g, b, a = pv, pv, pv, 1 end,
        [4]  = function() r, g, b, a = 1, 1, 1, 0.9; showGlow = true end,
        [5]  = function() UpdatePulse(); local rr, gg, bb = GetRainbowHue(); r, g, b, a = rr * pv, gg * pv, bb * pv, 1 end,
        [6]  = function() UpdatePulse(); local rr, gg, bb = GetRainbowHue(); r, g, b, a = rr * pv, gg * pv, bb * pv, 1; showGlow = true end,
        [7]  = function() r, g, b, a = trailColor.r, trailColor.g, trailColor.b, trailColor.a end,
        [8]  = function() UpdatePulse(); r, g, b, a = trailColor.r * pv, trailColor.g * pv, trailColor.b * pv, trailColor.a end,
        [9]  = function() r, g, b, a = trailColor.r, trailColor.g, trailColor.b, 0.8; showGlow = true end,
        [10] = function() UpdatePulse(); r, g, b, a = trailColor.r * pv, trailColor.g * pv, trailColor.b * pv, trailColor.a; showGlow = true end,
        [11] = function() r, g, b = GetRainbowHue(); a = 1; showGlow = true end,
        [12] = function() r, g, b, a = 0.5, 0.7, 1, 0.8; showGlow = true end,
        [13] = function() UpdatePulse(); r, g, b = GetRainbowHue(); a = 0.9; showGlow = true end,
        [14] = function() UpdatePulse(); r = 0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail); g = 0.5 + 0.5 * math.cos(EasyCursorTrails.colorIndexTrail + 1); b = 0.5 + 0.5 * math.sin(EasyCursorTrails.colorIndexTrail + 2); a = pv end,
        [15] = function() r, g, b, a = 0.2, 0.1, 0.3, 0.7; showGlow = true end,
        [16] = function() UpdatePulse(); r, g, b, a = 0, 0.7 * pv, 0.6, 1; showGlow = true end,
        [17] = function() UpdatePulse(); r, g, b, a = 0.8 + 0.2 * pv, 0.8 + 0.2 * pv, 1, 1; showGlow = true end,
        [18] = function() UpdatePulse(); r, g, b = EasyCursorTrails.HSVToRGB(hueOffset % 360, 1, 1); a = 0.9; showGlow = true end,
        [19] = function() UpdatePulse(); r, g, b, a = 1, 0.4 + 0.4 * pv, 0.2, 1; showGlow = true end,
        [20] = function() r, g, b, a = 1, 1, 0.8, 0.9; showGlow = true end,
        [21] = function() UpdatePulse(); r, g, b, a = 0.3, 0.3, 0.7, pv end,
        [22] = function()
            r, g, b, a = 0.8, 0.9, 1, 1
            trail.texture:SetVertexColor(r, g, b, a * textureOpacity)
            EasyCursorTrails.ApplyTwinkleStarsEffect(trail, index, glowIntensityFactor)
        end
    }

    (effectMap[effect] or effectMap[1])()

    ---------------------------------------------------------------
    -- 6) Apply final color and overlays
    ---------------------------------------------------------------
    local finalA = a * textureOpacity
    trail.texture:SetVertexColor(r, g, b, finalA)

    if profile.enableTwinkleStars then
        EasyCursorTrails.ApplyTwinkleStarsEffect(trail, index, profile.glowIntensityFactor or 1)
    end

    if profile.enableStaticArc then
        EasyCursorTrails.ApplyStaticArcEffect(trail, index, profile.staticArcColor or EasyCursorTrails.defaults.staticArcColor)
    else
        EasyCursorTrails.ClearStaticArcEffect(trail)
    end

    ---------------------------------------------------------------
    -- 7) Glow Layers: radiant animated glow
    ---------------------------------------------------------------
    if showGlow then
        local glowFactor     = (EasyCursorTrails.glowFactorSlider and EasyCursorTrails.glowFactorSlider:GetValue())
                            or (EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.glowIntensityFactor)
                            or 0.8

        local safeAlpha      = math.max(math.min(glowFactor, 1.0), 0.6)
        local brightness     = math.min(glowFactor * 2.0, 3.0)
        local baseW          = math.max(trail:GetWidth() or 0, 1)
        local baseH          = math.max(trail:GetHeight() or 0, 1)
        local minGlowSize    = 28

        if not trail.glowLayers then
            trail.glowLayers = {}
            for i = 1, 3 do
                local glowFrame = CreateFrame("Frame", nil, trail)
                glowFrame:SetFrameLevel(math.max(trail:GetFrameLevel() - 5 - i, 0))
                glowFrame:SetPoint("CENTER", trail, "CENTER")

                local glowTex = glowFrame:CreateTexture(nil, "OVERLAY")
                glowTex:SetTexture(customGlowTex)
                glowTex:SetBlendMode("ADD")
                glowTex:SetAllPoints(true)
                glowFrame.texture = glowTex

                glowFrame:Hide()
                table.insert(trail.glowLayers, glowFrame)
            end
        end

                for i, glowLayer in ipairs(trail.glowLayers) do
            local expansion = 16 + (i * 14)  -- Larger expansion for stronger aura
            local glowW = math.max(baseW + expansion, minGlowSize)
            local glowH = math.max(baseH + expansion, minGlowSize)
            glowLayer:SetSize(glowW, glowH)

            -- Animate alpha with phase offset
            local time = GetTime()
            local phaseOffset = i * 0.6
            local pulse = 0.9 + 0.1 * math.sin(time * 3 + phaseOffset)
            local layerAlpha = math.min(safeAlpha * pulse, 1)

            glowLayer.texture:SetVertexColor(
                r * brightness,
                g * brightness,
                b * brightness,
                layerAlpha
            )

            -- Optional: rotate texture if supported
            if glowLayer.texture.SetRotation then
                local rotationSpeed = 20 + i * 10
                glowLayer.texture:SetRotation(math.rad((time * rotationSpeed) % 360))
            end

            if layerAlpha > 0.01 then
                glowLayer:Show()
            else
                glowLayer:Hide()
            end
        end
    end
end

function EasyCursorTrails.ApplyColorEffectCursor(elapsed)
    -------------------------------------------------------
    -- 1) Validate customCursor
    -------------------------------------------------------
    if not customCursor or not customCursor.texture then return end

    -------------------------------------------------------
    -- 2) Retrieve profile and defaults
    -------------------------------------------------------
    local profile = EasyCursorTrails.GetCurrentProfile() or {}
    local defaults = EasyCursorTrails.defaults or {}

    local function getVal(key)
        return profile[key] ~= nil and profile[key] or defaults[key]
    end

    -------------------------------------------------------
    -- 3) Gather config
    -------------------------------------------------------
    local glowColor     = getVal("glowColor")     or { r = 1, g = 1, b = 1, a = 1 }
    local glowIntensity = getVal("glowIntensity") or 1
    local effect        = getVal("cursorColorEffect") or 1
    local cursorColor   = getVal("cursorColor") or EasyCursorTrailsDB.cursorColor or { r = 1, g = 1, b = 1, a = 1 }

    -------------------------------------------------------
    -- 4) Blend Mode
    -------------------------------------------------------
    customCursor.texture:SetBlendMode("ADD")

    -------------------------------------------------------
    -- 5) Effect Logic
    -------------------------------------------------------
    if effect == 1 then
        -- Static White
        customCursor.texture:SetVertexColor(1, 1, 1, 1)

    elseif effect == 2 then
        -- Rainbow Effect (ignores cursorColor tint)
        customCursor.colorIndexCursor = (customCursor.colorIndexCursor or 0) + (elapsed or 0.05) * 60
        customCursor.colorIndexCursor = customCursor.colorIndexCursor % 360
        local hue = customCursor.colorIndexCursor
        local r, g, b = EasyCursorTrails.HSVToRGB(hue, 1, 1)
        customCursor.texture:SetVertexColor(r, g, b, cursorColor.a)

    elseif effect == 3 then
        -- Pulsing White
        EasyCursorTrails.ApplyPulsingEffect(cursorColor, elapsed)

    elseif effect == 4 then
        -- Rainbow + Pulsing
        EasyCursorTrails.ApplyRainbowPulsingEffect(cursorColor, elapsed)

    elseif effect == 5 then
        -- Static Custom Color
        customCursor.texture:SetVertexColor(cursorColor.r, cursorColor.g, cursorColor.b, cursorColor.a)

    elseif effect == 6 then
        -- Pulsing with Static Color
        EasyCursorTrails.ApplyPulsingEffect(cursorColor, elapsed)

    elseif effect == 7 then
        -- Glow Effect
        EasyCursorTrails.ApplyGlowEffect(cursorColor, elapsed)

    else
        -- Fallback
        customCursor.texture:SetVertexColor(1, 1, 1, 1)
    end
end

function EasyCursorTrails.ApplyPulsingEffect(cursorColor, elapsed)
    if not customCursor or not customCursor.texture then return end
    if type(cursorColor) ~= "table" then return end
    if type(elapsed) ~= "number" then return end

    -- 🔧 Pulse parameters
    local speed     = 1.1
    local minScale  = 0.3
    local maxScale  = 1.0
    local frameRate = GetFramerate() > 0 and GetFramerate() or 60
    local delta     = elapsed * speed

    -- 🔁 Pulse state
    local pulse     = tonumber(customCursor.pulseValueCursor) or 0.5
    local direction = tonumber(customCursor.pulseDirectionCursor) or -1

    pulse = pulse + direction * delta

    if pulse > maxScale then
        pulse = maxScale
        direction = -1
    elseif pulse < minScale then
        pulse = minScale
        direction = 1
    end

    customCursor.pulseValueCursor     = pulse
    customCursor.pulseDirectionCursor = direction

    -- 🎨 Apply pulsing color
    local r = (tonumber(cursorColor.r) or 1) * pulse
    local g = (tonumber(cursorColor.g) or 1) * pulse
    local b = (tonumber(cursorColor.b) or 1) * pulse
    local a = (tonumber(cursorColor.a) or 1) * (0.6 + 0.4 * pulse)

    customCursor.texture:SetVertexColor(r, g, b, a)
end


-- Helper: Apply Rainbow + Pulsing Effect
-- Helper: Apply Rainbow + Pulsing Effect
function EasyCursorTrails.ApplyRainbowPulsingEffect(cursorColor, elapsed)
    if not customCursor or not customCursor.texture then return end

    -- Rainbow cycling
    local rainbowSpeed = 60                      -- Degrees per second
    customCursor.colorIndexCursor = (customCursor.colorIndexCursor or 0) + (elapsed or 0.016) * rainbowSpeed
    customCursor.colorIndexCursor = customCursor.colorIndexCursor % 360
    local hue = customCursor.colorIndexCursor / 360
    local baseR, baseG, baseB = EasyCursorTrails.HSVToRGB(hue * 360, 1, 1)

    -- Pulsing effect
    local pulseSpeed = 1.5                       -- Pulse speed multiplier
    local minPulse   = 0.2                       -- Minimum brightness
    local maxPulse   = 1.0                       -- Maximum brightness
    local pulse      = customCursor.pulseValueCursor or 0.5
    local direction  = customCursor.pulseDirectionCursor or 1

    pulse = pulse + direction * (elapsed or 0.016) * pulseSpeed
    if pulse > maxPulse then
        pulse = maxPulse
        direction = -1
    elseif pulse < minPulse then
        pulse = minPulse
        direction = 1
    end

    customCursor.pulseValueCursor     = pulse
    customCursor.pulseDirectionCursor = direction

    -- Apply color with pulsing brightness and optional alpha shimmer
    local r = baseR * pulse
    local g = baseG * pulse
    local b = baseB * pulse
    local a = cursorColor.a * (0.6 + 0.4 * pulse) -- Optional: pulsing alpha

    customCursor.texture:SetVertexColor(r, g, b, a)
end

-- Helper: Apply Glow Effect
function EasyCursorTrails.ApplyGlowEffect(cursorColor, elapsed)
    if not customCursor or not customCursor.texture then return end

    -- Configurable parameters
    local glowSpeed   = 1.0                      -- Breathing speed
    local minAlpha    = 0.6                      -- Minimum glow
    local maxAlpha    = 1.0                      -- Maximum glow
    local trailSize   = customCursor:GetWidth() or 0
    local time        = GetTime()

    -- Sinusoidal breathing for smooth glow
    local pulse       = 0.5 + 0.5 * math.sin(time * glowSpeed)
    local alpha       = minAlpha + (maxAlpha - minAlpha) * pulse

    -- Boost alpha if trail is small
    if trailSize < 15 then
        alpha = math.max(alpha, 0.9)
    end

    -- Optional: glow tinting (slightly warmer glow)
    local glowR = math.min(cursorColor.r + 0.1, 1)
    local glowG = math.min(cursorColor.g + 0.05, 1)
    local glowB = math.min(cursorColor.b + 0.05, 1)

    -- Apply glow with pulsing alpha
    customCursor.texture:SetVertexColor(glowR, glowG, glowB, alpha)
end



-- Function to update glow effects based on saved or selected state
function EasyCursorTrails.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


function EasyCursorTrails.InitializeSettingsMenu()
    if EasyCursorTrails.menuInitialized then return end
    EasyCursorTrails.menuInitialized = true

    -- Reset settingsChanged flag
    EasyCursorTrails.settingsChanged = false

    -- Create the settings menu frame
    local menu = CreateFrame("Frame", "EasyCursorTrailsMenu", UIParent, "BasicFrameTemplateWithInset")
    menu:SetSize(1520, 720)

    -- Restore saved position if available
    local pos = EasyCursorTrailsDB.menuPosition
    if pos then
        menu:SetPoint(pos.point or "CENTER", UIParent, pos.relativePoint or "CENTER", pos.x or 0, pos.y or 0)
    else
        menu:SetPoint("CENTER", UIParent, "CENTER")
    end

    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
        }
        EasyCursorTrails.SaveToCurrentProfile("menuPosition", EasyCursorTrailsDB.menuPosition)
    end)

    -- Store reference
    EasyCursorTrails.settingsMenu = menu

    -- Populate dropdown after frame is created
    EasyCursorTrails.PopulateProfileDropdownAndSelectCurrent()

    -- Register other UI elements here (sliders, checkboxes, etc.)
    -- Example:
    -- EasyCursorTrails.CreateOpacitySlider(menu)
    -- EasyCursorTrails.CreateSparkleCheckbox(menu)

  local sloganText = "Unleash Your Creativity!"
local letterSpacing = 12
local startX = -(#sloganText * letterSpacing) -- start from the right edge and move left
local letters = {}
local tickers = {}

-- Cosmic color palette
local cosmicColors = {
    {0.8, 0.6, 1},   -- Lavender
    {0.4, 0.9, 1},   -- Icy Blue
    {1, 0.8, 0.4},   -- Golden Amber
    {0.9, 0.4, 0.6}, -- Rose
}

-- Function to spawn a falling sparkle near a letter
local function spawnSparkle(letter)
    local sparkle = menu:CreateTexture(nil, "ARTWORK")
    sparkle:SetTexture("Interface\\Cooldown\\star4")
    sparkle:SetSize(6, 6)
    sparkle:SetBlendMode("ADD")
    sparkle:SetAlpha(0.8)
    sparkle:SetPoint("CENTER", letter, "CENTER", math.random(-6, 6), math.random(-6, 6))

    local ag = sparkle:CreateAnimationGroup()

    local fall = ag:CreateAnimation("Translation")
    fall:SetOffset(math.random(-4, 4), math.random(-12, -6))
    fall:SetDuration(1.2)
    fall:SetSmoothing("IN_OUT")

    local fade = ag:CreateAnimation("Alpha")
    fade:SetFromAlpha(0.8)
    fade:SetToAlpha(0)
    fade:SetDuration(1.2)

    ag:SetScript("OnFinished", function()
        sparkle:Hide()
        sparkle:SetTexture(nil)
    end)

    ag:Play()
end

-- Create animated slogan letters (anchored to RIGHT)
for i = 1, #sloganText do
    local char = sloganText:sub(i, i)

    local letter = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    letter:SetText(char)
    letter:SetPoint("TOPRIGHT", menu, "TOPRIGHT", startX + (i - 1) * letterSpacing, -35)

    letter:SetShadowOffset(1, -1)
    letter:SetShadowColor(0, 0, 0, 0.8)
    table.insert(letters, letter)

    C_Timer.After(i * 0.1, function()
        local ticker = C_Timer.NewTicker(1.2, function()
            local color = cosmicColors[math.random(#cosmicColors)]
            letter:SetTextColor(unpack(color))
        end)
        table.insert(tickers, ticker)
    end)

    C_Timer.NewTicker(0.5, function()
        spawnSparkle(letter)
    end)
end

EasyCursorTrails.sloganTickers = tickers


-- 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", 570, 100)
    resetPositionButton:SetScript("OnClick", function()
        menu:ClearAllPoints()
        menu:SetPoint("CENTER", UIParent, "CENTER")
        EasyCursorTrailsDB.menuPosition = { point = "CENTER", relativePoint = "CENTER", x = 0, y = 0 }
        EasyCursorTrails.SaveToCurrentProfile("menuPosition", EasyCursorTrailsDB.menuPosition)
        --print("EasyCursorTrails: Menu position reset to default.")
    end)


   -- A text note (two lines) in a larger font
local reloadNote = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
reloadNote:SetPoint("TOP", resetPositionButton, "BOTTOM", 0, -20)
reloadNote:SetText("Hint:\nDon’t forget to save after updates or profile changes\n Effects will look much better on reload!")


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


    -- ============================
-- 1) Enable Trails Checkbox
-- ============================
local enableTrailsCheckbox = CreateFrame("CheckButton", "EnableTrailsCheckbox", menu, "UICheckButtonTemplate")
enableTrailsCheckbox:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", -50, -50)

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

-- Set the initial checked state based on the current profile

local currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
enableTrailsCheckbox:SetChecked(currentProfile and currentProfile.enableTrails or false)

enableTrailsCheckbox:SetScript("OnClick", function(self)
    local isEnabled = self:GetChecked()

    -- ✅ Force sync immediately into both DB and runtime table
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profile = EasyCursorTrailsDB.profiles[profileName]
    if profile then
        profile.enableTrails = isEnabled
        EasyCursorTrails.currentProfileTable.enableTrails = isEnabled
    end

    -- 🌀 Apply changes
    if isEnabled then
        if EasyCursorTrails.RebuildTrails then
            EasyCursorTrails.RebuildTrails()
        end
    else
        if EasyCursorTrails.trailPool then
            for _, layerPool in pairs(EasyCursorTrails.trailPool) do
                for _, trail in ipairs(layerPool) do
                    if trail then trail:Hide() end
                end
            end
        end
    end

    -- 🔁 Delay refresh to avoid race condition
    C_Timer.After(0.1, function()
        if EasyCursorTrails.RefreshSettingsUI then
            EasyCursorTrails.RefreshSettingsUI()
            -- ✅ Re-sync UI state AFTER everything else
            enableTrailsCheckbox:SetChecked(EasyCursorTrails.currentProfileTable.enableTrails)
        end
    end)
end)


-- Assign the checkbox to the namespace for easy access elsewhere
EasyCursorTrails.enableTrailsCheckbox = enableTrailsCheckbox

-- 📏 Separator Line Below Heading
local cursorSeparator = CreateFrame("Frame", nil, menu)
cursorSeparator:SetPoint("TOPLEFT", menuTitle, "BOTTOMLEFT", -580, -30)
cursorSeparator:SetSize(400, 1)

local sepTexture = cursorSeparator:CreateTexture(nil, "BACKGROUND")
sepTexture:SetAllPoints(true)
sepTexture:SetColorTexture(0.6, 0.6, 0.6, 0.8) -- Light gray line

-- 🧩 Cursor Settings Heading (Centered on Line)
local cursorHeading = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
cursorHeading:SetText("Cursor Settings")
cursorHeading:SetJustifyH("CENTER")
cursorHeading:SetPoint("CENTER", cursorSeparator, "CENTER", 0, 10)

    
    
-- Glow Below Cursor Checkbox
local glowBelowCheckbox = CreateFrame("CheckButton", "GlowBelowCursorCheckbox", menu, "UICheckButtonTemplate")
glowBelowCheckbox:SetPoint("TOPLEFT", cursorHeading, "BOTTOMLEFT", 80, -20)

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

-- 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()
    EasyCursorTrails.SaveToCurrentProfile("glowBelow", EasyCursorTrailsDB.glowBelow)

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


-- 🛠 Trail Size Start Slider
local trailSizeStartSlider =  EasyCursorTrails.CreateSlider(
    "TrailSizeStartSlider",
    menu,
    "Trail Size Start",
    1,
    100,
    1,
    EasyCursorTrailsDB.trailSizeStart or EasyCursorTrails.defaults.trailSizeStart,
    function(slider, value)
    EasyCursorTrailsDB.trailSizeStart = value
    EasyCursorTrails.SaveToCurrentProfile("trailSizeStart", value)

   
    -- Instant visual update
    EasyCursorTrails.RebuildTrails()

 end

)

-- Position and store reference
trailSizeStartSlider:SetPoint("TOPLEFT", enableTrailsCheckbox, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailSizeStartSlider = trailSizeStartSlider

-- 🛠 Trail Size End Slider
local trailSizeEndSlider =  EasyCursorTrails.CreateSlider(
    "TrailSizeEndSlider",
    menu,
    "Trail Size End",
    1,
    100,
    1,
    EasyCursorTrailsDB.trailSizeEnd or EasyCursorTrails.defaults.trailSizeEnd,
   function(slider, value)
    EasyCursorTrailsDB.trailSizeEnd = value
    EasyCursorTrails.settingsChanged = true
    EasyCursorTrails.SaveToCurrentProfile("trailSizeEnd", value)

   
    -- Instant visual update
    EasyCursorTrails.RebuildTrails()

    -- Debounced rebuild for safety (optional)
    
end

)

-- Position and store reference
trailSizeEndSlider:SetPoint("TOPLEFT", trailSizeStartSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailSizeEndSlider = trailSizeEndSlider




-- 🛠 Trail Count Slider
local profile = EasyCursorTrails.currentProfileTable
    or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    or EasyCursorTrails.defaults

local initialTrailCount = profile.trailCount or EasyCursorTrails.defaults.trailCount or 45

local trailCountSlider = EasyCursorTrails.CreateSlider(
    "TrailCountSlider",
    menu,
    "Trail Length",
    1, -- Avoid 0 if your code doesn’t handle zero trails well
    200,
    1,
    initialTrailCount,
    function(slider, value)
        local activeProfile = EasyCursorTrails.currentProfileTable
            or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not activeProfile then return end

        activeProfile.trailCount = value
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailCount", value)

        -- 🔁 Instant visual update
        EasyCursorTrails.RebuildTrails()
    end
)

trailCountSlider:SetPoint("TOPLEFT", trailSizeEndSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailCountSlider = trailCountSlider

-- 🛠 Trail Duplicate Slider
local trailDuplicatesSlider =  EasyCursorTrails.CreateSlider(
    "trailDuplicatesSlider",
    menu,
    "Trail Duplicate",
    1,      -- Minimum value
    20,     -- Maximum value
    1,      -- Step size
    EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.trailLayerCount
        or EasyCursorTrails.defaults.trailLayerCount
        or 14,
    function(slider, value)
        local newValue = math.floor(value)
        EasyCursorTrailsDB.trailLayerCount = newValue
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailLayerCount", newValue)
        
 
   
    -- Instant visual update
    EasyCursorTrails.RebuildTrails()

    -- Debounced rebuild for safety (optional)
    
    end, 2
    
)
trailDuplicatesSlider:SetPoint("TOPLEFT", trailCountSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailDuplicatesSlider = trailDuplicatesSlider
-- 🧼 Ensure defaults table and chainSegment default exist
EasyCursorTrails.defaults = EasyCursorTrails.defaults or {}
EasyCursorTrails.defaults.chainSegment = EasyCursorTrails.defaults.chainSegment or 10

-- 🔁 Deep copy utility to prevent shared references
local function DeepCopy(tbl)
    if type(tbl) ~= "table" then return tbl end
    local copy = {}
    for k, v in pairs(tbl) do
        copy[k] = DeepCopy(v)
    end
    return copy
end

-- 🔍 Determine current profile safely
local currentProfileName = EasyCursorTrailsDB.currentProfile or "Default"
EasyCursorTrailsDB.profiles[currentProfileName] = EasyCursorTrailsDB.profiles[currentProfileName] or {}
local rawProfile = EasyCursorTrailsDB.profiles[currentProfileName]
local currentProfile = DeepCopy(rawProfile)
EasyCursorTrails.currentProfileTable = currentProfile

-- 🛡 Normalize chainSegment value
local storedVal = currentProfile.chainSegment
if type(storedVal) == "table" then
    storedVal = tonumber(storedVal.value) or EasyCursorTrails.defaults.chainSegment
elseif type(storedVal) ~= "number" then
    storedVal = EasyCursorTrails.defaults.chainSegment
end

-- 🧪 Final effective value
local CHAIN_GAP_FACTOR = 1
local chainSegmentInitial = tonumber(storedVal) or EasyCursorTrails.defaults.chainSegment
local chainSegmentInitialEffective = chainSegmentInitial * CHAIN_GAP_FACTOR

-- 🛠 Safe setter for profile values
local function SetProfileValue(key, value)
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    EasyCursorTrailsDB.profiles[profileName] = EasyCursorTrailsDB.profiles[profileName] or {}
    EasyCursorTrailsDB.profiles[profileName][key] = value
end

-- 🧩 Create Chain Segment Slider
local chainSegmentSlider = EasyCursorTrails.CreateSlider(
    "ChainSegmentSlider",
    menu,
    "Trail Distance",
    1,
    100,
    1,
    chainSegmentInitial,
    function(slider, value)
        local effectiveGap = value * CHAIN_GAP_FACTOR
        SetProfileValue("chainSegment", effectiveGap)
        EasyCursorTrails.settingsChanged = true

        if slider.editBox then
            slider.editBox:SetText(string.format("%.0f", effectiveGap))
        end

        -- 🔄 Trigger visual update
        EasyCursorTrails.RebuildTrails()
    end,
    2
)

-- 📍 Position slider
chainSegmentSlider:SetPoint("TOPLEFT", trailDuplicatesSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.chainSegmentSlider = chainSegmentSlider

-- 🖊️ Initialize edit box display
if chainSegmentSlider.editBox then
    chainSegmentSlider.editBox:SetText(string.format("%.0f", chainSegmentInitialEffective))
end



EasyCursorTrails.defaults.trailInitialSeparation = EasyCursorTrails.defaults.trailInitialSeparation or 50

-- 🛠 Create Trail Layer Separation Slider
local trailInitialSeparationSlider =  EasyCursorTrails.CreateSlider(
    "TrailInitialSeparationSlider",
    menu,
    "Trail Separation",
    36,
    500,
    1,
    EasyCursorTrailsDB.trailInitialSeparation or EasyCursorTrails.defaults.trailInitialSeparation,
    function(slider, value)
        EasyCursorTrailsDB.trailInitialSeparation = value
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailInitialSeparation", value)
        
    -- Instant visual update
    EasyCursorTrails.RebuildTrails()

    -- Debounced rebuild for safety (optional)
    
    end, 2
)
trailInitialSeparationSlider:SetPoint("TOPLEFT", chainSegmentSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailInitialSeparationSlider = trailInitialSeparationSlider

-- 🛠️ Ensure default fallback
EasyCursorTrails.defaults.trailTextureOpacity = EasyCursorTrails.defaults.trailTextureOpacity or 1.0

-- 🔍 Determine initial value
local currentProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] or {}
local initialOpacity = currentProfile.trailTextureOpacity or EasyCursorTrails.defaults.trailTextureOpacity

-- 🎚️ Create Trail Texture Opacity Slider
local trailTextureOpacitySlider =  EasyCursorTrails.CreateSlider(
    "trailTextureOpacity",
    menu,
    "Texture Opacity",
    0.0, -- Min
    1.0, -- Max
    0.01, -- Step
    initialOpacity,
    function(slider, value)
        -- 1️⃣ Update profile
        local currentProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not currentProfile then
            --EasyCursorTrails.HandleError"trailTextureOpacitySlider: current profile not found.")
            return
        end

        currentProfile.trailTextureOpacity = value
        EasyCursorTrails.SaveToCurrentProfile("trailTextureOpacity", value)

        -- 2️⃣ Rebuild trails
        EasyCursorTrails.RebuildTrails()

        -- 3️⃣ Apply opacity to trail textures
        local function applyTrailOpacity(trailPool)
            for _, trail in ipairs(trailPool or {}) do
                if trail.texture then
                    local r, g, b = trail.texture:GetVertexColor()
                    trail.texture:SetVertexColor(r, g, b, value)
                end
            end
        end

        for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
            applyTrailOpacity(layerPool)
        end

        -- 4️⃣ Update preview texture
        if EasyCursorTrails.TrailPreview and EasyCursorTrails.TrailPreview.texture then
            local r, g, b = EasyCursorTrails.TrailPreview.texture:GetVertexColor()
            EasyCursorTrails.TrailPreview.texture:SetVertexColor(r, g, b, value)
        end
    end,
    2 -- Decimal precision
)


-- 📍 Positioning
trailTextureOpacitySlider:SetPoint("TOPLEFT", trailInitialSeparationSlider, "CENTER", -75, -110)
EasyCursorTrails.trailTextureOpacitySlider = trailTextureOpacitySlider

-- 🌐 Ensure default values
EasyCursorTrails.defaults.glowIntensityFactor = EasyCursorTrails.defaults.glowIntensityFactor or 0.8
EasyCursorTrails.defaults.trailUpdateMultiplier = EasyCursorTrails.defaults.trailUpdateMultiplier or 1

-- 🔍 Determine initial profile values
local currentProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] or {}
local initialGlowFactor = currentProfile.glowIntensityFactor or EasyCursorTrails.defaults.glowIntensityFactor
local initialFollowSpeed = currentProfile.trailUpdateMultiplier or EasyCursorTrails.defaults.trailUpdateMultiplier

-- 🎚️ Create Glow Intensity Slider
local glowFactorSlider =  EasyCursorTrails.CreateSlider(
    "glowIntensityFactor",
    menu,
    "Glow Intensity",
    0.0, -- Min
    1.0, -- Max
    0.01, -- Step
    initialGlowFactor,
    function(slider, value)
        -- 1️⃣ Update profile
        local currentProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not currentProfile then
            --EasyCursorTrails.HandleError"glowIntensityFactorSlider: current profile not found.")
            return
        end

        currentProfile.glowIntensityFactor = value
        EasyCursorTrails.SaveToCurrentProfile("glowIntensityFactor", value)

        -- 2️⃣ Rebuild trails
        EasyCursorTrails.RebuildTrails()

        -- 3️⃣ Re-apply color logic
        if EasyCursorTrails.trailPool and EasyCursorTrails.ApplyColorEffectTrail then
            for _, layerPool in pairs(EasyCursorTrails.trailPool) do
                for i, trail in ipairs(layerPool) do
                    if trail and trail.texture then
                        EasyCursorTrails.ApplyColorEffectTrail(trail, i)
                    end
                end
            end
        end

        -- 4️⃣ Apply glow intensity using base color
        local function applyGlowIntensity(trailPool)
            for _, trail in ipairs(trailPool or {}) do
                if trail.glowLayers then
                    for _, glowFrame in ipairs(trail.glowLayers) do
                        local tex = glowFrame.texture
                        local base = glowFrame.baseColor
                        if tex and base then
                        
                            local fadedAlpha = math.max(0.05, base.a * value)
                            tex:SetVertexColor(base.r * value, base.g * value, base.b * value, fadedAlpha)

                        end
                    end
                end
            end
        end

        for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
            applyGlowIntensity(layerPool)
        end

        -- 5️⃣ Update preview glow
        applyGlowIntensity(EasyCursorTrails.TrailPreview and EasyCursorTrails.TrailPreview.glowLayers)
    end,
    2 -- Decimal precision
)

glowFactorSlider:SetPoint("TOPLEFT", trailTextureOpacitySlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.glowFactorSlider = glowFactorSlider

-- 🛠 Create Trail Follow Speed Slider
local trailFollowSpeedSlider =  EasyCursorTrails.CreateSlider(
    "TrailFollowSpeedSlider",
    menu,
    "Trail Speed",
    1,
    100,
    1,
    initialFollowSpeed,
    function(slider, value)
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[currentProfileName]
        if not profile then
            --EasyCursorTrails.HandleError"trailFollowSpeedSlider: Current profile not found.")
            return
        end

        profile.trailUpdateMultiplier = value
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailUpdateMultiplier", value)
            -- Instant visual update
            EasyCursorTrails.RebuildTrails()

            -- Debounced rebuild for safety (optional)
            
    end
)
trailFollowSpeedSlider:SetPoint("TOPLEFT", glowFactorSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailFollowSpeedSlider = trailFollowSpeedSlider


if trailFollowSpeedSlider.editBox then
    trailFollowSpeedSlider.editBox:SetText(string.format("%.0f", initialFollowSpeed))
    trailFollowSpeedSlider.editBox:SetScript("OnEnterPressed", function(self)
        local text = self:GetText()
        local num = tonumber(text)
        if num then
            trailFollowSpeedSlider:SetValue(num, true)
            local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[currentProfileName]
            if profile then
                profile.trailUpdateMultiplier = num
                EasyCursorTrails.SaveToCurrentProfile("trailUpdateMultiplier", num)
                
                            -- Instant visual update
                EasyCursorTrails.RebuildTrails()

                -- Debounced rebuild for safety (optional)
                
            end
        end
        self:ClearFocus()
    end)
      menu:Hide()


end


function EasyCursorTrails.UpdateTrailOffsets()
    local db = EasyCursorTrailsDB
    local defaults = EasyCursorTrails.defaults or {}
    local profile = db.profiles[db.currentProfile or "Default"]
    if not profile then return end

    local trailOffsetX = tonumber(profile.trailOffsetX) or tonumber(defaults.trailOffsetX) or 0
    local trailOffsetY = tonumber(profile.trailOffsetY) or tonumber(defaults.trailOffsetY) or 0
    local maxOffset     = tonumber(profile.trailLayerSpacingSlider) or 30
    local initialSep    = tonumber(profile.trailInitialSeparation) or 30
    local chainSegment  = tonumber(profile.chainSegment) or tonumber(defaults.chainSegment) or 10
    local bufferSize    = tonumber(EasyCursorTrails.bufferSize) or 100

    local trailPool = EasyCursorTrails.trailPool
    if not trailPool or not trailPool[1] or #trailPool[1] < 1 then return end
    local firstTrail = trailPool[1][1]

    -- 🧠 Use ring buffer position or fallback to cursor
    local posIndex = EasyCursorTrails.headIndex - 1
    if posIndex < 1 then posIndex = posIndex + bufferSize end
    local history = EasyCursorTrails.cursorHistory
    local basePos = history and history[posIndex]

    if not basePos then
        local scale = UIParent:GetEffectiveScale()
        local x, y = GetCursorPosition()
        basePos = { x = x / scale, y = y / scale }
    end

    -- 🌀 Compute dynamic offset
    local angle = 0
    local frac = 0
    local distance = initialSep + frac * (maxOffset - initialSep)
    local effectIndex = profile.trailMovementEffect or 1
    local movementFunc = EasyCursorTrails.movementEffects and EasyCursorTrails.movementEffects[effectIndex]
                        or function() return {0, 0} end
    local offset = movementFunc(angle, frac, distance, profile, 1, 0, maxOffset)
    local dx = (offset[1] or 0) + distance * math.cos(angle)
    local dy = (offset[2] or 0) + distance * math.sin(angle)

    -- 🎯 Final position
    local finalX = basePos.x + trailOffsetX + dx
    local finalY = basePos.y + trailOffsetY + dy

    firstTrail:ClearAllPoints()
    firstTrail:SetPoint("CENTER", UIParent, "BOTTOMLEFT", finalX, finalY)
    firstTrail:Show()

    -- 🧼 Hide other preview trails
    for i = 2, #trailPool[1] do
        local trail = trailPool[1][i]
        if trail and trail:IsShown() then trail:Hide() end
    end

    -- ✨ Update glow frames
    if EasyCursorTrails.UpdateGlowFrames then
        EasyCursorTrails.UpdateGlowFrames()
    else
        --EasyCursorTrails.HandleError"UpdateTrailOffsets: UpdateGlowFrames function is missing.")
    end
end



--------------------------------------------
-- 6) Trail Offset X Slider
--------------------------------------------
local trailOffsetXSlider =  EasyCursorTrails.CreateSlider(
    "TrailOffsetXSlider",
    menu,
    "Offset-Left or Right",
    -100,
    100,
    1,
    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailOffsetX or EasyCursorTrails.defaults.trailOffsetX,
    function(slider, value)
        EasyCursorTrails.SaveToCurrentProfile("trailOffsetX", value)
        EasyCursorTrails.RebuildTrails()
        if EasyCursorTrails.UpdateTrailOffsets then
            EasyCursorTrails.UpdateTrailOffsets()
        end
    end
)
trailOffsetXSlider:SetPoint("TOPLEFT", trailInitialSeparationSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailOffsetXSlider = trailOffsetXSlider

--------------------------------------------
-- 7) Trail Offset Y Slider
--------------------------------------------
local trailOffsetYSlider =  EasyCursorTrails.CreateSlider(
    "TrailOffsetYSlider",
    menu,
    "Offset-Up or Down",
    -100,
    100,
    1,
    EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].trailOffsetY or EasyCursorTrails.defaults.trailOffsetY,
    function(slider, value)
        EasyCursorTrails.SaveToCurrentProfile("trailOffsetY", value)
        EasyCursorTrails.RebuildTrails()
        if EasyCursorTrails.UpdateTrailOffsets then
            EasyCursorTrails.UpdateTrailOffsets()
        end
    end
)
trailOffsetYSlider:SetPoint("TOPLEFT", trailOffsetXSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailOffsetYSlider = trailOffsetYSlider


--======================================================================================================

-------------------------------
-- Effects Settings Section
-------------------------------
-- 🌀 Trail Effects Settings (left side)
local trailEffectsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
trailEffectsHeader:SetPoint("TOPLEFT", menuTitle, "CENTER", -150, -28)
trailEffectsHeader:SetText("Trail Effects Settings")

-- ✨ Trail Particle Effects (right side)
local particleEffectsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
particleEffectsHeader:SetPoint("TOPRIGHT", menuTitle, "CENTER", 320, -28)
particleEffectsHeader:SetText("Trail Particle Effects")



function EasyCursorTrails.CreateValidatedDropdown(name, parent, label, options, selectedIndex, onSelect, maxPerLevel)
    maxPerLevel = maxPerLevel or 30 -- Default to 30 for flat lists

    local dropdown = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate")
    dropdown:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 30, 20) -- Adjust positioning as needed

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


    -- Initialize the dropdown
    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        if level == 1 then
            for i, option in ipairs(options) do
                local info = UIDropDownMenu_CreateInfo()
                info.text = option.text
                info.arg1 = i
                info.func = function(_, arg1)
                    onSelect(arg1)
                    UIDropDownMenu_SetSelectedID(dropdown, arg1)
                    UIDropDownMenu_SetText(dropdown, options[arg1].text)
                
                end
                UIDropDownMenu_AddButton(info, level)
            end
        end
    end)

    -- Set the selected option based on selectedIndex
    if selectedIndex and selectedIndex <= #options then
        UIDropDownMenu_SetSelectedID(dropdown, selectedIndex)
        UIDropDownMenu_SetText(dropdown, options[selectedIndex].text)
    elseif #options > 0 then
        UIDropDownMenu_SetSelectedID(dropdown, 1)
        UIDropDownMenu_SetText(dropdown, options[1].text)
    else
        UIDropDownMenu_SetSelectedID(dropdown, 0)
        UIDropDownMenu_SetText(dropdown, "None")
    end

    -- Store onSelect as a property for later reference
    dropdown.onSelect = onSelect

    return dropdown
end


function EasyCursorTrails.PopulateTrailTextureDropdown()
    local MAX_PER_LEVEL = 30

    -- Ensure trailTextures exist before proceeding
    if not EasyCursorTrails.trailTextures or #EasyCursorTrails.trailTextures == 0 then
        EasyCursorTrails.trailTextures = {
            { name = "Default Texture", texture = "Interface\\CURSOR\\Arrow" }
        }
    end

    -- Retrieve active profile
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profileSettings = EasyCursorTrailsDB.profiles[profileName] or {}
    local defaults = EasyCursorTrails.defaults or {}

    -- Get saved trail texture index
    local storedIndex = tonumber(profileSettings.trailTexture) or tonumber(defaults.trailTexture) or 1
    if not EasyCursorTrails.trailTextures[storedIndex] then
        storedIndex = 1
        EasyCursorTrails.SaveToCurrentProfile("trailTexture", storedIndex)
    end

    -- Create dropdown options
    local textureOptions = {}
    for i, textureInfo in ipairs(EasyCursorTrails.trailTextures) do
        table.insert(textureOptions, {
            text = textureInfo.name,
            icon = textureInfo.texture
        })
    end

    -- Ensure dropdown exists
    if not EasyCursorTrails.trailTextureDropdown then return end

    -- Initialize dropdown
    UIDropDownMenu_Initialize(EasyCursorTrails.trailTextureDropdown, function(self, level, menuList)
        local function addOption(i)
            local option = textureOptions[i]
            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()
                EasyCursorTrails.SaveToCurrentProfile("trailTexture", i)
                EasyCursorTrails.settingsChanged = true
                EasyCursorTrails.RebuildTrails()

                if EasyCursorTrails.RefreshSettingsUI then
                    EasyCursorTrails.RefreshSettingsUI()
                end

                EasyCursorTrails.trailTextureDropdown:SetSelectedIndex(i)
                CloseDropDownMenus()
            end
            UIDropDownMenu_AddButton(info, level)
        end

        if level == 1 then
            for i = 1, math.min(#textureOptions, MAX_PER_LEVEL) do
                addOption(i)
            end

            if #textureOptions > MAX_PER_LEVEL then
                local info = UIDropDownMenu_CreateInfo()
                info.text = "More..."
                info.hasArrow = true
                info.notCheckable = true
                info.menuList = "TrailTextureDropdown_EXTRA_OPTIONS"
                UIDropDownMenu_AddButton(info, level)
            end

        elseif level == 2 and menuList == "TrailTextureDropdown_EXTRA_OPTIONS" then
            for i = MAX_PER_LEVEL + 1, #textureOptions do
                addOption(i)
            end
        end
    end)

    -- Add SetSelectedIndex method for external sync
    function EasyCursorTrails.trailTextureDropdown:SetSelectedIndex(index)
        local option = textureOptions[index]
        if not option then return end
        UIDropDownMenu_SetSelectedID(EasyCursorTrails.trailTextureDropdown, index)
        UIDropDownMenu_SetText(EasyCursorTrails.trailTextureDropdown, option.text or "Unknown")
    end

    -- Delay sync to ensure dropdown is ready
    C_Timer.After(0.1, function()
        EasyCursorTrails.trailTextureDropdown:SetSelectedIndex(storedIndex)
    end)
end


function EasyCursorTrails.RefreshTrailDropdowns()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profileSettings = EasyCursorTrailsDB.profiles[profileName] or {}
    local defaults = EasyCursorTrails.defaults or {}

    -------------------------------
    -- Refresh Trail Texture Dropdown
    -------------------------------
    local textureIndex = profileSettings.trailTexture or defaults.trailTexture or 1
    if EasyCursorTrails.trailTextureDropdown and EasyCursorTrails.trailTextures then
        if not EasyCursorTrails.trailTextures[textureIndex] then
            textureIndex = 1
        end
        UIDropDownMenu_SetSelectedID(EasyCursorTrails.trailTextureDropdown, textureIndex)
        local selectedTextureName = EasyCursorTrails.trailTextures[textureIndex].name or "Unknown"
        UIDropDownMenu_SetText(EasyCursorTrails.trailTextureDropdown, selectedTextureName)
    else
       -- ----print("Error: trailTextureDropdown or trailTextures is nil!")
    end

    -------------------------------
    -- Refresh Trail Movement Effects Dropdown
    -------------------------------
    local movementIndex = profileSettings.trailMovementEffect or defaults.trailMovementEffect or 1
    if EasyCursorTrails.trailMovementEffectDropdown and EasyCursorTrails.trailMovementEffectOptions then
        if not EasyCursorTrails.trailMovementEffectOptions[movementIndex] then
            movementIndex = 1
        end
        UIDropDownMenu_SetSelectedID(EasyCursorTrails.trailMovementEffectDropdown, movementIndex)
        local selectedMovementText = EasyCursorTrails.trailMovementEffectOptions[movementIndex].text or "Custom Movement Effect"
        UIDropDownMenu_SetText(EasyCursorTrails.trailMovementEffectDropdown, selectedMovementText)
    else
       -- ----print("Error: trailMovementEffectDropdown or trailMovementEffectOptions is nil!")
    end
end



-- Function to retrieve saved trail texture index with fallbacks
function EasyCursorTrails.GetSavedTrailTextureIndex()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profileSettings = EasyCursorTrailsDB.profiles[profileName] or {}
    local defaultSettings = EasyCursorTrails.defaults or {}

    local savedIndex = profileSettings.trailTexture or defaultSettings.trailTexture or 1

    -- Validate Index
    if not EasyCursorTrails.trailTextures or not EasyCursorTrails.trailTextures[savedIndex] then
        savedIndex = 1 -- Default if invalid
    end

    return savedIndex
end


-- 🧼 Ensure profile access

local currentProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[currentProfileName] or {}
EasyCursorTrails.currentProfileTable = currentProfile


-- 🛠 Create Trail Texture Dropdown
EasyCursorTrails.trailTextureDropdown = EasyCursorTrails.CreateValidatedDropdown(
    "TrailTextureDropdown", 
    menu,
    "Trail Textures",
    EasyCursorTrails.trailTextures,  -- Available textures
    EasyCursorTrails.GetSavedTrailTextureIndex(), -- Saved index
    function(textureIndex)
        currentProfile.trailTexture = textureIndex
        EasyCursorTrails.SaveToCurrentProfile("trailTexture", textureIndex)
        
       -- Instant visual update
    EasyCursorTrails.RebuildTrails()

    -- Debounced rebuild for safety (optional)
    
    end
)



EasyCursorTrails.trailTextureDropdown:SetPoint("TOPLEFT", EasyCursorTrails.trailFollowSpeedSlider, "BOTTOMLEFT", 120, -45)

-- Populate textures **before** updating the selection
EasyCursorTrails.PopulateTrailTextureDropdown()

function EasyCursorTrails.CreateCheckbox(name, parent, label, checked, onClick, tooltipText)
    local checkbox = CreateFrame("CheckButton", name, parent, "InterfaceOptionsCheckButtonTemplate")
    checkbox:SetChecked(checked == true)
    checkbox.Text:SetText(label or "Checkbox")

    -- 🔊 Click handler
    checkbox:SetScript("OnClick", function(self)
        local isChecked = self:GetChecked()
        PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
        if type(onClick) == "function" then
            onClick(isChecked)
        end
    end)

    -- 🧩 Optional tooltip
    if tooltipText then
        checkbox:SetScript("OnEnter", function()
            GameTooltip:SetOwner(checkbox, "ANCHOR_RIGHT")
            GameTooltip:SetText(tooltipText, nil, nil, nil, nil, true)
            GameTooltip:Show()
        end)
        checkbox:SetScript("OnLeave", function()
            GameTooltip:Hide()
        end)
    end

    return checkbox
end


function EasyCursorTrails.CreateColorPicker(name, parent, label, initialColor, onColorChanged)
    -- 🛡️ Sanitize initial color input
    local function sanitizeColor(c)
        if type(c) ~= "table" or type(c.r) ~= "number" or type(c.g) ~= "number" or type(c.b) ~= "number" then
            return { r = 1, g = 1, b = 1, a = 1 }
        end
        c.a = type(c.a) == "number" and c.a or 1
        return c
    end
    initialColor = sanitizeColor(initialColor)

    local picker = CreateFrame("Button", name, parent, "UIPanelButtonTemplate")
    picker:SetSize(24, 24)
    picker:SetFrameStrata("MEDIUM")
    picker:EnableMouse(true)

    -- 🎨 Swatch texture
    local swatch = picker:CreateTexture(nil, "ARTWORK")
    swatch:SetAllPoints()
    swatch:SetColorTexture(initialColor.r, initialColor.g, initialColor.b, initialColor.a)
    picker.swatch = swatch

    -- 🎀 Border
    local border = picker:CreateTexture(nil, "OVERLAY")
    border:SetTexture("Interface\\Common\\WhiteIconFrame")
    border:SetAllPoints()
    border:SetVertexColor(1, 0.82, 0)
    picker.border = border

    -- 🏷️ Optional label
    if label and label ~= "" then
        local labelText = picker:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        labelText:SetPoint("LEFT", picker, "RIGHT", 8, 1)
        labelText:SetText(label)
        picker.label = labelText
    end

    -- 🖱️ Tooltip
    picker:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText("Click to pick a color.", 1, 1, 1)
        GameTooltip:Show()
    end)
    picker:SetScript("OnLeave", GameTooltip_Hide)

    -- 🖌️ Click to open color picker
    picker:SetScript("OnClick", function()
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        local color = sanitizeColor(profile and profile[name .. "Color"] or initialColor)

        local r, g, b, a = color.r, color.g, color.b, color.a

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

        local function apply()
            local nr, ng, nb = ColorPickerFrame:GetColorRGB()
            local na = 1 - (ColorPickerFrame.opacity or 0)
            if type(onColorChanged) == "function" then
                onColorChanged(nr, ng, nb, na)
            end
            swatch:SetColorTexture(nr, ng, nb, na)
        end

        local function cancel()
            local pv = ColorPickerFrame.previousValues
            if pv and type(onColorChanged) == "function" then
                onColorChanged(pv[1], pv[2], pv[3], pv[4])
                swatch:SetColorTexture(pv[1], pv[2], pv[3], pv[4])
            end
        end

        ColorPickerFrame.func = apply
        ColorPickerFrame.swatchFunc = apply
        ColorPickerFrame.opacityFunc = apply
        ColorPickerFrame.cancelFunc = cancel

        ColorPickerFrame:Show()
    end)

    -- 🧭 Store reference for external access (e.g., in ResetColorFeature)
    EasyCursorTrails[name .. "ColorPicker"] = picker

    return picker
end




--==============================================================================================================
function EasyCursorTrails:SetTrailEffectsOverride(disable)
    local profile = self.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    self.effectTickerRegistry = self.effectTickerRegistry or {}
    self.liveEffects = self.liveEffects or {}

    if disable then
        -- 🧠 Backup current state
        self._effectStateBackup = {}
        for effectFlag, ticker in pairs(self.effectTickerRegistry) do
            self._effectStateBackup[effectFlag] = {
                profile = profile[effectFlag],
                live = self.liveEffects[effectFlag]
            }

            profile[effectFlag] = false
            self.liveEffects[effectFlag] = false

            if ticker.stop and type(ticker.stop) == "function" then
                ticker.stop()
            end
        end

        self._effectStateBackup.enableTrailEffects = profile.enableTrailEffects
        profile.enableTrailEffects = false

        -- 🧼 Clear visuals
        for _, pool in pairs(self.trailPool or {}) do
            for _, trail in ipairs(pool) do
                if self.DisableTrailEffects then
                    self.DisableTrailEffects(trail)
                end
            end
        end

        self.effectsPaused = true
        if self.PauseActiveEffects then self.PauseActiveEffects() end

    else
        local backup = self._effectStateBackup
        if backup then
            -- 🔁 Restore backed-up state
            for effectFlag in pairs(self.effectTickerRegistry) do
                local saved = backup[effectFlag]
                profile[effectFlag] = saved and saved.profile or false
                self.liveEffects[effectFlag] = profile[effectFlag] == true
            end

            profile.enableTrailEffects = backup.enableTrailEffects ~= false
            self._effectStateBackup = nil
        else
            -- 🧯 Fallback: enable all effects from profile
            for effectFlag in pairs(self.effectTickerRegistry) do
                self.liveEffects[effectFlag] = profile[effectFlag] == true
            end
            profile.enableTrailEffects = true
        end

        self.effectsPaused = not profile.enableTrailEffects
        if profile.enableTrailEffects and self.ResumePausedEffects then
            self.ResumePausedEffects()
        end
    end

    -- 🔄 Rebuild trails
    if self.RebuildTrails then
        self.RebuildTrails()
    end

    -- 🎨 Reapply visuals
    if profile.enableTrailEffects and self.trailPool and self.ApplyEnabledEffects then
        for _, pool in pairs(self.trailPool) do
            for _, trail in ipairs(pool) do
                self.ApplyEnabledEffects(trail)
            end
        end
    end

    -- 🔁 Restart tickers
    if profile.enableTrailEffects then
        for effectFlag, ticker in pairs(self.effectTickerRegistry) do
            if self.liveEffects[effectFlag] and ticker.start and type(ticker.start) == "function" then
                ticker.start()
            end
        end

        -- 🌸 Restart Spring Season Trails if enabled
        if profile.enableSpringSeasonTrails and type(self.StartNatureTicker) == "function" then
            self.StartNatureTicker()
        end
    end

    -- 🔁 Refresh UI
    if self.RefreshSettingsUI then
        self.RefreshSettingsUI()
    end

    -- 🔘 Sync checkboxes from profile
    if self.SyncEffectCheckboxStates then
        self.SyncEffectCheckboxStates(true)
    end

    if self.disableTrailEffectsCheckbox then
        self.disableTrailEffectsCheckbox:SetChecked(disable)
    end
end


function EasyCursorTrails.SyncEffectCheckboxStates(forceSync)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    local effectsAllowed = profile.enableTrailEffects ~= false

    local checkboxMap = {
        connectTrails              = "connectTrailsCheckbox",
        enableEmbers               = "emberCheckbox",
        enableFire                 = "fireEffectCheckbox",
        enableLightningEmbers      = "lightningEmberCheckbox",
        enableLightningSparks      = "lightningSparkCheckbox",
        enableSmokeEffect          = "smokeEffectCheckbox",
        enableSmokeEffectTrails    = "smokeTrailCheckbox",
        enableSpringSeasonTrails   = "springSeasonCheckbox",
        enableStarDust             = "starDustCheckbox",
        enableStarEmbers           = "starEmberCheckbox",
        enableStaticArc            = "staticArcEffectCheckbox",
        enableTrailShadows         = "shadowEffectCheckbox",
        enableTwinkleStars         = "twinkleStarsCheckbox",
    }

    for effectFlag, checkboxVar in pairs(checkboxMap) do
        local checkbox = EasyCursorTrails[checkboxVar]
        if checkbox and checkbox.SetChecked then
            local state = (forceSync or effectsAllowed) and profile[effectFlag] == true
            checkbox:SetChecked(state)
        end
    end
end


-- 🧱 Create checkbox frame
local disableTrailEffectsCheckbox = CreateFrame("CheckButton", "DisableTrailEffectsCheckbox", menu, "UICheckButtonTemplate")
disableTrailEffectsCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.trailSizeStartSlider, "TOPRIGHT", 126, 50)

-- 🏷️ Label
disableTrailEffectsCheckbox.text = disableTrailEffectsCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormal")
disableTrailEffectsCheckbox.text:SetPoint("LEFT", disableTrailEffectsCheckbox, "RIGHT", 8, 0)
disableTrailEffectsCheckbox.text:SetText("Disable Trail Effects")

-- 🧠 Tooltip support
disableTrailEffectsCheckbox:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:SetText("Disables all glow, fire, lightning, smoke, twinkle, and ember effects.\nTrail textures remain visible.", nil, nil, nil, nil, true)
    GameTooltip:Show()
end)

disableTrailEffectsCheckbox:SetScript("OnLeave", GameTooltip_Hide)

-- 📦 Load initial state from profile (inverted logic)
local profile = EasyCursorTrails.GetCurrentProfile() or {}
local trailEffectsEnabled = profile.enableTrailEffects
if trailEffectsEnabled == nil then
    trailEffectsEnabled = EasyCursorTrails.defaults and EasyCursorTrails.defaults.enableTrailEffects or true
end
disableTrailEffectsCheckbox:SetChecked(not trailEffectsEnabled)

-- 🧠 OnClick logic
disableTrailEffectsCheckbox:SetScript("OnClick", function(self)
    if EasyCursorTrails.isSyncingUI then return end
    local disable = self:GetChecked()
    EasyCursorTrails:SetTrailEffectsOverride(disable)
end)

-- 🔗 Store reference
EasyCursorTrails.disableTrailEffectsCheckbox = disableTrailEffectsCheckbox



--====================================================================================================
-- 🧩 Section Header: Trail Effects
local trailEffectsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
trailEffectsHeader:SetPoint("TOPLEFT", EasyCursorTrails.trailSizeStartSlider, "TOPRIGHT", 130, 0)
trailEffectsHeader:SetText("Trail Effects")

-- 🧩 Section Header: Trail Effects
local trailColorEffectsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
trailColorEffectsHeader:SetPoint("TOPLEFT", EasyCursorTrails.trailSizeStartSlider, "TOPRIGHT", 245, 0)
trailColorEffectsHeader:SetText("Pick a Color")

--============================================================================================================

local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]


function EasyCursorTrails.UpdateTwinkleTrailColors()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableTwinkleStars then return end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for i, trail in ipairs(pool) do
            -- 🧱 Ensure sparkle effect is applied
            if not trail.twinkleSpark or not trail.twinkleSpark.texture then
                EasyCursorTrails.ApplyTwinkleStarsEffect(trail, i, profile.twinkleStarsIntensity or 1)
            end

            -- 🎨 Apply animated or static color
            local tex = trail.twinkleSpark and trail.twinkleSpark.texture
            if tex then
                if tex.colorTicker then
                    tex.colorTicker:Cancel()
                    tex.colorTicker = nil
                end

                if profile.randomTwinkleStarsColor then
                    tex.colorTicker = C_Timer.NewTicker(0.3, function()
                        local randColor = EasyCursorTrails.GetRandomTwinkleColor()
                        tex:SetVertexColor(randColor.r, randColor.g, randColor.b, randColor.a or 1)
                    end)
                else
                    local color = profile.twinkleStarsColor or EasyCursorTrails.GetDefaultColor("twinkleStarsColor")
                    tex:SetVertexColor(color.r, color.g, color.b, color.a or 1)
                end

                trail.twinkleSpark:Show()
            end
        end
    end
end



-- 🌟 Twinkle Stars Toggle
local twinkleStarsCheckbox = EasyCursorTrails.CreateCheckbox(
  "EnableTwinkleStars", menu, "Sparkles",
  EasyCursorTrails.GetCurrentProfile().enableTwinkleStars,
  function(checked)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.enableTwinkleStars = checked
    EasyCursorTrails.SaveToCurrentProfile("enableTwinkleStars", checked)

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
      for i, trail in ipairs(pool) do
        if not checked then
          if trail.twinkleSpark then
            if trail.twinkleSpark.ag then trail.twinkleSpark.ag:Stop() end
            if trail.twinkleSpark.texture and trail.twinkleSpark.texture.colorTicker then
              trail.twinkleSpark.texture.colorTicker:Cancel()
              trail.twinkleSpark.texture.colorTicker = nil
            end
            trail.twinkleSpark:Hide()
          end
          trail.twinkleSpark = nil
        else
          EasyCursorTrails.ApplyColorEffectTrail(trail, i)
        end
      end
    end

    C_Timer.After(0.2, function()
      EasyCursorTrails.UpdateTwinkleTrailColors()
    end)
  end
)
twinkleStarsCheckbox:SetSize(28, 28)
EasyCursorTrails.twinkleStarsCheckbox = twinkleStarsCheckbox
twinkleStarsCheckbox:SetPoint("TOPLEFT", trailEffectsHeader, "TOPRIGHT", -70, -20)

-- 🎨 Color Picker
EasyCursorTrails.twinkleStarsColorPicker = EasyCursorTrails.CreateColorPicker(
  "TwinkleStarsColor", menu, "",
  EasyCursorTrails.GetCurrentProfile().twinkleStarsColor or EasyCursorTrails.GetDefaultColor("twinkleStarsColor"),
  function(r, g, b, a)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.twinkleStarsColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("twinkleStarsColor", profile.twinkleStarsColor)

    if EasyCursorTrails.twinkleStarsColorPicker and EasyCursorTrails.twinkleStarsColorPicker.SetColorRGBA then
      EasyCursorTrails.twinkleStarsColorPicker:SetColorRGBA(r, g, b, a)
    end

    if profile.enableTwinkleStars and not profile.twinkleStarsRandomColor then
      EasyCursorTrails.UpdateTwinkleTrailColors()
    end
  end
)
EasyCursorTrails.twinkleStarsColorPicker:SetPoint("TOPLEFT", twinkleStarsCheckbox, "BOTTOMLEFT", 130, 25)
EasyCursorTrails.twinkleStarsColorPicker:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Click to pick star sparkle color", 1, 1, 1)
  GameTooltip:Show()
end)
EasyCursorTrails.twinkleStarsColorPicker:SetScript("OnLeave", GameTooltip_Hide)

-- 🎲 Random Color Toggle
local twinkleStarsRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_TwinkleStarsRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
twinkleStarsRandomCheckbox:SetSize(28, 28)
twinkleStarsRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.twinkleStarsColorPicker, "RIGHT", 20, 0)
twinkleStarsRandomCheckbox:SetHitRectInsets(0, 0, 0, 0)
EasyCursorTrails.twinkleStarsRandomColorCheckbox = twinkleStarsRandomCheckbox

local twinkleRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
twinkleRandLabel:SetPoint("LEFT", twinkleStarsRandomCheckbox, "RIGHT", 4, 1)
twinkleRandLabel:SetText("Random")
twinkleRandLabel:SetTextColor(1, 0.82, 0)

twinkleStarsRandomCheckbox:SetChecked(EasyCursorTrails.GetCurrentProfile().twinkleStarsRandomColor == true)
twinkleStarsRandomCheckbox:SetScript("OnClick", function(self)
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.twinkleStarsRandomColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("twinkleStarsRandomColor", profile.twinkleStarsRandomColor)

  if profile.enableTwinkleStars then
    EasyCursorTrails.UpdateTwinkleTrailColors()
  end
end)

-- 🔄 Reset Button
EasyCursorTrails.resetTwinkleStarsBtn = CreateFrame("Button", "EasyCursorTrails_ResetTwinkleStarsBtn", menu, "UIPanelButtonTemplate")
local resetBtn = EasyCursorTrails.resetTwinkleStarsBtn
resetBtn:SetSize(48, 24)
resetBtn:SetText("Reset")
resetBtn:SetPoint("LEFT", twinkleRandLabel, "RIGHT", 12, 0)
resetBtn:SetScript("OnClick", function()
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.enableTwinkleStars = false
  profile.twinkleStarsRandomColor = false
  profile.twinkleStarsColor = CopyTable(EasyCursorTrails.GetDefaultColor("twinkleStarsColor") or { r = 1, g = 1, b = 1, a = 1 })

  EasyCursorTrails.SaveToCurrentProfile("enableTwinkleStars", false)
  EasyCursorTrails.SaveToCurrentProfile("twinkleStarsRandomColor", false)
  EasyCursorTrails.SaveToCurrentProfile("twinkleStarsColor", profile.twinkleStarsColor)

  if EasyCursorTrails.twinkleStarsCheckbox then
    EasyCursorTrails.twinkleStarsCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.twinkleStarsRandomColorCheckbox then
    EasyCursorTrails.twinkleStarsRandomColorCheckbox:SetChecked(false)
  end

  local picker = EasyCursorTrails.twinkleStarsColorPicker
  if picker and picker.SetColorRGBA then
    picker:SetColorRGBA(profile.twinkleStarsColor.r, profile.twinkleStarsColor.g, profile.twinkleStarsColor.b, profile.twinkleStarsColor.a)
  end

  for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
    for _, trail in ipairs(pool) do
      if trail.twinkleSpark then
        if trail.twinkleSpark.ag then trail.twinkleSpark.ag:Stop() end
        if trail.twinkleSpark.texture and trail.twinkleSpark.texture.colorTicker then
          trail.twinkleSpark.texture.colorTicker:Cancel()
          trail.twinkleSpark.texture.colorTicker = nil
        end
        trail.twinkleSpark:Hide()
      end
      trail.twinkleSpark = nil
    end
  end

  EasyCursorTrails.RebuildTrails()

  C_Timer.After(0.2, function()
    EasyCursorTrails.UpdateTwinkleTrailColors()
  end)
end)
resetBtn:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Reset sparkle color and disable effect", 1, 1, 1)
  GameTooltip:Show()
end)
resetBtn:SetScript("OnLeave", GameTooltip_Hide)


--===================================================================================================================
-- 🔍 Fetch current profile
local profile = EasyCursorTrails.GetCurrentProfile()
if not profile then return end

-- 🔌 Static Arc Toggle Checkbox
local staticArcEffectCheckbox = EasyCursorTrails.CreateCheckbox(
  "EnableStaticArc",
  menu,
  "Static Sparkles",
  profile.enableStaticArc == true,
  function(checked)
    profile.enableStaticArc = checked
    EasyCursorTrails.SaveToCurrentProfile("enableStaticArc", checked)

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
      for i, trail in ipairs(pool) do
        if checked then
          EasyCursorTrails.ApplyStaticArcEffect(trail, i, nil, true)
        else
          EasyCursorTrails.ClearStaticArcEffect(trail)
        end
      end
    end
  end
)
staticArcEffectCheckbox:SetSize(28, 28)
EasyCursorTrails.staticArcEffectCheckbox = staticArcEffectCheckbox
staticArcEffectCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.twinkleStarsCheckbox, "BOTTOMLEFT", 0, -20)

-- 🎨 Static Arc Color Picker
EasyCursorTrails.staticArcColorPicker = EasyCursorTrails.CreateColorPicker(
  "StaticArcColor", menu, "", profile.staticArcColor or EasyCursorTrails.defaults.staticArcColor,
  function(r, g, b, a)
    profile.staticArcColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("staticArcColor", profile.staticArcColor)

    if profile.enableStaticArc then
      for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for i, trail in ipairs(pool) do
          EasyCursorTrails.ClearStaticArcEffect(trail)
          EasyCursorTrails.ApplyStaticArcEffect(trail, i, profile.staticArcColor, true)
        end
      end
    end
  end
)
EasyCursorTrails.staticArcColorPicker:SetPoint("LEFT", staticArcEffectCheckbox, "RIGHT", 104, 0)
EasyCursorTrails.staticArcColorPicker:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Click to pick a color.", 1, 1, 1)
  GameTooltip:Show()
end)
EasyCursorTrails.staticArcColorPicker:SetScript("OnLeave", GameTooltip_Hide)

-- 🎲 Random Static Arc Checkbox
local staticRandCheck = CreateFrame("CheckButton", "EasyCursorTrails_StaticArcRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
staticRandCheck:SetSize(28, 28)
staticRandCheck:SetPoint("LEFT", EasyCursorTrails.staticArcColorPicker, "RIGHT", 20, 0)
staticRandCheck:SetHitRectInsets(0, 0, 0, 0)
EasyCursorTrails.staticArcRandomColorCheckbox = staticRandCheck

local staticRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
staticRandLabel:SetText("Random")
staticRandLabel:SetTextColor(1, 0.82, 0)
staticRandLabel:SetPoint("LEFT", staticRandCheck, "RIGHT", 4, 1)

staticRandCheck:SetChecked(profile.randomStaticArcColor == true)
staticRandCheck:SetScript("OnClick", function(self)
  profile.randomStaticArcColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomStaticArcColor", profile.randomStaticArcColor)

  if profile.enableStaticArc then
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
      for i, trail in ipairs(pool) do
        EasyCursorTrails.ClearStaticArcEffect(trail)
        EasyCursorTrails.ApplyStaticArcEffect(trail, i, nil, true)
      end
    end
  end
end)

-- ♻️ Reset Button
EasyCursorTrails.resetStaticArcRandomBtn = CreateFrame("Button", "EasyCursorTrails_ResetStaticArcRandomBtn", menu, "UIPanelButtonTemplate")
local resetBtn = EasyCursorTrails.resetStaticArcRandomBtn
resetBtn:SetSize(48, 24)
resetBtn:SetText("Reset")
resetBtn:SetPoint("LEFT", EasyCursorTrails.resetTwinkleStarsBtn, "RIGHT", -48, -45)

resetBtn:SetScript("OnClick", function()
  profile.enableStaticArc = false
  profile.randomStaticArcColor = false
  profile.staticArcColor = CopyTable(EasyCursorTrails.GetDefaultColor("staticArcColor") or { r = 1, g = 1, b = 1, a = 0.8 })

  EasyCursorTrails.SaveToCurrentProfile("enableStaticArc", false)
  EasyCursorTrails.SaveToCurrentProfile("randomStaticArcColor", false)
  EasyCursorTrails.SaveToCurrentProfile("staticArcColor", profile.staticArcColor)

  if EasyCursorTrails.staticArcEffectCheckbox then
    EasyCursorTrails.staticArcEffectCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.staticArcRandomColorCheckbox then
    EasyCursorTrails.staticArcRandomColorCheckbox:SetChecked(false)
  end

  local picker = EasyCursorTrails.staticArcColorPicker
  if picker then
    if picker.SetColorRGBA then
      picker:SetColorRGBA(profile.staticArcColor.r, profile.staticArcColor.g, profile.staticArcColor.b, profile.staticArcColor.a)
    elseif picker.swatch then
      picker.swatch:SetColorTexture(profile.staticArcColor.r, profile.staticArcColor.g, profile.staticArcColor.b, profile.staticArcColor.a)
    end
  end

  for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
    for _, trail in ipairs(pool) do
      EasyCursorTrails.ClearStaticArcEffect(trail)
    end
  end

  EasyCursorTrails.RebuildTrails()
end)

resetBtn:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Reset Static Arc color and disable effect", 1, 1, 1)
  GameTooltip:Show()
end)
resetBtn:SetScript("OnLeave", GameTooltip_Hide)


--===================================================================================================================

EasyCursorTrails.liveEffects = EasyCursorTrails.liveEffects or {}

EasyCursorTrails.lightningSparkCheckbox = EasyCursorTrails.CreateCheckbox(
  "EnableLightningSparks",
  menu,
  "Lightnings",
  EasyCursorTrails.GetCurrentProfile().enableLightningSparks == true,
  function(isChecked)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.enableLightningSparks = isChecked
    EasyCursorTrails.liveEffects.enableLightningSparks = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableLightningSparks", isChecked)

    EasyCursorTrails:SetTrailEffectsOverride(false)
  end
)

EasyCursorTrails.lightningSparkCheckbox:SetSize(28, 28)
EasyCursorTrails.lightningSparkCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.staticArcEffectCheckbox, "BOTTOMLEFT", 0, -20)



EasyCursorTrails.lightningSparkColorPicker = EasyCursorTrails.CreateColorPicker(
  "LightningSparkColor",
  menu,
  "",
  EasyCursorTrails.GetCurrentProfile().lightningSparkColor or { r = 0.8, g = 0.9, b = 1, a = 1 },
  function(r, g, b, a)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.lightningSparkColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("lightningSparkColor", profile.lightningSparkColor)

    if EasyCursorTrails.liveEffects.enableLightningSpark then
      EasyCursorTrails.RestartLightningSparkTicker()
    end
  end
)
EasyCursorTrails.lightningSparkColorPicker:SetPoint("LEFT", EasyCursorTrails.lightningSparkCheckbox, "RIGHT", 104, 0)
EasyCursorTrails.lightningSparkColorPicker:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Click to pick lightning color.", 1, 1, 1)
  GameTooltip:Show()
end)
EasyCursorTrails.lightningSparkColorPicker:SetScript("OnLeave", GameTooltip_Hide)


local lightningSparkRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_LightningSparkRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
lightningSparkRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.lightningSparkColorPicker, "RIGHT", 20, 0)
lightningSparkRandomCheckbox:SetSize(28, 28)
lightningSparkRandomCheckbox:SetHitRectInsets(6, 6, 6, 6)
EasyCursorTrails.lightningSparkRandomColorCheckbox = lightningSparkRandomCheckbox

local lightningRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
lightningRandLabel:SetPoint("LEFT", lightningSparkRandomCheckbox, "RIGHT", 4, 0)
lightningRandLabel:SetText("Random")
lightningRandLabel:SetTextColor(1, 0.82, 0)

lightningSparkRandomCheckbox:SetChecked(EasyCursorTrails.GetCurrentProfile().randomLightningSparkColor == true)
lightningSparkRandomCheckbox:SetScript("OnClick", function(self)
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.randomLightningSparkColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomLightningSparkColor", profile.randomLightningSparkColor)

  if EasyCursorTrails.liveEffects.enableLightningSpark then
    EasyCursorTrails.RestartLightningSparkTicker()
  end
end)

local resetLightningSparkBtn = CreateFrame("Button", "EasyCursorTrails_LightningSparkResetButton", menu, "UIPanelButtonTemplate")
resetLightningSparkBtn:SetPoint("LEFT", EasyCursorTrails.resetStaticArcRandomBtn, "RIGHT", -48, -48)
resetLightningSparkBtn:SetSize(48, 24)
resetLightningSparkBtn:SetText("Reset")
resetLightningSparkBtn:SetScript("OnClick", function()
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.enableLightningSpark = false
  profile.randomLightningSparkColor = false
  profile.lightningSparkColor = { r = 0.8, g = 0.9, b = 1, a = 1 }

  EasyCursorTrails.SaveToCurrentProfile("enableLightningSpark", false)
  EasyCursorTrails.SaveToCurrentProfile("randomLightningSparkColor", false)
  EasyCursorTrails.SaveToCurrentProfile("lightningSparkColor", profile.lightningSparkColor)

  if EasyCursorTrails.lightningSparkCheckbox then
    EasyCursorTrails.lightningSparkCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.lightningSparkRandomColorCheckbox then
    EasyCursorTrails.lightningSparkRandomColorCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.lightningSparkColorPicker and EasyCursorTrails.lightningSparkColorPicker.SetColorRGBA then
    EasyCursorTrails.lightningSparkColorPicker:SetColorRGBA(0.8, 0.9, 1, 1)
  end

  if EasyCursorTrails.lightningSparkTicker then
    EasyCursorTrails.lightningSparkTicker:Cancel()
    EasyCursorTrails.lightningSparkTicker = nil
  end

  for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
    for _, trail in ipairs(pool) do
      EasyCursorTrails.ClearLightningSparkEffect(trail)
    end
  end
end)

function EasyCursorTrails.RestartLightningSparkTicker()
  EasyCursorTrails.StopLightningSparkTicker()

  EasyCursorTrails.lightningSparkTicker = C_Timer.NewTicker(0.25, function()
    if not EasyCursorTrails.liveEffects.enableLightningSpark then return end

    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
      for _, trail in ipairs(pool) do
        if trail:IsVisible() then
          EasyCursorTrails.ApplyLightningSparkEffect(trail)
        end
      end
    end
  end)
end

function EasyCursorTrails.StopLightningSparkTicker()
  if EasyCursorTrails.lightningSparkTicker then
    EasyCursorTrails.lightningSparkTicker:Cancel()
    EasyCursorTrails.lightningSparkTicker = nil
  end
end

function EasyCursorTrails.ClearAllLightningSparkEffects()
  for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
    for _, trail in ipairs(pool) do
      EasyCursorTrails.ClearLightningSparkEffect(trail)
    end
  end
end




--===================================================================================================================
-- 🔥 Fire Effect Checkbox
EasyCursorTrails.fireEffectCheckbox = EasyCursorTrails.CreateCheckbox(
  "EnableFire",
  menu,
  "Burning Fire",
  EasyCursorTrails.GetCurrentProfile().enableFire == true,
  function(isChecked)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.enableFire = isChecked
    EasyCursorTrails.liveEffects.enableFire = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableFire", isChecked)

    EasyCursorTrails:SetTrailEffectsOverride(false)
  end
)


EasyCursorTrails.fireEffectCheckbox:SetSize(28, 28)
EasyCursorTrails.fireEffectCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.lightningSparkCheckbox, "BOTTOMLEFT", 0, -20)

EasyCursorTrails.fireColorPicker = EasyCursorTrails.CreateColorPicker(
  "FireGlowColor",
  menu,
  "",
  EasyCursorTrails.GetCurrentProfile().fireColor or EasyCursorTrails.GetDefaultColor("fireColor"),
  function(r, g, b, a)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.fireColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("fireColor", profile.fireColor)

    EasyCursorTrails:SetTrailEffectsOverride(false)
  end
)

EasyCursorTrails.fireColorPicker:SetPoint("LEFT", EasyCursorTrails.fireEffectCheckbox, "RIGHT", 104, 0)


local fireRandomColorCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_FireRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
fireRandomColorCheckbox:SetPoint("LEFT", EasyCursorTrails.fireColorPicker, "RIGHT", 20, 0)
fireRandomColorCheckbox:SetSize(28, 28)
fireRandomColorCheckbox:SetHitRectInsets(0, 0, 0, 0)
EasyCursorTrails.fireRandomColorCheckbox = fireRandomColorCheckbox

local fireRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
fireRandLabel:SetPoint("LEFT", fireRandomColorCheckbox, "RIGHT", 4, 0)
fireRandLabel:SetText("Random")
fireRandLabel:SetTextColor(1, 0.82, 0)

fireRandomColorCheckbox:SetChecked(EasyCursorTrails.GetCurrentProfile().randomFireColor == true)
fireRandomColorCheckbox:SetScript("OnClick", function(self)
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.randomFireColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomFireColor", profile.randomFireColor)

  EasyCursorTrails:SetTrailEffectsOverride(false)
end)


local resetFireBtn = CreateFrame("Button", "EasyCursorTrails_FireColorResetButton", menu, "UIPanelButtonTemplate")
resetFireBtn:SetPoint("LEFT", resetLightningSparkBtn, "RIGHT", -48, -48)
resetFireBtn:SetSize(48, 24)
resetFireBtn:SetText("Reset")
resetFireBtn:SetScript("OnClick", function()
  local profile = EasyCursorTrails.GetCurrentProfile()
  if not profile then return end

  profile.enableFire = false
  profile.randomFireColor = false
  profile.fireColor = CopyTable(EasyCursorTrails.GetDefaultColor("fireColor") or { r = 1, g = 0.5, b = 0.1, a = 0.8 })
  EasyCursorTrails.liveEffects.enableFire = false

  EasyCursorTrails.SaveToCurrentProfile("enableFire", false)
  EasyCursorTrails.SaveToCurrentProfile("randomFireColor", false)
  EasyCursorTrails.SaveToCurrentProfile("fireColor", profile.fireColor)

  if EasyCursorTrails.fireEffectCheckbox then
    EasyCursorTrails.fireEffectCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.fireRandomColorCheckbox then
    EasyCursorTrails.fireRandomColorCheckbox:SetChecked(false)
  end
  if EasyCursorTrails.fireColorPicker and EasyCursorTrails.fireColorPicker.SetColorRGBA then
    local c = profile.fireColor
    EasyCursorTrails.fireColorPicker:SetColorRGBA(c.r, c.g, c.b, c.a)
  end

  EasyCursorTrails:SetTrailEffectsOverride(false)
end)

--===================================================================================================================
local shadowEffectCheckbox = EasyCursorTrails.CreateCheckbox(
  "EnableTrailShadows",
  menu,
  "Trail Shadow",
  (EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.enableTrailShadows) == true,
  function(isChecked)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.enableTrailShadows = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableTrailShadows", isChecked)

    local tickerPair = EasyCursorTrails.effectTickerRegistry["enableTrailShadows"]
    if isChecked then
      -- 🟣 Rebuild shadow frames
      EasyCursorTrails.RefreshAllTrailShadows()

      -- 🔁 Start via registry
      if tickerPair and type(tickerPair.start) == "function" then
        tickerPair.start()
      end
    else
      -- 🧼 Stop via registry
      if tickerPair and type(tickerPair.stop) == "function" then
        tickerPair.stop()
      end
    end
  end
)

shadowEffectCheckbox:SetSize(28, 28)
EasyCursorTrails.shadowEffectCheckbox = shadowEffectCheckbox
shadowEffectCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.fireEffectCheckbox, "BOTTOMLEFT", 0, -20)


-- Ensure settings apply after game reload
C_Timer.After(0.1, function()
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if profile and EasyCursorTrails.shadowEffectCheckbox then
        local checkbox = EasyCursorTrails.shadowEffectCheckbox
        checkbox:SetChecked(profile.enableTrailShadows == true)

        local onClick = checkbox:GetScript("OnClick")
        if onClick then onClick(checkbox) end
    end
end)

-- Safely access current profile
local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]

-- 🎨 Shadow color picker
EasyCursorTrails.shadowColorPicker = EasyCursorTrails.CreateColorPicker(
    "ShadowTrailColor",
    menu,
    "",
    (profile and profile.shadowTrailColor) or { r = 0, g = 0, b = 0, a = 0.4 },
    function(r, g, b, a)
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile then return end

        profile.shadowTrailColor = { r = r, g = g, b = b, a = a }
        EasyCursorTrails.SaveToCurrentProfile("shadowTrailColor", profile.shadowTrailColor)

        -- 🌀 Force refresh shadows with updated color
        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                EasyCursorTrails.SpawnTrailShadow(trail)
            end
        end
    end
)

EasyCursorTrails.shadowColorPicker:SetPoint("LEFT", EasyCursorTrails.shadowEffectCheckbox, "RIGHT", 104, 0)
EasyCursorTrails.shadowColorPicker:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:SetText("Pick a color for trail shadows.", 1, 1, 1)
    GameTooltip:Show()
end)
EasyCursorTrails.shadowColorPicker:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)

-- 🔀 Random color toggle
local shadowRandCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_ShadowRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
shadowRandCheckbox:SetPoint("LEFT", EasyCursorTrails.shadowColorPicker, "RIGHT", 20, 0)
shadowRandCheckbox:SetSize(28, 28) -- 📏 Smaller hit box

-- 🏷️ Label
local shadowRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
shadowRandLabel:SetPoint("LEFT", shadowRandCheckbox, "RIGHT", 4, 0)
shadowRandLabel:SetText("Random")
shadowRandLabel:SetTextColor(1, 0.82, 0)

-- 🧾 Checkbox visual cleanup
shadowRandCheckbox:SetHitRectInsets(0, 0, 0, 0) -- Ensure the hit box matches the visual box
shadowRandCheckbox:SetChecked(profile and profile.randomShadowColor == true)
EasyCursorTrails.shadowRandomColorCheckbox = shadowRandCheckbox

-- 🧠 Behavior
shadowRandCheckbox:SetScript("OnClick", function(self)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    profile.randomShadowColor = self:GetChecked()
    EasyCursorTrails.SaveToCurrentProfile("randomShadowColor", profile.randomShadowColor)

    -- 🌀 Force respawn with random coloring
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            EasyCursorTrails.SpawnTrailShadow(trail)
        end
    end
end)



-- 🔄 Shadow Trail Reset Button
local resetShadowColorButton = CreateFrame("Button", "EasyCursorTrails_ShadowColorResetButton", menu, "UIPanelButtonTemplate")
resetShadowColorButton:SetSize(48, 24)
resetShadowColorButton:SetPoint("LEFT", resetFireBtn, "RIGHT", -48, -48)
resetShadowColorButton:SetText("Reset")
resetShadowColorButton:SetScript("OnClick", function()
  local activeProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not activeProfile then
    --⚠️ No active profile found during Shadow reset")
    return
  end

  -- 🛑 Stop ticker BEFORE changing state
  if EasyCursorTrails.shadowEffectTicker then
    EasyCursorTrails.shadowEffectTicker:Cancel()
    EasyCursorTrails.shadowEffectTicker = nil
  end

  -- ✅ Disable effect using consistent key
  activeProfile.enableTrailShadows = false
  EasyCursorTrails.SaveToCurrentProfile("enableTrailShadows", false)

  -- ⛔ Suppress checkbox callback and visually uncheck
  local checkbox = EasyCursorTrails.shadowEffectCheckbox
  if checkbox then
    local originalScript = checkbox:GetScript("OnClick")
    checkbox:SetScript("OnClick", nil)
    checkbox:SetChecked(false)
    checkbox:SetScript("OnClick", originalScript)
  else
    --⚠️ shadowEffectCheckbox is nil during reset")
  end

  -- 🌈 Reset color
  local defaultColor = EasyCursorTrails.GetDefaultColor("shadowTrailColor") or { r = 0, g = 0, b = 0, a = 0.4 }
  activeProfile.shadowTrailColor = CopyTable(defaultColor)
  EasyCursorTrails.SaveToCurrentProfile("shadowTrailColor", activeProfile.shadowTrailColor)


  if EasyCursorTrails.shadowColorPicker then
    local picker = EasyCursorTrails.shadowColorPicker
        if picker and picker.SetColorRGBA then
        picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
        elseif picker and picker.swatch then
        picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
        else
        --⚠️ shadowColorPicker is present but missing SetColorRGBA and swatch")
        end

    end


  -- 🎲 Disable random toggle
  activeProfile.randomShadowColor = false
  EasyCursorTrails.SaveToCurrentProfile("randomShadowColor", false)

  if EasyCursorTrails.shadowRandomColorCheckbox then
    EasyCursorTrails.shadowRandomColorCheckbox:SetChecked(false)
  end

  -- ✨ Refresh visuals
  if EasyCursorTrails.trailPool and EasyCursorTrails.SpawnTrailShadow then
    for _, pool in pairs(EasyCursorTrails.trailPool) do
      for _, trail in ipairs(pool) do
        EasyCursorTrails.SpawnTrailShadow(trail)
      end
    end
  end
end)

--===================================================================================================================
-- 🏷️ Section Header
local EmberEffectsHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
EmberEffectsHeader:SetPoint("TOPLEFT", EasyCursorTrails.shadowEffectCheckbox, "TOPRIGHT", -25, -50)
EmberEffectsHeader:SetText("Particle Effects")

-- 🌟 Star Dust Checkbox
local profile = EasyCursorTrails.GetCurrentProfile()
local initialState = profile.enableStarDust == true

local starDustCheckbox = EasyCursorTrails.CreateCheckbox(
 "EnableStarDust",
  menu,
  "Star Dust",
  initialState,
  function(isChecked)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    profile.enableStarDust = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableStarDust", isChecked)

    local tickerPair = EasyCursorTrails.effectTickerRegistry["enableStarDust"]
    if isChecked then
      if tickerPair and tickerPair.start then tickerPair.start() end
    else
      if tickerPair and tickerPair.stop then tickerPair.stop() end
    end
  end
)

starDustCheckbox:SetSize(28, 28)
EasyCursorTrails.starDustCheckbox = starDustCheckbox
starDustCheckbox:SetPoint("TOPLEFT", EmberEffectsHeader, "BOTTOMLEFT", 0, -10)

-- 🎨 Star Dust Color Picker
EasyCursorTrails.starDustColorPicker = EasyCursorTrails.CreateColorPicker(
  "StarDustColor",
  menu,
  "",
  EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.starDustColor
    or EasyCursorTrails.GetDefaultColor("starDustColor"),
  function(r, g, b, a)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    profile.starDustColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("starDustColor", profile.starDustColor)

    -- Optional: rebuild trails to apply color
    C_Timer.After(0.1, function()
      EasyCursorTrails.RebuildTrails()
    end)
  end
)
EasyCursorTrails.starDustColorPicker:SetPoint("LEFT", starDustCheckbox.Text, "RIGHT", 58, 0)

local starDustRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_StarDustRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
starDustRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.starDustColorPicker, "RIGHT", 20, 0)
starDustRandomCheckbox:SetSize(28, 28)
starDustRandomCheckbox:SetHitRectInsets(0, 0, 0, 0)

local starDustRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
starDustRandLabel:SetPoint("LEFT", starDustRandomCheckbox, "RIGHT", 4, 0)
starDustRandLabel:SetText("Random")
starDustRandLabel:SetTextColor(1, 0.82, 0)

local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
starDustRandomCheckbox:SetChecked(profile and profile.randomStarDustColor == true)
EasyCursorTrails.starDustRandomColorCheckbox = starDustRandomCheckbox

starDustRandomCheckbox:SetScript("OnClick", function(self)
  if EasyCursorTrails.isSyncingUI then return end

  local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not profile then return end

  profile.randomStarDustColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomStarDustColor", profile.randomStarDustColor)
end)

local resetStarDustColorBtn = CreateFrame("Button", nil, menu, "UIPanelButtonTemplate")
resetStarDustColorBtn:SetPoint("LEFT", resetShadowColorButton, "RIGHT", -48, -68)
resetStarDustColorBtn:SetSize(48, 24)
resetStarDustColorBtn:SetText("Reset")

resetStarDustColorBtn:SetScript("OnClick", function()
  EasyCursorTrails.isResettingStarDust = true

  local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not profile then return end

  -- 🔄 Reset random toggle
  profile.randomStarDustColor = false
  EasyCursorTrails.SaveToCurrentProfile("randomStarDustColor", false)
  if starDustRandomCheckbox and starDustRandomCheckbox.SetChecked then
    starDustRandomCheckbox:SetChecked(false)
  end

  -- 🎨 Reset color
  local defaultColor = EasyCursorTrails.GetDefaultColor("starDustColor") or { r = 1, g = 1, b = 0.8, a = 0.6 }
  profile.starDustColor = CopyTable(defaultColor)
  EasyCursorTrails.SaveToCurrentProfile("starDustColor", profile.starDustColor)

  local picker = EasyCursorTrails.starDustColorPicker
  if picker then
    if picker.SetColorRGBA then
      picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    elseif picker.swatch then
      picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    end
  end

  -- ❌ Disable effect
  profile.enableStarDust = false
  EasyCursorTrails.SaveToCurrentProfile("enableStarDust", false)

  if EasyCursorTrails.StopStarDustTicker then
    EasyCursorTrails.StopStarDustTicker()
  end

  if EasyCursorTrails.starDustCheckbox then
    local originalScript = EasyCursorTrails.starDustCheckbox:GetScript("OnClick")
    EasyCursorTrails.starDustCheckbox:SetScript("OnClick", nil)
    EasyCursorTrails.starDustCheckbox:SetChecked(false)
    EasyCursorTrails.starDustCheckbox:SetScript("OnClick", originalScript)
  end

  C_Timer.After(0.1, function()
    EasyCursorTrails.RebuildTrails()
    EasyCursorTrails.isResettingStarDust = false
  end)
end)

--==============================================================================================
local smokeEffectCheckbox = EasyCursorTrails.CreateCheckbox(
  "enableSmokeEffect",  -- ✅ Corrected key
  menu,
  "Smokes",
  EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.enableSmokeEffect,
  function(isChecked)
    if EasyCursorTrails.isSyncingUI or EasyCursorTrails.isResettingSmoke then return end

    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    profile.enableSmokeEffect = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableSmokeEffect", isChecked)

    if isChecked then
      EasyCursorTrails.StartSmokeTicker()
    else
      EasyCursorTrails.StopSmokeTicker()
    end
  end
)

smokeEffectCheckbox:SetSize(28, 28)
EasyCursorTrails.smokeEffectCheckbox = smokeEffectCheckbox
smokeEffectCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.starDustCheckbox, "BOTTOMLEFT", 0, -20)

-- 💨 Smoke Color Picker
EasyCursorTrails.smokeColorPicker = EasyCursorTrails.CreateColorPicker(
  "SmokeColor",
  menu,
  "",
  EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.smokeColor
    or EasyCursorTrails.GetDefaultColor("smokeColor"),
  function(r, g, b, a)
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    if not profile then return end

    profile.smokeColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("smokeColor", profile.smokeColor)
  end
)
EasyCursorTrails.smokeColorPicker:SetPoint("LEFT", smokeEffectCheckbox.Text, "RIGHT", 65, 0)

-- 🎲 Smoke Random Toggle
local smokeRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_SmokeRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
smokeRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.smokeColorPicker, "RIGHT", 20, 0)
smokeRandomCheckbox:SetSize(28, 28)
smokeRandomCheckbox:SetHitRectInsets(0, 0, 0, 0)

local smokeRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
smokeRandLabel:SetPoint("LEFT", smokeRandomCheckbox, "RIGHT", 4, 0)
smokeRandLabel:SetText("Random")
smokeRandLabel:SetTextColor(1, 0.82, 0)

local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
smokeRandomCheckbox:SetChecked(profile and profile.randomSmokeColor == true)
EasyCursorTrails.smokeRandomColorCheckbox = smokeRandomCheckbox

smokeRandomCheckbox:SetScript("OnClick", function(self)
  if EasyCursorTrails.isSyncingUI then return end

  local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not profile then return end

  profile.randomSmokeColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomSmokeColor", profile.randomSmokeColor)
end)

-- ♻️ Smoke Reset Button
local resetSmokeColorButton = CreateFrame("Button", nil, menu, "UIPanelButtonTemplate")
resetSmokeColorButton:SetPoint("LEFT", resetStarDustColorBtn, "RIGHT", -48, -46)
resetSmokeColorButton:SetSize(48, 24)
resetSmokeColorButton:SetText("Reset")

resetSmokeColorButton:SetScript("OnClick", function()
  EasyCursorTrails.isResettingSmoke = true

  local activeProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not activeProfile then return end

  -- 🔄 Reset random toggle
  activeProfile.randomSmokeColor = false
  EasyCursorTrails.SaveToCurrentProfile("randomSmokeColor", false)
  if smokeRandomCheckbox and smokeRandomCheckbox.SetChecked then
    smokeRandomCheckbox:SetChecked(false)
  end

  -- 🎨 Reset color
  local defaultColor = EasyCursorTrails.GetDefaultColor("smokeColor") or { r = 0.1, g = 0.1, b = 0.1, a = 0.4 }
  activeProfile.smokeColor = CopyTable(defaultColor)
  EasyCursorTrails.SaveToCurrentProfile("smokeColor", activeProfile.smokeColor)

  local picker = EasyCursorTrails.smokeColorPicker
  if picker then
    if picker.SetColorRGBA then
      picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    elseif picker.swatch then
      picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    end
  end

  -- ❌ Disable smoke effect
  activeProfile.enableSmokeEffect = false
  EasyCursorTrails.SaveToCurrentProfile("enableSmokeEffect", false)

  if EasyCursorTrails.StopSmokeTicker then
    EasyCursorTrails.StopSmokeTicker()
  end

 if EasyCursorTrails.smokeEffectCheckbox then
  local originalScript = EasyCursorTrails.smokeEffectCheckbox:GetScript("OnClick")
  EasyCursorTrails.smokeEffectCheckbox:SetScript("OnClick", nil)
  EasyCursorTrails.smokeEffectCheckbox:SetChecked(false)
  EasyCursorTrails.smokeEffectCheckbox:SetScript("OnClick", originalScript)
end


  C_Timer.After(0.1, function()
    EasyCursorTrails.RebuildTrails()
    EasyCursorTrails.isResettingSmoke = false
  end)
end)

--==============================================================================================
-- 🌸 Spring Season Checkbox
EasyCursorTrails.springSeasonCheckbox = EasyCursorTrails.CreateCheckbox(
  "SpringSeasonToggle",
  menu,
  "Spring Season",
  profile.enableSpringSeasonTrails ~= false,
  function(isChecked)
    profile.enableSpringSeasonTrails = isChecked
    EasyCursorTrails.SaveToCurrentProfile("enableSpringSeasonTrails", isChecked)

    if isChecked then
      EasyCursorTrails.StartNatureTicker()
    else
      EasyCursorTrails.StopNatureTicker()
    end
  end
)

-- ✅ Fix: Use the correct reference
EasyCursorTrails.springSeasonCheckbox:SetSize(28, 28)
EasyCursorTrails.springSeasonCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.smokeEffectCheckbox, "TOPRIGHT", -28, -45)

-- 🎨 Spring Season Color Picker
EasyCursorTrails.springSeasonColorPicker = EasyCursorTrails.CreateColorPicker(
  "SpringSeasonColor",
  menu,
  "",
  profile.springSeasonColor or { r = 0.8, g = 0.9, b = 1, a = 0.8 },
  function(r, g, b, a)
    profile.springSeasonColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("springSeasonColor", profile.springSeasonColor)
    if EasyCursorTrails.springSeasonColorPicker.swatch then
      EasyCursorTrails.springSeasonColorPicker.swatch:SetColorTexture(r, g, b, a)
    end
  end
)
EasyCursorTrails.springSeasonColorPicker:SetPoint("LEFT", EasyCursorTrails.springSeasonCheckbox.Text, "RIGHT", 31, 0)

EasyCursorTrails.springSeasonColorPicker:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Click to choose Spring Season color.", 1, 1, 1)
  GameTooltip:Show()
end)
EasyCursorTrails.springSeasonColorPicker:SetScript("OnLeave", GameTooltip_Hide)

-- 🎲 SpringSeason Random Checkbox
local springSeasonRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_SpringSeasonRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
springSeasonRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.springSeasonColorPicker, "RIGHT", 20, 0)
springSeasonRandomCheckbox:SetSize(28, 28)
springSeasonRandomCheckbox:SetHitRectInsets(0, 0, 0, 0)

local springSeasonRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
springSeasonRandLabel:SetPoint("LEFT", springSeasonRandomCheckbox, "RIGHT", 4, 0)
springSeasonRandLabel:SetText("Random")
springSeasonRandLabel:SetTextColor(1, 0.82, 0)

springSeasonRandomCheckbox:SetChecked(profile.randomSpringSeasonColor ~= false)
EasyCursorTrails.springSeasonRandomColorCheckbox = springSeasonRandomCheckbox

springSeasonRandomCheckbox:SetScript("OnClick", function(self)
  profile.randomSpringSeasonColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomSpringSeasonColor", profile.randomSpringSeasonColor)
end)

-- ♻️ Reset Spring Season Button
local resetSpringSeasonButton = CreateFrame("Button", nil, menu, "UIPanelButtonTemplate")
resetSpringSeasonButton:SetPoint("LEFT", resetSmokeColorButton, "RIGHT", -48, -46)
resetSpringSeasonButton:SetSize(48, 24)
resetSpringSeasonButton:SetText("Reset")

resetSpringSeasonButton:SetScript("OnClick", function()
  local activeProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not activeProfile then
    --⚠️ No active profile found during Spring Season reset
    return
  end

  -- 🎲 Reset random toggle
  activeProfile.randomSpringSeasonColor = false
  EasyCursorTrails.SaveToCurrentProfile("randomSpringSeasonColor", false)

  if springSeasonRandomCheckbox and springSeasonRandomCheckbox.SetChecked then
    springSeasonRandomCheckbox:SetChecked(false)
  end

  -- 🎨 Reset color
  local defaultColor = { r = 0.8, g = 0.9, b = 1, a = 0.8 }
  activeProfile.springSeasonColor = CopyTable(defaultColor)
  EasyCursorTrails.SaveToCurrentProfile("springSeasonColor", activeProfile.springSeasonColor)

  local picker = EasyCursorTrails.springSeasonColorPicker
  if picker then
    if picker.SetColorRGBA then
      picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    elseif picker.swatch then
      picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    end
  end

  -- ❌ Disable Spring Season effect
  activeProfile.enableSpringSeasonTrails = false
  EasyCursorTrails.SaveToCurrentProfile("enableSpringSeasonTrails", false)

  if EasyCursorTrails.springSeasonCheckbox then
    local checkbox = EasyCursorTrails.springSeasonCheckbox
    local originalScript = checkbox:GetScript("OnClick")
    checkbox:SetScript("OnClick", nil)
    checkbox:SetChecked(false)
    checkbox:SetScript("OnClick", originalScript)
  end

  if EasyCursorTrails.StopNatureTicker then
    EasyCursorTrails.StopNatureTicker()
  end

  -- ⏳ Delay to avoid UI sync hiccups
  C_Timer.After(0.1, function()
    EasyCursorTrails.RebuildTrails()
  end)
end)


--=======================================================================================================
-- 🔥 Ember Toggle
local enableEmbers = profile.enableEmbers
if enableEmbers == nil then
    enableEmbers = EasyCursorTrails.defaults.enableEmbers or false
end

EasyCursorTrails.emberCheckbox = EasyCursorTrails.CreateCheckbox(
  "EmberToggle",
  menu,
  "Embers",
  enableEmbers,
  function(isChecked)
    profile.enableEmbers = isChecked == true
    EasyCursorTrails.SaveToCurrentProfile("enableEmbers", profile.enableEmbers)

    if profile.enableEmbers then
      EasyCursorTrails.StartEmberTicker()
    else
      EasyCursorTrails.StopEmberTicker()
    end
  end
)

-- ✅ Fix: Explicit sizing for consistency
EasyCursorTrails.emberCheckbox:SetSize(28, 28)
EasyCursorTrails.emberCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.springSeasonCheckbox, "TOPRIGHT", -28, -45)


-- 🎨 Ember Color Picker
EasyCursorTrails.emberColorPicker = EasyCursorTrails.CreateColorPicker(
  "EmberColor",
  menu,
  "",
  profile.emberColor or { r = 1, g = 0.4, b = 0.1, a = 0.8 },
  function(r, g, b, a)
    profile.emberColor = { r = r, g = g, b = b, a = a }
    EasyCursorTrails.SaveToCurrentProfile("emberColor", profile.emberColor)
    if EasyCursorTrails.emberColorPicker.swatch then
      EasyCursorTrails.emberColorPicker.swatch:SetColorTexture(r, g, b, a)
    end

    if profile.enableEmbers and not profile.randomEmberColor then
      for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
          EasyCursorTrails.SpawnEmberEffect(trail)
        end
      end
    end
  end
)
EasyCursorTrails.emberColorPicker:SetPoint("LEFT", EasyCursorTrails.emberCheckbox.Text, "RIGHT", 65, 0)

EasyCursorTrails.emberColorPicker:SetScript("OnEnter", function(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
  GameTooltip:SetText("Click to choose Ember color.", 1, 1, 1)
  GameTooltip:Show()
end)
EasyCursorTrails.emberColorPicker:SetScript("OnLeave", GameTooltip_Hide)

-- 🎲 Ember Random Toggle
local emberRandomCheckbox = CreateFrame("CheckButton", "EasyCursorTrails_EmberRandomColorToggle", menu, "ChatConfigCheckButtonTemplate")
emberRandomCheckbox:SetPoint("LEFT", EasyCursorTrails.emberColorPicker, "RIGHT", 20, 0)
emberRandomCheckbox:SetSize(28, 28)
emberRandomCheckbox:SetHitRectInsets(0, 0, 0, 0)

local emberRandLabel = menu:CreateFontString(nil, "ARTWORK", "GameFontNormal")
emberRandLabel:SetPoint("LEFT", emberRandomCheckbox, "RIGHT", 4, 0)
emberRandLabel:SetText("Random")
emberRandLabel:SetTextColor(1, 0.82, 0)

emberRandomCheckbox:SetChecked(profile.randomEmberColor ~= false)
EasyCursorTrails.emberRandomColorCheckbox = emberRandomCheckbox

emberRandomCheckbox:SetScript("OnClick", function(self)
  profile.randomEmberColor = self:GetChecked()
  EasyCursorTrails.SaveToCurrentProfile("randomEmberColor", profile.randomEmberColor)

  if profile.enableEmbers then
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
      for _, trail in ipairs(pool) do
        EasyCursorTrails.SpawnEmberEffect(trail)
      end
    end
  end
end)

-- ♻️ Ember Reset Button
local resetEmberButton = CreateFrame("Button", nil, menu, "UIPanelButtonTemplate")
resetEmberButton:SetPoint("LEFT", resetSpringSeasonButton, "RIGHT", -48, -46)
resetEmberButton:SetSize(48, 24)
resetEmberButton:SetText("Reset")

resetEmberButton:SetScript("OnClick", function()
  local activeProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
  if not activeProfile then
    --⚠️ No active profile found during Ember reset")
    return
  end

  -- 🔄 Reset random ember toggle
  activeProfile.randomEmberColor = false
  if emberRandomCheckbox and emberRandomCheckbox.SetChecked then
    emberRandomCheckbox:SetChecked(false)
  else
    --⚠️ emberRandomCheckbox is nil or missing SetChecked")
  end
  EasyCursorTrails.SaveToCurrentProfile("randomEmberColor", false)

  -- 🌈 Reset ember color to default
  local defaultColor = { r = 1, g = 0.4, b = 0.1, a = 0.8 }
  activeProfile.emberColor = CopyTable(defaultColor)
  EasyCursorTrails.SaveToCurrentProfile("emberColor", activeProfile.emberColor)

  local picker = EasyCursorTrails.emberColorPicker
  if picker then
    if picker.SetColorRGBA then
      picker:SetColorRGBA(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    elseif picker.swatch then
      picker.swatch:SetColorTexture(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a)
    end
  else
    --⚠️ emberColorPicker is nil during reset")
  end

  -- 🔌 Disable embers entirely and update checkbox
  activeProfile.enableEmbers = false
  EasyCursorTrails.SaveToCurrentProfile("enableEmbers", false)
  if EasyCursorTrails.emberCheckbox and EasyCursorTrails.emberCheckbox.SetChecked then
    EasyCursorTrails.emberCheckbox:SetChecked(false)
  else
    --⚠️ emberCheckbox is nil or missing SetChecked")
  end

  -- 🛑 Stop ember ticker if running
  if EasyCursorTrails.StopEmberTicker then
    EasyCursorTrails.StopEmberTicker()
  else
    --⚠️ StopEmberTicker function is missing")
  end

  -- ⏳ Delay rebuild to avoid UI sync issues
  C_Timer.After(0.1, function()
    EasyCursorTrails.RebuildTrails()
  end)
end)



-- 🧭 Activate Ember Ticker on Load if enabled
local activeProfile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
if activeProfile and activeProfile.enableEmbers then
  EasyCursorTrails.StartEmberTicker()
end

--========================================================================================================

--------------------------------------------------------------------------
-- 🧭 Trail Behavior Settings
-- Customize how trails respond to cursor movement.
-- These options affect how trail segments behave visually.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Connect Trails Checkbox
--------------------------------------------------------------------------
local connectTrailsCheckbox = CreateFrame("CheckButton", "ConnectTrailsCheckbox", menu, "UICheckButtonTemplate")
connectTrailsCheckbox:SetPoint("TOPLEFT", enableTrailsCheckbox, "BOTTOMLEFT", 120, 32)

connectTrailsCheckbox.text = connectTrailsCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormal")
connectTrailsCheckbox.text:SetPoint("LEFT", connectTrailsCheckbox, "RIGHT", 8, 0)
connectTrailsCheckbox.text:SetText("Connect Trails")

connectTrailsCheckbox:SetScript("OnClick", function(self)
    if EasyCursorTrails.isSyncingUI then return end

    local isConnected = self:GetChecked()
    EasyCursorTrails.SaveToCurrentProfile("connectTrails", isConnected)

    if EasyCursorTrails.RebuildTrails then
        EasyCursorTrails.RebuildTrails()
    else
        --EasyCursorTrails.HandleError"ConnectTrailsCheckbox: RebuildTrails function is missing.")
    end

    if EasyCursorTrails.RefreshSettingsUI then
        EasyCursorTrails.RefreshSettingsUI()
    end
end)

EasyCursorTrails.connectTrailsCheckbox = connectTrailsCheckbox


--========================================================================================================
-- ✅ Random vibrant sparkle color
function EasyCursorTrails.GetRandomSparkleColor()
    local vibrant = {
        { r = 1, g = 1, b = 0.8 },
        { r = 0.9, g = 0.7, b = 1 },
        { r = 0.7, g = 1, b = 0.9 },
        { r = 1, g = 0.6, b = 0.6 },
        { r = 0.8, g = 0.9, b = 1 },
    }
    local pick = vibrant[math.random(#vibrant)]
    return { r = pick.r, g = pick.g, b = pick.b, a = 0.6 }
end

-- ✅ Random neutral tone generator
function EasyCursorTrails.GetRandomNeutralColor()
    local gray = math.random(20, 80) / 100
    return { r = gray, g = gray, b = gray, a = 0.4 }
end

-- ✅ Update sparkle visuals with color logic
function EasyCursorTrails.UpdateSparkleVisualTraits()
    if not profile or not profile.enableEmberSparkles then return end
    if not EasyCursorTrails.sparklePool then return end

    local NEUTRAL_CHANCE = 0.25

    for _, sparkle in ipairs(EasyCursorTrails.sparklePool) do
        local color

        if profile.randomSparkleColor then
            local useNeutral = math.random() < NEUTRAL_CHANCE
            color = useNeutral and EasyCursorTrails.GetRandomNeutralColor()
                              or EasyCursorTrails.GetRandomSparkleColor()
        else
            color = profile.sparkleColor or { r = 1, g = 1, b = 0.8, a = 0.6 }
        end

        -- Vary scale and alpha for uniqueness
        local alpha = color.a * (math.random(90, 100) / 100)
        sparkle:SetVertexColor(color.r, color.g, color.b, alpha)
        sparkle:SetScale(0.9 + math.random() * 0.2)
    end
end

--===========================================================================================

--------------------------------------------------------------------------
-- 2) Trail Movements Effects Dropdown
--------------------------------------------------------------------------
local trailMovementEffectDropdown = EasyCursorTrails.CreateValidatedDropdown(
    "TrailMovementEffectDropdown",
    menu,
    "Movement Effects",
    trailMovementEffectOptions,  -- This should be your local options table  
    EasyCursorTrailsDB.trailMovementEffect or 1,
    function(index)
        if not trailMovementEffectOptions[index] then
            return
        end

        EasyCursorTrailsDB.trailMovementEffect = index
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailMovementEffect", index)

        if EasyCursorTrails.UpdateTrailTextureDropdown then
            local success, err = pcall(EasyCursorTrails.UpdateTrailTextureDropdown, index)
            if not success then
                -- Debug error if needed.
            end
        end

        if EasyCursorTrails.RefreshSettingsUI then
            EasyCursorTrails.RefreshSettingsUI()
        end
    end
)
trailMovementEffectDropdown:SetPoint("TOPLEFT", EasyCursorTrails.trailFollowSpeedSlider, "BOTTOMLEFT", -20, -45)
EasyCursorTrails.trailMovementEffectDropdown = trailMovementEffectDropdown  -- Global assignment

-- IMPORTANT: Also assign the options table globally for refresh purposes.
EasyCursorTrails.trailMovementEffectOptions = trailMovementEffectOptions

--------------------------------------------------------------------------
-- Trail Color Effects Dropdown
--------------------------------------------------------------------------
local trailColorEffectDropdown = EasyCursorTrails.CreateDropdown(
    "TrailColorEffectDropdown",
    menu,
    "Trail Color Effects",
    TrailcolorEffects,
    EasyCursorTrailsDB.trailColorEffect or 1,
    function(index)
        EasyCursorTrailsDB.trailColorEffect = index
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailColorEffect", index)

        -- Apply new color effect across trails
        if EasyCursorTrails.trailPool then
            for layer, trails in pairs(EasyCursorTrails.trailPool) do
                for trailIndex, trail in ipairs(trails) do
                    if trail and trail.texture then
                        EasyCursorTrails.ApplyColorEffectTrail(trail, trailIndex)
                    end
                end
            end
        end

        -- ✅ Ensure UI updates when values change
        EasyCursorTrails.RefreshSettingsUI()
    end
)
trailColorEffectDropdown:SetPoint("TOPLEFT", trailMovementEffectDropdown, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.trailColorEffectDropdown = trailColorEffectDropdown

-----------------------------------------------------------
-- RGB ↔ HTML Color Code Conversion Functions
-----------------------------------------------------------
-- Converts normalized RGB (0–1) and optional alpha to hex string "#RRGGBB" or "#RRGGBBAA"
function RGBToHex(r, g, b, a)
    local function clamp(v) return math.max(0, math.min(1, v or 1)) end

    r = math.floor(clamp(r) * 255)
    g = math.floor(clamp(g) * 255)
    b = math.floor(clamp(b) * 255)

    if a ~= nil then
        a = math.floor(clamp(a) * 255)
        return string.format("#%02X%02X%02X%02X", r, g, b, a)
    else
        return string.format("#%02X%02X%02X", r, g, b)
    end
end

-- Converts hex string "#RGB", "#RRGGBB", or "#RRGGBBAA" to normalized r, g, b, a
function HexToRGB(hex)
    if type(hex) ~= "string" then return 1, 1, 1, 1 end

    hex = hex:gsub("#", "")
    local len = #hex

    -- Expand shorthand "#RGB" to "#RRGGBB"
    if len == 3 then
        hex = hex:sub(1,1):rep(2) .. hex:sub(2,2):rep(2) .. hex:sub(3,3):rep(2)
        len = 6
    end

    if len ~= 6 and len ~= 8 then return 1, 1, 1, 1 end

    local r = tonumber(hex:sub(1, 2), 16) or 255
    local g = tonumber(hex:sub(3, 4), 16) or 255
    local b = tonumber(hex:sub(5, 6), 16) or 255
    local a = len == 8 and tonumber(hex:sub(7, 8), 16) or 255

    return r / 255, g / 255, b / 255, a / 255
end


-- Create the Select Trail Color Button
local selectTrailColorButton = CreateFrame("Button", "SelectTrailColorButton", menu, "UIPanelButtonTemplate")
selectTrailColorButton:SetSize(120, 25)
selectTrailColorButton:SetText("Select Trail Color")
selectTrailColorButton:SetPoint("TOPLEFT", trailColorEffectDropdown, "BOTTOMLEFT", 20, -10)
EasyCursorTrails.selectTrailColorButton = selectTrailColorButton

-- Create the Trail Color Edit Box
local trailColorEditBox = CreateFrame("EditBox", "TrailColorEditBox", menu, "InputBoxTemplate")
trailColorEditBox:SetSize(60, 25)
trailColorEditBox:SetAutoFocus(false)
trailColorEditBox:SetMaxLetters(9)
trailColorEditBox:SetPoint("LEFT", selectTrailColorButton, "RIGHT", 10, 0) -- Horizontal alignment
EasyCursorTrails.trailColorEditBox = trailColorEditBox

-- Add a label above the edit box
local trailColorLabel = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
trailColorLabel:SetPoint("BOTTOMLEFT", trailColorEditBox, "TOPLEFT", 0, 0)
trailColorLabel:SetText("HTML Code")


-- Update the edit box text based on saved trail color
local function UpdateTrailColorEditBox()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profile = EasyCursorTrailsDB.profiles[profileName] or {}
    local defaults = EasyCursorTrails.defaults or {}

    local color = profile.trailColor or EasyCursorTrailsDB.trailColor or defaults.trailColor or { r = 1, g = 1, b = 1, a = 1 }
    local colorText = RGBToHex(color.r, color.g, color.b, color.a)

    if trailColorEditBox:GetText() ~= colorText then
        trailColorEditBox:SetText(colorText)
    end

    local textWidth = trailColorEditBox:GetText():len() * 8
    trailColorEditBox:SetWidth(math.max(80, textWidth + 20))
end

-- Handle user input when Enter is pressed
trailColorEditBox:SetScript("OnEnterPressed", function(self)
    local hexColor = "#" .. self:GetText():gsub("#", "")
    local r, g, b, a = HexToRGB(hexColor)
    if r and g and b then
        a = a or 1
        local profileName = EasyCursorTrailsDB.currentProfile or "Default"
        local profile = EasyCursorTrailsDB.profiles[profileName] or {}
        profile.trailColor = { r = r, g = g, b = b, a = a }
        EasyCursorTrails.SaveToCurrentProfile("trailColor", profile.trailColor)


        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

        UpdateTrailColorEditBox()
    else
                print("Invalid HTML color format! Use #RRGGBB or #RRGGBBAA")
    end

    self:ClearFocus()
end)

trailColorEditBox:SetScript("OnEditFocusLost", function(self)
    self:GetScript("OnEnterPressed")(self)
end)

-- Button click logic
selectTrailColorButton:SetScript("OnClick", function()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local profile = EasyCursorTrailsDB.profiles[profileName] or {}
    local initialColor = profile.trailColor or { r = 1, g = 1, b = 1, a = 1 }

    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        profile.trailColor = color
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("trailColor", color)

        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

        UpdateTrailColorEditBox()
    end)
end)


-- Initialize edit box
UpdateTrailColorEditBox()

--------------------------------------------------------------------------
-- 6) (Optional) Save to Current Profile if needed on load
--------------------------------------------------------------------------
-- 🌱 Ensure required globals
effectsSettingsHeader = effectsSettingsHeader or menu
-- 🧭 Profile Management Header (positioned below slogan)
local profileHeader = menu:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
profileHeader:SetText("Profile Settings")

-- Anchor to the last slogan letter
local lastLetter = letters[#letters]
profileHeader:SetPoint("TOPRIGHT", lastLetter, "BOTTOMRIGHT", -130, -20)


-- 🔽 Profile Dropdown
local profileDropdown = CreateFrame("Frame", "EasyCursorTrails_ProfileDropdown", menu, "UIDropDownMenuTemplate")
profileDropdown:SetPoint("TOPLEFT", profileHeader, "TOPRIGHT", -140, -20)
EasyCursorTrails.profileDropdown = profileDropdown

-- 🧬 Ensure default profile exists
local function EnsureDefaultProfile()
    EasyCursorTrailsDB.profiles = EasyCursorTrailsDB.profiles or {}

    if not EasyCursorTrailsDB.profiles["Default"] then
        EasyCursorTrailsDB.profiles["Default"] = EasyCursorTrails.DeepCopyDefaults(EasyCursorTrails.defaults or {})
    end
end



function EasyCursorTrails.InitializeProfileDropdown()
    local dropdown = EasyCursorTrails.profileDropdown
    if not dropdown then return end

    -- 🧩 Ensure required profiles exist
    if type(EnsureDefaultProfile) == "function" then EnsureDefaultProfile() end

    local profiles = EasyCursorTrailsDB.profiles or {}
    local activeProfile = EasyCursorTrailsDB.currentProfile or "Default"

    -- 📋 Sort profiles with current one first
    local sortedProfiles = {}
    for name in pairs(profiles) do
        table.insert(sortedProfiles, name)
    end
    table.sort(sortedProfiles, function(a, b)
        if a == activeProfile then return true end
        if b == activeProfile then return false end
        return a < b
    end)

    UIDropDownMenu_SetWidth(dropdown, 160)

    UIDropDownMenu_Initialize(dropdown, function(self, level)
        if level ~= 1 then return end

        for _, name in ipairs(sortedProfiles) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = name
            info.checked = (name == activeProfile)
            info.func = function()
                -- 🔄 Switch profile
                EasyCursorTrailsDB.currentProfile = name
                EasyCursorTrails.SaveLastSelectedProfile(name)

                -- 🧼 Reset UI controls before applying new settings
                if type(EasyCursorTrails.ResetEffectControls) == "function" then
                    EasyCursorTrails.ResetEffectControls()
                end

                -- 🔁 Reload profile and effects
                EasyCursorTrails.LoadCurrentProfile()
                EasyCursorTrails.ApplySelectedGlowEffect()
                EasyCursorTrails.UpdateGlowFrames()

                -- 🎛️ Sync UI
                local glowEffectID = tonumber(EasyCursorTrails.profile and EasyCursorTrails.profile.selectedGlowEffect) or 1
                if type(EasyCursorTrails.SyncEffectSettingsUI) == "function" then
                    EasyCursorTrails.SyncEffectSettingsUI(glowEffectID)
                end
                if type(EasyCursorTrails.RefreshSettingsUI) == "function" then
                    EasyCursorTrails.RefreshSettingsUI()
                end

                -- 🏷️ Update dropdown label
                UIDropDownMenu_SetText(dropdown, name)
            end
            UIDropDownMenu_AddButton(info, level)
        end
    end)

    -- 🏷️ Set initial dropdown label
    UIDropDownMenu_SetText(dropdown, activeProfile)
end


-- 🚀 Initialize dropdown after menu is built
EasyCursorTrails.InitializeProfileDropdown()


-- 🐉 Ensure Coper_Dragon profile exists
local function EnsureCoperDragonProfile()
    -- Ensure DB and profiles table exist
    EasyCursorTrailsDB = EasyCursorTrailsDB or {}
    EasyCursorTrailsDB.profiles = EasyCursorTrailsDB.profiles or {}

 -- Coper_Dragon
    if not EasyCursorTrailsDB.profiles["Coper_Dragon"] then
     EasyCursorTrailsDB.profiles["Coper_Dragon"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 0.7215686274509804, g = 0.4509803921568628, b = 0.2 },
    connectTrails = true,
    enableStaticArc = false,
    selectedGlowTexture = 3,
    cursorColorEffect = 4,
    minimapPosition = { x = 0, y = 0 },
    rainbowSpeed = 5,
    horizontalScale = 1,
    randomLightningSparkColor = false,
    enableStaticArcs = false,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1000000014901161,
    enableTrails = true,
    starDustColor = { a = 1, r = 0.7215686440467834, g = 0.4509804248809815, b = 0.2313725650310516 },
    randomStarEmberColor = false,
    numGlows = 30,
    glowColor = { a = 1, r = 0.7215686274509804, g = 0.4470588235294118, b = 0.2 },
    trailTextureOpacity = 1,
    splitLayoutEnabled = false,
    sweepSpeed = 19,
    trailRadius = 20,
    pulsingSpeed = 10,
    cursorOffsetX = 0,
    enableSpringSeason = false,
    glowThickness = 0.6,
    enableTrailShadows = true,
    twinkleStarsColor = { a = 1, r = 0.937255, g = 1, b = 0.97647065 },
    enableTrailEffects = true,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = true,
    pulseMin = 0.3,
    enableSpringSeasonTrails = false,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    arcEmitterCooldown = 2.24,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = false,
    splitLayoutHeight = 50,
    trailSizeEnd = 5,
    selectedCursorTextureName = "Yin_Yang_1",
    driftX = 0,
    starColor = { a = 1, r = 0.7215686440467834, g = 0.4509804248809815, b = 0.2000000178813934 },
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    starDustSpawnRateMax = 80,
    enableTwinkleStars = true,
    randomShadowColor = false,
    enableSmokeEffect = false,
    twinkleEnabled = false,
    patternGlowCount = 28,
    cursorFrameStrata = "HIGH",
    trailTexture = 1,
    glowBelow = false,
    cursorSize = 40,
    twinkleSpeed = 5,
    trailLayerSpacing = 0,
    glowIntensity = 1,
    splitEffectEnabled = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    chainSpacing = 1,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 55,
    trailSpacing = 9,
    counterClockwiseSpeed = 30,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = false,
    randomSpringSeasonColor = false,
    cursorColor = { a = 1, r = 0.7215686274509804, g = 0.4470588235294118, b = 0.2 },
    glowIntensityFactor = 0.2999999821186066,
    randomStarDustColor = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 36,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    additionalEffects = 1,
    enableStarDust = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = true,
    trailColorEffect = 9,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    trailIntensity = 0.5,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    trailMovementEffect = 1,
    enableSmokeEffectTrails = false,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomSmokeColor = false,
    cursorOffsetY = 0,
    trailOffsetY = -24,
    trailOffsetX = -33,
    shimmerFrequency = 50,
    randomEmberColor = false,
    driftEnabled = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    rippleScale = 1.2,
    cursorTexture = 32,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.7215686440467834, g = 0.4509804248809815, b = 0.2000000178813934 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    trailLayerCount = 1,
    clockwiseSpeed = 30,
    glowSize = 0.300000011920929
        }
    end

 
          -- Ghost_Sparkles
    if not EasyCursorTrailsDB.profiles["Heart_2_heart"] then
     EasyCursorTrailsDB.profiles["Heart_2_heart"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 1, g = 0.3921568989753723, b = 0.4431372880935669 },
    enableStaticArc = false,
    minimapPosition = { x = 0, y = 0 },
    cursorColorEffect = 6,
    connectTrails = true,
    selectedGlowTexture = 2,
    horizontalScale = 1,
    enableLightningSpark = false,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 7.712482929229736,
    glowRadius = 0.2599999904632568,
    trailLayerCount = 1,
    starDustColor = { a = 1, r = 1, g = 0.3529411852359772, b = 0.7098039388656616 },
    randomStarEmberColor = false,
    enableTrails = true,
    glowColor = { a = 1, r = 1, g = 0.5215686274509804, b = 0.8862745098039215 },
    numGlows = 30,
    splitLayoutEnabled = false,
    sweepSpeed = 9,
    trailRadius = 20,
    trailUpdateMultiplier = 20,
    cursorOffsetX = 0,
    pulseMin = 0.3,
    enableSpringSeason = false,
    enableTrailShadows = true,
    trailTextureOpacity = 1,
    driftEnabled = false,
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    trailDelay = 0,
    chainSegment = 25,
    pulseEnabled = false,
    disableGlowPulsing = false,
    enableSpringSeasonTrails = false,
    randomFireTrailColor = false,
    rippleScale = 1.2,
    enableRotation = false,
    cursorFrameStrata = "HIGH",
    twinkleSpeed = 14,
    selectedCursorTextureName = "Heart_White",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    trailSizeEnd = 30,
    enableTwinkleStars = false,
    starDustSpawnRateMax = 80,
    enableSmokeEffect = false,
    enableTrailEffects = true,
    patternGlowCount = 40,
    arcEmitterCooldown = 2.24,
    trailTexture = 28,
    twinkleEnabled = false,
    cursorSize = 35,
    glowBelow = false,
    randomSpringSeasonColor = false,
    glowIntensity = 1,
    trailLayerSpacing = 0,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    splitEffectEnabled = true,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 25,
    randomSmokeColor = false,
    counterClockwiseSpeed = 30,
    smokeColor = { a = 1, r = 1, g = 0.3529411852359772, b = 0.7098039388656616 },
    enableEmbers = true,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 1, g = 0.3529411764705883, b = 0.7098039215686275 },
    chainSpacing = 1,
    enableStarDust = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 30,
    randomStarDustColor = false,
    additionalEffects = 1,
    enableStarEmbers = false,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    counterClockwiseEnabled = false,
    lightningSparkColor = { a = 1, r = 1, g = 0.4509804248809815, b = 0.8666667342185974 },
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    glowIntensityFactor = 0.5299999713897705,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    trailMovementEffect = 1,
    trailColorEffect = 9,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    trailSpacing = 15,
    cursorOffsetY = 0,
    trailOffsetY = -30,
    trailOffsetX = -32,
    shimmerFrequency = 50,
    enableSmokeEffectTrails = true,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    randomSpringSeasonTrailColor = false,
    cursorTexture = 26,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 1, g = 0.3529411852359772, b = 0.7098039388656616 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    randomLightningSparkColor = false,
    clockwiseSpeed = 30,
    rainbowSpeed = 5,
    glowSize = 0.6000000238418579
        }
    end



          -- Butterfly
    if not EasyCursorTrailsDB.profiles["Butterfly"] then
    EasyCursorTrailsDB.profiles["Butterfly"] = {
       enableTrails = true,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 1,
    connectTrails = true,
    horizontalScale = 1,
    minimapPosition = { x = 0, y = 0 },
    enableStaticArcs = false,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1700000017881393,
    trailColor = { a = 1, r = 0.2588235437870026, g = 0.4117647409439087, b = 0.1450980454683304 },
    selectedGlowTexture = 1,
    randomStarEmberColor = false,
    randomLightningSparkColor = false,
    glowColor = { a = 1, r = 1, g = 0.9215686274509803, b = 0.5725490196078431 },
    trailLayerCount = 1,
    splitLayoutEnabled = false,
    sweepSpeed = 19,
    trailRadius = 20,
    cursorTexture = 36,
    cursorOffsetX = 31,
    glowThickness = 1.648499727249146,
    verticalScale = 2,
    enableTrailShadows = true,
    cursorFrameStrata = "HIGH",
    rippleScale = 1.2,
    randomSpringSeasonTrailColor = true,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    randomShadowColor = false,
    enableSpringSeason = false,
    chainSegment = 5,
    pulseEnabled = false,
    disableGlowPulsing = false,
    trailSizeEnd = 18,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = false,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonColor = true,
    selectedCursorTextureName = "Butterfly_1",
    driftX = 0,
    randomEmberColor = true,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    starDustSpawnRateMax = 80,
    enableTwinkleStars = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    enableSmokeEffect = true,
    enableSmokeEffectTrails = true,
    patternGlowCount = 14,
    trailTextureOpacity = 0,
    trailTexture = 30,
    randomSmokeColor = true,
    cursorSize = 60,
    counterClockwiseSpeed = 30,
    splitLayoutHeight = 50,
    glowIntensity = 0.05000000074505806,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    trailInitialSeparation = 36,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 40,
    trailSpacing = 5,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = true,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 1, g = 0.1921568627450981, b = 0.1568627450980392 },
    trailLayerSpacing = 0,
    splitEffectEnabled = false,
    shimmerEnabled = true,
    trailFrameStrata = "HIGH",
    chainSpacing = 10,
    trailMovementEffect = 1,
    additionalEffects = 1,
    enableStarDust = false,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 5,
    glowIntensityFactor = 0.09999999403953552,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    randomStarDustColor = false,
    enableStarEmbers = false,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    glowBelow = false,
    cursorOffsetY = 45,
    trailOffsetY = 31,
    trailOffsetX = 26,
    shimmerFrequency = 5,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    enableSpringSeasonTrails = true,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    driftEnabled = false,
    trailDelay = 0,
    enableFireTrails = false,
    pulseMin = 0.3,
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    numGlows = 14,
    clockwiseSpeed = 30,
    rainbowSpeed = 5,
    glowSize = 1.400000095367432
                  }
    end
 
          -- Ghost_Sparkles
    if not EasyCursorTrailsDB.profiles["Ghost_Sparkles"] then
     EasyCursorTrailsDB.profiles["Ghost_Sparkles"] = {
    verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 2,
    connectTrails = false,
    enableLightningSpark = false,
    horizontalScale = 1,
    trailColor = { a = 1, r = 0.658823549747467, g = 1, b = 0.7568628191947937 },
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1000000014901161,
    trailLayerCount = 1,
    selectedGlowTexture = 3,
    randomStarEmberColor = false,
    rainbowSpeed = 5,
    glowColor = { a = 1, r = 0.6588235294117647, g = 1, b = 0.7568627450980392 },
    splitLayoutEnabled = false,
    numGlows = 30,
    sweepSpeed = 15,
    trailRadius = 20,
    driftEnabled = false,
    cursorOffsetX = 0,
    randomSpringSeasonTrailColor = false,
    pulseMin = 0.3,
    enableTrailShadows = false,
    rippleScale = 1.2,
    cursorFrameStrata = "HIGH",
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    enableSmokeEffectTrails = false,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    patternGlowCount = 26,
    randomFireTrailColor = false,
    cursorTexture = 30,
    enableRotation = false,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonColor = false,
    selectedCursorTextureName = "RGB_Rotate_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    starDustSpawnRateMax = 80,
    enableTwinkleStars = true,
    trailOffsetY = -24,
    enableSmokeEffect = true,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    enableSpringSeasonTrails = false,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    trailTexture = 26,
    counterClockwiseSpeed = 30,
    cursorSize = 36,
    glowBelow = false,
    splitLayoutHeight = 50,
    glowIntensity = 1,
    twinkleStarsRandomColor = true,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = true,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    trailInitialSeparation = 30,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 40,
    randomSmokeColor = true,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.5411764705882353, g = 0.9921568627450981, b = 1 },
    trailLayerSpacing = 0,
    splitEffectEnabled = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    chainSpacing = 1,
    trailMovementEffect = 1,
    additionalEffects = 1,
    enableStarDust = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = true,
    trailColorEffect = 6,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 5,
    glowIntensityFactor = 0.09999999403953552,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    randomStarDustColor = true,
    trailIntensity = 0.5,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    trailSpacing = 10,
    cursorOffsetY = 0,
    trailSizeEnd = 3,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    trailTextureOpacity = 0.1499999910593033,
    randomShadowColor = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    trailUpdateMultiplier = 80,
    enableSpringSeason = false,
    enableFireTrails = false,
    enableTrails = true,
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    randomLightningSparkColor = false,
    clockwiseSpeed = 30,
    minimapPosition = { x = 0, y = 0 },
    glowSize = 0.2000000029802322
                  }
    end

        -- Green Serpent
    if not EasyCursorTrailsDB.profiles["Green_Serpent"] then
    EasyCursorTrailsDB.profiles["Green_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    enableLightningSpark = false,
    cursorColorEffect = 6,
    connectTrails = false,
    randomLightningSparkColor = false,
    horizontalScale = 1,
    clockwiseSpeed = 30,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 7.712482929229736,
    glowRadius = 0.1000000014901161,
    rainbowSpeed = 5,
    trailLayerCount = 1,
    randomStarEmberColor = false,
    enableTrails = true,
    glowColor = { a = 1, r = 0.3764705882352941, g = 1, b = 0.08627450980392157 },
    numGlows = 30,
    splitLayoutEnabled = false,
    sweepSpeed = 20,
    trailRadius = 20,
    rippleScale = 1.2,
    cursorOffsetX = 0,
    trailUpdateMultiplier = 100,
    glowThickness = 0.8,
    enableTrailShadows = true,
    cursorTexture = 31,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    trailTextureOpacity = 1,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    trailOffsetY = -24,
    randomFireTrailColor = false,
    driftEnabled = false,
    enableRotation = false,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    randomSpringSeasonColor = false,
    selectedCursorTextureName = "Yin_Yang_v1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    enableSmokeEffectTrails = false,
    enableTwinkleStars = false,
    rainbowEnabled = false,
    enableSmokeEffect = true,
    randomSmokeColor = false,
    patternGlowCount = 19,
    cursorFrameStrata = "HIGH",
    trailTexture = 1,
    counterClockwiseSpeed = 30,
    cursorSize = 40,
    smokeColor = { a = 1, r = 0.1215686351060867, g = 0.294117659330368, b = 0.05490196496248245 },
    splitLayoutHeight = 50,
    glowIntensity = 1,
    echoScale = 1.5,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    pulseScale = 1.1,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 40,
    trailSpacing = 10,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.984313725490196, g = 0.9176470588235294, b = 0 },
    enableLightningSparks = false,
    trailColorEffect = 9,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    randomStarDustColor = false,
    trailMovementEffect = 1,
    additionalEffects = 1,
    trailIntensity = 0.5,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 19.43741798400879,
    enableStarEmbers = false,
    glowIntensityFactor = 0.2349990904331207,
    lightningSparkColor = { a = 1, r = 0.04313725605607033, g = 1, b = 0.4470588564872742 },
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 14,
    counterClockwiseEnabled = false,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    trailInitialSeparation = 36,
    enableStarDust = false,
    chainSpacing = 1,
    splitEffectEnabled = true,
    trailLayerSpacing = 0,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 0,
    trailSizeEnd = 1,
    trailOffsetX = -35,
    shimmerFrequency = 16.26232147216797,
    enableSpringSeasonTrails = false,
    enableTrailEffects = true,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    enableSpringSeason = false,
    pulseMin = 0.3,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 1, g = 0.3529411852359772, b = 0.7098039388656616 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    minimapPosition = { x = 0, y = 0 },
    selectedGlowTexture = 2,
    trailColor = { a = 1, r = 0.3764705882352941, g = 1, b = 0.08627450980392157 },
    glowSize = 0.4000000059604645
                }
    end
   
    -- Golden_Dragon
    if not EasyCursorTrailsDB.profiles["Golden_Dragon"] then
    EasyCursorTrailsDB.profiles["Golden_Dragon"] = {
     verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    randomSpringSeasonTrailColor = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 0.796078431372549, g = 0.6313725490196078, b = 0.207843137254902 },
    enableStaticArc = false,
    chainSpacing = 1,
    cursorColorEffect = 5,
    connectTrails = true,
    additionalEffects = 1,
    horizontalScale = 1,
    effectSettings = {
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [21] = { flickerRate = 0.2, emberRise = 6 },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { cascadeSpeed = 1.6, rippleScale = 1.1 },
    },
    enableStaticArcs = false,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1100002229213715,
    enableSmokeEffectTrails = false,
    starDustColor = { a = 1, r = 1, g = 0.8274510502815247, b = 0.2313725650310516 },
    randomStarEmberColor = false,
    starColor = { a = 1, r = 0.7960785031318665, g = 0.6313725709915161, b = 0.207843154668808 },
    glowColor = { a = 1, r = 1, g = 0.792156862745098, b = 0.2901960784313726 },
    pulsingSpeed = 10,
    splitLayoutEnabled = false,
    sweepSpeed = 19,
    trailRadius = 20,
    numGlows = 30,
    cursorOffsetX = 0,
    layerCount = 1,
    minimapPosition = { x = 0, y = 0 },
    enableTrailShadows = true,
    trailLayerCount = 1,
    enableSpringSeason = false,
    glowThickness = 0.6,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    selectedGlowTexture = 2,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    cursorTexture = 35,
    randomFireTrailColor = false,
    rippleScale = 1.2,
    enableRotation = false,
    enableSpringSeasonTrails = false,
    cursorFrameStrata = "HIGH",
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 0.8, r = 0.7960785031318665, g = 0.6313725709915161, b = 0.2352941334247589 },
    randomLightningSparkColor = false,
    enableTwinkleStars = true,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    enableSmokeEffect = false,
    twinkleStarsColor = { a = 1, r = 0.7960785031318665, g = 0.6313725709915161, b = 0.207843154668808 },
    patternGlowCount = 29,
    arcEmitterCooldown = 2.24,
    trailTexture = 1,
    starDustSpawnRateMax = 80,
    cursorSize = 40,
    randomSmokeColor = false,
    enableTrails = true,
    glowIntensity = 1,
    counterClockwiseSpeed = 30,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    randomSpringSeasonColor = false,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 50,
    trailSpacing = 9,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = false,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 0.796078431372549, g = 0.6313725490196078, b = 0.207843137254902 },
    trailTextureOpacity = 1,
    trailOffsetY = -24,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    randomStarDustColor = false,
    trailInitialSeparation = 36,
    enableStarDust = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 36,
    enableStarEmbers = true,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    glowIntensityFactor = 0.3299999833106995,
    menuPosition = { x = -244.833, y = 72.4999, point = "RIGHT", relativePoint = "RIGHT" },
    trailLayerSpacing = 0,
    splitEffectEnabled = true,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    trailIntensity = 0.5,
    cursorOffsetY = 0,
    trailSizeEnd = 5,
    trailOffsetX = -35,
    shimmerFrequency = 29,
    twinkleSpeed = 5,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    randomShadowColor = false,
    rainbowSpeed = 5,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.5529412031173706, g = 1, b = 0.1921568810939789 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    trailUpdateMultiplier = 100,
    clockwiseSpeed = 30,
    driftEnabled = false,
    glowSize = 0.5,

        }
    end

    
      -- Echo
    if not EasyCursorTrailsDB.profiles["Echo"] then
    EasyCursorTrailsDB.profiles["Echo"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 1, g = 1, b = 1 },
    enableStaticArc = false,
    enableLightningSpark = true,
    selectedGlowTexture = 2,
    cursorColorEffect = 6,
    connectTrails = true,
    minimapPosition = { x = 0, y = 0 },
    rainbowSpeed = 4,
    randomLightningSparkColor = false,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1400000005960465,
    enableTrails = true,
    starDustColor = { a = 1, r = 1, g = 0.3450980484485626, b = 0.0941176563501358 },
    randomStarEmberColor = false,
    numGlows = 30,
    glowColor = { a = 1, r = 1, g = 0.4117647058823529, b = 0.0392156862745098 },
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    splitLayoutEnabled = false,
    sweepSpeed = 17,
    trailRadius = 20,
    pulseMin = 0.3,
    cursorOffsetX = 0,
    trailDelay = 0,
    randomSpringSeasonTrailColor = false,
    enableTrailShadows = true,
    arcEmitterCooldown = 2.24,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowThickness = 0.5,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    patternGlowCount = 29,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    trailTextureOpacity = 0.4199999868869782,
    randomFireTrailColor = false,
    cursorTexture = 12,
    enableRotation = false,
    twinkleSpeed = 6,
    trailSizeEnd = 1,
    selectedCursorTextureName = "Circle4",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    starDustSpawnRateMax = 80,
    enableTwinkleStars = false,
    enableTrailEffects = true,
    enableSmokeEffect = false,
    twinkleEnabled = false,
    enableSpringSeasonTrails = false,
    cursorFrameStrata = "HIGH",
    trailTexture = 13,
    glowBelow = false,
    cursorSize = 35,
    randomSpringSeasonColor = false,
    trailLayerSpacing = 0,
    glowIntensity = 0.800000011920929,
    splitEffectEnabled = true,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    chainSpacing = 1,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 35,
    trailSpacing = 10,
    counterClockwiseSpeed = 41,
    smokeColor = { a = 0.4, r = 1, g = 0.4313725829124451, b = 0.09019608050584793 },
    enableEmbers = false,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 1, g = 0.4117647058823529, b = 0.0392156862745098 },
    glowIntensityFactor = 0.3400000035762787,
    randomStarDustColor = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 30,
    trailMovementEffect = 1,
    additionalEffects = 1,
    trailColorEffect = 12,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 26,
    enableStarEmbers = false,
    lightningSparkColor = { a = 1, r = 1, g = 0.4117647409439087, b = 0.04313725605607033 },
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 18,
    trailIntensity = 0.5,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    enableStarDust = false,
    enableLightningSparks = true,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomSmokeColor = false,
    cursorOffsetY = 0,
    enableSmokeEffectTrails = true,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    trailOffsetY = -24,
    rippleScale = 1.2,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    driftEnabled = false,
    trailUpdateMultiplier = 100,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 1, g = 0.2156862914562225, b = 0.003921568859368563 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    horizontalScale = 1,
    clockwiseSpeed = 53,
    trailLayerCount = 1,
    glowSize = 0.7000000476837158
            }
    end

    
     if not EasyCursorTrailsDB.profiles["Chain"] then
    EasyCursorTrailsDB.profiles["Chain"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 5,
    connectTrails = true,
    horizontalScale = 1,
    numGlows = 30,
    enableStaticArcs = true,
    glowAboveCursor = true,
    pulseSpeed = 8,
    glowRadius = 0.1700000017881393,
    trailColor = { a = 1, r = 0.71764706, g = 0.25490196, b = 0.05490196 },
    layerCount = 1,
    randomStarEmberColor = false,
    chainSpacing = 1,
    glowColor = { a = 1, r = 1, g = 0.6313725490196078, b = 0.1098039215686275 },
    additionalEffects = 0,
    splitLayoutEnabled = false,
    sweepSpeed = 27,
    trailRadius = 20,
    trailSizeEnd = 16,
    cursorOffsetX = 0,
    pulsingSpeed = 10,
    minimapPosition = { x = 0, y = 0 },
    enableTrailShadows = true,
    enableSpringSeasonTrails = false,
    rippleScale = 1.2,
    glowThickness = 0.5,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    selectedGlowTexture = 2,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    randomLightningSparkColor = false,
    randomFireTrailColor = false,
    cursorTexture = 35,
    enableRotation = false,
    arcEmitterCooldown = 2.24,
    starDustSpawnRateMax = 80,
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    twinkleSpeed = 8,
    enableTwinkleStars = false,
    rainbowSpeed = 5,
    enableSmokeEffect = true,
    trailUpdateMultiplier = 50,
    patternGlowCount = 29,
    cursorFrameStrata = "HIGH",
    trailTexture = 46,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    cursorSize = 30,
    counterClockwiseSpeed = 30,
    enableTrails = true,
    glowIntensity = 1,
    trailLayerCount = 1,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    driftEnabled = false,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 35,
    randomSmokeColor = false,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = false,
    randomSpringSeasonColor = false,
    cursorColor = { a = 1, r = 1, g = 0.06274509803921569, b = 0.05490196078431373 },
    enableSmokeEffectTrails = false,
    trailTextureOpacity = 1,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    randomStarDustColor = false,
    trailInitialSeparation = 30,
    enableStarDust = false,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 54,
    enableStarEmbers = false,
    trailColorEffect = 9,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 16,
    glowIntensityFactor = 0.3499999940395355,
    menuPosition = {
        x = -20,
        y = -5,
        point = "CENTER",
        relativePoint = "CENTER",
    },
    trailLayerSpacing = 0,
    splitEffectEnabled = false,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    trailIntensity = 0.5,
    cursorOffsetY = 0,
    trailOffsetY = -24,
    trailOffsetX = -28,
    shimmerFrequency = 50,
    splitLayoutHeight = 50,
    smokeColor = { a = 0.4, r = 0.1294117718935013, g = 0.1215686351060867, b = 0.1176470667123795 },
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    trailSpacing = 10,
    randomShadowColor = false,
    enableFireTrails = false,
    enableSpringSeason = false,
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    randomSpringSeasonTrailColor = false,
    clockwiseSpeed = 30,
    twinkleStarsColor = { a = 1, r = 0.937255, g = 1, b = 0.97647065 },
    glowSize = 0.5464993715286255
    }
end


     -- Pink_Serpent
    if not EasyCursorTrailsDB.profiles["Pink_Serpent"] then
        EasyCursorTrailsDB.profiles["Pink_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 5,
    connectTrails = true,
    trailColor = { a = 1, r = 0.7215686274509804, g = 0.1019607843137255, b = 0.9294117647058824 },
    horizontalScale = 1,
    minimapPosition = { x = 0, y = 0 },
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1000000014901161,
    clockwiseSpeed = 30,
    randomLightningSparkColor = false,
    randomStarEmberColor = false,
    enableTrails = true,
    glowColor = { a = 1, r = 0.7176470588235294, g = 0.4196078431372549, b = 0.9568627450980393 },
    numGlows = 30,
    splitLayoutEnabled = false,
    sweepSpeed = 20,
    trailRadius = 20,
    driftEnabled = false,
    cursorOffsetX = 0,
    glowThickness = 0.8,
    trailDelay = 0,
    enableTrailShadows = true,
    rippleScale = 1.2,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    starColor = { a = 1, r = 0.8901961445808411, g = 0.6313725709915161, b = 0.8862745761871338 },
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    enableSmokeEffectTrails = false,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = false,
    cursorFrameStrata = "HIGH",
    enableTrailEffects = true,
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 0.8, r = 1, g = 1, b = 1 },
    randomSpringSeasonColor = false,
    enableTwinkleStars = true,
    trailOffsetY = -25,
    enableSmokeEffect = false,
    rainbowEnabled = false,
    enableSpringSeasonTrails = false,
    trailTextureOpacity = 0.7999999523162842,
    trailTexture = 1,
    trailSpacing = 10,
    cursorSize = 40,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    glowIntensity = 1,
    splitLayoutHeight = 50,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    echoScale = 1.5,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 45,
    randomSmokeColor = false,
    counterClockwiseSpeed = 30,
    glowBelow = false,
    enableEmbers = true,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.9137254901960784, g = 0.5568627450980392, b = 1 },
    pulseScale = 1.1,
    enableLightningSparks = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    randomStarDustColor = false,
    trailMovementEffect = 1,
    trailInitialSeparation = 36,
    enableStarEmbers = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    glowIntensityFactor = 0.2999999821186066,
    echoDuration = 0.6,
    trailSizeStart = 15,
    rotationDirection = 1,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    enableStarDust = true,
    additionalEffects = 1,
    chainSpacing = 1,
    splitEffectEnabled = true,
    trailLayerSpacing = 0,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 0,
    trailSizeEnd = 1,
    trailOffsetX = -33,
    shimmerFrequency = 50,
    twinkleStarsColor = { a = 1, r = 0.9215686917304993, g = 0.6980392336845398, b = 0.8235294818878174 },
    patternGlowCount = 29,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    cursorTexture = 35,
    pulseMin = 0.3,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.9215686917304993, g = 0.615686297416687, b = 0.8352941870689392 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    trailLayerCount = 1,
    selectedGlowTexture = 2,
    rainbowSpeed = 5,
    glowSize = 0.5

        }
    end



     -- Super Charge
    if not EasyCursorTrailsDB.profiles["Super_Charge"] then
     EasyCursorTrailsDB.profiles["Super_Charge"] = {
    verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    enableTrails = true,
    trailLayerCount = 1,
    clockwiseSpeed = 30,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    enableLightningSpark = true,
    rainbowSpeed = 5,
    cursorColorEffect = 6,
    connectTrails = true,
    randomLightningSparkColor = false,
    horizontalScale = 1,
    trailTextureOpacity = 0,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1400000005960465,
    numGlows = 30,
    starDustColor = { a = 1, r = 0.7529412508010864, g = 1, b = 0.062745101749897 },
    randomStarEmberColor = false,
    randomSpringSeasonTrailColor = false,
    glowColor = { a = 1, r = 0.0196078431372549, g = 0.7176470588235294, b = 0.7098039215686275 },
    pulsingSpeed = 10,
    splitLayoutEnabled = false,
    sweepSpeed = 19,
    trailRadius = 20,
    cursorFrameStrata = "HIGH",
    cursorOffsetX = 0,
    enableSpringSeason = false,
    enableStarDust = false,
    enableTrailShadows = false,
    starColor = { a = 1, r = 0.08627451, g = 0.92549026, b = 0.8588236 },
    enableSpringSeasonTrails = false,
    glowThickness = 0.9,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    arcEmitterCooldown = 2.24,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    trailOffsetY = -25,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 28.38986968994141,
    enableRotation = false,
    rainbowEnabled = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    selectedCursorTextureName = "Circle_1_Hovering",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 0.1450980454683304, b = 0.05098039656877518 },
    randomSmokeColor = false,
    enableTwinkleStars = false,
    twinkleEnabled = false,
    enableSmokeEffect = false,
    smokeColor = { a = 1, r = 0.0941176563501358, g = 1, b = 0.6039215922355652 },
    patternGlowCount = 31,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    trailTexture = 15,
    echoScale = 1.5,
    cursorSize = 35,
    pulseScale = 1.1,
    useMufflerSmoke = true,
    glowIntensity = 1,
    enableLightningSparks = true,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    twinkleSpeed = 5,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 40,
    trailSpacing = 10,
    counterClockwiseSpeed = 30,
    glowBelow = false,
    enableEmbers = true,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 0.0196078431372549, g = 1, b = 0.9764705882352941 },
    glowIntensityFactor = 0.2999999821186066,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { cascadeSpeed = 1.6, rippleScale = 1.1 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    randomStarDustColor = false,
    trailInitialSeparation = 36,
    trailIntensity = 0.5,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = false,
    counterClockwiseEnabled = false,
    lightningSparkColor = { a = 1, r = 0.02352941408753395, g = 0.7176470756530762, b = 0.6901960968971252 },
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 4,
    additionalEffects = 1,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    trailColorEffect = 9,
    randomSpringSeasonColor = false,
    chainSpacing = 1,
    splitEffectEnabled = true,
    trailLayerSpacing = 0,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 0,
    trailSizeEnd = 8,
    trailOffsetX = -33,
    shimmerFrequency = 50,
    rippleScale = 1.2,
    enableSmokeEffectTrails = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    cursorTexture = 34,
    driftEnabled = false,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.08235294371843338, g = 0.9725490808486938, b = 1 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    minimapPosition = { x = 0, y = 0 },
    selectedGlowTexture = 3,
    trailColor = { a = 1, r = 0.4823529720306397, g = 0.9490196704864502, b = 1 },
    glowSize = 0.4039996862411499

        }
    end


    -- Silver_Dragon
    if not EasyCursorTrailsDB.profiles["Silver_Dragon"] then
     EasyCursorTrailsDB.profiles["Silver_Dragon"] = {
    verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    trailColor = { a = 1, r = 0.9764705882352941, g = 0.9764705882352941, b = 0.9764705882352941 },
    selectedGlowEffect = 1,
    clockwiseSpeed = 30,
    enableStaticArc = false,
    trailLayerCount = 1,
    cursorColorEffect = 5,
    minimapPosition = { x = 0, y = 0 },
    enableStaticArcs = false,
    rainbowSpeed = 5,
    pulseSpeed = 5,
    glowAboveCursor = false,
    randomLightningSparkColor = false,
    glowRadius = 0.1000000014901161,
    enableTrails = true,
    layerCount = 1,
    randomStarEmberColor = false,
    splitLayoutEnabled = false,
    glowColor = { a = 1, r = 0.9764705882352941, g = 0.9764705882352941, b = 0.9764705882352941 },
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    numGlows = 30,
    sweepSpeed = 19,
    trailRadius = 20,
    cursorTexture = 32,
    cursorOffsetX = 0,
    trailUpdateMultiplier = 100,
    enableSpringSeason = false,
    enableTrailShadows = true,
    cursorFrameStrata = "HIGH",
    rippleScale = 1.2,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    randomEmberColor = false,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    arcEmitterCooldown = 2.24,
    randomFireTrailColor = false,
    driftEnabled = false,
    enableRotation = false,
    randomSpringSeasonColor = false,
    trailOffsetY = -25,
    selectedCursorTextureName = "Yin_Yang_1",
    driftX = 0,
    starColor = { a = 1, r = 0.8274510502815247, g = 0.8274510502815247, b = 0.8274510502815247 },
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    rainbowEnabled = false,
    enableTwinkleStars = true,
    randomSmokeColor = false,
    enableSmokeEffect = false,
    counterClockwiseSpeed = 30,
    enableSpringSeasonTrails = false,
    trailTextureOpacity = 1,
    trailTexture = 1,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    cursorSize = 40,
    splitLayoutHeight = 50,
    echoScale = 1.5,
    glowIntensity = 1,
    pulseScale = 1.1,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    enableLightningSparks = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 50,
    trailSpacing = 10,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 1, g = 1, b = 1 },
    enableSmokeEffectTrails = false,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { cascadeSpeed = 1.6, rippleScale = 1.1 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    additionalEffects = 1,
    trailMovementEffect = 1,
    trailInitialSeparation = 36,
    trailIntensity = 0.5,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = true,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 18,
    enableStarDust = true,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    randomStarDustColor = false,
    glowIntensityFactor = 0.2016662210226059,
    chainSpacing = 1,
    splitEffectEnabled = true,
    trailLayerSpacing = 0,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 0,
    trailSizeEnd = 2,
    trailOffsetX = -33,
    shimmerFrequency = 42,
    patternGlowCount = 29,
    enableTrailEffects = true,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    pulseMin = 0.3,
    glowThickness = 0.6,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.8274510502815247, g = 0.8274510502815247, b = 0.8274510502815247 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    horizontalScale = 1,
    selectedGlowTexture = 2,
    connectTrails = true,
    glowSize = 0.4198331236839294
        }
    end

    -- Burning_Serpent
    if not EasyCursorTrailsDB.profiles["Burning_Serpent"] then
        EasyCursorTrailsDB.profiles["Burning_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 29,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableLightningSpark = false,
    enableStaticArc = false,
    trailColor = { a = 1, r = 1, g = 0.4392157196998596, b = 0.04313725605607033 },
    cursorColorEffect = 6,
    connectTrails = true,
    enableFireEffect = true,
    horizontalScale = 1,
    selectedGlowTexture = 2,
    enableStaticArcs = false,
    glowAboveCursor = false,
    pulseSpeed = 10,
    glowRadius = 0.1266662776470184,
    minimapPosition = { x = 0, y = 0 },
    glowThickness = 0.6,
    randomStarEmberColor = false,
    pulsingSpeed = 10,
    glowColor = { a = 1, r = 1, g = 0.796078431372549, b = 0.2470588235294118 },
    enableSpringSeason = false,
    numGlows = 30,
    sweepSpeed = 19,
    trailRadius = 20,
    rippleScale = 1.2,
    cursorOffsetX = 0,
    cursorTexture = 35,
    rainbowSpeed = 5,
    enableTrailShadows = true,
    enableSpringSeasonTrails = false,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    cursorFrameStrata = "HIGH",
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    enableTrails = true,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = true,
    starDustSpawnRateMax = 80,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    trailSizeEnd = 5,
    enableTwinkleStars = false,
    randomSmokeColor = false,
    enableSmokeEffect = true,
    enableTrailEffects = true,
    patternGlowCount = 9,
    twinkleStarsColor = { a = 1, r = 0.88627458, g = 0.34509805, b = 0.13333334 },
    trailTexture = 1,
    glowBelow = false,
    cursorSize = 32,
    twinkleSpeed = 20,
    trailTextureOpacity = 0.4599999785423279,
    glowIntensity = 1,
    trailLayerSpacing = 0,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.2392157, b = 0.07843138 },
    splitEffectEnabled = false,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 40,
    trailSpacing = 10,
    twinkleEnabled = false,
    smokeColor = { a = 0.4, r = 0.1, g = 0.1, b = 0.1 },
    enableEmbers = true,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 1, g = 0.3333333333333333, b = 0.08235294117647059 },
    chainSpacing = 1,
    randomStarDustColor = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 36,
    trailMovementEffect = 1,
    additionalEffects = 1,
    enableStarEmbers = false,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 74.0123062133789,
    trailIntensity = 0.5,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 15,
    glowIntensityFactor = 0.5399999618530273,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    enableStarDust = false,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = true,
    counterClockwiseSpeed = 30,
    cursorOffsetY = 0,
    trailOffsetY = -30,
    trailOffsetX = -36,
    shimmerFrequency = 50,
    enableSmokeEffectTrails = true,
    randomSpringSeasonColor = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    driftEnabled = false,
    trailLayerCount = 1,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.7215686440467834, g = 0.4509804248809815, b = 0.2000000178813934 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    randomLightningSparkColor = false,
    clockwiseSpeed = 30,
    splitLayoutEnabled = false,
    glowSize = 0.7839983105659485
        }
    end


  -- Marbles
    if not EasyCursorTrailsDB.profiles["Marbles"] then
    EasyCursorTrailsDB.profiles["Marbles"] = {
    enableTrails = true,
    echoFrequency = 100,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = true,
    cursorColorEffect = 2,
    connectTrails = true,
    horizontalScale = 1,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 10,
    glowRadius = 0.1000000014901161,
    trailColor = { a = 1, r = 1, g = 1, b = 1 },
    randomLightningSparkColor = false,
    randomStarEmberColor = false,
    selectedGlowTexture = 2,
    glowColor = { a = 1, r = 0.7098039215686275, g = 1, b = 0.4313725490196079 },
    splitLayoutEnabled = false,
    numGlows = 30,
    sweepSpeed = 20,
    trailRadius = 20,
    verticalScale = 2,
    cursorOffsetX = 0,
    trailLayerCount = 1,
    glowThickness = 0.8,
    enableTrailShadows = true,
    pulsingSpeed = 10,
    trailDelay = 0,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    driftEnabled = false,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = true,
    disableGlowPulsing = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = true,
    enableSpringSeasonTrails = false,
    trailTextureOpacity = 1,
    selectedCursorTextureName = "RGB_Rotate_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    randomSpringSeasonColor = false,
    enableTwinkleStars = false,
    starDustSpawnRateMax = 80,
    enableSmokeEffect = true,
    enableTrailEffects = true,
    patternGlowCount = 8,
    cursorFrameStrata = "HIGH",
    trailTexture = 3,
    enableSmokeEffectTrails = true,
    cursorSize = 40,
    randomSmokeColor = true,
    counterClockwiseSpeed = 30,
    glowIntensity = 1,
    splitLayoutHeight = 50,
    randomFireColor = false,
    randomStaticArcColor = true,
    rainbowEnabled = true,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    trailMovementEffect = 1,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 30,
    trailSpacing = 10,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.5411764705882353, g = 0.9921568627450981, b = 1 },
    trailIntensity = 0.5,
    trailLayerSpacing = 0,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    splitEffectEnabled = false,
    randomStarDustColor = true,
    additionalEffects = 1,
    chainSpacing = 1,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 60,
    enableStarEmbers = true,
    trailColorEffect = 11,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    glowIntensityFactor = 0.2999999821186066,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    trailInitialSeparation = 30,
    enableStarDust = true,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    glowBelow = false,
    cursorOffsetY = 0,
    trailOffsetY = -25,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    trailSizeEnd = 15,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    arcEmitterCooldown = 2.24,
    rippleScale = 1.2,
    enableFireTrails = false,
    cursorTexture = 30,
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    rainbowSpeed = 5,
    clockwiseSpeed = 30,
    minimapPosition = { x = 0, y = 0 },
    glowSize = 0.5
     }
    end


    -- Rainbow_Comet
    if not EasyCursorTrailsDB.profiles["Rainbow_Comet"] then
        EasyCursorTrailsDB.profiles["Rainbow_Comet"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    clockwiseSpeed = 30,
    trailColor = { a = 1, r = 1, g = 0.4627451300621033, b = 0.02745098248124123 },
    trailLayerCount = 1,
    enableLightningSpark = false,
    minimapPosition = { x = 0, y = 0 },
    cursorColorEffect = 6,
    connectTrails = true,
    rainbowSpeed = 5,
    randomLightningSparkColor = false,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1000000014901161,
    enableTrails = true,
    layerCount = 1,
    randomStarEmberColor = false,
    numGlows = 30,
    glowColor = { a = 1, r = 0.7176470588235294, g = 0.4196078431372549, b = 0.9568627450980393 },
    trailUpdateMultiplier = 100,
    splitLayoutEnabled = false,
    sweepSpeed = 29,
    trailRadius = 20,
    trailDelay = 0,
    cursorOffsetX = 0,
    arcEmitterCooldown = 2.24,
    starDustSpawnRateMin = 60,
    enableTrailShadows = true,
    driftEnabled = false,
    enableSmokeEffectTrails = false,
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    patternGlowCount = 40,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    cursorFrameStrata = "HIGH",
    randomFireTrailColor = false,
    cursorTexture = 34,
    enableRotation = false,
    trailOffsetY = -25,
    starDustSpawnRateMax = 80,
    selectedCursorTextureName = "Circle_1_Hovering",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 0.8, r = 1, g = 1, b = 1 },
    pulseStep = 0.02,
    enableTwinkleStars = false,
    trailSpacing = 10,
    enableSmokeEffect = true,
    counterClockwiseSpeed = 30,
    enableSpringSeasonTrails = false,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    trailTexture = 13,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    cursorSize = 40,
    splitLayoutHeight = 50,
    echoScale = 1.5,
    glowIntensity = 1,
    pulseScale = 1.1,
    randomFireColor = false,
    randomStaticArcColor = true,
    rainbowEnabled = true,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    enableLightningSparks = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 30,
    randomSmokeColor = true,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.5411764705882353, g = 0.9921568627450981, b = 1 },
    randomSpringSeasonColor = false,
    trailMovementEffect = 1,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    additionalEffects = 1,
    randomStarDustColor = true,
    trailInitialSeparation = 36,
    enableStarEmbers = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 11,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 18,
    enableStarDust = true,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    glowIntensityFactor = 0.1299999952316284,
    trailTextureOpacity = 1,
    chainSpacing = 1,
    splitEffectEnabled = false,
    trailLayerSpacing = 0,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 0,
    trailSizeEnd = 18,
    trailOffsetX = -33,
    shimmerFrequency = 50,
    enableTrailEffects = true,
    rippleScale = 1.2,
    pulseMax = 1,
    randomSmokeTrailColor = false,
    pulseMin = 0.3,
    randomSpringSeasonTrailColor = false,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.8274510502815247, g = 0.8274510502815247, b = 0.8274510502815247 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    horizontalScale = 1,
    selectedGlowTexture = 1,
    enableStaticArc = true,
    glowSize = 0.6000000238418579
        }
    end

    -- Fairy
    if not EasyCursorTrailsDB.profiles["Fairy"] then
        EasyCursorTrailsDB.profiles["Fairy"] = {
    verticalScale = 2,
    echoFrequency = 55,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableLightningSpark = false,
    trailColor = { a = 1, r = 1, g = 0.8431373238563538, b = 0 },
    selectedGlowTexture = 1,
    enableStaticArc = false,
    horizontalScale = 1,
    cursorColorEffect = 6,
    minimapPosition = { x = 0, y = 0 },
    rainbowSpeed = 5,
    pulseSpeed = 5,
    enableStaticArcs = true,
    glowAboveCursor = false,
    randomLightningSparkColor = false,
    glowRadius = 0.1500000059604645,
    enableTrails = true,
    layerCount = 50,
    randomStarEmberColor = false,
    numGlows = 30,
    glowColor = { a = 1, r = 1, g = 0.8431372549019608, b = 0 },
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    splitLayoutEnabled = false,
    sweepSpeed = 19,
    trailRadius = 20,
    randomSpringSeasonTrailColor = false,
    cursorOffsetX = 52,
    pulseMin = 0.3,
    trailDelay = 0,
    enableTrailShadows = false,
    trailTextureOpacity = 1,
    randomEmberColor = true,
    glowThickness = 2,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 1,
    patternGlowCount = 21,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    cursorFrameStrata = "HIGH",
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = false,
    enableSmokeEffectTrails = false,
    starDustSpawnRateMax = 80,
    selectedCursorTextureName = "Fairy_Left_1_Hovering",
    driftX = 0,
    starColor = { a = 1, r = 0.9019608497619629, g = 0.7882353663444519, b = 0 },
    staticArcColor = { a = 1, r = 0.9019608497619629, g = 0.7882353663444519, b = 0 },
    enableTrailEffects = true,
    enableTwinkleStars = true,
    trailSpacing = 10,
    enableSmokeEffect = false,
    counterClockwiseSpeed = 30,
    enableSpringSeasonTrails = false,
    arcEmitterCooldown = 2.24,
    trailTexture = 19,
    glowBelow = false,
    cursorSize = 100,
    trailLayerSpacing = 55,
    splitEffectEnabled = false,
    glowIntensity = 0.05000000074505806,
    chainSpacing = 1,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    splitLayoutHeight = 50,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 10,
    randomSmokeColor = false,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 0.8352941870689392, b = 0.09019608050584793 },
    enableEmbers = true,
    randomSpringSeasonColor = false,
    cursorColor = { a = 1, r = 1, g = 0.8431372549019608, b = 0 },
    enableStarDust = true,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    additionalEffects = 1,
    randomStarDustColor = false,
    trailInitialSeparation = 40,
    enableStarEmbers = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 4,
    trailMovementEffect = 1,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    glowIntensityFactor = 0.09999999403953552,
    twinkleSpeed = 5,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomShadowColor = false,
    cursorOffsetY = 32,
    trailSizeEnd = 3,
    trailOffsetX = 53,
    shimmerFrequency = 50,
    trailOffsetY = 35,
    cursorTexture = 37,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    driftEnabled = false,
    rippleScale = 1.2,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.9019608497619629, g = 0.7882353663444519, b = 0 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    connectTrails = true,
    clockwiseSpeed = 30,
    trailLayerCount = 4,
    glowSize = 1.5
        }
    end


      -- Blue_Serpent
    if not EasyCursorTrailsDB.profiles["Blue_Serpent"] then
        EasyCursorTrailsDB.profiles["Blue_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    trailColor = { a = 1, r = 0, g = 1, b = 1 },
    cursorColorEffect = 2,
    connectTrails = true,
    twinkleStarsColor = { a = 1, r = 1, g = 1, b = 0.9568628072738647 },
    horizontalScale = 1,
    clockwiseSpeed = 30,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1500000059604645,
    randomSpringSeasonTrailColor = false,
    starDustColor = { a = 1, r = 0, g = 1, b = 0.9411765336990356 },
    randomStarEmberColor = false,
    minimapPosition = { x = 0, y = 0 },
    glowColor = { a = 1, r = 0, g = 1, b = 1 },
    trailDelay = 0,
    numGlows = 30,
    sweepSpeed = 20,
    trailRadius = 20,
    randomLightningSparkColor = false,
    cursorOffsetX = 0,
    cursorTexture = 35,
    randomShadowColor = false,
    enableTrailShadows = true,
    trailSpacing = 10,
    trailUpdateMultiplier = 100,
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    patternGlowCount = 15,
    enableSpringSeason = false,
    chainSegment = 7,
    pulseEnabled = false,
    disableGlowPulsing = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    randomFireTrailColor = false,
    rippleScale = 1.2,
    enableRotation = true,
    splitLayoutHeight = 50,
    trailLayerCount = 1,
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    starColor = { a = 1, r = 0, g = 1, b = 0.9411765336990356 },
    staticArcColor = { a = 0.8, r = 1, g = 1, b = 1 },
    rainbowEnabled = false,
    enableTwinkleStars = true,
    trailOffsetY = -24,
    enableSmokeEffect = false,
    driftEnabled = false,
    enableSpringSeasonTrails = false,
    arcEmitterCooldown = 2.24,
    trailTexture = 1,
    trailIntensity = 0.5,
    cursorSize = 30,
    twinkleEnabled = false,
    randomSpringSeasonColor = false,
    glowIntensity = 1,
    enableSmokeEffectTrails = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    echoScale = 1.5,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 50,
    randomSmokeColor = false,
    counterClockwiseSpeed = 30,
    glowBelow = false,
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 1, g = 0.1411764705882353, b = 0.09411764705882353 },
    pulseScale = 1.1,
    enableLightningSparks = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    randomStarDustColor = false,
    trailMovementEffect = 1,
    additionalEffects = 1,
    trailTextureOpacity = 1,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = true,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    glowIntensityFactor = 0.2999999821186066,
    echoDuration = 0.6,
    trailSizeStart = 15,
    rotationDirection = 1,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    enableStarDust = true,
    trailInitialSeparation = 36,
    chainSpacing = 1,
    splitEffectEnabled = false,
    trailLayerSpacing = 0,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    enableTrailEffects = true,
    cursorOffsetY = 0,
    trailSizeEnd = 1,
    trailOffsetX = -35,
    shimmerFrequency = 8,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    rainbowSpeed = 5,
    randomEmberColor = false,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0, g = 1, b = 0.9411765336990356 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    pulseMin = 0.3,
    selectedGlowTexture = 2,
    splitLayoutEnabled = false,
    glowSize = 0.300000011920929
            }
    end

      -- Black_Pink_Serpent
    if not EasyCursorTrailsDB.profiles["Black_Pink_Serpent"] then
    EasyCursorTrailsDB.profiles["Black_Pink_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 2,
    connectTrails = true,
    trailColor = { a = 1, r = 0.2862745225429535, g = 0.2313725650310516, b = 0.250980406999588 },
    horizontalScale = 1,
    rainbowSpeed = 5,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1000000014901161,
    selectedGlowTexture = 2,
    trailLayerCount = 1,
    randomStarEmberColor = false,
    enableTrails = true,
    glowColor = { a = 1, r = 0.7176470588235294, g = 0.4196078431372549, b = 0.9568627450980393 },
    splitLayoutEnabled = false,
    numGlows = 30,
    sweepSpeed = 20,
    trailRadius = 20,
    trailUpdateMultiplier = 100,
    cursorOffsetX = 0,
    pulsingSpeed = 10,
    randomSpringSeasonTrailColor = false,
    enableTrailShadows = true,
    driftEnabled = false,
    randomEmberColor = false,
    glowThickness = 0.8,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    trailTextureOpacity = 1,
    enableSpringSeason = false,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    enableSpringSeasonTrails = false,
    randomFireTrailColor = false,
    cursorTexture = 32,
    enableRotation = false,
    arcEmitterCooldown = 2.24,
    randomSpringSeasonColor = false,
    selectedCursorTextureName = "Yin_Yang_1",
    driftX = 0,
    starColor = { a = 1, r = 0.7960785031318665, g = 0.6392157077789307, b = 0.6980392336845398 },
    staticArcColor = { a = 1, r = 0.7960785031318665, g = 0.6392157077789307, b = 0.6980392336845398 },
    starDustSpawnRateMax = 80,
    enableTwinkleStars = true,
    trailSizeEnd = 1,
    enableSmokeEffect = false,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    patternGlowCount = 29,
    twinkleStarsColor = { a = 1, r = 0.7960785031318665, g = 0.6392157077789307, b = 0.6980392336845398 },
    trailTexture = 1,
    enableTrailEffects = true,
    cursorSize = 40,
    counterClockwiseSpeed = 30,
    glowBelow = false,
    glowIntensity = 1,
    splitLayoutHeight = 50,
    randomFireColor = false,
    randomStaticArcColor = false,
    rainbowEnabled = false,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    trailLayerSpacing = 0,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 40,
    randomSmokeColor = false,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = false,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.5411764705882353, g = 0.9921568627450981, b = 1 },
    splitEffectEnabled = true,
    chainSpacing = 1,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 36,
    trailMovementEffect = 1,
    additionalEffects = 1,
    enableStarDust = true,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    glowIntensityFactor = 0.7433335185050964,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    enableStarEmbers = true,
    randomStarDustColor = true,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    trailSpacing = 9,
    cursorOffsetY = 0,
    trailOffsetY = -24,
    trailOffsetX = -33,
    shimmerFrequency = 42,
    enableSmokeEffectTrails = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    rippleScale = 1.2,
    trailDelay = 0,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.5843137502670288, g = 0.125490203499794, b = 0.0313725508749485 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    randomLightningSparkColor = false,
    clockwiseSpeed = 30,
    minimapPosition = { x = 0, y = 0 },
    glowSize = 0.300000011920929

       }
    end

      -- Black_Serpent
    if not EasyCursorTrailsDB.profiles["Black_Serpent"] then
     EasyCursorTrailsDB.profiles["Black_Serpent"] = {
    verticalScale = 2,
    echoFrequency = 46,
    echoEnabled = false,
    trailColor = { a = 1, r = 0.02745098039215686, g = 0.00392156862745098, b = 0 },
    selectedGlowEffect = 1,
    minimapPosition = { x = 0, y = 0 },
    enableLightningSpark = false,
    clockwiseSpeed = 30,
    cursorColorEffect = 6,
    connectTrails = true,
    enableFireEffect = false,
    horizontalScale = 1,
    enableTrails = true,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1000000014901161,
    randomLightningSparkColor = false,
    trailLayerCount = 1,
    randomStarEmberColor = false,
    splitLayoutEnabled = false,
    glowColor = { a = 1, r = 1, g = 0.1647058823529412, b = 0.01568627450980392 },
    glowThickness = 0.8,
    numGlows = 30,
    sweepSpeed = 26,
    trailRadius = 20,
    driftEnabled = false,
    cursorOffsetX = 0,
    trailTextureOpacity = 1,
    cursorFrameStrata = "HIGH",
    enableTrailShadows = true,
    cursorTexture = 32,
    rippleScale = 1.2,
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulsingSpeed = 10,
    enableSmokeEffectTrails = false,
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    arcEmitterCooldown = 2.24,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 100,
    enableRotation = false,
    splitLayoutHeight = 50,
    trailOffsetY = -24,
    selectedCursorTextureName = "Yin_Yang_1",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 0.1176470667123795, g = 0.1176470667123795, b = 0.1176470667123795 },
    rainbowEnabled = false,
    enableTwinkleStars = false,
    trailSpacing = 10,
    enableSmokeEffect = true,
    counterClockwiseSpeed = 30,
    patternGlowCount = 29,
    twinkleStarsColor = { a = 1, r = 0.9843137860298157, g = 0.9294118285179138, b = 1 },
    trailTexture = 1,
    smokeColor = { a = 0.4, r = 0.1294117718935013, g = 0.1215686351060867, b = 0.1176470667123795 },
    cursorSize = 40,
    twinkleSpeed = 5,
    useMufflerSmoke = true,
    glowIntensity = 1,
    echoScale = 1.5,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.125490203499794, b = 0.05098039656877518 },
    pulseScale = 1.1,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 50,
    randomSmokeColor = false,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = true,
    randomSpringSeasonColor = false,
    cursorColor = { a = 1, r = 1, g = 0.5568627450980392, b = 0.2235294117647059 },
    enableLightningSparks = false,
    enableStarDust = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { rippleScale = 1.1, cascadeSpeed = 1.6 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    trailInitialSeparation = 36,
    trailIntensity = 0.5,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = false,
    glowIntensityFactor = 1,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    trailColorEffect = 10,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    additionalEffects = 1,
    randomStarDustColor = false,
    chainSpacing = 1,
    splitEffectEnabled = false,
    trailLayerSpacing = 0,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    enableTrailEffects = true,
    cursorOffsetY = 0,
    trailSizeEnd = 1,
    trailOffsetX = -35,
    shimmerFrequency = 50,
    enableSpringSeasonTrails = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    enableSpringSeason = false,
    pulseMin = 0.3,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 1, g = 0.3686274588108063, b = 0.06666667014360428 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    rainbowSpeed = 5,
    selectedGlowTexture = 2,
    enableStaticArc = false,
    glowSize = 0.2000000029802322
     }
    end    

        -- Jade_Dragon
    if not EasyCursorTrailsDB.profiles["Jade_Dragon"] then
    EasyCursorTrailsDB.profiles["Jade_Dragon"] = {
    enableTrails = true,
    echoFrequency = 46,
    echoEnabled = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 0.05882353335618973, g = 1, b = 0.5490196347236633 },
    minimapPosition = { x = 0, y = 0 },
    enableStaticArc = false,
    selectedGlowTexture = 1,
    cursorColorEffect = 6,
    connectTrails = true,
    enableLightningSpark = false,
    rainbowSpeed = 5,
    randomLightningSparkColor = false,
    enableStaticArcs = false,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1599999964237213,
    trailLayerCount = 1,
    layerCount = 1,
    randomStarEmberColor = false,
    splitLayoutEnabled = false,
    glowColor = { a = 1, r = 0.05882352941176471, g = 1, b = 0.5490196078431373 },
    cursorTexture = 35,
    numGlows = 30,
    sweepSpeed = 20,
    trailRadius = 20,
    randomSpringSeasonTrailColor = false,
    cursorOffsetX = 0,
    pulseMin = 0.3,
    cursorFrameStrata = "HIGH",
    enableTrailShadows = true,
    rippleScale = 1.2,
    randomEmberColor = false,
    glowThickness = 0.9,
    driftY = 0,
    clockwiseEnabled = true,
    pulsingSpeed = 10,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    randomFireTrailColor = false,
    driftEnabled = false,
    enableRotation = false,
    randomSpringSeasonColor = false,
    enableSmokeEffectTrails = false,
    selectedCursorTextureName = "Circle_focus_1",
    driftX = 0,
    starColor = { a = 1, r = 0, g = 0.658823549747467, b = 0.4196078777313232 },
    staticArcColor = { a = 1, r = 0.7960785031318665, g = 0.6392157077789307, b = 0.6980392336845398 },
    rainbowEnabled = false,
    enableTwinkleStars = true,
    enableTrailEffects = true,
    enableSmokeEffect = false,
    counterClockwiseSpeed = 30,
    enableSpringSeasonTrails = false,
    arcEmitterCooldown = 2.24,
    trailTexture = 1,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    cursorSize = 30,
    splitLayoutHeight = 50,
    trailLayerSpacing = 0,
    glowIntensity = 0.5,
    splitEffectEnabled = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    chainSpacing = 1,
    randomShadowColor = false,
    glowHollowness = 0,
    trailCount = 45,
    trailSpacing = 10,
    twinkleEnabled = false,
    glowBelow = false,
    enableEmbers = true,
    twinkleSpeed = 5,
    cursorColor = { a = 1, r = 0.05882352941176471, g = 1, b = 0.5490196078431373 },
    glowIntensityFactor = 0.2999999821186066,
    trailMovementEffect = 1,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailInitialSeparation = 30,
    randomStarDustColor = false,
    additionalEffects = 0,
    trailColorEffect = 10,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    trailIntensity = 0.5,
    lightningSparkColor = { a = 1, r = 0.2156862914562225, g = 0.5647059082984924, b = 1 },
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 18,
    enableStarEmbers = false,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    enableStarDust = false,
    trailTextureOpacity = 1,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = false,
    numTrails = 10,
    enableFire = false,
    randomSmokeColor = false,
    cursorOffsetY = 0,
    trailOffsetY = -25,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    patternGlowCount = 30,
    trailSizeEnd = 1,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    enableSpringSeason = false,
    trailUpdateMultiplier = 100,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.5529412031173706, g = 1, b = 0.1921568810939789 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    horizontalScale = 1,
    clockwiseSpeed = 30,
    verticalScale = 2,
    glowSize = 0.9000000357627869
     }
    end  

     -- Locator
    if not EasyCursorTrailsDB.profiles["Silver_Sky_Dragon"] then
   EasyCursorTrailsDB.profiles["Locator"] = {
    verticalScale = 2,
    horizontalScale = 1,
    glowRadius = 0.16,
    glowThickness = 0.8,
    glowSize = 0.5,
    glowIntensity = 1,
    glowIntensityFactor = 0.04333,
    glowHollowness = 0,
    glowAboveCursor = false,
    glowBelow = false,
    glowColor = { r = 0.06667, g = 0.93333, b = 1, a = 1 },

    selectedGlowEffect = 1,
    selectedGlowTexture = 2,
    selectedCursorTextureName = "Circle_focus_1",
    cursorTexture = 35,
    cursorSize = 30,
    cursorOffsetX = 0,
    cursorOffsetY = 0,
    cursorColor = { r = 1, g = 0.098, b = 0, a = 1 },
    cursorColorEffect = 6,
    cursorFrameStrata = "HIGH",

    trailCount = 15,
    trailRadius = 20,
    trailSpacing = 100,
    trailInitialSeparation = 30,
    trailSizeStart = 20,
    trailSizeEnd = 20,
    trailOffsetX = -28,
    trailOffsetY = -1,
    trailTexture = 38,
    trailTextureOpacity = 1,
    trailGlowIntensity = 1,
    trailIntensity = 0.5,
    trailLayerCount = 1,
    trailLayerSpacing = 0,
    trailMovementEffect = 1,
    trailColorEffect = 9,
    trailColor = { r = 0.06667, g = 0.93333, b = 1, a = 1 },

    enableTrails = true,
    enableTrailEffects = true,
    enableTrailShadows = true,
    enableSmokeEffectTrails = true,
    enableStarDust = false,
    enableStarEmbers = false,
    enableEmbers = false,
    enableFire = false,
    enableFireTrails = false,
    enableSmokeEffect = false,
    enableTwinkleStars = false,
    enableLightningSparks = false,
    enableRotation = true,
    enableStaticArc = false,
    enableStaticArcs = true,
    enableSpringSeason = false,
    enableSpringSeasonTrails = false,
    splitLayoutEnabled = false,
    splitLayoutHeight = 50,
    splitEffectEnabled = true,
    connectTrails = true,
    clockwiseEnabled = false,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    rotationSpeed = 30,
    clockwiseSpeed = 30,
    counterClockwiseSpeed = 30,
    driftEnabled = false,
    driftX = 0,
    driftY = 0,

    pulseEnabled = false,
    pulseSpeed = 8,
    pulseMin = 0.3,
    pulseScale = 1.1,
    glowPulsingIntensity = 0.5,
    disableGlowPulsing = false,

    shimmerEnabled = false,
    shimmerFrequency = 50,
    twinkleEnabled = false,
    twinkleSpeed = 5,
    echoEnabled = false,
    echoFrequency = 46,
    echoDuration = 0.6,
    echoScale = 1.5,
    sweepEnabled = false,
    sweepSpeed = 29,
    chainSegment = 100,
    rippleScale = 1.2,
    patternGlowCount = 30,
    arcEmitterCooldown = 2.24,
    trailDelay = 0,

    rainbowEnabled = false,
    rainbowSpeed = 4.9375,

    randomFireColor = false,
    randomFireTrailColor = false,
    randomSmokeColor = false,
    randomSmokeTrailColor = false,
    randomShadowColor = false,
    randomStarDustColor = false,
    randomStarEmberColor = false,
    randomEmberColor = false,
    randomLightningSparkColor = false,
    randomStaticArcColor = false,
    randomSpringSeasonColor = false,
    randomSpringSeasonTrailColor = false,
    randomTwinkleStarsColor = false,

    fireColor = { r = 1, g = 0.5, b = 0.2, a = 1 },
    staticArcColor = { r = 1, g = 1, b = 1, a = 1 },
    shadowTrailColor = { r = 0, g = 0, b = 0, a = 1 },
    smokeColor = { r = 1, g = 1, b = 1, a = 1 },
    twinkleStarsColor = { r = 0.9, g = 0.95, b = 1, a = 1 },

    starDustSpawnRateMin = 60,
    starDustSpawnRateMax = 80,

    menuPosition = {
        point = "TOP",
        relativePoint = "TOP",
        x = 250.1666412,
        y = -87.3333206,
    },
}

    end
    -- Silver_Sky_Dragon
    if not EasyCursorTrailsDB.profiles["Silver_Sky_Dragon"] then
    EasyCursorTrailsDB.profiles["Silver_Sky_Dragon"] = {
     verticalScale = 2,
    echoFrequency = 47,
    echoEnabled = false,
    selectedGlowEffect = 1,
    enableStaticArc = false,
    cursorColorEffect = 6,
    connectTrails = true,
    trailColor = { a = 1, r = 1, g = 1, b = 1 },
    horizontalScale = 1,
    minimapPosition = { x = 0, y = 0 },
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 8,
    glowRadius = 0.1349996626377106,
    clockwiseSpeed = 30,
    randomLightningSparkColor = false,
    randomStarEmberColor = false,
    enableTrails = true,
    glowColor = { a = 1, r = 1, g = 1, b = 1 },
    numGlows = 30,
    splitLayoutEnabled = false,
    sweepSpeed = 20,
    trailRadius = 20,
    cursorTexture = 34,
    cursorOffsetX = 0,
    glowThickness = 0.5,
    enableSpringSeason = false,
    enableTrailShadows = true,
    trailUpdateMultiplier = 100,
    twinkleStarsColor = { a = 1, r = 0.9, g = 0.95, b = 1 },
    randomSpringSeasonTrailColor = false,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    starColor = { a = 1, r = 1, g = 1, b = 1 },
    trailDelay = 0,
    chainSegment = 9,
    pulseEnabled = false,
    disableGlowPulsing = false,
    trailOffsetY = -25,
    randomFireTrailColor = false,
    rippleScale = 1.2,
    enableRotation = false,
    trailTextureOpacity = 0.468332827091217,
    randomShadowColor = false,
    selectedCursorTextureName = "Circle_1_Hovering",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 1, b = 1 },
    twinkleSpeed = 5,
    enableTwinkleStars = false,
    enableSmokeEffectTrails = true,
    enableSmokeEffect = true,
    rainbowEnabled = false,
    patternGlowCount = 26,
    cursorFrameStrata = "HIGH",
    trailTexture = 1,
    randomSmokeColor = false,
    cursorSize = 35,
    twinkleEnabled = false,
    smokeColor = { a = 1, r = 0.9372549653053284, g = 0.9372549653053284, b = 0.9372549653053284 },
    glowIntensity = 1,
    randomSpringSeasonColor = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    echoScale = 1.5,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    glowHollowness = 0,
    trailCount = 40,
    trailSpacing = 10,
    counterClockwiseSpeed = 30,
    glowBelow = false,
    enableEmbers = false,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 0.6666666666666666, g = 0.8117647058823529, b = 1 },
    pulseScale = 1.1,
    enableLightningSparks = false,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    randomStarDustColor = false,
    additionalEffects = 1,
    trailIntensity = 0.5,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 30,
    enableStarEmbers = false,
    trailColorEffect = 10,
    counterClockwiseEnabled = false,
    glowIntensityFactor = 0.2849994897842407,
    echoDuration = 0.6,
    trailSizeStart = 15,
    rotationDirection = 1,
    menuPosition = {
        x = 250.1666412353516,
        y = -87.33332061767578,
        point = "TOP",
        relativePoint = "TOP",
    },
    enableStarDust = false,
    trailInitialSeparation = 30,
    chainSpacing = 1,
    splitEffectEnabled = false,
    trailLayerSpacing = 0,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    enableTrailEffects = true,
    cursorOffsetY = 0,
    trailSizeEnd = 5,
    trailOffsetX = -30,
    shimmerFrequency = 50,
    arcEmitterCooldown = 2.24,
    enableSpringSeasonTrails = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    driftEnabled = false,
    pulsingSpeed = 10,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 0.08235294371843338, g = 0.9725490808486938, b = 1 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    trailLayerCount = 1,
    selectedGlowTexture = 2,
    rainbowSpeed = 5,
    glowSize = 0.4198331236839294
                }
    end  

    -- Sniper
    if not EasyCursorTrailsDB.profiles["Sniper"] then
    EasyCursorTrailsDB.profiles["Sniper"] = {
    enableTrails = true,
    echoFrequency = 47,
    echoEnabled = false,
    minimapPosition = { x = 0, y = 0 },
    driftEnabled = false,
    selectedGlowEffect = 1,
    trailColor = { a = 1, r = 1, g = 0.6117647290229797, b = 0.2666666805744171 },
    enableStaticArc = false,
    chainSpacing = 1,
    cursorColorEffect = 5,
    connectTrails = true,
    lightningSparkColor = { a = 1, r = 1, g = 0.2000000178813934, b = 0.03921568766236305 },
    horizontalScale = 1,
    additionalEffects = 1,
    enableStaticArcs = true,
    glowAboveCursor = false,
    pulseSpeed = 5,
    glowRadius = 0.1299999952316284,
    effectSettings = {
        [24] = { pulseScale = 1.15, driftSpeed = 2 },
        [25] = { driftX = 2, driftY = 2, fadeAlpha = 0.3 },
        [26] = { surgeSpeed = 0.25, pulseScale = 1.2 },
        [27] = { rotationChaos = true, flickerAlphaMin = 0.2, flickerAlphaMax = 0.8 },
        [28] = { flareScale = 1.4, shimmerAlpha = 0.5 },
        [29] = { cascadeSpeed = 1.6, rippleScale = 1.1 },
        [11] = { pulseScale = 1.2, rotationSpeed = 360, clockwise = true, customTexture = "Interface\\Cooldown\\star4" },
        [22] = { fallSpeed = 10, shimmerAlpha = 0.8 },
        [23] = { burstScale = 1.4, driftOffset = 4 },
        [21] = { flickerRate = 0.2, emberRise = 6 },
    },
    layerCount = 1,
    randomStarEmberColor = false,
    enableSmokeEffectTrails = false,
    glowColor = { a = 1, r = 1, g = 0.592156862745098, b = 0.1098039215686275 },
    pulsingSpeed = 10,
    splitLayoutEnabled = false,
    sweepSpeed = 11,
    trailRadius = 20,
    numGlows = 30,
    cursorOffsetX = 0,
    enableLightningSpark = false,
    enableTrailShadows = true,
    enableSpringSeasonTrails = false,
    cursorTexture = 8,
    glowThickness = 0.5,
    driftY = 0,
    clockwiseEnabled = false,
    pulseMin = 0.3,
    selectedGlowTexture = 2,
    enableSpringSeason = false,
    chainSegment = 100,
    pulseEnabled = false,
    disableGlowPulsing = false,
    rainbowSpeed = 5,
    randomFireTrailColor = false,
    trailUpdateMultiplier = 16,
    enableRotation = false,
    trailDelay = 0,
    randomSpringSeasonTrailColor = false,
    selectedCursorTextureName = "dirty_lens",
    driftX = 0,
    randomEmberColor = false,
    staticArcColor = { a = 1, r = 1, g = 0.1450980454683304, b = 0.05098039656877518 },
    cursorFrameStrata = 4,
    enableTwinkleStars = true,
    shadowTrailColor = { a = 0.4, r = 0, g = 0, b = 0 },
    enableSmokeEffect = false,
    trailLayerCount = 1,
    patternGlowCount = 19,
    twinkleStarsColor = { a = 1, r = 1, g = 0.5921568870544434, b = 0.1215686351060867 },
    trailTexture = 9,
    rainbowEnabled = false,
    cursorSize = 40,
    randomSmokeColor = false,
    verticalScale = 2,
    glowIntensity = 1,
    twinkleEnabled = false,
    randomFireColor = false,
    randomStaticArcColor = false,
    starDustSpawnRateMax = 80,
    fireColor = { a = 1, r = 1, g = 0.5, b = 0.2 },
    randomSpringSeasonColor = false,
    enableTrailEffects = true,
    glowHollowness = 0,
    trailCount = 15,
    trailSpacing = 100,
    counterClockwiseSpeed = 30,
    smokeColor = { a = 1, r = 1, g = 1, b = 1 },
    enableEmbers = true,
    splitLayoutHeight = 50,
    cursorColor = { a = 1, r = 0.4117647058823529, g = 0.4941176470588236, b = 0.207843137254902 },
    trailTextureOpacity = 1,
    trailOffsetY = -1,
    shimmerEnabled = false,
    trailFrameStrata = "HIGH",
    trailMovementEffect = 1,
    randomStarDustColor = false,
    trailInitialSeparation = 36,
    enableStarDust = false,
    glowPulsingIntensity = 0.5,
    rotationSpeed = 12,
    trailIntensity = 0.5,
    trailColorEffect = 9,
    counterClockwiseEnabled = false,
    rotationDirection = 1,
    echoDuration = 0.6,
    trailSizeStart = 20,
    glowIntensityFactor = 0.07999999821186066,
    menuPosition = {
        x = -244.833,
        y = 72.4999,
        point = "RIGHT",
        relativePoint = "RIGHT",
    },
    trailLayerSpacing = 0,
    splitEffectEnabled = false,
    enableLightningSparks = false,
    pulseScale = 1.1,
    echoScale = 1.5,
    sweepEnabled = true,
    numTrails = 10,
    enableFire = false,
    enableStarEmbers = false,
    cursorOffsetY = 0,
    trailSizeEnd = 20,
    trailOffsetX = -36,
    shimmerFrequency = 50,
    twinkleSpeed = 5,
    glowBelow = false,
    starDustSpawnRateMin = 60,
    randomSmokeTrailColor = false,
    randomShadowColor = false,
    randomLightningSparkColor = false,
    enableFireTrails = false,
    emberColor = { a = 0.8, r = 1, g = 0.3411764800548554, b = 0.0784313753247261 },
    randomTwinkleStarsColor = false,
    trailGlowIntensity = 1,
    arcEmitterCooldown = 2.24,
    clockwiseSpeed = 28,
    rippleScale = 1.2,
    glowSize = 0.4135019779205322
        }
    end
end




-- 🧠 Optional: Save trailMovementEffect on load
local function EnsureTrailMovementEffect()
    local currentProfileName = EasyCursorTrailsDB.currentProfile
    local currentProfile = currentProfileName and EasyCursorTrailsDB.profiles[currentProfileName]
    local defaultEffect = (EasyCursorTrails.defaults and EasyCursorTrails.defaults.trailMovementEffect) or 4

    if currentProfile and not currentProfile.trailMovementEffect then
        EasyCursorTrails.SaveToCurrentProfile("trailMovementEffect", defaultEffect)
    end
end

function EasyCursorTrails.PopulateProfileDropdown()
    local dropdown = EasyCursorTrails.profileDropdown
    if not dropdown then return end

    -- 🧩 Ensure required profiles exist
    if type(EnsureDefaultProfile) == "function" then EnsureDefaultProfile() end
    if type(EnsureCoperDragonProfile) == "function" then EnsureCoperDragonProfile() end
    if type(EnsureTrailMovementEffect) == "function" then EnsureTrailMovementEffect() end

    local profiles = EasyCursorTrailsDB.profiles or {}
    local currentProfile = EasyCursorTrailsDB.currentProfile or "Default"

    -- 📋 Sort profiles with current one first
    local sortedProfiles = {}
    for profileName in pairs(profiles) do
        table.insert(sortedProfiles, profileName)
    end
    table.sort(sortedProfiles, function(a, b)
        if a == currentProfile then return true end
        if b == currentProfile then return false end
        return a < b
    end)

    -- 🔽 Build dropdown menu
    UIDropDownMenu_Initialize(dropdown, function(self, level)
        if level ~= 1 then return end

        for _, profileName in ipairs(sortedProfiles) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = profileName
            info.checked = (profileName == currentProfile)
            info.func = function()
                -- 🔄 Switch profile
                EasyCursorTrailsDB.currentProfile = profileName
                EasyCursorTrails.SaveLastSelectedProfile(profileName)

                -- 🔁 Reload profile and effects
                EasyCursorTrails.LoadCurrentProfile()
                EasyCursorTrails.ApplySelectedGlowEffect()
                EasyCursorTrails.UpdateGlowFrames()

                -- 🎛️ Sync UI
                if EasyCursorTrails.profile and EasyCursorTrails.profile.selectedGlowEffect then
                    EasyCursorTrails.SyncEffectSettingsUI(EasyCursorTrails.profile.selectedGlowEffect)
                end
                EasyCursorTrails.RefreshSettingsUI()

                -- 🔄 Refresh dropdown label
                EasyCursorTrails.PopulateProfileDropdown()
                UIDropDownMenu_SetText(dropdown, profileName)
            end
            UIDropDownMenu_AddButton(info, level)
        end
    end)

    -- 🏷️ Set dropdown label
    UIDropDownMenu_SetText(dropdown, currentProfile)
end



-- 🌐 Store dropdown reference and populate
EasyCursorTrails.profileDropdown = profileDropdown
EasyCursorTrails.PopulateProfileDropdown()

-- 📦 Button Dimensions & Spacing
local buttonHeight = 25
local buttonSpacing = 10
local dropdownBottomOffset = -10

function EasyCursorTrails.OpenTextInputDialog(promptText, onAccept, defaultText, editBoxWidth)
    local dialog = StaticPopupDialogs["EASYCURSORTRAILS_TEXT_INPUT"]
    dialog.text = promptText or "Enter text:"
    EasyCursorTrails._onTextInputAccept = onAccept

    StaticPopup_Show("EASYCURSORTRAILS_TEXT_INPUT")

    local popupFrame = StaticPopup_FindVisible("EASYCURSORTRAILS_TEXT_INPUT")
    if popupFrame and popupFrame.editBox then
        popupFrame.editBox:SetText(defaultText or "")
        popupFrame.editBox:SetWidth(editBoxWidth or 200)
        popupFrame.editBox:SetFocus()
    end
end


-- 🌱 Create Profile Button
local createProfileButton = CreateFrame("Button", "CreateProfileButton", menu, "UIPanelButtonTemplate")
createProfileButton:SetSize(60, 25)
createProfileButton:SetText("Create")
createProfileButton:SetPoint("TOPLEFT", profileDropdown, "BOTTOMLEFT", 0, -10)

createProfileButton:SetScript("OnClick", function()
    EasyCursorTrails.OpenTextInputDialog("Enter new profile name:", function(newProfileName)
        if not newProfileName or newProfileName == "" then return end
        if EasyCursorTrailsDB.profiles[newProfileName] then
            UIErrorsFrame:AddMessage("Profile '" .. newProfileName .. "' already exists.", 1, 0.5, 0)
            return
        end

        EasyCursorTrailsDB.profiles[newProfileName] = EasyCursorTrails.DeepCopyDefaults(EasyCursorTrails.defaults)
        EasyCursorTrailsDB.currentProfile = newProfileName

        if EasyCursorTrails.PopulateProfileDropdown then
            EasyCursorTrails.PopulateProfileDropdown(EasyCursorTrails.profileDropdown)
        end
        UIDropDownMenu_SetText(EasyCursorTrails.profileDropdown, newProfileName)

        if EasyCursorTrails.LoadCurrentProfile then EasyCursorTrails.LoadCurrentProfile() end
        if EasyCursorTrails.RefreshSettingsUI then EasyCursorTrails.RefreshSettingsUI() end
        
        --EasyCursorTrails: Created and selected profile '" .. newProfileName .. "'.")
        UIErrorsFrame:AddMessage("Profile '" .. newProfileName .. "' created.", 0, 1, 0)
    end, "", 220)
end)


-- 🗑️ Delete Profile Button
local deleteProfileButton = CreateFrame("Button", "EasyCursorTrails_DeleteProfileButton", menu, "UIPanelButtonTemplate")
deleteProfileButton:SetSize(65, 25)
deleteProfileButton:SetText("Delete")
deleteProfileButton:SetPoint("LEFT", createProfileButton, "RIGHT", 10, 0)
EasyCursorTrails.deleteProfileButton = deleteProfileButton


StaticPopupDialogs["EASYCURSORTRAILS_DELETE_CONFIRM"] = {
    text = "Delete this profile and switch to default settings?",
    button1 = "Yes",
    button2 = "No",
    OnAccept = function()
        local selectedProfile = UIDropDownMenu_GetText(EasyCursorTrails.profileDropdown)
        local defaultProfileName = "Default"
        local defaults = EasyCursorTrails.defaults

        if not selectedProfile or selectedProfile == defaultProfileName then
            UIErrorsFrame:AddMessage("Cannot delete 'Default'. Use the Reset button instead.", 1, 0.2, 0.2)
            return
        end

        if not defaults then
            UIErrorsFrame:AddMessage("Delete failed: No default settings found.", 1, 0.2, 0.2)
            return
        end

        -- 🗑️ Delete selected profile
        EasyCursorTrailsDB.profiles[selectedProfile] = nil

        -- 🔄 Reset all checkboxes first
        EasyCursorTrails.ResetAllEffectCheckboxes()

        -- 🧼 Deep copy and sanitize default settings
        local newDefaults = EasyCursorTrails.DeepCopyDefaults(defaults)
        EasyCursorTrails.SanitizeProfileState(newDefaults)
        EasyCursorTrailsDB.profiles[defaultProfileName] = newDefaults

        -- 🔁 Switch to Default profile
        EasyCursorTrailsDB.currentProfile = defaultProfileName
        EasyCursorTrails.SaveLastSelectedProfile(defaultProfileName)

        -- 🔽 Refresh profile dropdown
        if EasyCursorTrails.profileDropdown then
            EasyCursorTrails.PopulateProfileDropdown(EasyCursorTrails.profileDropdown)
            UIDropDownMenu_SetSelectedName(EasyCursorTrails.profileDropdown, defaultProfileName)
            UIDropDownMenu_SetText(EasyCursorTrails.profileDropdown, defaultProfileName)
        end

        -- 🔄 Reload profile and UI
        EasyCursorTrails.LoadCurrentProfile()
        EasyCursorTrails.menuInitialized = true
        if EasyCursorTrails.RefreshSettingsUI then
            EasyCursorTrails.RefreshSettingsUI()
        end

        -- ✨ Rebuild visuals
        if newDefaults.enableTrails and EasyCursorTrails.RebuildTrails then
            EasyCursorTrails.RebuildTrails()
        elseif EasyCursorTrails.HideAllTrails then
            EasyCursorTrails.HideAllTrails()
        end

        -- 🔥 Ember ticker
        if newDefaults.enableEmbers and EasyCursorTrails.StartEmberTicker then
            EasyCursorTrails.StartEmberTicker()
        elseif EasyCursorTrails.StopEmberTicker then
            EasyCursorTrails.StopEmberTicker()
        end

        -- 💡 Final visual updates
        if EasyCursorTrails.UpdateGlowFrames then EasyCursorTrails.UpdateGlowFrames() end
        if EasyCursorTrails.InitializeCustomCursor then EasyCursorTrails.InitializeCustomCursor() end

        -- ✅ Confirmation
        UIErrorsFrame:AddMessage("Profile '" .. selectedProfile .. "' deleted. Switched to 'Default'.", 0, 1, 0)
        PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
    end,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,
}

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

    if selectedProfile and selectedProfile ~= "Default" and EasyCursorTrailsDB.profiles[selectedProfile] then
        StaticPopup_Show("EASYCURSORTRAILS_DELETE_CONFIRM")
    else
        UIErrorsFrame:SetFont("Fonts\\FRIZQT__.TTF", 18, "OUTLINE")
        UIErrorsFrame:AddMessage("Cannot delete 'Default'. Use the Reset button instead.", 0, 1, 0)
        PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE)
    end
end)



-- 🔄 Reset Profile Button
local resetButton = CreateFrame("Button", "ResetSettingsButton", menu, "UIPanelButtonTemplate")
resetButton:SetSize(65, 25)
resetButton:SetText("Reset")
resetButton:SetPoint("TOPLEFT", createProfileButton, "BOTTOMLEFT", 145, 25)

StaticPopupDialogs["EASYCURSORTRAILS_RESET_CONFIRM"] = {
    text = "Reset all settings to default values? This will apply immediately.",
    button1 = "Yes",
    button2 = "No",
    OnAccept = function()
        local defaults = EasyCursorTrails.defaults
        local defaultProfileName = "Default"

        if not defaults then
            UIErrorsFrame:AddMessage("Reset failed: No default settings found.", 1, 0.2, 0.2, 53)
            return
        end

                    -- 🔄 Reset all checkboxes first
            EasyCursorTrails.ResetAllEffectCheckboxes()

            -- 🧼 Deep copy and sanitize default settings
            local newDefaults = EasyCursorTrails.DeepCopyDefaults(defaults)
            EasyCursorTrails.SanitizeProfileState(newDefaults)
            EasyCursorTrailsDB.profiles[defaultProfileName] = newDefaults

            -- 🔁 Switch to Default profile
            EasyCursorTrailsDB.currentProfile = defaultProfileName
            EasyCursorTrails.SaveLastSelectedProfile(defaultProfileName)

        -- 🔽 Refresh profile dropdown
        if EasyCursorTrails.profileDropdown then
            EasyCursorTrails.PopulateProfileDropdown(EasyCursorTrails.profileDropdown)
            UIDropDownMenu_SetSelectedName(EasyCursorTrails.profileDropdown, defaultProfileName)
            UIDropDownMenu_SetText(EasyCursorTrails.profileDropdown, defaultProfileName)
        end

        -- 🔄 Reload profile and UI
        EasyCursorTrails.LoadCurrentProfile()
        EasyCursorTrails.menuInitialized = true
        if EasyCursorTrails.RefreshSettingsUI then
            EasyCursorTrails.RefreshSettingsUI()
        end

        -- ✨ Rebuild visuals
        if newDefaults.enableTrails and EasyCursorTrails.RebuildTrails then
            EasyCursorTrails.RebuildTrails()
        elseif EasyCursorTrails.HideAllTrails then
            EasyCursorTrails.HideAllTrails()
        end

        -- 🔥 Ember ticker
        if newDefaults.enableEmbers and EasyCursorTrails.StartEmberTicker then
            EasyCursorTrails.StartEmberTicker()
        elseif EasyCursorTrails.StopEmberTicker then
            EasyCursorTrails.StopEmberTicker()
        end

        -- 💡 Final visual updates
        if EasyCursorTrails.UpdateGlowFrames then EasyCursorTrails.UpdateGlowFrames() end
        if EasyCursorTrails.InitializeCustomCursor then EasyCursorTrails.InitializeCustomCursor() end

        -- ✅ Confirmation
        UIErrorsFrame:AddMessage("Reset complete. Switched to 'Default' profile.", 0, 1, 0)
    end,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,
}

resetButton:SetScript("OnClick", function()
    StaticPopup_Show("EASYCURSORTRAILS_RESET_CONFIRM")
end)


function EasyCursorTrails.TraceEmberState()
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    local defaults = EasyCursorTrails.defaults or {}

    --=== EasyCursorTrails: Ember Debug ===")
    if not profile then
        --❌ Profile missing. Cannot read ember state.")
        return
    end

    local rawFlag = profile.enableEmbers
    local defaultFlag = defaults.enableEmbers
    local checkbox = EasyCursorTrails.emberCheckbox
    local tickerRunning = EasyCursorTrails.EmberTickerActive and true or false

    --Profile Flag:", rawFlag)
    --Default Flag:", defaultFlag)
    --Checkbox Exists:", checkbox ~= nil)
    if checkbox then
        --Checkbox Checked:", checkbox:GetChecked())
    end
    --Ticker Running:", tickerRunning)

    if rawFlag == false then
        --⚠ Profile flag explicitly disables embers.")
    elseif checkbox and not checkbox:GetChecked() then
        --⚠ Checkbox is not checked despite profile flag.")
    elseif not tickerRunning then
        --⚠ Ember ticker not running. Try StartEmberTicker().")
    else
        --✅ Embers should be active.")
    end
end




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


------------------------------------------------------------------
-- Pattern Glow Count Slider
------------------------------------------------------------------
local patternGlowCountSlider =  EasyCursorTrails.CreateSlider(
    "PatternGlowCountSlider",
    menu,
    "Maximum Glows",
    3,
    40,
    1,
    EasyCursorTrailsDB.patternGlowCount or EasyCursorTrails.defaults.patternGlowCount,
    function(slider, value)
        value = math.floor(value)
        EasyCursorTrailsDB.patternGlowCount = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("patternGlowCount", value)
        EasyCursorTrails.UpdateGlowFrames()
        

    end
)
patternGlowCountSlider:SetPoint("TOPLEFT", trailCountSlider, "BOTTOMLEFT", -265, -20)
EasyCursorTrails.patternGlowCountSlider = patternGlowCountSlider

------------------------------------------------------------------
-- Glow Radius Slider
------------------------------------------------------------------
local initialGlowRadius =
    EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.glowRadius
    or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].glowRadius
    or EasyCursorTrails.defaults.glowRadius
    or 0.1

local glowRadiusSlider =  EasyCursorTrails.CreateSlider(
    "GlowRadiusSlider",
    menu,
    "Glow Radius",
    0.1,
    1.1,
    0.01,
    initialGlowRadius,
    function(slider, value)
        local profile = EasyCursorTrails.currentProfileTable
            or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile then
            --EasyCursorTrails.HandleError"glowRadiusSlider: Failed to retrieve current profile.")
            return
        end

        profile.glowRadius = value
        EasyCursorTrails.SaveToCurrentProfile("glowRadius", value)

        -- 🔁 Trigger live update
        EasyCursorTrails.ApplySelectedGlowEffect()
        

    end,
    2
)

glowRadiusSlider:SetPoint("TOPLEFT", patternGlowCountSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.glowRadiusSlider = glowRadiusSlider

------------------------------------------------------------------
-- Glow Intensity Slider
------------------------------------------------------------------
local initialGlowIntensity =
    EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.glowIntensity
    or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].glowIntensity
    or EasyCursorTrails.defaults.glowIntensity
    or 0.8

local glowIntensitySlider =  EasyCursorTrails.CreateSlider(
    "GlowIntensitySlider",
    menu,
    "Glow Intensity",
    0.0,
    2.0,
    0.05,
    initialGlowIntensity,
    function(slider, value)
        local profile = EasyCursorTrails.currentProfileTable
            or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile then
            --EasyCursorTrails.HandleError"glowIntensitySlider: No profile found.")
            return
        end

        profile.glowIntensity = value
        EasyCursorTrails.SaveToCurrentProfile("glowIntensity", value)

        -- 🔁 Fully reapply glow visuals with new intensity
        EasyCursorTrails.ApplySelectedGlowEffect()
        

    end,
    2 -- Show decimals like 0.75
)

glowIntensitySlider:SetPoint("TOPLEFT", glowRadiusSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.glowIntensitySlider = glowIntensitySlider

------------------------------------------------------------------
-- Glow Size Slider
------------------------------------------------------------------
local glowSizeSlider =  EasyCursorTrails.CreateSlider(
    "GlowSizeSlider",
    menu,
    "Glow Size",
    0.1,
    2.0,
    0.1,
    EasyCursorTrailsDB.glowSize or EasyCursorTrails.defaults.glowSize,
    function(slider, value)
        EasyCursorTrailsDB.glowSize = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("glowSize", value)
        EasyCursorTrails.UpdateGlowFrames()
        

    end
)
glowSizeSlider:SetPoint("TOPLEFT", glowIntensitySlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.glowSizeSlider = glowSizeSlider


------------------------------------------------------------------
-- Cursor Size Slider
------------------------------------------------------------------
local cursorSizeSlider =  EasyCursorTrails.CreateSlider(
    "CursorSizeSlider",
    menu,
    "Cursor Size",
    10,
    200,
    1,
    (EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] and EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile].cursorSize) or EasyCursorTrails.defaults.cursorSize,
    function(slider, value)
        EasyCursorTrailsDB.cursorSize = value
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorSize", value)
        EasyCursorTrails.UpdateCustomCursorSize(value)
        

    end
)
cursorSizeSlider:SetPoint("TOPLEFT", glowBelowCheckbox, "BOTTOMLEFT", 45, -20)
EasyCursorTrails.cursorSizeSlider = cursorSizeSlider


------------------------------------------------------------------
-- Cursor Offset X Slider
------------------------------------------------------------------
local cursorOffsetXSlider =  EasyCursorTrails.CreateSlider(
    "CursorOffsetXSlider",
    menu,
    "Cursor Offset X",
    -100,
    100,
    1,
    EasyCursorTrailsDB.cursorOffsetX or EasyCursorTrails.defaults.cursorOffsetX,
    function(slider, value)
        EasyCursorTrailsDB.cursorOffsetX = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorOffsetX", value)
        EasyCursorTrails.UpdateCustomCursorPosition()
        

    end
)
cursorOffsetXSlider:SetPoint("TOPLEFT", cursorSizeSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.cursorOffsetXSlider = cursorOffsetXSlider

------------------------------------------------------------------
-- Cursor Offset Y Slider
------------------------------------------------------------------
local cursorOffsetYSlider =  EasyCursorTrails.CreateSlider(
    "CursorOffsetYSlider",
    menu,
    "Cursor Offset Y",
    -100,
    100,
    1,
    EasyCursorTrailsDB.cursorOffsetY or EasyCursorTrails.defaults.cursorOffsetY,
    function(slider, value)
        value = math.max(-100, math.min(100, value))
        EasyCursorTrailsDB.cursorOffsetY = value
        slider:SetValue(value)
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorOffsetY", value)
        EasyCursorTrails.UpdateCustomCursorPosition()
        

    end
)
cursorOffsetYSlider:SetPoint("TOPLEFT", cursorOffsetXSlider, "BOTTOMLEFT", 0, -20)
EasyCursorTrails.cursorOffsetYSlider = cursorOffsetYSlider


-- Frame Strata Options (for reference, not used in this snippet)
EasyCursorTrails.frameStrataOptions = {
    { text = "BACKGROUND" },
    { text = "LOW" },
    { text = "MEDIUM" },
    { text = "HIGH" },
    { text = "DIALOG" },
}

-----------------------------------------------
-- Create the "Select Glow Color" Button
-----------------------------------------------
-- 🌟 Select Glow Color Button
local selectGlowColorButton = CreateFrame("Button", "SelectGlowColorButton", menu, "UIPanelButtonTemplate")
selectGlowColorButton:SetSize(150, 25)
selectGlowColorButton:SetText("Glow Color")
selectGlowColorButton:SetPoint("TOPLEFT", glowBelowCheckbox, "BOTTOMLEFT", -255, -80)
EasyCursorTrails.selectGlowColorButton = selectGlowColorButton

-- 🖍️ Glow Color Edit Box
local glowColorEditBox = CreateFrame("EditBox", "GlowColorEditBox", menu, "InputBoxTemplate")
glowColorEditBox:SetSize(80, 25)
glowColorEditBox:SetPoint("LEFT", selectGlowColorButton, "RIGHT", 10, 0)
glowColorEditBox:SetAutoFocus(false)
glowColorEditBox:SetMaxLetters(9) -- Supports #RRGGBBAA
EasyCursorTrails.glowColorEditBox = glowColorEditBox

-- 🏷️ Label: HTML Color Code
local glowColorLabel = menu:CreateFontString(nil, "OVERLAY", "GameFontNormal")
glowColorLabel:SetPoint("BOTTOMLEFT", glowColorEditBox, "TOPLEFT", 0, 0)
glowColorLabel:SetText("HTML Code")




-- 🔄 Update Edit Box Text
local function UpdateGlowColorEditBox()
    local color = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    glowColorEditBox:SetText(RGBToHex(color.r, color.g, color.b, color.a))

    local textWidth = glowColorEditBox:GetText():len() * 8
    glowColorEditBox:SetWidth(math.max(80, textWidth + 20))
end

-- 🎯 Handle Enter Pressed
glowColorEditBox:SetScript("OnEnterPressed", function(self)
    local hexColor = "#" .. self:GetText():gsub("#", "")
    local r, g, b, a = HexToRGB(hexColor)
    if r and g and b then
        a = a or 1
        EasyCursorTrailsDB.glowColor = { r = r, g = g, b = b, a = a }
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("glowColor", EasyCursorTrailsDB.glowColor)
        EasyCursorTrails.ApplySelectedGlowEffect()
        UpdateGlowColorEditBox()
    else
         print("Invalid HTML color format! Use #RRGGBB or #RRGGBBAA")
    end
    self:ClearFocus()
end)

-- 🧠 Apply on Focus Lost
glowColorEditBox:SetScript("OnEditFocusLost", function(self)
    self:GetScript("OnEnterPressed")(self)
end)

-- 🎨 Button Click Logic
selectGlowColorButton:SetScript("OnClick", function()
    local initialColor = EasyCursorTrailsDB.glowColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        EasyCursorTrailsDB.glowColor = color
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("glowColor", color)
        EasyCursorTrails.ApplySelectedGlowEffect()
        UpdateGlowColorEditBox()
    end)
end)

-- 🔧 Initialize Edit Box
UpdateGlowColorEditBox()


function EasyCursorTrails.CreatePaginatedDropdown(name, parent, label, options, selectedIndex, onSelect, maxPerLevel)
    maxPerLevel = maxPerLevel or 20

    if not parent or not name then return nil end
    if type(options) ~= "table" or #options == 0 then
        options = { { text = "None" } }
    end

    local dropdown = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate")
    dropdown:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 30, 20)

    local dropdownLabel = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    dropdownLabel:SetPoint("BOTTOMLEFT", dropdown, "TOPLEFT", 16, 5)
    dropdownLabel:SetText(label or "Dropdown")

    local menuListID = name .. "_EXTRA_OPTIONS"

    local function setDropdownText(text)
        if not text or type(text) ~= "string" then
            text = "None"
        end

        UIDropDownMenu_SetText(dropdown, "")
        UIDropDownMenu_SetText(dropdown, text)

        -- 🧮 Measure text width
        local tempFont = dropdown:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        tempFont:SetText(text)
        local textWidth = tempFont:GetStringWidth()
        tempFont:Hide()

        local finalWidth = math.max(140, textWidth + 60)
        dropdown:SetWidth(finalWidth)

        -- 🔧 Resize internal regions
        if dropdown.Middle then
            dropdown.Middle:SetWidth(finalWidth - 50)
        end
        if dropdown.Text then
            dropdown.Text:ClearAllPoints()
            dropdown.Text:SetPoint("LEFT", dropdown.Left, "RIGHT", 5, 2)
            dropdown.Text:SetWidth(finalWidth - 70)
            dropdown.Text:SetJustifyH("LEFT")
        end
        if dropdown.Right then
            dropdown.Right:SetWidth(25)
        end
    end

    UIDropDownMenu_Initialize(dropdown, function(self, level, menuList)
        local function addOption(i)
            local option = options[i]
            local text = type(option) == "table" and option.text or tostring(option)

            local info = UIDropDownMenu_CreateInfo()
            info.text = text
            info.arg1 = i
            info.func = function(_, arg1)
                -- 🧼 Reset controls before applying selection
                if type(EasyCursorTrails.ResetEffectControls) == "function" then
                    EasyCursorTrails.ResetEffectControls()
                end

                UIDropDownMenu_SetSelectedID(dropdown, arg1)
                setDropdownText(text)

                if type(onSelect) == "function" then
                    onSelect(arg1)
                end

                CloseDropDownMenus()
            end
            UIDropDownMenu_AddButton(info, level)
        end

        if level == 1 then
            for i = 1, math.min(#options, maxPerLevel) do
                addOption(i)
            end

            if #options > maxPerLevel then
                local info = UIDropDownMenu_CreateInfo()
                info.text = "More..."
                info.hasArrow = true
                info.notCheckable = true
                info.menuList = menuListID
                UIDropDownMenu_AddButton(info, level)
            end

        elseif level == 2 and menuList == menuListID then
            for i = maxPerLevel + 1, #options do
                addOption(i)
            end
        end
    end)

    -- 🧠 Initial selection
    local clampedIndex = math.max(1, math.min(selectedIndex or 1, #options))
    local initialText = type(options[clampedIndex]) == "table" and options[clampedIndex].text or tostring(options[clampedIndex])

    UIDropDownMenu_SetSelectedID(dropdown, clampedIndex)
    setDropdownText(initialText)

    dropdown.onSelect = onSelect
    return dropdown
end


-- 🛠 Create Glow Effect Dropdown
EasyCursorTrails.glowEffectDropdown = EasyCursorTrails.CreatePaginatedDropdown(
    "GlowEffectDropdown",
    menu,
    "Custom Effect",

    EasyCursorTrails.glowEffectOptions,
    EasyCursorTrailsDB.selectedGlowEffect or 1,
    function(index)
        local selected = EasyCursorTrails.glowEffectOptions[index]
        if selected and selected.id then
            EasyCursorTrailsDB.selectedGlowEffect = selected.id
            EasyCursorTrails.settingsChanged = true

            -- 🔧 Save to profile
            EasyCursorTrails.SaveToCurrentProfile("selectedGlowEffect", selected.id)

            -- 🔁 Refresh glow system
            EasyCursorTrails.ApplySelectedGlowEffect()
            EasyCursorTrails.UpdateGlowFrames()
            EasyCursorTrails.SyncEffectSettingsUI(selected.id)
        else
            -- print("[EasyCursorTrails] ⚠️ Invalid glow effect selection at index:", index)
        end
    end,
    20
)

-- 📍 Position Glow Effect Dropdown below glowBelowCheckbox
EasyCursorTrails.glowEffectDropdown:SetPoint("TOPLEFT", glowBelowCheckbox, "BOTTOMLEFT", -250, 10)

-- 🌟 Resolve selected index from saved texture ID
local selectedTextureID = EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.selectedGlowTexture or 1
local selectedIndex = 1

for i, option in ipairs(EasyCursorTrails.glowTextureOptions or {}) do
    if option.id == selectedTextureID then
        selectedIndex = i
        break
    end
end

-- 🌟 Create Glow Texture Dropdown
EasyCursorTrails.glowTextureDropdown = EasyCursorTrails.CreatePaginatedDropdown(
    "GlowTextureDropdown",
    menu,
    "Glow Texture",
    EasyCursorTrails.glowTextureOptions,
    selectedIndex,
    function(index)
        local selected = EasyCursorTrails.glowTextureOptions[index]
        if selected and selected.path then
            EasyCursorTrails.SaveToCurrentProfile("selectedGlowTexture", selected.id)

            EasyCursorTrails.settingsChanged = true
            EasyCursorTrails.InitializeGlowFrames()
            EasyCursorTrails.UpdateGlowFrames()
            EasyCursorTrails.ApplySelectedGlowEffect()
        else
            -- print("[EasyCursorTrails] Invalid texture selection at index:", index)
        end
    end,
    10
)

-- ✅ Add SetSelectedIndex method for external sync
function EasyCursorTrails.glowTextureDropdown:SetSelectedIndex(index)
    local option = EasyCursorTrails.glowTextureOptions[index]
    if not option then return end
    UIDropDownMenu_SetSelectedID(EasyCursorTrails.glowTextureDropdown, index)
    UIDropDownMenu_SetText(EasyCursorTrails.glowTextureDropdown, option.text or "Unknown")
end

-- 📍 Position Glow Texture Dropdown
EasyCursorTrails.glowTextureDropdown:SetPoint("TOPLEFT", EasyCursorTrails.glowEffectDropdown, "BOTTOMLEFT", 0, -20)

-- 📏 Optional: Auto-resize dropdown width
local maxTextLength = 0
for _, option in ipairs(EasyCursorTrails.glowTextureOptions) do
    maxTextLength = math.max(maxTextLength, option.text:len())
end



--===============================================================================================

local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔘 Pulse Checkbox
EasyCursorTrails.pulseCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnablePulseCheckbox",
    menu,
    "Pulse",
    profile.pulseEnabled == true,
    function(checked)
        EasyCursorTrailsDB.pulseEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("pulseEnabled", checked)

        -- 🛑 Stop pulse animation if disabled
        if not checked and EasyCursorTrails.activeGlows then
            for _, glow in ipairs(EasyCursorTrails.activeGlows) do
                if glow.animationGroup then
                    glow.animationGroup:Stop()
                    for _, anim in ipairs({ glow.animationGroup:GetAnimations() }) do
                        if anim and anim.Stop then anim:Stop() end
                    end
                end
            end
        end

        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.pulseCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.glowTextureDropdown, "BOTTOMLEFT", -10, -50)
EasyCursorTrails.pulseCheckbox:Show()

-- 🎛 Pulse Speed Slider
local initialPulseSpeed = tonumber(profile.pulseSpeed) or 5

EasyCursorTrails.pulseSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_PulseSpeedSlider",
    menu,
    "Pulse Speed",
    1, 10, 1,
    initialPulseSpeed,
    function(_, value)
        EasyCursorTrailsDB.pulseSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("pulseSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.pulseSpeedSlider:SetPoint("LEFT", EasyCursorTrails.pulseCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.pulseSpeedSlider:Show()

local profile = EasyCursorTrails.currentProfileTable or {}

-- 🌈 Rainbow Checkbox
EasyCursorTrails.rainbowCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableRainbowCheckbox",
    menu,
    "Rainbow",
    profile.rainbowEnabled == true,
    function(checked)
        EasyCursorTrailsDB.rainbowEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("rainbowEnabled", checked)

        -- 🛑 Stop rainbow cycle if disabled
        if not checked and EasyCursorTrails.activeGlows then
            for _, glow in ipairs(EasyCursorTrails.activeGlows) do
                local texture = glow and glow.texture
                if texture and EasyCursorTrails.rainbowTimers and EasyCursorTrails.rainbowTimers[texture] then
                    EasyCursorTrails.rainbowTimers[texture]:Cancel()
                    EasyCursorTrails.rainbowTimers[texture] = nil
                end
                -- Optional: reset to static color
                if texture then
                    local color = profile.glowColor or { r = 1, g = 1, b = 1, a = 1 }
                    texture:SetVertexColor(color.r, color.g, color.b, texture:GetAlpha())
                end
            end
        end

        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.rainbowCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.pulseCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.rainbowCheckbox:Show()

-- 🎛 Rainbow Speed Slider
local initialRainbowSpeed = tonumber(profile.rainbowSpeed) or 5

EasyCursorTrails.rainbowSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_RainbowSpeedSlider",
    menu,
    "Cycle Speed",
    1, 10, 1,
    initialRainbowSpeed,
    function(_, value)
        EasyCursorTrailsDB.rainbowSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("rainbowSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.rainbowSpeedSlider:SetPoint("LEFT", EasyCursorTrails.rainbowCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.rainbowSpeedSlider:Show()

local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔄 Glow Rotation Checkbox
EasyCursorTrails.rotationCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableRotationCheckbox",
    menu,
    "Rotate",
    profile.enableRotation == true,
    function(checked)
        EasyCursorTrailsDB.enableRotation = checked
        EasyCursorTrails.SaveToCurrentProfile("enableRotation", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.rotationCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.rainbowCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.rotationCheckbox:Show()

-- 🧠 Tooltip for Rotation Checkbox
EasyCursorTrails.rotationCheckbox:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:SetText("Enable full-pattern rotation.\nGlows will spin around the cursor like a wheel.", nil, nil, nil, nil, true)
    GameTooltip:Show()
end)
EasyCursorTrails.rotationCheckbox:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)

-- 🔁 Rotation Speed Slider (1 to 100)
local initialSpeed = math.max(1, math.min(100, tonumber(profile.rotationSpeed) or 30))

EasyCursorTrails.rotationSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_RotationSpeedSlider",
    menu,
    "Rotation Speed",
    1, 100, 1,
    initialSpeed,
    function(_, value)
        local clamped = math.max(1, math.min(100, value))
        EasyCursorTrailsDB.rotationSpeed = clamped
        EasyCursorTrails.SaveToCurrentProfile("rotationSpeed", clamped)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.rotationSpeedSlider:SetPoint("LEFT", EasyCursorTrails.rotationCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.rotationSpeedSlider:Show()

-- 🧠 Tooltip for Rotation Speed Slider
EasyCursorTrails.rotationSpeedSlider:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:SetText("Controls how fast the glow pattern rotates.\nValues above 50 will rotate in the opposite direction.", nil, nil, nil, nil, true)
    GameTooltip:Show()
end)
EasyCursorTrails.rotationSpeedSlider:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)



local profile = EasyCursorTrails.currentProfileTable or {}

-- ✨ Twinkle Checkbox
EasyCursorTrails.twinkleCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableTwinkleCheckbox",
    menu,
    "Twinkle",
    profile.twinkleEnabled == true,
    function(checked)
        EasyCursorTrailsDB.twinkleEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("twinkleEnabled", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.twinkleCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.rotationCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.twinkleCheckbox:Show()

-- 🎛 Twinkle Speed Slider (1 = slowest, 20 = fastest)
local initialTwinkleSpeed = tonumber(profile.twinkleSpeed) or 5

EasyCursorTrails.twinkleSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_TwinkleSpeedSlider",
    menu,
    "Twinkle Speed",
    1, 20, 1,
    initialTwinkleSpeed,
    function(_, value)
        EasyCursorTrailsDB.twinkleSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("twinkleSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.twinkleSpeedSlider:SetPoint("LEFT", EasyCursorTrails.twinkleCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.twinkleSpeedSlider:Show()



local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔀 Directional Sweep Checkbox
EasyCursorTrails.sweepCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableSweepCheckbox",
    menu,
    "Sweep",
    profile.sweepEnabled == true,
    function(checked)
        EasyCursorTrailsDB.sweepEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("sweepEnabled", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.sweepCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.twinkleCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.sweepCheckbox:Show()

-- 🎛 Sweep Speed Slider
local initialSweepSpeed = tonumber(profile.sweepSpeed) or 40

EasyCursorTrails.sweepSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_SweepSpeedSlider",
    menu,
    "Sweep Speed",
    1, 100, 1,
    initialSweepSpeed,
    function(_, value)
        EasyCursorTrailsDB.sweepSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("sweepSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.sweepSpeedSlider:SetPoint("LEFT", EasyCursorTrails.sweepCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.sweepSpeedSlider:Show()



local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔁 Clockwise Rotation Checkbox
EasyCursorTrails.clockwiseCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableClockwiseCheckbox",
    menu,
    "Clockwise",
    profile.clockwiseEnabled == true,
    function(checked)
        EasyCursorTrailsDB.clockwiseEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("clockwiseEnabled", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.clockwiseCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.sweepCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.clockwiseCheckbox:Show()

-- 🎛 Clockwise Rotation Speed Slider
local initialClockwiseSpeed = tonumber(profile.clockwiseSpeed) or 30

EasyCursorTrails.clockwiseSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_ClockwiseSpeedSlider",
    menu,
    "Clockwise Speed",
    1, 100, 1,
    initialClockwiseSpeed,
    function(_, value)
        EasyCursorTrailsDB.clockwiseSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("clockwiseSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.clockwiseSpeedSlider:SetPoint("LEFT", EasyCursorTrails.clockwiseCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.clockwiseSpeedSlider:Show()

local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔁 Counter-Clockwise Rotation Checkbox
EasyCursorTrails.counterClockwiseCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableCounterClockwiseCheckbox",
    menu,
    "CC",
    profile.counterClockwiseEnabled == true,
    function(checked)
        EasyCursorTrailsDB.counterClockwiseEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("counterClockwiseEnabled", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.counterClockwiseCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.clockwiseCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.counterClockwiseCheckbox:Show()

-- 🎛 Counter-Clockwise Speed Slider
local initialCCSpeed = tonumber(profile.counterClockwiseSpeed) or 30

EasyCursorTrails.counterClockwiseSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_CounterClockwiseSpeedSlider",
    menu,
    "Counter-Clockwise Speed",
    1, 100, 1,
    initialCCSpeed,
    function(_, value)
        EasyCursorTrailsDB.counterClockwiseSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("counterClockwiseSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.counterClockwiseSpeedSlider:SetPoint("LEFT", EasyCursorTrails.counterClockwiseCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.counterClockwiseSpeedSlider:Show()


local profile = EasyCursorTrails.currentProfileTable or {}

-- 🔀 Split Rotation Checkbox
EasyCursorTrails.splitEffectCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableSplitEffectCheckbox",
    menu,
    "Split",
    profile.splitEffectEnabled == true,
    function(checked)
        EasyCursorTrailsDB.splitEffectEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("splitEffectEnabled", checked)

        if EasyCursorTrails.splitLayoutHeightSlider then
            EasyCursorTrails.splitLayoutHeightSlider:SetEnabled(checked)
        end
        if EasyCursorTrails.splitRotationSpeedSlider then
            EasyCursorTrails.splitRotationSpeedSlider:SetEnabled(checked)
        end

        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)
EasyCursorTrails.splitEffectCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.counterClockwiseCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.splitEffectCheckbox:Show()

-- 🎛 Split Rotation Speed Slider
local initialSplitSpeed = tonumber(profile.rotationSpeed) or 30

EasyCursorTrails.splitRotationSpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_SplitRotationSpeedSlider",
    menu,
    "Split Rotation Speed",
    1, 60, 1,
    initialSplitSpeed,
    function(_, value)
        EasyCursorTrailsDB.rotationSpeed = value
        EasyCursorTrails.SaveToCurrentProfile("rotationSpeed", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)
EasyCursorTrails.splitRotationSpeedSlider:SetPoint("LEFT", EasyCursorTrails.splitEffectCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.splitRotationSpeedSlider:SetEnabled(profile.splitEffectEnabled == true)
EasyCursorTrails.splitRotationSpeedSlider:Show()


-- ✨ Shimmer Checkbox
local profile = EasyCursorTrails.GetCurrentProfile()
EasyCursorTrails.shimmerCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableShimmerCheckbox",
    menu,
    "Shimmer",
    profile.shimmerEnabled == true,
    function(checked)
        profile.shimmerEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("shimmerEnabled", checked)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)

EasyCursorTrails.shimmerCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.splitEffectCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.shimmerCheckbox:Show()


local profile = EasyCursorTrails.GetCurrentProfile()
EasyCursorTrails.shimmerFrequencySlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_ShimmerFrequencySlider",
    menu,
    "Shimmer Frequency",
    1, 100, 1,
    tonumber(profile.shimmerFrequency) or 50,
    function(_, value)
        profile.shimmerFrequency = value
        EasyCursorTrails.SaveToCurrentProfile("shimmerFrequency", value)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    0
)

EasyCursorTrails.shimmerFrequencySlider:SetPoint("LEFT", EasyCursorTrails.shimmerCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.shimmerFrequencySlider:Show()

-- 🌌 Echo Relay Checkbox
local profile = EasyCursorTrails.currentProfileTable or {}
local initialEchoEnabled = profile.echoEnabled == true

EasyCursorTrails.echoRelayCheckbox = EasyCursorTrails.CreateCheckbox(
    "EasyCursorTrails_EnableEchoRelayCheckbox",
    menu,
    "Echo Relay",
    initialEchoEnabled,
    function(checked)
        EasyCursorTrailsDB.echoEnabled = checked
        EasyCursorTrails.SaveToCurrentProfile("echoEnabled", checked)

        if not checked then
            if customCursor.echoRelayTicker then
                customCursor.echoRelayTicker:Cancel()
                customCursor.echoRelayTicker = nil
            end

            for _, glow in ipairs(customCursor.glowEffects or {}) do
                if glow.echoAnim then
                    glow.echoAnim:Cancel()
                    glow.echoAnim = nil
                end
                if glow.texture then
                    glow.texture:SetAlpha(1)
                    glow.texture:SetScale(1)
                    glow.texture:Show()
                end
            end
        end

        EasyCursorTrails.ApplySelectedGlowEffect()
    end
)

EasyCursorTrails.echoRelayCheckbox:SetPoint("TOPLEFT", EasyCursorTrails.shimmerCheckbox, "BOTTOMLEFT", 0, -15)
EasyCursorTrails.echoRelayCheckbox:Show()

-- 🎛 Echo Relay Speed Slider
local storedFrequency = tonumber(profile.echoFrequency) or 55
local initialSliderValue = math.max(0, math.min(10, (storedFrequency - 10) / 9)) -- maps 10–100 → 0–10

EasyCursorTrails.echoRelaySpeedSlider = EasyCursorTrails.CreateSlider(
    "EasyCursorTrails_EchoRelaySpeedSlider",
    menu,
    "Echo Relay Speed",
    1, 10, 0.1,
    initialSliderValue,
    function(_, value)
        local percentSpeed = math.floor(10 + value * 9)
        EasyCursorTrailsDB.echoFrequency = percentSpeed
        EasyCursorTrails.SaveToCurrentProfile("echoFrequency", percentSpeed)
        EasyCursorTrails.ApplySelectedGlowEffect()
    end,
    1
)

EasyCursorTrails.echoRelaySpeedSlider:SetPoint("LEFT", EasyCursorTrails.echoRelayCheckbox, "RIGHT", 60, 0)
EasyCursorTrails.echoRelaySpeedSlider:Show()


--==============================================================================================================================================



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

-- Function to get the index of a given frame strata
EasyCursorTrails.GetStrataIndex = function(strata)
    if not strata then return 4 end -- Default to "HIGH" if nil

    for i, v in ipairs(EasyCursorTrails.frameStrataOptions) do
        if v.text == strata then
            return i
        end
    end

    return 4 -- Default to "HIGH" if no match is found
end
-- 🧭 Create container to join cursor UI elements
local cursorOptionsGroup = CreateFrame("Frame", "EasyCursorTrails_CursorOptionsGroup", menu)
cursorOptionsGroup:SetSize(1, 1)
cursorOptionsGroup:SetPoint("TOPLEFT", glowSizeSlider, "BOTTOMLEFT", -20, -20)

local spacing = -14
local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]

-- 1️⃣ Cursor Frame Strata Dropdown
local initialFrameStrataIndex = EasyCursorTrails.GetStrataIndex(EasyCursorTrailsDB.cursorFrameStrata or "HIGH")
local cursorFrameStrataDropdown = EasyCursorTrails.CreateDropdown(
    "CursorFrameStrataDropdown",
    cursorOptionsGroup,
    "Cursor Frame Strata",
    EasyCursorTrails.frameStrataOptions,
    initialFrameStrataIndex,
    function(selectedIndex)
        local selectedStrata = EasyCursorTrails.frameStrataOptions[selectedIndex].text
        EasyCursorTrailsDB.cursorFrameStrata = selectedStrata
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorFrameStrata", selectedStrata)
        if customCursor then
            customCursor:SetFrameStrata(selectedStrata)
        end
    end
)
cursorFrameStrataDropdown:SetPoint("TOPLEFT", cursorOptionsGroup, "TOPLEFT", 0, 0)
EasyCursorTrails.cursorFrameStrataDropdown = cursorFrameStrataDropdown


-- 2️⃣ Cursor Texture Dropdown (Profile-Aware)
local cursorTextureOptions = {}
for _, cursorData in ipairs(EasyCursorTrails.customCursorTextures or {}) do
    local name = cursorData.name or "Unknown"
    if cursorData.animated then name = name .. " (Animated)" end
    table.insert(cursorTextureOptions, { text = name, icon = cursorData.texture })
end

-- Get current profile texture index
local profile = EasyCursorTrails.profile or EasyCursorTrails.defaults
local selectedIndex = profile.cursorTexture or 1

EasyCursorTrails.cursorTextureDropdown = EasyCursorTrails.CreateDropdown(
    "CursorTextureDropdown",
    cursorOptionsGroup,
    "Cursor Textures",
    cursorTextureOptions,
    selectedIndex,
    function(index)
        -- Save to profile, not global DB
        EasyCursorTrails.profile.cursorTexture = index
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorTexture", index)
        EasyCursorTrails.InitializeCustomCursor()
    end
)
EasyCursorTrails.cursorTextureDropdown:SetPoint("TOPLEFT", cursorFrameStrataDropdown, "BOTTOMLEFT", 0, spacing)


-- 3️⃣ Cursor Color Effect Dropdown
EasyCursorTrails.cursorColorEffectOptions = {}
for _, effect in ipairs(colorEffects or {}) do
    table.insert(EasyCursorTrails.cursorColorEffectOptions, { text = effect.text })
end
local cursorColorEffectDropdown = EasyCursorTrails.CreateDropdown(
    "CursorColorEffectDropdown",
    cursorOptionsGroup,
    "Cursor Color Effects",
    EasyCursorTrails.cursorColorEffectOptions,
    EasyCursorTrailsDB.cursorColorEffect or 1,
    function(index)
        EasyCursorTrailsDB.cursorColorEffect = index
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorColorEffect", index)
        EasyCursorTrails.ApplyColorEffectCursor()
    end
)
cursorColorEffectDropdown:SetPoint("TOPLEFT", EasyCursorTrails.cursorTextureDropdown, "BOTTOMLEFT", 0, spacing)
EasyCursorTrails.cursorColorEffectDropdown = cursorColorEffectDropdown
-- 4️⃣ Select Cursor Color Button
local selectCursorColorButton = CreateFrame("Button", "SelectCursorColorButton", cursorOptionsGroup, "UIPanelButtonTemplate")
selectCursorColorButton:SetSize(150, 25)
selectCursorColorButton:SetText("Select Cursor Color")
selectCursorColorButton:SetPoint("TOPLEFT", cursorColorEffectDropdown, "BOTTOMLEFT", 18, -2)
EasyCursorTrails.selectCursorColorButton = selectCursorColorButton

-- 5️⃣ Cursor Color Edit Box
local cursorColorEditBox = CreateFrame("EditBox", "CursorColorEditBox", cursorOptionsGroup, "InputBoxTemplate")
cursorColorEditBox:SetSize(80, 25)
cursorColorEditBox:SetPoint("LEFT", selectCursorColorButton, "RIGHT", 10, 0)
cursorColorEditBox:SetAutoFocus(false)
cursorColorEditBox:SetMaxLetters(9)
EasyCursorTrails.cursorColorEditBox = cursorColorEditBox

-- 🏷️ Label: HTML Color Code
local cursorColorLabel = cursorOptionsGroup:CreateFontString(nil, "OVERLAY", "GameFontNormal")
cursorColorLabel:SetPoint("BOTTOMLEFT", cursorColorEditBox, "TOPLEFT", 5, 0)
cursorColorLabel:SetText("HTML Code")

-- 🔄 Update Edit Box Text
local function UpdateCursorColorEditBox()
    local color = EasyCursorTrailsDB.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
    local colorText = RGBToHex(color.r, color.g, color.b, color.a)
    if cursorColorEditBox:GetText() ~= colorText then
        cursorColorEditBox:SetText(colorText)
    end
    local textWidth = cursorColorEditBox:GetText():len() * 8
    cursorColorEditBox:SetWidth(math.max(80, textWidth + 20))
end

-- 🎯 Handle Enter Pressed
cursorColorEditBox:SetScript("OnEnterPressed", function(self)
    local hexColor = "#" .. self:GetText():gsub("#", "")
    local r, g, b, a = HexToRGB(hexColor)
    if r and g and b then
        a = a or 1
        EasyCursorTrailsDB.cursorColor = { r = r, g = g, b = b, a = a }
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorColor", EasyCursorTrailsDB.cursorColor)
        EasyCursorTrails.ApplyColorEffectCursor()
        UpdateCursorColorEditBox()
    else
        print("Invalid HTML color format! Use #RRGGBB or #RRGGBBAA")
    end
    self:ClearFocus()
end)

-- 🧠 Apply on Focus Lost
cursorColorEditBox:SetScript("OnEditFocusLost", function(self)
    self:GetScript("OnEnterPressed")(self)
end)

-- 🎨 Button Click Logic
selectCursorColorButton:SetScript("OnClick", function()
    local initialColor = EasyCursorTrailsDB.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
    EasyCursorTrails.OpenColorPicker(initialColor, function(color)
        local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if not profile then return end
        local savedRadius = profile.glowRadius

        EasyCursorTrailsDB.cursorColor = color
        EasyCursorTrails.settingsChanged = true
        EasyCursorTrails.SaveToCurrentProfile("cursorColor", color)
        EasyCursorTrails.ApplyColorEffectCursor()

        if savedRadius then
            profile.glowRadius = savedRadius
            EasyCursorTrails.SaveToCurrentProfile("glowRadius", savedRadius)
            if EasyCursorTrails.UpdateCursorGlow then
                EasyCursorTrails.UpdateCursorGlow(savedRadius)
            end
        end

        UpdateCursorColorEditBox()
    end)
end)

-- 🔧 Initialize Edit Box
UpdateCursorColorEditBox()

-- Store reference
EasyCursorTrails.cursorColorEditBox = cursorColorEditBox


-- ===========================
-- Define Static Popup Dialogs
-- ===========================

-- 🔄 Save & Reload Confirmation
StaticPopupDialogs["EASYCURSORTRAILS_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 settings to current profile
        if EasyCursorTrails.SaveAllSettingsToProfile then
            EasyCursorTrails.SaveAllSettingsToProfile()
        end

        -- Save connectTrails checkbox state
        local checkbox = EasyCursorTrails.connectTrailsCheckbox
        if checkbox and checkbox.GetChecked then
            EasyCursorTrails.SaveToCurrentProfile("connectTrails", checkbox:GetChecked())
        end

        ReloadUI()
    end,
    OnCancel = function()
        -- Optional: log or notify cancellation
        -- --print("EasyCursorTrails: Reload canceled. Changes saved but not applied.")
    end,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,
}

-- 🔁 Reload Prompt After Saving
StaticPopupDialogs["EASYCURSORTRAILS_RELOAD_UI"] = {
    text = "Configuration changes saved. Reload UI to apply changes? This will also improves the effects.",
    button1 = "Reload",
    button2 = "Later",
    OnAccept = function()
        ReloadUI()
    end,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,
}
-- ===========================
-- Save Button
-- ===========================
local SaveButton = CreateFrame("Button", "SaveButton", menu, "UIPanelButtonTemplate")
SaveButton:SetSize(100, 25)
SaveButton:SetText("Save")
SaveButton:SetPoint("BOTTOMRIGHT", menu, "BOTTOMRIGHT", -200, 10)

SaveButton:SetScript("OnClick", function()
    -- 💾 Commit profile changes
    if EasyCursorTrails.SaveAllSettingsToProfile then
        EasyCursorTrails.SaveAllSettingsToProfile()
    end

    -- 📦 Reload current profile table
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    EasyCursorTrails.currentProfileName = profileName
    EasyCursorTrails.currentProfileTable = EasyCursorTrailsDB.profiles[profileName]

    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    -- ✅ Sync key toggles
    local trailsState = EasyCursorTrails.enableTrailsCheckbox and EasyCursorTrails.enableTrailsCheckbox:GetChecked()
    local starEmbersState = EasyCursorTrails.starEmbersCheckbox and EasyCursorTrails.starEmbersCheckbox:GetChecked()

    profile.enableTrails = trailsState
    profile.enableStarEmbers = starEmbersState

    EasyCursorTrails.SaveToCurrentProfile("enableTrails", trailsState)
    EasyCursorTrails.SaveToCurrentProfile("enableStarEmbers", starEmbersState)

    -- 🔁 Rebuild or hide trails
    if trailsState and EasyCursorTrails.RebuildTrails then
        EasyCursorTrails.RebuildTrails()
    elseif EasyCursorTrails.trailPool then
        for _, layerPool in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(layerPool) do
                if trail then trail:Hide() end
            end
        end
    end

    -- 💬 Show reload prompt
    local popup = StaticPopup_Show("EASYCURSORTRAILS_RELOAD_WARNING")
    if popup then
        popup:SetPoint("CENTER", UIParent, "CENTER")
    end

    -- 🔒 Reset dirty flag
    EasyCursorTrails.settingsChanged = false

    -- 🧩 Optional: trigger post-save hook
    if EasyCursorTrails.OnProfileSaved then
        EasyCursorTrails.OnProfileSaved(profileName)
    end
end)


function EasyCursorTrails.ApplyStarEmbersIfEnabled()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableStarEmbers then return end

    if EasyCursorTrails.StarDustTicker then
        EasyCursorTrails.StarDustTicker()
    end

    if EasyCursorTrails.SpawnSparkles and EasyCursorTrails.trailPool then
        for _, pool in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(pool) do
                if trail:IsVisible() then
                    EasyCursorTrails.SpawnSparkles(trail)
                end
            end
        end
    end
end


-- ===========================
-- Menu Hide Hook
-- ===========================
menu:HookScript("OnHide", function()
    if EasyCursorTrails.settingsChanged then
        if EasyCursorTrails.SaveAllSettingsToProfile then
            EasyCursorTrails.SaveAllSettingsToProfile()
        end

        -- ✅ Respect checkbox state
        local trailsState = enableTrailsCheckbox and enableTrailsCheckbox:GetChecked()
        local profile = EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        if profile then
            profile.enableTrails = trailsState
            EasyCursorTrails.currentProfileTable.enableTrails = trailsState
        end

        local popup = StaticPopup_Show("EASYCURSORTRAILS_RELOAD_UI")
        if popup then
            popup:SetPoint("CENTER", UIParent, "CENTER")
        end

        EasyCursorTrails.settingsChanged = false
    end
end)



-- ❌ Close Button
local closeButton = CreateFrame("Button", "CloseButton", menu, "UIPanelButtonTemplate")
closeButton:SetSize(100, 25)
closeButton:SetText("Close")
closeButton:SetPoint("BOTTOMRIGHT", SaveButton, "BOTTOMRIGHT", 150, 0)

closeButton:SetScript("OnClick", function()
    menu:Hide() -- Triggers OnHide logic
end)

--------------------------------------------------
-- Minimap Button
--------------------------------------------------

local minimapButton = CreateFrame("Button", "EasyCursorTrailsMinimapButton", Minimap)
minimapButton:SetSize(20, 20)
minimapButton:SetNormalTexture("Interface\\AddOns\\EasyCursorTrails\\Textures\\icon.tga")
minimapButton:SetHighlightTexture("Interface\\Buttons\\UI-Minimap-ZoomButton-Highlight.blp")

-- Restore saved position or default
local pos = EasyCursorTrailsDB.minimapPos or { x = -10, y = -10 }
minimapButton:SetPoint("TOPLEFT", Minimap, "TOPLEFT", pos.x, pos.y)

--------------------------------------------------
-- Shift + Drag Movement
--------------------------------------------------
minimapButton:SetMovable(true)
minimapButton:EnableMouse(true)

minimapButton:SetScript("OnMouseDown", function(self, button)
    if IsShiftKeyDown() and button == "LeftButton" then
        self:StartMoving()
        self.isMoving = true
        self.ignoreNextClick = true   -- prevent menu opening after drag
    end
end)

minimapButton:SetScript("OnMouseUp", function(self)
    if self.isMoving then
        self:StopMovingOrSizing()
        self.isMoving = false

        -- Save new position
        local point, _, _, x, y = self:GetPoint()
        EasyCursorTrailsDB.minimapPos = { x = x, y = y }
    end
end)

--------------------------------------------------
-- Click to Toggle Menu (unless dragged)
--------------------------------------------------
minimapButton:SetScript("OnClick", function(self)
    if self.ignoreNextClick then
        self.ignoreNextClick = false
        return -- suppress click after dragging
    end

    menu:SetShown(not menu:IsShown())
end)

--------------------------------------------------
-- Tooltip
--------------------------------------------------
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:AddLine("Shift + Drag to move.", 0.4, 0.8, 1)
    GameTooltip:Show()
end)

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


end



--------------------------------------------------------
-- Animations for Glow
--------------------------------------------------------
function CreatePulsingAnimation(group, color, intensity, duration, delay)
    group:Stop()
    for _, anim in ipairs({ group:GetAnimations() }) do
        if anim and anim.Stop then anim:Stop() end
    end

    local fadeOut = group:CreateAnimation("Alpha")
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0.3)
    fadeOut:SetDuration(duration)
    fadeOut:SetSmoothing("IN_OUT")
    fadeOut:SetOrder(1)

    local fadeIn = group:CreateAnimation("Alpha")
    fadeIn:SetFromAlpha(0.3)
    fadeIn:SetToAlpha(1)
    fadeIn:SetDuration(duration)
    fadeIn:SetSmoothing("IN_OUT")
    fadeIn:SetOrder(2)

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


function EasyCursorTrails.ApplyDefaultCircularGlow()
    -- 🔒 Ensure customCursor and glowEffects are valid
    if not customCursor or not customCursor.glowEffects then return end

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

    -- 🎨 Retrieve glow settings
    local glowColor     = EasyCursorTrailsDB.glowColor     or EasyCursorTrails.defaults.glowColor     or { r = 1, g = 1, b = 1, a = 1 }
    local glowSize      = tonumber(EasyCursorTrailsDB.glowSize) or EasyCursorTrails.defaults.glowSize or 1
    local glowIntensity = tonumber(EasyCursorTrailsDB.glowIntensity) or EasyCursorTrails.defaults.glowIntensity or 1
    local glowRadius    = tonumber(EasyCursorTrailsDB.glowRadius) or EasyCursorTrails.defaults.glowRadius or 0.1

    -- 📐 Geometry
    local angleStep    = 360 / glowCount
    local cursorRadius = customCursor:GetWidth() / 1.5
    local offsetDist   = cursorRadius * glowRadius
    local alpha        = glowIntensity * (glowColor.a or 1)

    -- ✨ Position and style each glow
    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) * offsetDist
            local offsetY = math.sin(angle) * offsetDist

            glow:ClearAllPoints()
            glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)

            local size = customCursor:GetWidth() * glowSize
            glow:SetSize(size, size)

            glow.texture:SetVertexColor(glowColor.r, glowColor.g, glowColor.b)
            glow.texture:SetAlpha(alpha)

            glow:Show()
        end
    end
end



function EasyCursorTrails.ClearAllGlows()
    for _, glow in ipairs(EasyCursorTrails.activeGlows or {}) do
        glow:Hide()
        if glow.texture then
            glow.texture:SetTexture(nil)
        end
    end
    EasyCursorTrails.activeGlows = {}
end


function EasyCursorTrails.ResetEffectControls()
    for _, control in pairs(EasyCursorTrails.effectUIControls or {}) do
        if control then
            if control.SetChecked then
                control:SetChecked(false)
            end
            if control.SetValue then
                control:SetValue(0)
            end
            if control.SetText then
                control:SetText("")
            end
            if control.SetShown then
                control:SetShown(false)
            end
        end
    end
end


function EasyCursorTrails.HideAllEffectControls()
    for _, control in pairs(EasyCursorTrails.effectUIControls or {}) do
        if control and control.SetShown then
            control:SetShown(false)
        end
    end
end

EasyCursorTrails.effectUIControls = {
    -- 🔘 Rotation & Direction
    EasyCursorTrails.rotationCheckbox,
    EasyCursorTrails.clockwiseCheckbox,
    EasyCursorTrails.counterClockwiseCheckbox,
    EasyCursorTrails.rotationSpeedSlider,
    EasyCursorTrails.rotationChaosCheckbox,

    -- 🔁 Pulse
    EasyCursorTrails.pulseCheckbox,
    EasyCursorTrails.pulseSpeedSlider,
    EasyCursorTrails.pulseScaleSlider,

    -- 🌈 Rainbow
    EasyCursorTrails.rainbowCheckbox,
    EasyCursorTrails.rainbowSpeedSlider,

    -- ✨ Glow & Visuals
    EasyCursorTrails.texturePathBox,
    EasyCursorTrails.glowThicknessSlider,
    EasyCursorTrails.glowSizeSlider,
    EasyCursorTrails.glowRadiusSlider,
    EasyCursorTrails.glowIntensitySlider,

    -- 🌟 Twinkle & Shimmer
    EasyCursorTrails.shimmerAlphaSlider,
    EasyCursorTrails.flickerAlphaMinSlider,
    EasyCursorTrails.flickerAlphaMaxSlider,

    -- 🔥 Ember & Flare
    EasyCursorTrails.emberRiseSlider,
    EasyCursorTrails.fallSpeedSlider,
    EasyCursorTrails.flareScaleSlider,

    -- 🌊 Drift & Ripple
    EasyCursorTrails.driftOffsetSlider,
    EasyCursorTrails.driftXSlider,
    EasyCursorTrails.driftYSlider,
    EasyCursorTrails.driftSpeedSlider,
    EasyCursorTrails.rippleScaleSlider,

    -- 💥 Burst & Cascade
    EasyCursorTrails.burstScaleSlider,
    EasyCursorTrails.cascadeSpeedSlider,

    -- 🌪️ Surge & Fade
    EasyCursorTrails.surgeSpeedSlider,
    EasyCursorTrails.fadeAlphaSlider,
}



EasyCursorTrails.effectUIControls = {
    EasyCursorTrails.clockwiseCheckbox,
    EasyCursorTrails.pulseScaleSlider,
    EasyCursorTrails.rotationSpeedSlider,
    EasyCursorTrails.texturePathBox,
    EasyCursorTrails.flickerRateSlider,
    EasyCursorTrails.emberRiseSlider,
    EasyCursorTrails.fallSpeedSlider,
    EasyCursorTrails.shimmerAlphaSlider,
    EasyCursorTrails.burstScaleSlider,
    EasyCursorTrails.driftOffsetSlider,
    EasyCursorTrails.driftXSlider,
    EasyCursorTrails.driftYSlider,
    EasyCursorTrails.fadeAlphaSlider,
    EasyCursorTrails.surgeSpeedSlider,
    EasyCursorTrails.flickerAlphaMinSlider,
    EasyCursorTrails.flickerAlphaMaxSlider,
    EasyCursorTrails.rotationChaosCheckbox,
    EasyCursorTrails.flareScaleSlider,
    EasyCursorTrails.driftSpeedSlider,
    EasyCursorTrails.cascadeSpeedSlider,
    EasyCursorTrails.rippleScaleSlider,
    EasyCursorTrails.pulseEnabledCheckbox,
    EasyCursorTrails.pulseSpeedSlider,
    EasyCursorTrails.rainbowEnabledCheckbox,
    EasyCursorTrails.rainbowSpeedSlider,
    EasyCursorTrails.glowThicknessSlider,
    EasyCursorTrails.glowSizeSlider,
    EasyCursorTrails.glowRadiusSlider,
    EasyCursorTrails.glowIntensitySlider,
}



function EasyCursorTrails.SyncGlobalSettingsUI()
    local profile = EasyCursorTrails.currentProfileTable or {}

    -- 🔁 Echo Relay
    if EasyCursorTrails.echoRelayCheckbox then
        EasyCursorTrails.echoRelayCheckbox:SetChecked(profile.echoEnabled == true)
    end
    if EasyCursorTrails.echoRelaySpeedSlider then
        local freq = tonumber(profile.echoFrequency) or 55
        local sliderValue = math.max(0, math.min(10, (freq - 10) / 9))
        EasyCursorTrails.echoRelaySpeedSlider:SetValue(sliderValue)
    end

      -- 🔘 Pulse
    if EasyCursorTrails.pulseCheckbox then
        EasyCursorTrails.pulseCheckbox:SetChecked(profile.pulseEnabled == true)
    end
    if EasyCursorTrails.pulseSpeedSlider then
        EasyCursorTrails.pulseSpeedSlider:SetValue(tonumber(profile.pulseSpeed) or 5)
    end

      -- 🌈 Rainbow
    if EasyCursorTrails.rainbowCheckbox then
        EasyCursorTrails.rainbowCheckbox:SetChecked(profile.rainbowEnabled == true)
    end
    if EasyCursorTrails.rainbowSpeedSlider then
        EasyCursorTrails.rainbowSpeedSlider:SetValue(tonumber(profile.rainbowSpeed) or 5)
    end

    -- 🔘 Rotation & Direction
    if EasyCursorTrails.rotationCheckbox then
        EasyCursorTrails.rotationCheckbox:SetChecked(profile.enableRotation == true)
    end

    if EasyCursorTrails.clockwiseCheckbox then
        EasyCursorTrails.clockwiseCheckbox:SetChecked(profile.clockwiseEnabled == true)
    end

    if EasyCursorTrails.counterClockwiseCheckbox then
        EasyCursorTrails.counterClockwiseCheckbox:SetChecked(profile.counterClockwiseEnabled == true)
    end

    if EasyCursorTrails.rotationDirectionDropdown and profile.rotationDirection then
        UIDropDownMenu_SetSelectedValue(EasyCursorTrails.rotationDirectionDropdown, profile.rotationDirection)
    end

    -- 🎚 Rotation Speeds
    if EasyCursorTrails.rotationSpeedSlider then
        EasyCursorTrails.rotationSpeedSlider:SetValue(tonumber(profile.rotationSpeed) or 0)
    end
    if EasyCursorTrails.clockwiseSpeedSlider then
        EasyCursorTrails.clockwiseSpeedSlider:SetValue(tonumber(profile.clockwiseSpeed) or 30)
    end
    if EasyCursorTrails.counterClockwiseSpeedSlider then
        EasyCursorTrails.counterClockwiseSpeedSlider:SetValue(tonumber(profile.counterClockwiseSpeed) or 30)
    end

    -- ✂️ Split Layout
    if EasyCursorTrails.splitEffectCheckbox then
        EasyCursorTrails.splitEffectCheckbox:SetChecked(profile.splitEffectEnabled == true)
    end
    if EasyCursorTrails.splitLayoutCheckbox then
        EasyCursorTrails.splitLayoutCheckbox:SetChecked(profile.splitLayoutEnabled == true)
    end
    if EasyCursorTrails.splitRotationSpeedSlider then
        EasyCursorTrails.splitRotationSpeedSlider:SetValue(tonumber(profile.rotationSpeed) or 30)
        EasyCursorTrails.splitRotationSpeedSlider:SetEnabled(profile.splitEffectEnabled == true)
    end

    -- ✨ Shimmer
    if EasyCursorTrails.shimmerCheckbox then
        EasyCursorTrails.shimmerCheckbox:SetChecked(profile.shimmerEnabled == true)
    end
    if EasyCursorTrails.shimmerFrequencySlider then
        EasyCursorTrails.shimmerFrequencySlider:SetValue(tonumber(profile.shimmerFrequency) or 50)
    end

    -- 🌀 Sweep
    if EasyCursorTrails.sweepCheckbox then
        EasyCursorTrails.sweepCheckbox:SetChecked(profile.sweepEnabled == true)
    end
    if EasyCursorTrails.sweepEnabledCheckbox then
        EasyCursorTrails.sweepEnabledCheckbox:SetChecked(profile.sweepEnabled == true)
    end
    if EasyCursorTrails.sweepSpeedSlider then
        EasyCursorTrails.sweepSpeedSlider:SetValue(tonumber(profile.sweepSpeed) or 40)
    end

    -- ✨ Twinkle
    if EasyCursorTrails.twinkleCheckbox then
        EasyCursorTrails.twinkleCheckbox:SetChecked(profile.twinkleEnabled == true)
    end

    if EasyCursorTrails.twinkleSpeedSlider then
        EasyCursorTrails.twinkleSpeedSlider:SetValue(tonumber(profile.twinkleSpeed) or 5)
    end

    -- 🔁 Echo
    if EasyCursorTrails.echoEnabledCheckbox then
        EasyCursorTrails.echoEnabledCheckbox:SetChecked(profile.echoEnabled == true)
    end
    if EasyCursorTrails.echoFrequencySlider then
        EasyCursorTrails.echoFrequencySlider:SetValue(tonumber(profile.echoFrequency) or 50)
    end
    if EasyCursorTrails.echoScaleSlider then
        EasyCursorTrails.echoScaleSlider:SetValue(tonumber(profile.echoScale) or 1.5)
    end
    if EasyCursorTrails.echoDurationSlider then
        EasyCursorTrails.echoDurationSlider:SetValue(tonumber(profile.echoDuration) or 0.6)
    end

    -- 🧭 Cursor Size & Offset
    if EasyCursorTrails.cursorSizeSlider then
        EasyCursorTrails.cursorSizeSlider:SetValue(profile.cursorSize or 40)
    end
    if EasyCursorTrails.cursorOffsetXSlider then
        EasyCursorTrails.cursorOffsetXSlider:SetValue(profile.cursorOffsetX or 0)
    end
    if EasyCursorTrails.cursorOffsetYSlider then
        EasyCursorTrails.cursorOffsetYSlider:SetValue(profile.cursorOffsetY or 0)
    end

    -- 🎨 Cursor Color
    if EasyCursorTrails.cursorColorPicker and profile.cursorColor then
        if type(EasyCursorTrails.cursorColorPicker.SetColorRGB) == "function" then
            EasyCursorTrails.cursorColorPicker:SetColorRGB(
                profile.cursorColor.r or 1,
                profile.cursorColor.g or 1,
                profile.cursorColor.b or 1
            )
        end
    end

    -- 🌟 Glow Texture Dropdown (Paginated)
    C_Timer.After(0.1, function()
        if EasyCursorTrails.glowTextureDropdown and profile.selectedGlowTexture then
            local textureID = profile.selectedGlowTexture
            for index, option in ipairs(EasyCursorTrails.glowTextureOptions or {}) do
                if option.id == textureID then
                    if type(EasyCursorTrails.glowTextureDropdown.SetSelectedIndex) == "function" then
                        EasyCursorTrails.glowTextureDropdown:SetSelectedIndex(index)
                    end
                    break
                end
            end
        end
    end)

    -- 🖼️ Cursor Texture
    if EasyCursorTrails.cursorTextureDropdown and profile.selectedCursorTextureName then
        UIDropDownMenu_SetSelectedName(EasyCursorTrails.cursorTextureDropdown, profile.selectedCursorTextureName)
    end

    -- 🧱 Frame Strata
    if EasyCursorTrails.cursorStrataDropdown and profile.cursorFrameStrata then
        UIDropDownMenu_SetSelectedName(EasyCursorTrails.cursorStrataDropdown, profile.cursorFrameStrata)
    end
end



function EasyCursorTrails.SyncEffectSettingsUI(effectID, profileOverride)
    local profile = profileOverride
        or EasyCursorTrails.currentProfileTable
        or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
        or EasyCursorTrails.defaults

    if not profile then return end

    local settings = profile.effectSettings and profile.effectSettings[effectID]
    if not settings then return end

    -- 🛠 Sync Trail Count Slider
    if EasyCursorTrails.trailCountSlider and EasyCursorTrails.trailCountSlider.SetValue then
        EasyCursorTrails.trailCountSlider:SetValue(profile.trailCount or EasyCursorTrails.defaults.trailCount or 45)
    end

    -- 🎨 Pulse Enabled Checkbox
    if EasyCursorTrails.pulseEnabledCheckbox then
        EasyCursorTrails.pulseEnabledCheckbox:SetShown(true)
        EasyCursorTrails.pulseEnabledCheckbox:SetChecked(settings.pulseEnabled == true)
    end

    -- 🎛 Pulse Speed Slider
    if EasyCursorTrails.pulseSpeedSlider then
        EasyCursorTrails.pulseSpeedSlider:SetShown(true)
        EasyCursorTrails.pulseSpeedSlider:SetValue(tonumber(settings.pulseSpeed) or 5)
    end

    -- 🔍 Pulse Scale Slider
    if EasyCursorTrails.pulseScaleSlider then
        EasyCursorTrails.pulseScaleSlider:SetShown(true)
        EasyCursorTrails.pulseScaleSlider:SetValue(tonumber(settings.pulseScale) or 1.1)
    end

    -- 🌈 Rainbow
    if EasyCursorTrails.rainbowEnabledCheckbox then
        EasyCursorTrails.rainbowEnabledCheckbox:SetShown(true)
        EasyCursorTrails.rainbowEnabledCheckbox:SetChecked(settings.rainbowEnabled or false)
    end
    if EasyCursorTrails.rainbowSpeedSlider then
        EasyCursorTrails.rainbowSpeedSlider:SetShown(true)
        EasyCursorTrails.rainbowSpeedSlider:SetValue(settings.rainbowSpeed or 5)
    end

    -- 🌊 Ripple
    if EasyCursorTrails.rippleScaleSlider then
        EasyCursorTrails.rippleScaleSlider:SetShown(true)
        EasyCursorTrails.rippleScaleSlider:SetValue(settings.rippleScale or 1.2)
    end

    -- 🔆 Glow Size & Intensity
    if EasyCursorTrails.glowSizeSlider then
        EasyCursorTrails.glowSizeSlider:SetShown(true)
        EasyCursorTrails.glowSizeSlider:SetValue(settings.glowSize or 0.5)
    end
    if EasyCursorTrails.glowIntensitySlider then
        EasyCursorTrails.glowIntensitySlider:SetShown(true)
        EasyCursorTrails.glowIntensitySlider:SetValue(settings.glowIntensity or 1)
    end

    -- 🔄 Rotation
    if EasyCursorTrails.rotationSpeedSlider then
        EasyCursorTrails.rotationSpeedSlider:SetShown(true)
        EasyCursorTrails.rotationSpeedSlider:SetValue(settings.rotationSpeed or 30)
    end
    if EasyCursorTrails.clockwiseCheckbox then
        EasyCursorTrails.clockwiseCheckbox:SetShown(true)
        EasyCursorTrails.clockwiseCheckbox:SetChecked(settings.clockwiseEnabled or false)
    end

    -- 🌀 Radius
    if EasyCursorTrails.glowRadiusSlider then
        EasyCursorTrails.glowRadiusSlider:SetShown(true)
        EasyCursorTrails.glowRadiusSlider:SetValue(settings.glowRadius or 0.1)
    end

    -- 🌬️ Drift
    if EasyCursorTrails.driftXSlider then
        EasyCursorTrails.driftXSlider:SetShown(true)
        EasyCursorTrails.driftXSlider:SetValue(settings.driftX or 0)
    end
    if EasyCursorTrails.driftYSlider then
        EasyCursorTrails.driftYSlider:SetShown(true)
        EasyCursorTrails.driftYSlider:SetValue(settings.driftY or 0)
    end

    -- 🔳 Hollow
    if EasyCursorTrails.glowThicknessSlider then
        EasyCursorTrails.glowThicknessSlider:SetShown(true)
        EasyCursorTrails.glowThicknessSlider:SetValue(settings.glowThickness or 0.8)
    end

    -- 🌌 Echo
    if EasyCursorTrails.echoEnabledCheckbox then
        EasyCursorTrails.echoEnabledCheckbox:SetShown(true)
        EasyCursorTrails.echoEnabledCheckbox:SetChecked(settings.echoEnabled or false)
    end
    if EasyCursorTrails.echoFrequencySlider then
        EasyCursorTrails.echoFrequencySlider:SetShown(true)
        EasyCursorTrails.echoFrequencySlider:SetValue(settings.echoFrequency or 50)
    end

    -- ✨ Shimmer
    if EasyCursorTrails.shimmerEnabledCheckbox then
        EasyCursorTrails.shimmerEnabledCheckbox:SetShown(true)
        EasyCursorTrails.shimmerEnabledCheckbox:SetChecked(settings.shimmerEnabled or false)
    end
    if EasyCursorTrails.shimmerFrequencySlider then
        EasyCursorTrails.shimmerFrequencySlider:SetShown(true)
        EasyCursorTrails.shimmerFrequencySlider:SetValue(settings.shimmerFrequency or 50)
    end

    -- 🌟 Twinkle
    if EasyCursorTrails.twinkleEnabledCheckbox then
        EasyCursorTrails.twinkleEnabledCheckbox:SetShown(true)
        EasyCursorTrails.twinkleEnabledCheckbox:SetChecked(settings.twinkleEnabled or false)
    end
    if EasyCursorTrails.twinkleSpeedSlider then
        EasyCursorTrails.twinkleSpeedSlider:SetShown(true)
        EasyCursorTrails.twinkleSpeedSlider:SetValue(settings.twinkleSpeed or 5)
    end

    -- 🧩 Sweep
    if EasyCursorTrails.sweepEnabledCheckbox then
        EasyCursorTrails.sweepEnabledCheckbox:SetShown(true)
        EasyCursorTrails.sweepEnabledCheckbox:SetChecked(settings.sweepEnabled or false)
    end
    if EasyCursorTrails.sweepSpeedSlider then
        EasyCursorTrails.sweepSpeedSlider:SetShown(true)
        EasyCursorTrails.sweepSpeedSlider:SetValue(settings.sweepSpeed or 40)
    end


    if EasyCursorTrails.texturePathBox then
        EasyCursorTrails.texturePathBox:SetShown(true)
        EasyCursorTrails.texturePathBox:SetText(settings.customTexture or "")
    end

    -- 🔥 Burning Effect
    if EasyCursorTrails.flickerRateSlider then
        EasyCursorTrails.flickerRateSlider:SetShown(true)
        EasyCursorTrails.flickerRateSlider:SetValue(settings.flickerRate or 0.2)
    end
    if EasyCursorTrails.emberRiseSlider then
        EasyCursorTrails.emberRiseSlider:SetShown(true)
        EasyCursorTrails.emberRiseSlider:SetValue(settings.emberRise or 6)
    end

    -- 🌠 Starfall
    if EasyCursorTrails.fallSpeedSlider then
        EasyCursorTrails.fallSpeedSlider:SetShown(true)
        EasyCursorTrails.fallSpeedSlider:SetValue(settings.fallSpeed or 10)
    end
    if EasyCursorTrails.shimmerAlphaSlider then
        EasyCursorTrails.shimmerAlphaSlider:SetShown(true)
        EasyCursorTrails.shimmerAlphaSlider:SetValue(settings.shimmerAlpha or 0.8)
    end

    -- 🔥 Phoenix Flame
    if EasyCursorTrails.burstScaleSlider then
        EasyCursorTrails.burstScaleSlider:SetShown(true)
        EasyCursorTrails.burstScaleSlider:SetValue(settings.burstScale or 1.4)
    end
    if EasyCursorTrails.driftOffsetSlider then
        EasyCursorTrails.driftOffsetSlider:SetShown(true)
        EasyCursorTrails.driftOffsetSlider:SetValue(settings.driftOffset or 4)
    end

    -- 🌌 Celestial Pulse
    if EasyCursorTrails.driftSpeedSlider then
        EasyCursorTrails.driftSpeedSlider:SetShown(true)
        EasyCursorTrails.driftSpeedSlider:SetValue(settings.driftSpeed or 2)
    end


    if EasyCursorTrails.fadeAlphaSlider then
        EasyCursorTrails.fadeAlphaSlider:SetShown(true)
        EasyCursorTrails.fadeAlphaSlider:SetValue(settings.fadeAlpha or 0.3)
    end

    -- 🌈 Rainbow Surge
    if EasyCursorTrails.surgeSpeedSlider then
        EasyCursorTrails.surgeSpeedSlider:SetShown(true)
        EasyCursorTrails.surgeSpeedSlider:SetValue(settings.surgeSpeed or 0.25)
    end

    -- 🕳️ Void Flicker
    if EasyCursorTrails.flickerAlphaMinSlider then
        EasyCursorTrails.flickerAlphaMinSlider:SetShown(true)
        EasyCursorTrails.flickerAlphaMinSlider:SetValue(settings.flickerAlphaMin or 0.2)
    end
    if EasyCursorTrails.flickerAlphaMaxSlider then
        EasyCursorTrails.flickerAlphaMaxSlider:SetShown(true)
        EasyCursorTrails.flickerAlphaMaxSlider:SetValue(settings.flickerAlphaMax or 0.8)
    end
    if EasyCursorTrails.rotationChaosCheckbox then
        EasyCursorTrails.rotationChaosCheckbox:SetShown(true)
        EasyCursorTrails.rotationChaosCheckbox:SetChecked(settings.rotationChaos or false)
    end

    -- ☀️ Solar Flare
    if EasyCursorTrails.flareScaleSlider then
        EasyCursorTrails.flareScaleSlider:SetShown(true)
        EasyCursorTrails.flareScaleSlider:SetValue(settings.flareScale or 1.4)
    end


    -- 🌟 Starlight Cascade
    if EasyCursorTrails.cascadeSpeedSlider then
        EasyCursorTrails.cascadeSpeedSlider:SetShown(true)
        EasyCursorTrails.cascadeSpeedSlider:SetValue(settings.cascadeSpeed or 1.6)
    end


end



function EasyCursorTrails.ApplySelectedGlowEffect()
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local currentProfile = EasyCursorTrailsDB.profiles and EasyCursorTrailsDB.profiles[profileName]
    if not currentProfile then return end
    EasyCursorTrails.currentProfileTable = currentProfile

    local profile = currentProfile -- ✅ Fix: define local 'profile'

    if not customCursor or not customCursor.glowEffects or #customCursor.glowEffects == 0 then
        EasyCursorTrails.InitializeGlowFrames()
    end

    EasyCursorTrails.activeGlows = customCursor.glowEffects
    EasyCursorTrails.rotationTimers = EasyCursorTrails.rotationTimers or {}
    EasyCursorTrails.shimmerTimers  = EasyCursorTrails.shimmerTimers  or {}
    EasyCursorTrails.sweepTimers    = EasyCursorTrails.sweepTimers    or {}
    EasyCursorTrails.twinkleTimers = EasyCursorTrails.twinkleTimers  or {}
    EasyCursorTrails.rainbowTimers = EasyCursorTrails.rainbowTimers  or {}

    -- 🧼 Cancel rotation ticker if needed
    if EasyCursorTrails.rotationTicker then
        EasyCursorTrails.rotationTicker:Cancel()
        EasyCursorTrails.rotationTicker = nil
    end

    -- 🧼 Reset shimmer timers
    for texture, ticker in pairs(EasyCursorTrails.shimmerTimers) do
        if ticker then ticker:Cancel() end
        EasyCursorTrails.shimmerTimers[texture] = nil
    end

    -- 🔧 Visual parameters
    local glowColor     = currentProfile.glowColor     or EasyCursorTrails.defaults.glowColor     or { r = 1, g = 1, b = 1, a = 1 }
    local intensity     = math.max(0, math.min(2, currentProfile.glowIntensity or EasyCursorTrails.defaults.glowIntensity or 1))

    local clampedAlpha  = math.max(0.0, math.min(1.0, (glowColor.a or 1) * intensity))

    local glowRadius    = tonumber(currentProfile.glowRadius) or EasyCursorTrails.defaults.glowRadius or 0.1
    local glowSize      = tonumber(currentProfile.glowSize) or EasyCursorTrails.defaults.glowSize or 1
    local cursorWidth   = customCursor:GetWidth() or 64
    local radiusScale   = glowRadius * (cursorWidth / 5.5)

    local maxAvailable = #customCursor.glowEffects
    local glowCount = math.min(tonumber(EasyCursorTrailsDB.patternGlowCount) or maxAvailable, maxAvailable)

               -- 🎨 Texture
        local textureID = currentProfile.selectedGlowTexture or 1
        local texturePath = "Interface\\Cooldown\\star4"

        -- 🔍 Find texture path by matching ID
        for _, option in ipairs(EasyCursorTrails.glowTextureOptions or {}) do
            if tonumber(option.id) == tonumber(textureID) and option.path then
                texturePath = option.path
                break
            end
        end



    -- 🧠 Pattern resolution
    local textureName = currentProfile.selectedCursorTextureName
    local patternKey

    if EasyCursorTrails.dynamicPatterns[textureName .. "_Pattern"] then
        patternKey = textureName .. "_Pattern"
    elseif EasyCursorTrails.cursorGlowMapping and EasyCursorTrails.cursorGlowMapping[textureName] then
        local mappedKey = EasyCursorTrails.cursorGlowMapping[textureName]
        if EasyCursorTrails.dynamicPatterns[mappedKey .. "_Pattern"] then
            patternKey = mappedKey .. "_Pattern"
        else
            patternKey = mappedKey
        end
    else
        patternKey = "Circle_White"
    end

    local glowPattern = EasyCursorTrails.dynamicPatterns and EasyCursorTrails.dynamicPatterns[patternKey]
    if not glowPattern then
        EasyCursorTrails.ApplyDefaultCircularGlow()
        return
    end

    local coords = type(glowPattern) == "function" and glowPattern(glowCount) or glowPattern
    if not coords or type(coords) ~= "table" then
        EasyCursorTrails.ApplyDefaultCircularGlow()
        return
    end

    EasyCursorTrails.lastPatternCoords = coords -- ✅ Store original layout for rotation


    -- 🧩 Animation options
    local selectedEffect = currentProfile.selectedGlowEffect or 1
    local isCustomEffect = selectedEffect == 1
 
    local handler = EasyCursorTrails.effectHandlers and EasyCursorTrails.effectHandlers[selectedEffect]
    local effectConfig = currentProfile.effectSettings and currentProfile.effectSettings[selectedEffect] or {}

    if not handler then return end


      local animationOptions = {
            pulseEnabled     = isCustomEffect and currentProfile.pulseEnabled == true or selectedEffect == 2,
            pulseSpeed       = tonumber(currentProfile.pulseSpeed) or 5,
            rainbowEnabled   = currentProfile.rainbowEnabled == true or effectConfig.forceRainbow == true,
            rainbowSpeed     = tonumber(currentProfile.rainbowSpeed) or 5,
            vibrantEnabled   = currentProfile.vibrantEnabled == true or selectedEffect == 7,
        }



    local splitLayout = currentProfile.splitLayoutEnabled == true
    local splitHeight = tonumber(currentProfile.splitLayoutHeight) or 50


    
    -- 🧩 Shared effect settings
    local effectSettings = {
        clampedAlpha             = clampedAlpha,
        rotationSpeed            = tonumber(currentProfile.rotationSpeed) or 0,
        enableRotation           = currentProfile.enableRotation == true,
        clockwiseEnabled         = currentProfile.clockwiseEnabled == true,
        counterClockwiseEnabled  = currentProfile.counterClockwiseEnabled == true,
        clockwiseSpeed           = tonumber(currentProfile.clockwiseSpeed) or 30,
        counterClockwiseSpeed    = tonumber(currentProfile.counterClockwiseSpeed) or 30,
        splitEffectEnabled       = currentProfile.splitEffectEnabled == true,
        splitLayoutEnabled       = splitLayout,
        shimmerEnabled           = currentProfile.shimmerEnabled == true,
        shimmerFrequency         = tonumber(currentProfile.shimmerFrequency) or 50,
        sweepEnabled             = currentProfile.sweepEnabled == true,
        sweepSpeed               = tonumber(currentProfile.sweepSpeed) or 40,
        twinkleEnabled           = currentProfile.twinkleEnabled == true,
        twinkleSpeed             = tonumber(currentProfile.twinkleSpeed) or 5,
        echoEnabled              = currentProfile.echoEnabled == true,
        echoFrequency            = tonumber(currentProfile.echoFrequency) or 50,
        echoScale                = tonumber(currentProfile.echoScale) or 1.5,
        echoDuration             = tonumber(currentProfile.echoDuration) or 0.6,
        pulseEnabled             = animationOptions.pulseEnabled,
        pulseSpeed               = animationOptions.pulseSpeed,
        rotationDirection        = tonumber(currentProfile.rotationDirection) or 1,
        glowRadius               = glowRadius,
        cursorWidth              = cursorWidth,
        radiusScale              = radiusScale -- ✅ NEW
    }



    local modules = EasyCursorTrails.effectModules

    -- 🌀 Create rotation container
   if not EasyCursorTrails.rotationContainer then
    EasyCursorTrails.rotationContainer = CreateFrame("Frame", "EasyCursorTrailsRotationContainer", customCursor)
end

EasyCursorTrails.rotationContainer:SetSize(cursorWidth, cursorWidth)
EasyCursorTrails.rotationContainer:ClearAllPoints()
EasyCursorTrails.rotationContainer:SetPoint("CENTER", customCursor, "CENTER", 0, 0)


    -- ✨ Apply glow effects
    for i = 1, glowCount do
        local glow = customCursor.glowEffects[i]
        local coord = coords[i]

        if glow and glow.texture and coord then
            -- 🧼 Reset animation group
            if glow.animationGroup then
                glow.animationGroup:Stop()
                for _, anim in ipairs({ glow.animationGroup:GetAnimations() }) do
                    if anim and anim.Stop then anim:Stop() end
                end

                    
                -- 🧼 Cancel any lingering tickers (e.g. rainbow, random color)
                if glow.animationGroup.rainbowTicker then
                    glow.animationGroup.rainbowTicker:Cancel()
                    glow.animationGroup.rainbowTicker = nil
                end
                if glow.animationGroup.randomColorTicker then
                    glow.animationGroup.randomColorTicker:Cancel()
                    glow.animationGroup.randomColorTicker = nil
                end
                
            end

            glow.animationGroup = glow:CreateAnimationGroup()

            -- 🧩 Size and layout
            local size = math.max(cursorWidth * glowSize, 12)
            glow:SetSize(size, size)
            glow:SetParent(EasyCursorTrails.rotationContainer)
            glow:SetFrameStrata("HIGH")
            glow:SetFrameLevel(customCursor:GetFrameLevel() + 10)

            local x = coord.x * radiusScale
            local y = coord.y * radiusScale

            -- 🧭 Positioning
            glow:ClearAllPoints()
            glow:SetPoint("CENTER", EasyCursorTrails.rotationContainer, "CENTER", x, y)

            -- ✅ Visibility and fade
            glow:Show()
            glow:SetAlpha(1)

            
            local texture = glow.texture
            if texture then
                local intensity = profile.glowIntensity or 1
                local baseAlpha = glowColor.a or 1
                local fadedAlpha = math.max(0.0, math.min(1.0, baseAlpha * intensity))

               texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
                texture:SetBlendMode("ADD")

                texture:SetVertexColor(
                    math.min(glowColor.r * intensity, 1),
                    math.min(glowColor.g * intensity, 1),
                    math.min(glowColor.b * intensity, 1),
                    fadedAlpha
                )
                texture:SetAlpha(fadedAlpha)

                texture:ClearAllPoints()
                texture:SetPoint("CENTER")
                texture:SetSize(size, size)
                texture:Show()
                -- ✨ Add soft glow halo behind main texture
                if not glow.glowLayer then
                    glow.glowLayer = glow:CreateTexture(nil, "BACKGROUND")
                    glow.glowLayer:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
                    glow.glowLayer:SetBlendMode("ADD")
                    glow.glowLayer:SetPoint("CENTER")
                end

                glow.glowLayer:SetSize(size * 0.5, size * 0.5)

                -- 🎨 Match glow layer color to texture color
                local haloAlpha = math.min(0.4 * intensity, 1)
                glow.glowLayer:SetVertexColor(
                    math.min(glowColor.r * intensity, 1),
                    math.min(glowColor.g * intensity, 1),
                    math.min(glowColor.b * intensity, 1),
                    haloAlpha
                )
                glow.glowLayer:Show()



                -- 🧼 Cancel rainbow timer if disabled
                if not animationOptions.rainbowEnabled and EasyCursorTrails.rainbowTimers[texture] then
                    EasyCursorTrails.rainbowTimers[texture]:Cancel()
                    EasyCursorTrails.rainbowTimers[texture] = nil
                end

                -- 🌀 Rotation
                if modules.rotation then
                    modules.rotation(texture, glow, effectSettings, i, glowCount)
                end

                -- ✨ Twinkle
                if modules.twinkle then
                    modules.twinkle(texture, glow, effectSettings)
                end

                -- 🌊 Sweep
                if modules.sweep then
                    modules.sweep(texture, glow, effectSettings, i, glowCount)
                end

                -- 💫 Shimmer
                if modules.shimmer then
                    modules.shimmer(texture, glow, effectSettings)
                end

                -- 💓 Pulse
                if modules.pulse then
                    modules.pulse(texture, glow.animationGroup, effectSettings)
                end

                -- 🚀 Custom animation handler
                if handler then
                    handler(texture, glow.animationGroup, glowColor, fadedAlpha, intensity, i, texturePath, animationOptions)
                end
            end

            glow.animationGroup:SetLooping("REPEAT")
            glow.animationGroup:Play()
        else
           -- print(string.format("⚠️ Glow %d skipped → coord: %s, texture: %s", i, coord and "✓" or "✗", glow and glow.texture and "✓" or "✗"))
        end
    end

    -- 🔄 Full-pattern rotation (wheel-style)
    if modules.patternRotation then
        modules.patternRotation(EasyCursorTrails.rotationContainer, effectSettings)
    end

    
    -- 💫 Reset shimmer visuals if shimmer is disabled
    if not effectSettings.shimmerEnabled then
        for _, glow in ipairs(customCursor.glowEffects) do
            if glow and glow.texture then
                glow.texture:SetAlpha(clampedAlpha)
            end
            if glow and glow.SetScale then
                glow:SetScale(1)
            end
        end
    end

    -- 💫 Reset echo visuals if echo is disabled
    if not effectSettings.echoEnabled then
        for _, glow in ipairs(customCursor.glowEffects) do
            if glow and glow.texture then
                glow.texture:SetAlpha(clampedAlpha)
                glow:SetScale(1)
            end
            if glow.echoAnim then
                glow.echoAnim:Cancel()
                glow.echoAnim = nil
            end
        end
    end

    -- 🌌 Echo Relay (centralized dispatch)
    if modules.echoRelay then
        if customCursor.echoRelayTicker then
            customCursor.echoRelayTicker:Cancel()
            customCursor.echoRelayTicker = nil
        end

        if effectSettings.echoEnabled and #customCursor.glowEffects > 0 then
            modules.echoRelay(customCursor.glowEffects, effectSettings)
        end
    end

    
    -- 🔄 Full-pattern rotation (wheel-style)
    -- 🔄 Modular full-pattern rotation
    if modules.patternRotation then
        modules.patternRotation(EasyCursorTrails.rotationContainer, effectSettings)
    end

end


EasyCursorTrails.effectModules = {
 rotation = function(texture, glow, settings, index, total)
    local segmentedCW  = settings.clockwiseEnabled == true and settings.counterClockwiseEnabled ~= true
    local segmentedCCW = settings.counterClockwiseEnabled == true and settings.clockwiseEnabled ~= true
    local isSegmented  = segmentedCW or segmentedCCW
    local splitEnabled = settings.splitEffectEnabled == true

    -- 🧠 Determine speed
    local speed
    if splitEnabled then
        speed = tonumber(settings.rotationSpeed) or 30
    elseif isSegmented then
        speed = (segmentedCW and tonumber(settings.clockwiseSpeed)) or tonumber(settings.counterClockwiseSpeed) or 30
    else
        speed = tonumber(settings.rotationSpeed) or 30
    end

    local direction = isSegmented and 0 or (settings.clockwiseEnabled and 1 or (settings.counterClockwiseEnabled and -1 or 0))

    -- 🧼 Cancel previous timer
    if EasyCursorTrails.rotationTimers[texture] then
        EasyCursorTrails.rotationTimers[texture]:Cancel()
    end
-- 🔀 Split Rotation
        if splitEnabled and speed > 0 and texture and texture.SetAlpha then
            local trailLength = math.max(3, math.floor(total * 0.2))
            local activeAlpha = math.min(1, settings.clampedAlpha * 5.2) -- 20% brighter
            local dimAlpha    = settings.clampedAlpha * 0.1
            local interval    = math.max(0.01, 5 / (speed * 5.2)) -- 20% faster

            EasyCursorTrails.rotationTimers[texture] = C_Timer.NewTicker(interval, function()
                local time = GetTime()
                local phaseCW  = math.floor(time * speed) % total
                local phaseCCW = (total - phaseCW) % total

                local distCW  = (index - phaseCW + total) % total
                local distCCW = (index - phaseCCW + total) % total

                local alphaCW  = distCW <= trailLength and (activeAlpha - (distCW / trailLength) * (activeAlpha - dimAlpha)) or dimAlpha
                local alphaCCW = distCCW <= trailLength and (activeAlpha - (distCCW / trailLength) * (activeAlpha - dimAlpha)) or dimAlpha

                texture:SetAlpha(math.max(alphaCW, alphaCCW))
            end)
     

    -- 🔁 Segmented Rotation
    elseif isSegmented and speed > 0 then
        local trailLength = 10
        local activeAlpha = math.min(1, settings.clampedAlpha * 1.5)
        local dimAlpha    = settings.clampedAlpha * 0.1

        EasyCursorTrails.rotationTimers[texture] = C_Timer.NewTicker(1 / speed, function()
            local phase = math.floor(GetTime() * speed) % total
          
            local targetIndex = segmentedCW and (total - phase) or (phase + 1)


            local distance = (index - targetIndex + total) % total
            if distance == 0 then
                texture:SetAlpha(activeAlpha)
            elseif distance < trailLength then
                local fade = 1 - (distance / trailLength)
                texture:SetAlpha(settings.clampedAlpha * fade)
            else
                texture:SetAlpha(dimAlpha)
            end
        end)

    -- 🔄 Continuous Rotation
    elseif direction ~= 0 and speed > 0 then
        local angle = 0
        EasyCursorTrails.rotationTimers[texture] = C_Timer.NewTicker(0.016, function()
            angle = (angle + direction * speed * 0.016) % 360
            if texture and texture.SetRotation then
                texture:SetRotation(math.rad(angle))
            end
        end)

    -- 🧯 Fallback: static glow
    else
        EasyCursorTrails.rotationTimers[texture] = nil
        if texture.SetRotation then
            texture:SetRotation(0)
        end
        if texture and texture.SetAlpha then
            texture:SetAlpha(settings.clampedAlpha)
        end
    end
end,

patternRotation = function(container, settings)
    if EasyCursorTrails.rotationTicker then
        EasyCursorTrails.rotationTicker:Cancel()
        EasyCursorTrails.rotationTicker = nil
    end

    local rawSpeed = tonumber(settings.rotationSpeed) or 0
    if not settings.enableRotation or rawSpeed <= 0 then return end

    -- 🔁 Direction: CW if ≤ 50, CCW if ≥ 51
    local direction = rawSpeed <= 50 and 1 or -1

    -- 🎚 Speed curve:
    -- 0–50 → rawSpeed * 10
    -- 51–100 → (100 - rawSpeed) * 10
    local normalizedSpeed
    if rawSpeed <= 50 then
        normalizedSpeed = rawSpeed * 10
    else
        normalizedSpeed = (100 - rawSpeed) * 10
    end

    local angle = 0
    local coords = EasyCursorTrails.lastPatternCoords or {}
    local radiusScale = tonumber(settings.radiusScale) or 12
    local glows = customCursor.glowEffects or {}

    EasyCursorTrails.rotationTicker = C_Timer.NewTicker(0.016, function()
        angle = (angle + direction * normalizedSpeed * 0.016) % 360
        local radians = math.rad(angle)

        for i = 1, #glows do
            local glow = glows[i]
            local coord = coords[i]
            if glow and glow:IsShown() and coord then
                local x0 = coord.x * radiusScale
                local y0 = coord.y * radiusScale

                local x = x0 * math.cos(radians) - y0 * math.sin(radians)
                local y = x0 * math.sin(radians) + y0 * math.cos(radians)

                glow:ClearAllPoints()
                glow:SetPoint("CENTER", container, "CENTER", x, y)
            end
        end
    end)
end,




   twinkle = function(texture, glow, settings)
    local enabled = settings.twinkleEnabled
     local rawValue = tonumber(settings.twinkleSpeed or EasyCursorTrailsDB.twinkleSpeed) or 5

    local sliderValue = math.max(1, math.min(rawValue, 20))  -- Clamp to 1–10
    local alpha = tonumber(settings.clampedAlpha) or 1

    if enabled then
        EasyCursorTrails.twinkleTimers = EasyCursorTrails.twinkleTimers or {}

        if EasyCursorTrails.twinkleTimers[texture] then
            EasyCursorTrails.twinkleTimers[texture]:Cancel()
        end

        -- 🎚 Map slider value (1–10) to full cycle duration (4s to 0.8s)
        local cycleDuration = 4.0 - ((sliderValue - 1) * 0.35)  -- 4s → 0.8s
        local phaseOffset = math.random() * math.pi * 2

        EasyCursorTrails.twinkleTimers[texture] = C_Timer.NewTicker(0.05, function()
            if texture and texture.SetAlpha then
                local time = GetTime()
                local phase = (time % cycleDuration) / cycleDuration * math.pi * 2
                local pulse = 0.5 + 0.5 * math.sin(phase + phaseOffset)
                local twinkleAlpha = alpha * (0.2 + 0.8 * pulse)  -- Range: 20%–100%
                texture:SetAlpha(twinkleAlpha)
            end
        end)
    else
        if EasyCursorTrails.twinkleTimers and EasyCursorTrails.twinkleTimers[texture] then
            EasyCursorTrails.twinkleTimers[texture]:Cancel()
            EasyCursorTrails.twinkleTimers[texture] = nil
        end
        if texture and texture.SetAlpha then
            texture:SetAlpha(alpha)
        end
    end
end,


echoRelay = function(glowPool, settings)
    -- 🧼 Cancel previous ticker
    if customCursor.echoRelayTicker then
        customCursor.echoRelayTicker:Cancel()
        customCursor.echoRelayTicker = nil
    end

    -- 🧼 Reset all glows before starting
    for _, glow in ipairs(glowPool) do
        if glow.echoAnim then
            glow.echoAnim:Cancel()
            glow.echoAnim = nil
        end
        if glow.texture then
            glow.texture:SetAlpha(settings.clampedAlpha or 1)
            glow.texture:SetScale(1)
        end
    end

    -- 🧩 Divide glows into two sides
    local total = #glowPool
    local half = math.floor(total / 2)
    local sideA, sideB = {}, {}

    for i = 1, total do
        if i <= half then
            table.insert(sideA, glowPool[i])
        else
            table.insert(sideB, glowPool[i])
        end
    end

    -- ✨ Animate a glow
    local function animateGlow(glow)
        if not glow or not glow.texture then return end

        local texture = glow.texture
        local duration = tonumber(settings.echoDuration) or 0.6
        local scaleMax = tonumber(settings.echoScale) or 1.5
        local alpha    = tonumber(settings.clampedAlpha) or 1
        local elapsed  = 0

        if glow.echoAnim then
            glow.echoAnim:Cancel()
            glow.echoAnim = nil
        end

        texture:SetAlpha(alpha)
        texture:SetScale(1)
        texture:Show()

        glow.echoAnim = C_Timer.NewTicker(0.016, function()
            elapsed = elapsed + 0.016
            local progress = elapsed / duration
            if progress >= 1 then
                texture:SetAlpha(0)
                texture:SetScale(1)
                glow.echoAnim:Cancel()
                glow.echoAnim = nil
            else
                local fade  = math.pow(1 - progress, 2.5)
                local scale = 1 + math.pow(progress, 1.2) * scaleMax
                texture:SetAlpha(alpha * fade)
                texture:SetScale(scale)
            end
        end)
    end

    -- 🔁 Animate a group of glows
    local function animateGroup(group)
        local count = math.max(1, math.floor(#group * 0.2)) -- 20%
        for i = 1, count do
            local glow = group[math.random(#group)]
            animateGlow(glow)
        end
    end

    -- ⏱ Speed mapping: echoFrequency 10–100 → delay 2.0s to 0.2s
    local percent = math.max(10, math.min(100, tonumber(settings.echoFrequency) or 50))
    local normalizedSpeed = (percent - 10) / 9
    local delay = math.max(0.1, 2.0 - normalizedSpeed * 1.5)


    -- 🔁 Relay ticker
    local sideToggle = true
    customCursor.echoRelayTicker = C_Timer.NewTicker(delay, function()
        if sideToggle then
            animateGroup(sideA)
        else
            animateGroup(sideB)
        end
        sideToggle = not sideToggle
    end)
end,



   twinkle = function(texture, glow, settings)
    local enabled = settings.twinkleEnabled
     local rawValue = tonumber(settings.twinkleSpeed or EasyCursorTrailsDB.twinkleSpeed) or 5

    local sliderValue = math.max(1, math.min(rawValue, 20))  -- Clamp to 1–10
    local alpha = tonumber(settings.clampedAlpha) or 1

    if enabled then
        EasyCursorTrails.twinkleTimers = EasyCursorTrails.twinkleTimers or {}

        if EasyCursorTrails.twinkleTimers[texture] then
            EasyCursorTrails.twinkleTimers[texture]:Cancel()
        end

        -- 🎚 Map slider value (1–10) to full cycle duration (4s to 0.8s)
        local cycleDuration = 4.0 - ((sliderValue - 1) * 0.35)  -- 4s → 0.8s
        local phaseOffset = math.random() * math.pi * 2

        EasyCursorTrails.twinkleTimers[texture] = C_Timer.NewTicker(0.05, function()
            if texture and texture.SetAlpha then
                local time = GetTime()
                local phase = (time % cycleDuration) / cycleDuration * math.pi * 2
                local pulse = 0.5 + 0.5 * math.sin(phase + phaseOffset)
                local twinkleAlpha = alpha * (0.2 + 0.8 * pulse)  -- Range: 20%–100%
                texture:SetAlpha(twinkleAlpha)
            end
        end)
    else
        if EasyCursorTrails.twinkleTimers and EasyCursorTrails.twinkleTimers[texture] then
            EasyCursorTrails.twinkleTimers[texture]:Cancel()
            EasyCursorTrails.twinkleTimers[texture] = nil
        end
        if texture and texture.SetAlpha then
            texture:SetAlpha(alpha)
        end
    end
end,

shimmer = function(texture, glow, settings)
    local enabled   = settings.shimmerEnabled
    local frequency = tonumber(settings.shimmerFrequency) or 80 -- bumped default
    local alpha     = tonumber(settings.clampedAlpha) or 1

    -- 🧼 Always cancel previous shimmer ticker
    if EasyCursorTrails.shimmerTimers[texture] then
        EasyCursorTrails.shimmerTimers[texture]:Cancel()
        EasyCursorTrails.shimmerTimers[texture] = nil
    end

    -- ✨ Start shimmer if enabled and valid
    if enabled and frequency > 0 then
        EasyCursorTrails.shimmerTimers[texture] = C_Timer.NewTicker(1 / frequency, function()
            if texture and texture.SetAlpha then
                local burst = math.random(60, 160) / 100 -- wider range
                texture:SetAlpha(math.min(1, alpha * burst))
            end
            if glow and glow.SetScale then
                local scaleBurst = math.random(85, 120) / 100 -- stronger pulse
                glow:SetScale(scaleBurst)
            end
        end)
    else
        -- 🔧 Reset to default state
        if texture and texture.SetAlpha then
            texture:SetAlpha(alpha)
        end
        if glow and glow.SetScale then
            glow:SetScale(1)
        end
    end
end,



    sweep = function(texture, glow, settings, index, total)
        local enabled = settings.sweepEnabled
        local speed   = settings.sweepSpeed or 40
        if enabled and speed > 0 then
            if EasyCursorTrails.sweepTimers[texture] then
                EasyCursorTrails.sweepTimers[texture]:Cancel()
            end
            EasyCursorTrails.sweepTimers[texture] = C_Timer.NewTicker(1 / speed, function()
                if texture then
                    local phase = math.sin(GetTime() * speed + index)
                    local alpha = settings.clampedAlpha * (0.5 + 0.5 * phase)
                    texture:SetAlpha(alpha)
                end
            end)
        else
            if EasyCursorTrails.sweepTimers[texture] then
                EasyCursorTrails.sweepTimers[texture]:Cancel()
                EasyCursorTrails.sweepTimers[texture] = nil
            end
        end
    end
}



EasyCursorTrails.glowTextureOptions = {
    [1]  = { id = 1,  text = "Circular",         path = "Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64" },
    [2]  = { id = 2,  text = "Star",             path = "Interface\\Cooldown\\star4" },
    [3]  = { id = 3,  text = "Starburst",        path = "Interface\\Cooldown\\starburst" },
    [4]  = { id = 4,  text = "Box",              path = "Interface\\SpellActivationOverlay\\IconAlert" },
    [5]  = { id = 5,  text = "Arrow Shape",      path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Arrow.blp" },
    [6]  = { id = 6,  text = "BroomStick1",      path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\BroomStick1" },
    [7]  = { id = 7,  text = "Bullet1",          path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Military\\Bullet1" },
    [8]  = { id = 8,  text = "Circle White",     path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle_White" },
    [9]  = { id = 9,  text = "Circle4",          path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Circle4" },
    [10] = { id = 10, text = "Cross Shape",      path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Cross.blp" },
    [11] = { id = 11, text = "Diamond Crystal",  path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Diamond_Crystal" },
    [12] = { id = 12, text = "Diamond Left",     path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Diamond_Left" },
    [13] = { id = 13, text = "Diamond Shape",    path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Diamond.blp" },
    [14] = { id = 14, text = "Heart White",      path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Cursors\\Heart_White" },
    [15] = { id = 15, text = "Heart1",           path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Heart\\Heart1_Trail" },
    [16] = { id = 16, text = "Magic Ball Trail", path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Magic\\Magic_Ball_Trail.tga" },
    [17] = { id = 17, text = "Rain",             path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Nature\\Rain.tga" },
    [18] = { id = 18, text = "Seeds Circle",     path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Circle\\Seeds.tga" },
    [19] = { id = 19, text = "Star Shape",       path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Shapes\\Star.blp" },
    [20] = { id = 20, text = "Star1",            path = "Interface\\AddOns\\EasyCursorTrails\\Textures\\Trails\\Star\\Star1" },
}



------------------------------------------------------------
-- Glow Effect Dropdown Setup
------------------------------------------------------------
EasyCursorTrails.glowEffectOptions = {
    { id = 1,  text = "1 - Custom Effect", description = "Use a custom static color for the glow effect." },
    { id = 2,  text = "2 - Custom Color + Normal Pulse", description = "Apply a steady pulsing effect to the custom color." },
    { id = 3,  text = "3 - Rainbow Glow", description = "Create a dynamic animated rainbow glow effect." },
    { id = 4,  text = "4 - Flickering Glow", description = "Add a flickering fire-like effect." },
    { id = 5,  text = "5 - Strobing Glow", description = "Apply a strobing light effect." },
    { id = 6,  text = "6 - Trailing Glow", description = "Create a trailing light effect as the cursor moves." },
    { id = 7,  text = "7 - Vibrant Pulse", description = "Add a vibrant and dynamic pulsing glow." },
    { id = 8,  text = "8 - Disco Lights", description = "Create a randomized multicolor disco effect." },
    { id = 9,  text = "9 - Wave Effect", description = "Apply a wave-like motion to the glow." },
    { id = 10, text = "10 - Airport Lights", description = "Simulate trailing airport runway lights." },
    { id = 11, text = "11 - Pulsing (Clockwise)", description = "Pulse the glow effect in a clockwise direction." },
    { id = 12, text = "12 - Random Colors (Clockwise)", description = "Use random colors for a clockwise glow effect." },
    { id = 13, text = "13 - Pulsing (Anticlockwise)", description = "Pulse the glow effect in an anticlockwise direction." },
    { id = 14, text = "14 - Random Colors (Anticlockwise)", description = "Use random colors for an anticlockwise glow effect." },
    { id = 15, text = "15 - Fast Pulsing", description = "Apply a fast pulsing effect to the custom color." },
    { id = 16, text = "16 - Slow Pulsing", description = "Apply a slow pulsing effect to the custom color." },
    { id = 17, text = "17 - Stretch Segments", description = "Stretch and contract glow segments dynamically." },
    { id = 18, text = "18 - Burning Effect", description = "Simulate a burning fire effect for the glow." },
    { id = 19, text = "19 - Lightning Pulse", description = "Add a pulsing lightning effect to the custom color." },
    { id = 20, text = "20 - Tinker Bell Effect", description = "Create a whimsical, fairy-like effect." },
    { id = 21, text = "21 - Random Effect", description = "Select a random glow effect each time." },
    { id = 22, text = "22 - Random Sparkle Effect", description = "Random Sparkle Effect." },
    { id = 23, text = "23 - Starfall Glow", description = "Simulate falling stars with shimmering trails and twinkles." },
    { id = 24, text = "24 - Phoenix Flame", description = "Create a majestic, rising flame effect with glowing embers." },
    { id = 25, text = "25 - Aurora Veil", description = "Wrap the cursor in smooth, shifting aurora gradients." },
    { id = 26, text = "26 - Celestial Pulse", description = "Emit rhythmic pulses of light like a distant star beacon." },
    { id = 27, text = "27 - Nebula Drift", description = "Surround the cursor with drifting, colorful nebula clouds." },
    { id = 28, text = "28 - Rainbow Surge", description = "Cycle through vibrant rainbow hues with energetic motion." },
    { id = 29, text = "29 - Void Flicker", description = "Add subtle flickers of dark energy with occasional bursts." },
    { id = 30, text = "30 - Solar Flare", description = "Radiate intense golden light with flare bursts and heat shimmer." },
    { id = 31, text = "31 - Lunar Echo", description = "Trail soft moonlight with echoing glow pulses." },
    { id = 32, text = "32 - Starlight Cascade", description = "Cascade tiny star particles in a gentle waterfall motion." },
    { id = 33, text = "33 - Spinner Starlight", description = "Simulate a rotating glow like Blizzard's loading animation." },
}




function EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, total, color, alpha)
    local modules = EasyCursorTrails.effectModules

    -- 🌈 Rainbow or fallback color
    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    elseif color and alpha then
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    -- 🔁 Pulse
    if animationOptions.pulseEnabled then
        local speed = math.max(0.1, 1.0 - (animationOptions.pulseSpeed or 5) * 0.09)
        EasyCursorTrails.CreatePulsingAnimation(animationGroup, speed)
    end

    -- 🔄 Rotation
    if animationOptions.enableRotation then
        modules.rotation(texture, glow, animationOptions, index, total)
    end

    -- ✨ Shimmer
    if animationOptions.shimmerEnabled then
        modules.shimmer(texture, glow, animationOptions)
    end

    -- 🌟 Twinkle
    if animationOptions.twinkleEnabled then
        modules.twinkle(texture, glow, animationOptions)
    end

    -- 🧹 Sweep
    if animationOptions.sweepEnabled then
        modules.sweep(texture, glow, animationOptions, index, total)
    end

    -- 🔥 Flicker
    if animationOptions.flickerEnabled then
        EasyCursorTrails.ApplyFlickerEffect(texture, animationGroup, color, alpha, animationOptions.flickerIntensity or 1)
    end

    -- 💡 Strobe
    if animationOptions.strobeEnabled then
        EasyCursorTrails.ApplyStrobeEffect(texture, animationGroup, color, alpha)
    end

    -- 🧵 Trailing
    if animationOptions.trailingEnabled then
        EasyCursorTrails.ApplyTrailingGlow(texture, animationGroup, color, alpha)
    end

    -- ✨ Sparkle
    if animationOptions.sparkleEnabled then
        EasyCursorTrails.ApplySparkleEffect(texture, animationGroup)
    end

    -- 📏 Stretch
    if animationOptions.stretchEnabled then
        EasyCursorTrails.ApplyStretchEffect(texture, animationGroup, color, alpha, animationOptions.stretchIntensity or 1, index)
    end

    -- 🔥 Burning
    if animationOptions.burningEnabled then
        EasyCursorTrails.ApplyBurningEffect(texture, animationGroup, color, alpha)
    end

    -- ⚡ Lightning
    if animationOptions.lightningEnabled then
        EasyCursorTrails.ApplyLightningPulse(texture, animationGroup, color, alpha)
    end

    -- 🧚 Fairy Trail
    if animationOptions.fairyTrailEnabled then
        EasyCursorTrails.ApplyFairyTrail(texture, animationGroup)
    end

    -- 🌠 Starfall
    if animationOptions.starfallEnabled then
        EasyCursorTrails.ApplyStarfallEffect(texture, animationGroup)
    end

    -- 🔥 Phoenix Flame
    if animationOptions.phoenixEnabled then
        EasyCursorTrails.ApplyPhoenixFlame(texture, animationGroup)
    end

    -- 🌌 Aurora Gradient
    if animationOptions.auroraEnabled then
        EasyCursorTrails.ApplyAuroraGradient(texture, animationGroup)
    end

    -- 🌟 Celestial Pulse
    if animationOptions.celestialEnabled then
        EasyCursorTrails.ApplyCelestialPulse(texture, animationGroup)
    end

    -- ☁️ Nebula Drift
    if animationOptions.nebulaEnabled then
        EasyCursorTrails.ApplyNebulaDrift(texture, animationGroup)
    end

    -- 🌈 Rainbow Surge
    if animationOptions.rainbowSurgeEnabled then
        EasyCursorTrails.ApplyRainbowSurge(texture, animationGroup)
    end

    -- 🌑 Void Flicker
    if animationOptions.voidFlickerEnabled then
        EasyCursorTrails.ApplyVoidFlicker(texture, animationGroup)
    end

    -- ☀️ Solar Flare
    if animationOptions.solarFlareEnabled then
        EasyCursorTrails.ApplySolarFlare(texture, animationGroup)
    end

    -- 🌙 Lunar Echo
    if animationOptions.lunarEchoEnabled then
        EasyCursorTrails.ApplyLunarEcho(texture, animationGroup)
    end

    -- 🌧️ Starlight Cascade
    if animationOptions.starlightCascadeEnabled then
        EasyCursorTrails.ApplyStarlightCascade(texture, animationGroup)
    end

    -- 🔄 Spinner Starlight
    if animationOptions.spinnerStarlightEnabled then
        EasyCursorTrails.ApplySpinnerStarlight(texture, animationGroup)
    end
end





EasyCursorTrails.effectHandlers = {
    -- 🛠️ 1. Custom Color (with optional pulse/rainbow)
    [1] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
        texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
        texture:SetBlendMode("ADD")

        -- 🎨 Boosted glow color
        texture:SetVertexColor(
            math.min((color.r or 1) * intensity * 1.5, 1),
            math.min((color.g or 1) * intensity * 1.5, 1),
            math.min((color.b or 1) * intensity * 1.5, 1),
            math.min(alpha or 1, 1)
        )
        texture:SetAlpha(math.min(alpha or 1, 1))

        -- 🌈 Rainbow cycle
        if animationOptions.rainbowEnabled then
            EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
        end

        -- 💓 Pulse animation
        if animationOptions.pulseEnabled then
            local speed = math.max(0.1, 1.0 - (animationOptions.pulseSpeed or 5) * 0.09)
            EasyCursorTrails.CreatePulsingAnimation(animationGroup, speed)
        end
    end,


[2] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r, color.g, color.b, alpha)

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    end

    if animationOptions.pulseEnabled then
        local speed = math.max(0.1, 1.0 - (animationOptions.pulseSpeed or 5) * 0.09)
        EasyCursorTrails.CreatePulsingAnimation(animationGroup, speed)
    end

    local glow = customCursor.glowEffects[index]
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects, color, alpha)
end,


[3] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")
    texture:SetAlpha(math.max(0.05, (alpha or 1) * (intensity or 1)))

    -- Apply static color first
    texture:SetVertexColor(color.r, color.g, color.b, alpha)

    -- Apply rainbow after a short delay
    if animationOptions.rainbowEnabled then
        C_Timer.After(0.01, function()
            EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
        end)
    end

    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects, color, alpha)
end,



[4] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    -- Apply flicker to this segment only
    EasyCursorTrails.ApplyFlickerEffect(texture, animationGroup, color, alpha, intensity)

    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects, color, alpha)
end,


[5] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyStrobeEffect(texture, animationGroup, color, alpha)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[6] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyTrailingGlow(texture, animationGroup, color, alpha)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[7] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    -- Boost color intensity
    local vibrantColor = {
        r = math.min(1, color.r * 1.5),
        g = math.min(1, color.g * 1.5),
        b = math.min(1, color.b * 1.5),
    }

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(vibrantColor.r, vibrantColor.g, vibrantColor.b, alpha)
    end

    -- Apply fast pulse
    EasyCursorTrails.CreatePulsingAnimation(animationGroup, 0.1)

    -- Optional shimmer for vibrancy
    if animationOptions.shimmerEnabled ~= false then
        EasyCursorTrails.effectModules.shimmer(texture, glow, animationOptions)
    end

    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects, vibrantColor, alpha)
end,


[8] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyDiscoEffect(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[9] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyWaveEffect(texture, animationGroup, color, alpha, intensity, index)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[10] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyRunwayEffect(texture, animationGroup, color, alpha, intensity, index)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[11] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texturePath = texturePath or "Interface\\Cooldown\\star4"
    texture:SetTexture(texturePath)
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyDirectionalPulse(texture, animationGroup, color, alpha, intensity, index, texturePath, true)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[12] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyRandomColorCycle(texture, animationGroup, true)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[13] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyDirectionalPulse(texture, animationGroup, color, alpha, intensity, index, texturePath, false)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[14] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyRandomColorCycle(texture, animationGroup, false)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[15] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.CreatePulsingAnimation(animationGroup, 0.1)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[16] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.CreatePulsingAnimation(animationGroup, 0.9)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[17] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyStretchEffect(texture, animationGroup, color, alpha, intensity, index)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[18] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyBurningEffect(texture, animationGroup, color, alpha)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[19] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyLightningPulse(texture, animationGroup, color, alpha)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[20] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyFairyTrail(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[21] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    local randomID = math.random(1, 20)
    local handler = EasyCursorTrails.effectHandlers[randomID]
    if handler then
        handler(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    end
end,

[22] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplySparkleEffect(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[23] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyStarfallEffect(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[24] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyPhoenixFlame(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[25] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyAuroraGradient(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[26] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyCelestialPulse(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[27] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyNebulaDrift(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[28] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyRainbowSurge(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[29] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyVoidFlicker(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[30] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplySolarFlare(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[31] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyLunarEcho(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[32] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplyStarlightCascade(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,

[33] = function(texture, animationGroup, color, alpha, intensity, index, texturePath, animationOptions)
    local glow = customCursor.glowEffects[index]
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    if animationOptions.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, animationOptions.rainbowSpeed or 5)
    else
        texture:SetVertexColor(color.r, color.g, color.b, alpha)
    end

    EasyCursorTrails.ApplySpinnerStarlight(texture, animationGroup)
    EasyCursorTrails.ApplyOptionalEffects(texture, animationGroup, glow, animationOptions, index, #customCursor.glowEffects)
end,


}

function EasyCursorTrails.ApplyDiscoEffect(texture, animationGroup)
    if not texture or not animationGroup then return end

    animationGroup:Stop()

    -- 💃 Color pulse: randomized vibrant hues
    local colorPulse = animationGroup:CreateAnimation("Alpha")
    colorPulse:SetDuration(0.1)
    colorPulse:SetFromAlpha(math.random(0.4, 0.8))
    colorPulse:SetToAlpha(math.random(0.8, 1.0))
    colorPulse:SetOrder(1)

    -- 🔄 Scale bounce
    local scale = animationGroup:CreateAnimation("Scale")
    scale:SetDuration(0.15)
    scale:SetScale(1 + math.random() * 0.3, 1 + math.random() * 0.3)
    scale:SetOrder(2)

    -- 🌀 Optional rotation for extra funk
    local rotate = animationGroup:CreateAnimation("Rotation")
    rotate:SetDuration(0.2)
    rotate:SetDegrees(math.random(-45, 45))
    rotate:SetOrder(3)

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

    -- 🌈 Randomize color every cycle
    local function discoColorCycle()
        local hue = math.random()
        local r, g, b = EasyCursorTrails.HSVtoRGB(hue, 1, 1)
        texture:SetVertexColor(r, g, b, texture:GetAlpha())

        C_Timer.After(0.15, discoColorCycle)
    end

    discoColorCycle()
end


function EasyCursorTrails.ApplyStrobeEffect(texture, animationGroup, color, alpha)
    if not texture or not animationGroup then return end

    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    local strobe = animationGroup:CreateAnimation("Alpha")
    strobe:SetDuration(0.1)
    strobe:SetFromAlpha(1)
    strobe:SetToAlpha(0.2)
    strobe:SetOrder(1)

    local restore = animationGroup:CreateAnimation("Alpha")
    restore:SetDuration(0.1)
    restore:SetFromAlpha(0.2)
    restore:SetToAlpha(1)
    restore:SetOrder(2)

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

function EasyCursorTrails.ApplyFairyTrail(texture, animationGroup)
    if not texture or not animationGroup then return end

    -- ✨ Random sparkle pulse
    local sparkle = animationGroup:CreateAnimation("Alpha")
    sparkle:SetDuration(0.3)
    sparkle:SetFromAlpha(0.2)
    sparkle:SetToAlpha(1)
    sparkle:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.3)
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0.2)
    fade:SetOrder(2)

    -- 🌟 Random scale twinkle
    local twinkle = animationGroup:CreateAnimation("Scale")
    twinkle:SetDuration(0.6)
    twinkle:SetScale(1.2, 1.2)
    twinkle:SetOrder(3)

    -- 🌀 Optional rotation shimmer
    local spin = animationGroup:CreateAnimation("Rotation")
    spin:SetDuration(1.2)
    spin:SetDegrees(math.random(-45, 45))
    spin:SetOrder(4)

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


function EasyCursorTrails.ApplySpinnerStarlight(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)

    -- 🌀 Continuous rotation
    local spin = animationGroup:CreateAnimation("Rotation")
    spin:SetDuration(1.5)
    spin:SetDegrees(360)
    spin:SetOrder(1)

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

function EasyCursorTrails.ApplyStretchEffect(texture, animationGroup, color, alpha, intensity, index)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🫁 Stretch outward
    local stretchOut = animationGroup:CreateAnimation("Scale")
    stretchOut:SetDuration(0.4)
    stretchOut:SetScale(1.3, 1.3)
    stretchOut:SetOrder(1)

    -- 🫀 Contract inward
    local stretchIn = animationGroup:CreateAnimation("Scale")
    stretchIn:SetDuration(0.4)
    stretchIn:SetScale(1.0, 1.0)
    stretchIn:SetOrder(2)

    -- 🌊 Optional offset for staggered timing
    local delay = (index % 5) * 0.05
    stretchOut:SetStartDelay(delay)
    stretchIn:SetStartDelay(delay)

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

function EasyCursorTrails.ApplyLightningPulse(texture, animationGroup, color, alpha)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- ⚡ Sudden flash
    local flash = animationGroup:CreateAnimation("Alpha")
    flash:SetDuration(0.1)
    flash:SetFromAlpha(0.2)
    flash:SetToAlpha(1)
    flash:SetOrder(1)

    -- ⚡ Quick fade
    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.1)
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0.2)
    fade:SetOrder(2)

    -- ⚡ Jitter scale
    local jitter = animationGroup:CreateAnimation("Scale")
    jitter:SetDuration(0.2)
    jitter:SetScale(1.1, 1.1)
    jitter:SetOrder(3)

    -- ⚡ Optional rotation burst
    local burst = animationGroup:CreateAnimation("Rotation")
    burst:SetDuration(0.2)
    burst:SetDegrees(math.random(-30, 30))
    burst:SetOrder(4)

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

function EasyCursorTrails.ApplyAuroraGradient(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)

    -- 🌈 Gradient shimmer via color cycling
    local gradientColors = {
        { r = 0.4, g = 0.8, b = 1 },
        { r = 0.6, g = 1.0, b = 0.8 },
        { r = 0.9, g = 0.6, b = 1 },
        { r = 0.7, g = 0.9, b = 1 },
    }

    local index = 1
    local function cycleColor()
        local c = gradientColors[index]
        texture:SetVertexColor(c.r, c.g, c.b, 1)
        index = (index % #gradientColors) + 1
    end

    -- 🕒 Start color cycle ticker
    animationGroup.auroraTicker = C_Timer.NewTicker(0.6, cycleColor)

    -- 🌫️ Gentle pulsing alpha
    local pulseOut = animationGroup:CreateAnimation("Alpha")
    pulseOut:SetDuration(1.2)
    pulseOut:SetFromAlpha(0.6)
    pulseOut:SetToAlpha(1)
    pulseOut:SetOrder(1)

    local pulseIn = animationGroup:CreateAnimation("Alpha")
    pulseIn:SetDuration(1.2)
    pulseIn:SetFromAlpha(1)
    pulseIn:SetToAlpha(0.6)
    pulseIn:SetOrder(2)

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


function EasyCursorTrails.ApplySparkleEffect(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)

    -- ✨ Random sparkle pulse
    local sparkle = animationGroup:CreateAnimation("Alpha")
    sparkle:SetDuration(0.2)
    sparkle:SetFromAlpha(0.2)
    sparkle:SetToAlpha(1)
    sparkle:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.2)
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0.2)
    fade:SetOrder(2)

    -- 🌟 Twinkle scale
    local twinkle = animationGroup:CreateAnimation("Scale")
    twinkle:SetDuration(0.4)
    twinkle:SetScale(1.3, 1.3)
    twinkle:SetOrder(3)

    -- 🕒 Random delay for sparkle timing
    local delay = math.random(0, 20) * 0.05
    sparkle:SetStartDelay(delay)
    fade:SetStartDelay(delay)
    twinkle:SetStartDelay(delay)

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

function EasyCursorTrails.ApplyTrailingGlow(texture, animationGroup, color, alpha)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🧭 Fade in
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(0.3)
    fadeIn:SetFromAlpha(0.2)
    fadeIn:SetToAlpha(alpha or 1)
    fadeIn:SetOrder(1)

    -- 🧭 Fade out
    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(0.3)
    fadeOut:SetFromAlpha(alpha or 1)
    fadeOut:SetToAlpha(0.2)
    fadeOut:SetOrder(2)

    -- 🌀 Optional trailing scale
    local stretch = animationGroup:CreateAnimation("Scale")
    stretch:SetDuration(0.6)
    stretch:SetScale(1.2, 1.0)
    stretch:SetOrder(3)

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



function EasyCursorTrails.ApplyWaveEffect(texture, animationGroup, color, alpha, intensity, index)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🌊 Vertical wave motion
    local wave = animationGroup:CreateAnimation("Translation")
    wave:SetDuration(1.2)
    wave:SetOffset(0, math.sin(index) * 6)
    wave:SetSmoothing("IN_OUT")
    wave:SetOrder(1)

    -- 🌫️ Optional alpha pulse
    local pulse = animationGroup:CreateAnimation("Alpha")
    pulse:SetDuration(1.2)
    pulse:SetFromAlpha(0.4)
    pulse:SetToAlpha(alpha or 1)
    pulse:SetOrder(2)

    -- 🕒 Staggered delay for ripple effect
    local delay = (index % 5) * 0.1
    wave:SetStartDelay(delay)
    pulse:SetStartDelay(delay)

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


function EasyCursorTrails.ApplyRunwayEffect(texture, animationGroup, color, alpha, intensity, index)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🛫 Sequential pulse
    local pulse = animationGroup:CreateAnimation("Alpha")
    pulse:SetDuration(0.3)
    pulse:SetFromAlpha(0.2)
    pulse:SetToAlpha(alpha or 1)
    pulse:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.3)
    fade:SetFromAlpha(alpha or 1)
    fade:SetToAlpha(0.2)
    fade:SetOrder(2)

    -- 🕒 Staggered delay based on index
    local delay = (index % 10) * 0.1
    pulse:SetStartDelay(delay)
    fade:SetStartDelay(delay)

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

function EasyCursorTrails.ApplyBurningEffect(texture, animationGroup, color, alpha, intensity, index, separationFactor)
    if not texture or not animationGroup then return end

    index = index or 1
    separationFactor = separationFactor or 0

    local safeIntensity = tonumber(intensity) or 1
    local safeAlpha = tonumber(alpha) or 1
    local fadedAlpha = math.max(0.1, safeAlpha * safeIntensity)

    texture:SetBlendMode("ADD")
    texture:SetAlpha(fadedAlpha)
    texture:Show()

    animationGroup:Stop()

    -- 🔥 Fire color blend: orange, yellow, white
    local fireColors = {
        { r = 1.0, g = 0.5, b = 0.1 },   -- deep orange
        { r = 1.0, g = 0.85, b = 0.2 },  -- bright yellow
        { r = 1.0, g = 1.0, b = 0.9 },   -- white-hot
    }

    local function blendFireColor()
        local base = fireColors[math.random(1, #fireColors)]
        local r = math.min(1, base.r * safeIntensity)
        local g = math.min(1, base.g * safeIntensity)
        local b = math.min(1, base.b * safeIntensity)
        texture:SetVertexColor(r, g, b, texture:GetAlpha())
        C_Timer.After(0.12 + math.random() * 0.1, blendFireColor)
    end

    blendFireColor()

    -- 🔥 Outward burst direction from ring center
    local angle = separationFactor * 2 * math.pi
    local chaos = (math.random() - 0.5) * 0.4 -- ±0.2 radians
    local flameAngle = angle + chaos

    local directionX = math.cos(flameAngle)
    local directionY = math.sin(flameAngle)

    -- 🔥 Snappy burst motion
    local drift = animationGroup:CreateAnimation("Translation")
    drift:SetDuration(0.2 + math.random() * 0.15)
    drift:SetOffset(directionX * math.random(3, 6), directionY * math.random(3, 6))
    drift:SetSmoothing("NONE") -- raw flame snap
    drift:SetOrder(1)

    -- 🔥 Heat shimmer (scale spike)
    local scale = animationGroup:CreateAnimation("Scale")
    scale:SetDuration(0.25)
    scale:SetScale(1.2 + math.random() * 0.3, 1.2 + math.random() * 0.3)
    scale:SetOrder(2)

    -- 🔥 Chaotic flicker
    local flicker = animationGroup:CreateAnimation("Alpha")
    flicker:SetDuration(0.15)
    flicker:SetFromAlpha(0.2)
    flicker:SetToAlpha(1.0)
    flicker:SetOrder(3)

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




function EasyCursorTrails.ApplyStarfallEffect(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌠 Falling motion
    local fall = animationGroup:CreateAnimation("Translation")
    fall:SetDuration(1.2)
    fall:SetOffset(0, -10)
    fall:SetSmoothing("IN_OUT")
    fall:SetOrder(1)

    -- ✨ Fade in
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(0.6)
    fadeIn:SetFromAlpha(0.2)
    fadeIn:SetToAlpha(1)
    fadeIn:SetOrder(2)

    -- ✨ Fade out
    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(0.6)
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0.2)
    fadeOut:SetOrder(3)

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

function EasyCursorTrails.ApplyPhoenixFlame(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🔥 Radiant burst (scale pulse)
    local burst = animationGroup:CreateAnimation("Scale")
    burst:SetDuration(0.4)
    burst:SetScale(1.3, 1.3)
    burst:SetOrder(1)
    burst:SetSmoothing("OUT")

    local shrink = animationGroup:CreateAnimation("Scale")
    shrink:SetDuration(0.4)
    shrink:SetScale(1.0, 1.0)
    shrink:SetOrder(2)
    shrink:SetSmoothing("IN")

    -- 🔥 Flame flicker (alpha pulse)
    local flicker = animationGroup:CreateAnimation("Alpha")
    flicker:SetDuration(0.2)
    flicker:SetFromAlpha(0.4)
    flicker:SetToAlpha(1)
    flicker:SetOrder(3)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.2)
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0.4)
    fade:SetOrder(4)

    -- 🔥 Ember drift (vertical motion)
    local drift = animationGroup:CreateAnimation("Translation")
    drift:SetDuration(0.6)
    drift:SetOffset(0, math.random(3, 6))
    drift:SetSmoothing("IN_OUT")
    drift:SetOrder(5)

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

function EasyCursorTrails.ApplyCelestialPulse(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌠 Gentle pulse (scale)
    local expand = animationGroup:CreateAnimation("Scale")
    expand:SetDuration(0.6)
    expand:SetScale(1.2, 1.2)
    expand:SetSmoothing("OUT")
    expand:SetOrder(1)

    local contract = animationGroup:CreateAnimation("Scale")
    contract:SetDuration(0.6)
    contract:SetScale(1.0, 1.0)
    contract:SetSmoothing("IN")
    contract:SetOrder(2)

    -- ✨ Soft glow fade
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(0.6)
    fadeIn:SetFromAlpha(0.3)
    fadeIn:SetToAlpha(1)
    fadeIn:SetOrder(3)

    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(0.6)
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0.3)
    fadeOut:SetOrder(4)

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

function EasyCursorTrails.ApplyNebulaDrift(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌫️ Gentle horizontal drift
    local drift = animationGroup:CreateAnimation("Translation")
    drift:SetDuration(2.4)
    drift:SetOffset(math.random(-6, 6), math.random(-2, 2))
    drift:SetSmoothing("IN_OUT")
    drift:SetOrder(1)

    -- 🌌 Soft alpha breathing
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(1.2)
    fadeIn:SetFromAlpha(0.3)
    fadeIn:SetToAlpha(0.8)
    fadeIn:SetOrder(2)

    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(1.2)
    fadeOut:SetFromAlpha(0.8)
    fadeOut:SetToAlpha(0.3)
    fadeOut:SetOrder(3)

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

function EasyCursorTrails.ApplyRainbowSurge(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌈 Define rainbow palette
    local rainbowColors = {
        { r = 1, g = 0, b = 0 },     -- Red
        { r = 1, g = 0.5, b = 0 },   -- Orange
        { r = 1, g = 1, b = 0 },     -- Yellow
        { r = 0, g = 1, b = 0 },     -- Green
        { r = 0, g = 0, b = 1 },     -- Blue
        { r = 0.5, g = 0, b = 1 },   -- Indigo
        { r = 1, g = 0, b = 1 },     -- Violet
    }

    local current = 1
    local function surge()
        local c = rainbowColors[current]
        texture:SetVertexColor(c.r, c.g, c.b, 1)
        current = current % #rainbowColors + 1
    end

    -- 🔁 Start color surge ticker
    animationGroup.rainbowTicker = C_Timer.NewTicker(0.25, surge)

    -- ⚡ Add pulse motion
    local pulse = animationGroup:CreateAnimation("Scale")
    pulse:SetDuration(0.25)
    pulse:SetScale(1.2, 1.2)
    pulse:SetOrder(1)

    local settle = animationGroup:CreateAnimation("Scale")
    settle:SetDuration(0.25)
    settle:SetScale(1.0, 1.0)
    settle:SetOrder(2)

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

function EasyCursorTrails.ApplyVoidFlicker(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🕳️ Erratic flicker (alpha)
    local flickerOut = animationGroup:CreateAnimation("Alpha")
    flickerOut:SetDuration(0.15)
    flickerOut:SetFromAlpha(0.8)
    flickerOut:SetToAlpha(0.2)
    flickerOut:SetOrder(1)

    local flickerIn = animationGroup:CreateAnimation("Alpha")
    flickerIn:SetDuration(0.15)
    flickerIn:SetFromAlpha(0.2)
    flickerIn:SetToAlpha(0.8)
    flickerIn:SetOrder(2)

    -- 🌌 Dimensional pulse (scale)
    local pulseExpand = animationGroup:CreateAnimation("Scale")
    pulseExpand:SetDuration(0.3)
    pulseExpand:SetScale(1.1, 1.1)
    pulseExpand:SetOrder(3)

    local pulseContract = animationGroup:CreateAnimation("Scale")
    pulseContract:SetDuration(0.3)
    pulseContract:SetScale(1.0, 1.0)
    pulseContract:SetOrder(4)

    -- 🌀 Optional rotation for instability
    local spin = animationGroup:CreateAnimation("Rotation")
    spin:SetDuration(1.2)
    spin:SetDegrees(math.random(-180, 180))
    spin:SetOrder(5)

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


function EasyCursorTrails.ApplySolarFlare(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- ☀️ Radiant burst (scale)
    local burst = animationGroup:CreateAnimation("Scale")
    burst:SetDuration(0.3)
    burst:SetScale(1.4, 1.4)
    burst:SetSmoothing("OUT")
    burst:SetOrder(1)

    local settle = animationGroup:CreateAnimation("Scale")
    settle:SetDuration(0.3)
    settle:SetScale(1.0, 1.0)
    settle:SetSmoothing("IN")
    settle:SetOrder(2)

    -- 🔥 Heat shimmer (alpha pulse)
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(0.2)
    fadeIn:SetFromAlpha(0.5)
    fadeIn:SetToAlpha(1)
    fadeIn:SetOrder(3)

    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(0.2)
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0.5)
    fadeOut:SetOrder(4)

    -- 🌪️ Optional flare drift
    local drift = animationGroup:CreateAnimation("Translation")
    drift:SetDuration(0.6)
    drift:SetOffset(math.random(-4, 4), math.random(-2, 2))
    drift:SetSmoothing("IN_OUT")
    drift:SetOrder(5)

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

function EasyCursorTrails.ApplyLunarEcho(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌙 Echo pulse (scale)
    local expand = animationGroup:CreateAnimation("Scale")
    expand:SetDuration(0.8)
    expand:SetScale(1.15, 1.15)
    expand:SetSmoothing("OUT")
    expand:SetOrder(1)

    local contract = animationGroup:CreateAnimation("Scale")
    contract:SetDuration(0.8)
    contract:SetScale(1.0, 1.0)
    contract:SetSmoothing("IN")
    contract:SetOrder(2)

    -- 🌫️ Soft fade
    local fadeIn = animationGroup:CreateAnimation("Alpha")
    fadeIn:SetDuration(0.8)
    fadeIn:SetFromAlpha(0.4)
    fadeIn:SetToAlpha(0.9)
    fadeIn:SetOrder(3)

    local fadeOut = animationGroup:CreateAnimation("Alpha")
    fadeOut:SetDuration(0.8)
    fadeOut:SetFromAlpha(0.9)
    fadeOut:SetToAlpha(0.4)
    fadeOut:SetOrder(4)

    -- 🌌 Gentle drift
    local drift = animationGroup:CreateAnimation("Translation")
    drift:SetDuration(1.6)
    drift:SetOffset(math.random(-2, 2), math.random(-2, 2))
    drift:SetSmoothing("IN_OUT")
    drift:SetOrder(5)

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


function EasyCursorTrails.ApplyStarlightCascade(texture, animationGroup)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)
    texture:Show()

    -- 🌟 Vertical cascade motion
    local fall = animationGroup:CreateAnimation("Translation")
    fall:SetDuration(1.6)
    fall:SetOffset(0, -12)
    fall:SetSmoothing("IN_OUT")
    fall:SetOrder(1)

    -- ✨ Gentle shimmer pulse
    local pulse = animationGroup:CreateAnimation("Alpha")
    pulse:SetDuration(0.8)
    pulse:SetFromAlpha(0.3)
    pulse:SetToAlpha(0.9)
    pulse:SetOrder(2)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.8)
    fade:SetFromAlpha(0.9)
    fade:SetToAlpha(0.3)
    fade:SetOrder(3)

    -- 🌌 Optional scale ripple
    local ripple = animationGroup:CreateAnimation("Scale")
    ripple:SetDuration(1.2)
    ripple:SetScale(1.1, 1.1)
    ripple:SetOrder(4)

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



function EasyCursorTrails.ApplyRunwayEffect(texture, animationGroup, color, alpha, intensity, index, texturePath)
    if not texture or not animationGroup then return end

    local safeAlpha = tonumber(alpha) or 1
    local fadedAlpha = math.max(0.05, safeAlpha * (intensity or 1))

    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r * intensity, color.g * intensity, color.b * intensity, fadedAlpha)
    texture:SetAlpha(fadedAlpha)
    texture:Show()

    -- 🛫 Sequential pulse
    local pulse = animationGroup:CreateAnimation("Alpha")
    pulse:SetDuration(0.3)
    pulse:SetFromAlpha(0.2)
    pulse:SetToAlpha(fadedAlpha)
    pulse:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.3)
    fade:SetFromAlpha(fadedAlpha)
    fade:SetToAlpha(0.2)
    fade:SetOrder(2)

    -- 🕒 Staggered delay based on index
    local delay = (index % 10) * 0.1
    pulse:SetStartDelay(delay)
    fade:SetStartDelay(delay)

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


function EasyCursorTrails.ApplyDirectionalPulse(texture, animationGroup, color, alpha, intensity, index, texturePath, clockwise)
    if not texture or not animationGroup then return end

    -- 🧼 Defensive fallback values
    local safeAlpha = tonumber(alpha) or 1
    local safeIntensity = tonumber(intensity) or 1
    local fadedAlpha = math.max(0.05, safeAlpha * safeIntensity)

    -- 🎨 Texture setup
    local resolvedTexturePath = texturePath or "Interface\\Cooldown\\star4"
    texture:SetTexture(resolvedTexturePath)
    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r * safeIntensity, color.g * safeIntensity, color.b * safeIntensity, fadedAlpha)
    texture:SetAlpha(fadedAlpha)
    texture:ClearAllPoints()
    texture:SetPoint("CENTER")
    texture:SetSize(32, 32) -- Ensure non-zero size
    texture:Show()

    -- 💓 Pulse animation
    local pulseOut = animationGroup:CreateAnimation("Alpha")
    pulseOut:SetDuration(0.3)
    pulseOut:SetFromAlpha(0.3)
    pulseOut:SetToAlpha(fadedAlpha)
    pulseOut:SetOrder(1)

    local pulseIn = animationGroup:CreateAnimation("Alpha")
    pulseIn:SetDuration(0.3)
    pulseIn:SetFromAlpha(fadedAlpha)
    pulseIn:SetToAlpha(0.3)
    pulseIn:SetOrder(2)

    -- 🌀 Directional rotation
    local rotation = animationGroup:CreateAnimation("Rotation")
    rotation:SetDuration(1.2)
    rotation:SetDegrees(clockwise and 360 or -360)
    rotation:SetOrder(3)

    -- 🕒 Staggered delay for ripple effect
    local delay = (index % 6) * 0.1
    pulseOut:SetStartDelay(delay)
    pulseIn:SetStartDelay(delay)
    rotation:SetStartDelay(delay)

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

function EasyCursorTrails.ApplyRandomColorCycle(texture, animationGroup, useAlpha)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetAlpha(1)

    -- 🎨 Define a palette of vibrant colors
    local palette = {
        { r = 1, g = 0.3, b = 0.3 },   -- Red
        { r = 0.3, g = 1, b = 0.3 },   -- Green
        { r = 0.3, g = 0.3, b = 1 },   -- Blue
        { r = 1, g = 1, b = 0.3 },     -- Yellow
        { r = 1, g = 0.3, b = 1 },     -- Magenta
        { r = 0.3, g = 1, b = 1 },     -- Cyan
        { r = 1, g = 1, b = 1 },       -- White
    }

    local function cycleColor()
        local color = palette[math.random(1, #palette)]
        texture:SetVertexColor(color.r, color.g, color.b, useAlpha and 0.8 or 1)
    end

    -- 🔁 Start ticker to cycle colors every 0.4s
    animationGroup.randomColorTicker = C_Timer.NewTicker(0.4, cycleColor)

    -- 💫 Optional shimmer pulse
    local pulse = animationGroup:CreateAnimation("Alpha")
    pulse:SetDuration(0.4)
    pulse:SetFromAlpha(0.4)
    pulse:SetToAlpha(1)
    pulse:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.4)
    fade:SetFromAlpha(1)
    fade:SetToAlpha(0.4)
    fade:SetOrder(2)

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

function EasyCursorTrails.ApplyFlickerEffect(texture, animationGroup, color, alpha, intensity)
    if not texture or not animationGroup then return end

    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🔥 Flicker pulse: fast alpha changes
    local flicker = animationGroup:CreateAnimation("Alpha")
    flicker:SetDuration(0.1)
    flicker:SetFromAlpha(math.random(0.2, 0.6))
    flicker:SetToAlpha(math.random(0.6, 1.0))
    flicker:SetOrder(1)

    local fade = animationGroup:CreateAnimation("Alpha")
    fade:SetDuration(0.1)
    fade:SetFromAlpha(math.random(0.6, 1.0))
    fade:SetToAlpha(math.random(0.2, 0.6))
    fade:SetOrder(2)

    -- 🔁 Optional scale jitter
    local scale = animationGroup:CreateAnimation("Scale")
    scale:SetDuration(0.2)
    scale:SetScale(1 + math.random() * 0.2, 1 + math.random() * 0.2)
    scale:SetOrder(3)

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



function EasyCursorTrails.CreateStaticGlow(texture, animationGroup, color, alpha, texturePath, opts)
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")
    texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)

    -- 🌈 Rainbow
    if opts.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, opts.rainbowSpeed or 5)
    else
        if EasyCursorTrails.rainbowTimers and EasyCursorTrails.rainbowTimers[texture] then
            EasyCursorTrails.rainbowTimers[texture]:Cancel()
            EasyCursorTrails.rainbowTimers[texture] = nil
        end
        texture:SetVertexColor(color.r or 1, color.g or 1, color.b or 1, alpha or 1)
    end

    -- 🔘 Pulse
    if opts.pulseEnabled then
        local speed = math.max(0.1, 1.0 - (opts.pulseSpeed or 5) * 0.09)
        EasyCursorTrails.CreatePulsingAnimation(animationGroup, speed)
    else
        -- 🛑 Force-stop pulse animation
        animationGroup:Stop()
        for _, anim in ipairs({ animationGroup:GetAnimations() }) do
            if anim and anim.Stop then anim:Stop() end
        end
    end
end

function EasyCursorTrails.CreatePulsingGlow(texture, animationGroup, color, alpha, intensity, texturePath, opts)
    if not texture or not animationGroup then return end
    opts = opts or {}

    -- 🎨 Texture and blending
    texture:SetTexture(texturePath or "Interface\\Cooldown\\star4")
    texture:SetBlendMode("ADD")

    -- 🌈 Color and alpha
    local r = color and color.r or 1
    local g = color and color.g or 1
    local b = color and color.b or 1
    local a = alpha or 1
    local scaledAlpha = math.max(0.05, a * (intensity or 1))
    texture:SetVertexColor(r, g, b, scaledAlpha)

    -- 💓 Pulse
    if opts.pulseEnabled then
        local speed = math.max(0.1, 1.0 - (opts.pulseSpeed or 5) * 0.09)
        EasyCursorTrails.CreatePulsingAnimation(animationGroup, speed)
    end

    -- 🌈 Rainbow
    if opts.rainbowEnabled then
        EasyCursorTrails.ApplyRainbowCycle(texture, opts.rainbowSpeed or 5)
    end

    -- 🔄 Rotation
    if opts.enableRotation then
        EasyCursorTrails.ApplyRotation(texture, opts.rotationSpeed or 10)
    end

    -- ✨ Shimmer
    if opts.shimmerEnabled then
        EasyCursorTrails.ApplyShimmerEffect(texture, opts.shimmerAlphaMin or 0.2, opts.shimmerAlphaMax or 1.0)
    end

    -- 🔀 Chaos Rotation
    if opts.rotationChaosEnabled then
        EasyCursorTrails.ApplyRotationChaos(texture, opts.rotationChaosSpeed or 6)
    end

    -- 🔁 Flicker
    if opts.flickerEnabled then
        EasyCursorTrails.ApplyFlickerEffect(texture, animationGroup, color, scaledAlpha, intensity)
    end

    -- 🌊 Wave
    if opts.waveEnabled then
        EasyCursorTrails.ApplyWaveEffect(texture, animationGroup, color, scaledAlpha, intensity, opts.waveIndex or 1)
    end

    -- 🛫 Runway
    if opts.runwayEnabled then
        EasyCursorTrails.ApplyRunwayEffect(texture, animationGroup, color, scaledAlpha, intensity, opts.runwayIndex or 1)
    end

    -- 🌬️ Drift
    if opts.driftEnabled then
        EasyCursorTrails.ApplyDriftEffect(texture, opts.driftX or 0, opts.driftY or 0, opts.driftSpeed or 1)
    end

    -- 🔥 Flare
    if opts.flareEnabled then
        EasyCursorTrails.ApplyFlareEffect(texture, opts.flareScale or 1.0)
    end

    -- 🌟 Twinkle
    if opts.twinkleEnabled then
        EasyCursorTrails.ApplyTwinkleEffect(texture, opts.twinkleSpeed or 1.0)
    end

    -- 🎉 Disco
    if opts.discoEnabled then
        EasyCursorTrails.ApplyDiscoEffect(texture, animationGroup)
    end
end

function EasyCursorTrails.CreatePulsingAnimation(group, duration)
    if not group then return end
    group:Stop()

    -- 🧼 Clear existing animations safely
    for _, anim in ipairs(group:GetAnimations() or {}) do
        if anim.Stop then anim:Stop() end
    end

    -- 🌀 Reuse or create fadeOut
    local fadeOut = group.fadeOut
    if not fadeOut or fadeOut:GetAnimationType() ~= "Alpha" then
        fadeOut = group:CreateAnimation("Alpha")
        group.fadeOut = fadeOut
    end
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0.3)
    fadeOut:SetDuration(duration)
    fadeOut:SetSmoothing("IN_OUT")
    fadeOut:SetOrder(1)

    -- 🌀 Reuse or create fadeIn
    local fadeIn = group.fadeIn
    if not fadeIn or fadeIn:GetAnimationType() ~= "Alpha" then
        fadeIn = group:CreateAnimation("Alpha")
        group.fadeIn = fadeIn
    end
    fadeIn:SetFromAlpha(0.3)
    fadeIn:SetToAlpha(1)
    fadeIn:SetDuration(duration)
    fadeIn:SetSmoothing("IN_OUT")
    fadeIn:SetOrder(2)

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



EasyCursorTrails.rainbowTimers = EasyCursorTrails.rainbowTimers or {}

function EasyCursorTrails.ApplyRainbowCycle(texture, speed)
    if not texture then return end
    local hue = math.random()
    local r, g, b = EasyCursorTrails.HSVtoRGB(hue, 1, 1)
    texture:SetVertexColor(r, g, b, texture:GetAlpha())

    -- Cancel previous timer if any
    if EasyCursorTrails.rainbowTimers[texture] then
        EasyCursorTrails.rainbowTimers[texture]:Cancel()
    end

    local interval = math.max(0.05, 1.0 - (speed or 5) * 0.09)
    local timer = C_Timer.NewTimer(interval, function()
        EasyCursorTrails.ApplyRainbowCycle(texture, speed)
    end)

    EasyCursorTrails.rainbowTimers[texture] = timer
end


function EasyCursorTrails.HSVtoRGB(h, s, v)
    local i = math.floor(h * 6)
    local f = h * 6 - i
    local p = v * (1 - s)
    local q = v * (1 - f * s)
    local t = v * (1 - (1 - f) * s)

    i = i % 6
    if i == 0 then return v, t, p
    elseif i == 1 then return q, v, p
    elseif i == 2 then return p, v, t
    elseif i == 3 then return p, q, v
    elseif i == 4 then return t, p, v
    else return v, p, q end
end




function EasyCursorTrails.InitializeGlowFrames()
    local currentProfileName = EasyCursorTrailsDB.currentProfile or "Default"
    local currentProfile = EasyCursorTrailsDB.profiles[currentProfileName]
    if not currentProfile then
        currentProfile = EasyCursorTrailsDB.profiles["Default"]
        if not currentProfile then return end
    end

    if not customCursor or not customCursor.texture then return end

    customCursor.glowEffects = customCursor.glowEffects or {}
    for _, glow in ipairs(customCursor.glowEffects) do
        glow:Hide()
        glow:ClearAllPoints()
        glow:SetParent(nil)
    end
    customCursor.glowEffects = {}

    local glowCount     = math.max(1, math.min(tonumber(currentProfile.patternGlowCount) or EasyCursorTrails.defaults.patternGlowCount or 30, 40))
    local cursorWidth   = customCursor:GetWidth() or 64
    local glowSize      = tonumber(currentProfile.glowSize) or EasyCursorTrails.defaults.glowSize or 1
    local glowIntensity = math.max(0, math.min(1, currentProfile.glowIntensity or EasyCursorTrails.defaults.glowIntensity or 1))

    for i = 1, glowCount do
        local glow = CreateFrame("Frame", nil, customCursor, "BackdropTemplate")
        glow:SetSize(cursorWidth * glowSize, cursorWidth * glowSize)
        glow:SetFrameStrata("HIGH")
        glow:SetFrameLevel(customCursor:GetFrameLevel() + 3)

        glow.texture = glow:CreateTexture(nil, "OVERLAY")
        glow.texture:SetAllPoints(true)
        glow.texture:SetBlendMode("ADD")
        glow.texture:SetTexture("Interface\\GLUES\\MODELS\\UI_Draenei\\GenericGlow64")
        glow.texture:SetVertexColor(1, 1, 1, 1) -- full alpha
   


        glow:Hide()
        table.insert(customCursor.glowEffects, glow)
    end
end



function EasyCursorTrails.UpdateGlowFrames()
    if not customCursor or not customCursor.texture then return end

    local defaults = EasyCursorTrails.defaults
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile] or {}

    local cursorWidth     = customCursor:GetWidth() or 64
    local glowRadius      = tonumber(profile.glowRadius) or defaults.glowRadius
    local glowSize        = tonumber(profile.glowSize) or defaults.glowSize
    local alpha           = profile.glowIntensity or defaults.glowIntensity
    local enableRotation  = profile.enableRotation == true

    local splitLayout     = profile.splitLayoutEnabled == true
    local splitEffect     = profile.splitEffectEnabled == true
    local splitHeight     = tonumber(profile.splitLayoutHeight) or 50

    local glowCount = math.max(1, math.min(tonumber(EasyCursorTrailsDB.patternGlowCount) or defaults.patternGlowCount, 40))

    customCursor.glowEffects = customCursor.glowEffects or {}
    local currentGlows = #customCursor.glowEffects

    -- 🔁 Resize glow pool
    if currentGlows > glowCount then
        for i = currentGlows, glowCount + 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 < glowCount then
        for i = currentGlows + 1, glowCount 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

    -- 🧠 Pattern resolution
    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 coords = patternFunction and patternFunction(glowCount) or nil

    -- 🎯 Position and style glows
    for i, glow in ipairs(customCursor.glowEffects) do
        glow:ClearAllPoints()

        if splitLayout then
            local half = math.floor(glowCount / 2)
            local isLeft = i <= half
            local index = isLeft and i or (i - half)
            local xOffset = (isLeft and -1 or 1) * cursorWidth * 0.3
            local yOffset = (index / half) * cursorWidth * (splitHeight / 100)
            glow:SetPoint("CENTER", customCursor, "CENTER", xOffset, yOffset)
        elseif coords and coords[i] 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:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
        else
            local angle = math.rad((i - 1) * (360 / glowCount))
            local offsetDist = cursorRadius * glowRadius
            local offsetX = offsetDist * math.cos(angle)
            local offsetY = offsetDist * math.sin(angle)
            glow:SetPoint("CENTER", customCursor, "CENTER", offsetX, offsetY)
        end

        glow:SetSize(cursorWidth * glowSize, cursorWidth * glowSize)
    

        -- 🔄 Reset rotation if disabled (safe for split effect)
        if not enableRotation and glow.texture.SetRotation then
            glow.texture:SetRotation(0)
        end

        glow:Show()
    end

    -- 🚀 Reapply animations
    if EasyCursorTrails.ApplySelectedGlowEffect then
        EasyCursorTrails.ApplySelectedGlowEffect()
    end
end

function EasyCursorTrails.InitializeCustomCursor()
    -- 1️⃣ Retrieve current profile
    local profileName = EasyCursorTrailsDB.currentProfile or "Default"
    local currentProfile = EasyCursorTrailsDB.profiles[profileName]

    if not currentProfile then
        currentProfile = CopyTable(EasyCursorTrails.defaults)
        EasyCursorTrailsDB.profiles[profileName] = currentProfile
    end
    EasyCursorTrails.currentProfileTable = currentProfile

    -- 2️⃣ Create cursor frame if needed
    if not customCursor then
        customCursor = CreateFrame("Frame", "EasyCursorCustomCursor", UIParent, "BackdropTemplate")
        customCursor:SetPoint("CENTER", UIParent, "CENTER")
        customCursor:EnableMouse(false)
    end

    -- 3️⃣ Apply frame strata and size
    customCursor:SetFrameStrata(currentProfile.cursorFrameStrata or "MEDIUM")
    local rawSize = tonumber(currentProfile.cursorSize) or EasyCursorTrails.defaults.cursorSize or 32
    local cursorSize = math.max(8, math.min(rawSize, 256))
    customCursor:SetSize(cursorSize, cursorSize)

    -- 4️⃣ Create texture if missing
    if not customCursor.texture then
        customCursor.texture = customCursor:CreateTexture(nil, "OVERLAY")
        customCursor.texture:SetAllPoints(true)
        customCursor.texture:SetBlendMode("ADD")
    end

    -- 5️⃣ Load cursor texture data
    local cursorIndex = currentProfile.cursorTexture or 1
    local cursorData  = EasyCursorTrails.customCursorTextures[cursorIndex]

    local function extractFilename(path)
        local filename = path:match("([^/\\]+)$") or ""
        return filename:gsub("%.tga", ""):gsub("%.blp", "")
    end

    if not cursorData then
        currentProfile.selectedCursorTextureName = "Default"
        customCursor.texture:SetTexture("Interface\\CURSOR\\Arrow")

        customCursor:SetScript("OnUpdate", function(_, elapsed)
            local color = currentProfile.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
            if EasyCursorTrailsDB.pulseEnabled then
                EasyCursorTrails.ApplyPulsingEffect(color, elapsed)
            else
                customCursor.texture:SetVertexColor(color.r, color.g, color.b, color.a)
            end
        end)
    else
        -- 🧠 Extract texture name
        if cursorData.texture then
            currentProfile.selectedCursorTextureName = extractFilename(cursorData.texture)
        elseif cursorData.textures and #cursorData.textures > 0 then
            currentProfile.selectedCursorTextureName = extractFilename(cursorData.textures[1])
        else
            currentProfile.selectedCursorTextureName = "Unknown"
        end

        -- 🔁 Cursor update logic
        local function updateCursor(_, elapsed)
            if type(elapsed) ~= "number" then
                -- print("⚠️ updateCursor: 'elapsed' is not a number:", type(elapsed))
                return
            end

            -- 🎞️ Animate texture
            if cursorData.animated and cursorData.textures and customCursor.texture then
                customCursor.elapsedTime = (customCursor.elapsedTime or 0) + elapsed
                local totalFrames = #cursorData.textures
                local duration = cursorData.animationDuration or 1
                local frameIndex = math.floor((customCursor.elapsedTime % duration) / duration * totalFrames) + 1
                local texturePath = cursorData.textures[frameIndex] or "Interface\\CURSOR\\Arrow"
                customCursor.texture:SetTexture(texturePath)
            end

            -- 🎨 Apply color or pulse
            local color = currentProfile.cursorColor or { r = 1, g = 1, b = 1, a = 1 }
            if EasyCursorTrailsDB.pulseEnabled then
                EasyCursorTrails.ApplyPulsingEffect(color, elapsed)
            elseif customCursor.texture then
                customCursor.texture:SetVertexColor(color.r, color.g, color.b, color.a)
            end
        end

        -- 🖼️ Set initial texture
        customCursor.texture:SetTexture(cursorData.texture or (cursorData.textures and cursorData.textures[1]) or "Interface\\CURSOR\\Arrow")
        customCursor:SetScript("OnUpdate", updateCursor)
    end

    -- 6️⃣ Initialize and apply glow effects
    EasyCursorTrails.InitializeGlowFrames()
    EasyCursorTrails.UpdateGlowFrames()
    EasyCursorTrails.ApplySelectedGlowEffect()

    -- 7️⃣ Ensure trail pool exists
    EasyCursorTrails.trailPool = EasyCursorTrails.trailPool or {}

    -- 8️⃣ Show the cursor
    customCursor:Show()
end


---------------------------------------------------------
-- UpdateCustomCursorPosition:
---------------------------------------------------------
-- This is the function that repositions your custom cursor overlay based on the system cursor.
function EasyCursorTrails.UpdateCustomCursorPosition()
    if not customCursor then
        return
    end

    -- Retrieve the active profile or fall back to "Default"
    local cp = EasyCursorTrailsDB.currentProfile or "Default"
    local profile = EasyCursorTrailsDB.profiles[cp] or EasyCursorTrailsDB.profiles["Default"]
    if not profile then
        return
    end

    -- Obtain user-defined offsets (if any)
    local xOffset = profile.cursorOffsetX or 0
    local yOffset = profile.cursorOffsetY or 0

    -- Get the system cursor’s position.
    local x, y = GetCursorPosition()
    
    -- Adjust the coordinates for UI scaling.
    local scale = UIParent:GetEffectiveScale()
    local computedX = (x / scale) + xOffset
    local computedY = (y / scale) + yOffset

    -- Immediately reposition the custom cursor overlay.
    customCursor:ClearAllPoints()
    customCursor:SetPoint("CENTER", UIParent, "BOTTOMLEFT", computedX, computedY)
    customCursor:Show()
end

---------------------------------------------------------
-- High-Frequency Custom Cursor Update:
-- We use C_Timer.NewTicker to update the custom cursor position
-- at a very high frequency (every 0.005 seconds, ~200 Hz).
-- This is our best effort to keep the overlay in sync with the system cursor.
---------------------------------------------------------
if C_Timer then
    if not EasyCursorTrails.CustomCursorTicker then
        EasyCursorTrails.CustomCursorTicker = C_Timer.NewTicker(0.001, function()
            EasyCursorTrails.UpdateCustomCursorPosition()
  
        end)
    end
else
    -- If C_Timer is unavailable, fall back to an OnUpdate handler.
    if not EasyCursorTrails.CustomCursorFrameUpdater then
        local updateFrame = CreateFrame("Frame", "EasyCursorTrailsCursorUpdater", UIParent)
        updateFrame:SetAllPoints(UIParent)
        updateFrame:SetFrameStrata("TOOLTIP")
        updateFrame:SetFrameLevel(100)
        updateFrame:SetScript("OnUpdate", function(self, elapsed)
            EasyCursorTrails.UpdateCustomCursorPosition()
          end)
        EasyCursorTrails.CustomCursorFrameUpdater = updateFrame
    end
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 EasyCursorTrails.StartTrailShadowTicker()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableTrailShadows or not profile.enableTrails then return end

    -- 🟣 Rebuild shadow frames
    EasyCursorTrails.RefreshAllTrailShadows()

    -- 🛑 Cancel existing ticker
    if EasyCursorTrails.shadowEffectTicker then
        EasyCursorTrails.shadowEffectTicker:Cancel()
    end

    -- 🔁 Start new ticker
    EasyCursorTrails.shadowEffectTicker = C_Timer.NewTicker(0.1, function()
        for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(pool) do
                local shadow = trail.shadowFrame
                if trail:IsVisible() and trail.texture and trail.texture:GetAlpha() > 0.01 then
                    EasyCursorTrails.SpawnTrailShadow(trail)
                    if shadow and shadow.glowTex then
                        shadow:Show()
                        shadow.glowTex:SetAlpha(0.25)
                    end
                elseif shadow and shadow.glowTex then
                    shadow:Hide()
                    shadow.glowTex:SetAlpha(0)
                end
            end
        end
    end)
end

function EasyCursorTrails.StopTrailShadowTicker()
    if EasyCursorTrails.shadowEffectTicker then
        EasyCursorTrails.shadowEffectTicker:Cancel()
        EasyCursorTrails.shadowEffectTicker = nil
    end

    -- 🧼 Hide and detach shadow frames
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            local shadow = trail.shadowFrame
            if shadow then
                shadow:Hide()
                shadow:SetParent(nil)
                trail.shadowFrame = nil
            end
        end
    end
end


function EasyCursorTrails.ClearAllTrailShadows()
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            local shadow = trail.shadowFrame
            if shadow then
                shadow:Hide()
                shadow:SetParent(nil)
                trail.shadowFrame = nil
                trail:SetScript("OnUpdate", nil)
            end
        end
    end
end



function EasyCursorTrails.RefreshTrailShadows()
    EasyCursorTrails.ClearAllTrailShadows()
    for _, pool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(pool) do
            if not trail.shadowFrame then
                EasyCursorTrails.SpawnTrailShadow(trail)
            end
        end
    end
end

function EasyCursorTrails.ClearAllEffects(trail)
    if not trail then return end

    local effectFields = {
        "twinkleSpark", "staticArc", "lightningEmber", "lightningSpark",
        "emberGlow", "starGlow", "starEmber", "starDust",
        "smoke", "smokeTrail", "fireGlow", "fireTrail",
        "springLeaf", "springTrail", "ember", "shadowEmitter"
    }

    for _, key in ipairs(effectFields) do
        local effect = trail[key]
        if effect then
            if effect.ag and type(effect.ag.Stop) == "function" then
                effect.ag:Stop()
            end
            if effect.texture then
                effect.texture:Hide()
                if effect.texture.SetTexture then effect.texture:SetTexture(nil) end
                effect.texture:SetParent(nil)
            end
            if effect.Hide then effect:Hide() end
            if effect.SetTexture then effect:SetTexture(nil) end
            if effect.SetParent then effect:SetParent(nil) end
            trail[key] = nil
        end
    end

    -- 🍃 Nature Embers (tracked individually)
    if trail.natureEmbers then
        for _, ember in ipairs(trail.natureEmbers) do
            if ember.ag and type(ember.ag.Stop) == "function" then
                ember.ag:Stop()
            end
            ember:Hide()
            ember:SetParent(nil)
        end
        trail.natureEmbers = nil
    end

    -- 🌠 Glow Layers
    if trail.glowLayers then
        for _, g in ipairs(trail.glowLayers) do
            if g.texture then
                g.texture:Hide()
                g.texture:SetTexture(nil)
                g.texture:SetParent(nil)
            end
            g:Hide()
            g:SetParent(nil)
        end
        trail.glowLayers = nil
    end

    -- 🎨 Trail Texture
    if trail.texture then
        trail.texture:Hide()
        trail.texture:SetVertexColor(1, 1, 1, (EasyCursorTrails.currentProfileTable and EasyCursorTrails.currentProfileTable.trailIntensity) or 0.5)
    end
end


function EasyCursorTrails.ValidateSettings(profile)
    local defaults = EasyCursorTrails.defaults
    local rules = {
        { key = "trailSizeStart", min = 1, max = 200 },
        { key = "trailSizeEnd", min = 1, max = 200 },
        { key = "trailCount", min = 1, max = 200 },
        { key = "trailSpacing", min = 1, max = 50 },
        { key = "trailIntensity", min = 0.1, max = 1.0 },
        { key = "glowIntensityFactor", min = 0.0, max = 1.0 },
        { key = "chainSegment", min = 1, max = 100 },
        { key = "trailLayerCount", min = 1, max = 20 },
    }

    for _, r in ipairs(rules) do
        local v = profile[r.key]
        if type(v) ~= "number" or v < r.min or v > r.max then
            profile[r.key] = defaults[r.key]
        end
    end

    if type(profile.enableTrails) ~= "boolean" then
        profile.enableTrails = defaults.enableTrails
    end

    profile.trailLayerCount = math.floor(profile.trailLayerCount)
    profile.trailSpacing = profile.chainSegment or defaults.chainSegment or 10
end


function EasyCursorTrails.ClearTrailPool()
    if not EasyCursorTrails.trailPool then return end

    for _, layer in pairs(EasyCursorTrails.trailPool) do
        for _, trail in ipairs(layer) do
            if trail and trail ~= EasyCursorTrails.TrailPreview then
                EasyCursorTrails.CleanupTrail(trail)
            end
        end
    end

    EasyCursorTrails.trailPool = {}
end


function EasyCursorTrails.CreateTrailPool(profile)
    local texIdx = profile.trailTexture or 1
    local trailTex = (EasyCursorTrails.trailTextures[texIdx] and EasyCursorTrails.trailTextures[texIdx].texture)
                     or "Interface\\CURSOR\\Arrow"

    for layer = 1, profile.trailLayerCount do
        EasyCursorTrails.trailPool[layer] = {}
        for i = 1, profile.trailCount do
            local size = profile.trailSizeStart + ((profile.trailSizeEnd - profile.trailSizeStart) * ((i - 1) / (profile.trailCount - 1)))
            local trail = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
            trail:SetSize(size, size)
            trail:SetFrameStrata(profile.trailFrameStrata or "TOOLTIP")

            local tex = trail:CreateTexture(nil, "BACKGROUND")
            tex:SetAllPoints()
            tex:SetTexture(trailTex)
            tex:SetVertexColor(1, 1, 1, profile.trailIntensity or 0.5)
            trail.texture = tex

            if i == 1 then
                local x, y = GetCursorPosition()
                trail:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x, y)
            else
                trail:SetPoint("CENTER", EasyCursorTrails.trailPool[layer][i - 1], "CENTER", profile.trailSpacing, 0)
            end

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


function EasyCursorTrails.PauseActiveEffects()
    EasyCursorTrails._pausedEffects = {}

    for effectFlag, tickerPair in pairs(EasyCursorTrails.effectTickerRegistry or {}) do
        if type(tickerPair.stop) == "function" then
            tickerPair.stop()
            EasyCursorTrails._pausedEffects[effectFlag] = true
        end
    end

    -- Hide pooled visuals
    for _, effectPool in pairs(EasyCursorTrails.effectPools or {}) do
        for _, effect in ipairs(effectPool) do
            if effect.Hide then effect:Hide() end
            effect.active = false
        end
    end
end

local resumeEffectsTimer

function EasyCursorTrails.ResumePausedEffects(delay)
    delay = delay or 0.15

    if resumeEffectsTimer then
        resumeEffectsTimer:Cancel()
    end

    resumeEffectsTimer = C_Timer.NewTimer(delay, function()
        local paused = EasyCursorTrails._pausedEffects
        if not paused then return end

        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile then return end

        for effectFlag, wasPaused in pairs(paused) do
            local flagEnabled = profile[effectFlag]
            local tickerPair = EasyCursorTrails.effectTickerRegistry and EasyCursorTrails.effectTickerRegistry[effectFlag]
            if wasPaused and flagEnabled and tickerPair and type(tickerPair.start) == "function" then
                tickerPair.start()
            end
        end

        EasyCursorTrails._pausedEffects = nil
    end)
end


function EasyCursorTrails.ApplyEnabledEffects(trail)
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or profile.enableTrailEffects == false then return end

    local live = EasyCursorTrails.liveEffects or {}
    local registry = EasyCursorTrails.effectApplyRegistry or {}

    for effectFlag, applyFunc in pairs(registry) do
        if live[effectFlag] and type(applyFunc) == "function" then
            applyFunc(trail)
        end
    end
end


EasyCursorTrails.effectTickerRegistry = {
    enableEmbers = {
        start = EasyCursorTrails.StartEmberTicker,
        stop  = EasyCursorTrails.StopEmberTicker,
    },
    enableFire = {
        start = EasyCursorTrails.StartFireTicker,
        stop  = EasyCursorTrails.StopFireTicker,
    },
    enableLightningEmbers = {
        start = EasyCursorTrails.StartLightningEmberTicker,
        stop  = EasyCursorTrails.StopLightningEmberTicker,
    },
    enableLightningSparks = {
        start = EasyCursorTrails.StartLightningSparkEffect,
        stop  = EasyCursorTrails.StopLightningSparkEffect,
    },
    enableSmokeEffect = {
        start = EasyCursorTrails.StartSmokeTicker,
        stop  = EasyCursorTrails.StopSmokeTicker,
    },
    enableSmokeEffectTrails = {
        start = EasyCursorTrails.StartSmokeTrailTicker,
        stop  = EasyCursorTrails.StopSmokeTrailTicker,
    },

    enableSpringSeasonTrails = {
        start = EasyCursorTrails.StartNatureTicker,
        stop  = EasyCursorTrails.StopNatureTicker,
    },
    enableStarDust = {
        start = EasyCursorTrails.StarDustTicker,
        stop  = EasyCursorTrails.StopDustTicker,
    },
    enableStarEmbers = {
        start = EasyCursorTrails.StartStarEmberTicker,
        stop  = EasyCursorTrails.StopStarEmberTicker,
    },
    enableStaticArc = {
        start = EasyCursorTrails.StartStaticArcTicker,
        stop  = EasyCursorTrails.StopStaticArcTicker,
    },
    enableTrailShadows = {
        start = EasyCursorTrails.StartTrailShadowTicker,
        stop  = EasyCursorTrails.StopTrailShadowTicker,
    },
    enableTwinkleStars = {
        start = EasyCursorTrails.StartTwinkleStarsTicker,
        stop  = EasyCursorTrails.StopTwinkleStarsTicker,
    },
}





-- 🧪 Registry Validator
function EasyCursorTrails.ValidateEffectRegistry()
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[EasyCursorTrailsDB.currentProfile]
    for effectFlag, _ in pairs(EasyCursorTrails.effectTickerRegistry) do
        if profile and profile[effectFlag] ~= nil then
           ----print("✅ Found:", effectFlag, "=", tostring(profile[effectFlag]))
        else
         --   --print("⛔ Missing or nil:", effectFlag)
        end
    end
end



EasyCursorTrails.effectApplyRegistry = {
    enableStaticArc = function(trail, index)
        if not trail or not trail:IsVisible() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableStaticArc then return end
        local color = profile.staticArcColor or { r = 0.8, g = 0.8, b = 1.0, a = 0.6 }
        EasyCursorTrails.ApplyStaticArcEffect(trail, index, color)
    end,

    enableEmbers = function(trail)
        if not trail or not trail:IsVisible() or trail:GetAlpha() < 0.1 then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableEmbers then return end
        EasyCursorTrails.SpawnEmberEffect(trail)
    end,

    enableFire = function(trail)
        if not trail or not trail:IsVisible() then return end
        if not EasyCursorTrails.IsFireEnabled() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile then return end
        local color = profile.randomFireColor and EasyCursorTrails.GetRandomVibrantColor()
                   or profile.fireColor or { r = 1, g = 0.5, b = 0.1, a = 0.8 }
        EasyCursorTrails.SpawnFireGlow(trail, color)
    end,

    enableLightningSparks = function(trail)
        if not trail or not trail:IsVisible() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableLightningSparks then return end
        EasyCursorTrails.ApplyLightningSparkEffect(trail)
    end,

    enableSpringSeason = function(trail)
        if not trail or not trail:IsVisible() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableSpringSeason then return end
        local trailX, trailY = trail:GetCenter()
        if not trailX or not trailY then return end
        local baseScale = trail:GetWidth() or 15
        EasyCursorTrails.SpawnNatureEmbers(baseScale, trailX, trailY, 0, 0)
    end,

    enableSmokeEffect = function(trail)
        if not trail or not trail:IsVisible() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableSmokeEffect then return end
        EasyCursorTrails.SpawnSmokeTrail(trail)
    end,

    enableStarEmbers = function(trail)
        if not trail or not trail:IsVisible() then return end
        local profile = EasyCursorTrails.GetCurrentProfile()
        if not profile or not profile.enableStarEmbers then return end
        EasyCursorTrails.SpawnSparkles(trail)
    end,
}



-- 📦 Profile Accessor
function EasyCursorTrails.GetCurrentProfile()
    local name = EasyCursorTrails.currentProfileName or "Default"
    local profile = EasyCursorTrails.currentProfileTable or EasyCursorTrailsDB.profiles[name]
    if not profile then
        --EasyCursorTrails.HandleError"RebuildTrails: '" .. name .. "' profile is missing or invalid.")
        return nil
    end
    EasyCursorTrails.currentProfileName = name
    EasyCursorTrails.currentProfileTable = profile
    return profile
end


function EasyCursorTrails.SyncEffectUI(profile)
    if type(profile) ~= "table" then return end

    local effects = {
        { flag = "enableEmbers",               pickerKey = "emberColorPicker",              colorKey = "emberColor" },
        { flag = "enableFire",                 pickerKey = "fireColorPicker",               colorKey = "fireColor" },
        { flag = "enableLightningEmbers",      pickerKey = "lightningEmberColorPicker",     colorKey = "lightningEmberColor" },
        { flag = "enableLightningSparks",      pickerKey = "lightningSparkColorPicker",     colorKey = "lightningSparkColor" },
        { flag = "enableSmokeEffect",          pickerKey = "smokeColorPicker",              colorKey = "smokeColor" },
        { flag = "enableSmokeEffectTrails",    pickerKey = "smokeTrailColorPicker",         colorKey = "smokeTrailColor" },
        { flag = "enableSpringSeason",         pickerKey = "springSeasonColorPicker",       colorKey = "springSeasonColor" },
        { flag = "enableSpringSeasonTrails",   pickerKey = "springSeasonTrailColorPicker",  colorKey = "springSeasonTrailColor" },
        { flag = "enableStarDust",             pickerKey = "starDustColorPicker",           colorKey = "starDustColor" },
        { flag = "enableStarEmbers",           pickerKey = "starEmbersColorPicker",         colorKey = "starColor" },
        { flag = "enableStaticArc",            pickerKey = "staticArcColorPicker",          colorKey = "staticArcColor" },
        { flag = "enableTwinkleStars",         pickerKey = "twinkleStarsColorPicker",       colorKey = "twinkleStarsColor" },
    }

    for _, e in ipairs(effects) do
        if profile[e.flag] then
            local picker = EasyCursorTrails[e.pickerKey]
            local color = profile[e.colorKey]
            if picker and type(color) == "table" then
                local r = color.r or 1
                local g = color.g or 1
                local b = color.b or 1
                local a = color.a or 1

                if picker.SetColorRGBA then
                    picker:SetColorRGBA(r, g, b, a)
                elseif picker.swatch and picker.swatch.SetColorTexture then
                    picker.swatch:SetColorTexture(r, g, b, a)
                end
            end
        end
    end
end



function EasyCursorTrails.RebuildTrails()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile then return end

    local allowEffects = profile.enableTrailEffects ~= false

    -- 🛑 Pause active effects
    EasyCursorTrails.PauseActiveEffects()
    EasyCursorTrails.SyncEffectUI(profile)
    EasyCursorTrails.ValidateSettings(profile)

    -- 🧼 Reset trail shadows checkbox
    if EasyCursorTrails.trailShadowsCheckbox then
        EasyCursorTrails.trailShadowsCheckbox:SetChecked(false)
        local click = EasyCursorTrails.trailShadowsCheckbox:GetScript("OnClick")
        if click then click(EasyCursorTrails.trailShadowsCheckbox) end
    end

    -- 🧼 Refresh shadows
    if EasyCursorTrails.RefreshTrailShadows then
        EasyCursorTrails.RefreshTrailShadows()
    end

    -- 🧹 Cleanup old trails
    if EasyCursorTrails.trailPool then
        for _, layerPool in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(layerPool) do
                if EasyCursorTrails.CleanupTrail then
                    EasyCursorTrails.CleanupTrail(trail)
                end
            end
        end
    end

    -- 🧼 Clear pool and rebuild
    EasyCursorTrails.ClearTrailPool()
    if not profile.enableTrails then return end

    EasyCursorTrails.CreateTrailPool(profile)

    -- ✨ Reapply Star Embers
    if EasyCursorTrails.ApplyStarEmbersIfEnabled then
        EasyCursorTrails.ApplyStarEmbersIfEnabled()
    end

    -- 🔄 Resume paused effects
    EasyCursorTrails.ResumePausedEffects()
    EasyCursorTrails.ValidateEffectRegistry()

    -- 🎨 Apply enabled effects
    for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(layerPool) do
            if EasyCursorTrails.ApplyEnabledEffects then
                EasyCursorTrails.ApplyEnabledEffects(trail)
            end
        end
    end

    -- 🧼 Disable visuals if globally disabled
    if not allowEffects then
        for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(layerPool) do
                if EasyCursorTrails.DisableTrailEffects then
                    EasyCursorTrails.DisableTrailEffects(trail)
                end
            end
        end

        -- 🧹 Explicitly clean up all registered effects
        for effectFlag, cleanupFunc in pairs(EasyCursorTrails.effectCleanupRegistry or {}) do
            if type(cleanupFunc) == "function" then
                for _, layerPool in pairs(EasyCursorTrails.trailPool or {}) do
                    for _, trail in ipairs(layerPool) do
                        cleanupFunc(trail)
                    end
                end
            end
        end

        return
    end


    -- 🌟 Twinkle Stars color reapplication
    if profile.enableTwinkleStars and type(EasyCursorTrails.UpdateTwinkleTrailColors) == "function" then
        C_Timer.After(0.1, function()
            EasyCursorTrails.UpdateTwinkleTrailColors()
        end)
    end

    -- 🔁 Registry-driven ticker reapplication
    for effectFlag, ticker in pairs(EasyCursorTrails.effectTickerRegistry or {}) do
        if EasyCursorTrails.liveEffects and EasyCursorTrails.liveEffects[effectFlag] then
            if ticker.start and type(ticker.start) == "function" then
                C_Timer.After(0.2, function()
                    ticker.start()
                end)
            end
        end
    end
end


EasyCursorTrails.effectCleanupRegistry = {
    enableEmbers = EasyCursorTrails.ClearEmberEffect,

    enableFire = EasyCursorTrails.ClearFireGlow,

    enableLightningEmbers = function(trail)
        if trail.lightningEmberEmitter then
            trail.lightningEmberEmitter:Stop()
            trail.lightningEmberEmitter:Hide()
        end
    end,

    enableLightningSparks = EasyCursorTrails.ClearLightningSparkEffect,

    enableSmokeEffect = EasyCursorTrails.ClearSmokeEffect,

    enableSmokeEffectTrails = function(trail)
        if trail.smokeTrailEmitter then
            trail.smokeTrailEmitter:Stop()
            trail.smokeTrailEmitter:Hide()
        end
    end,

    enableSpringSeason = EasyCursorTrails.ClearNatureEmbersEffect,

    enableSpringSeasonTrails = function(trail)
        if trail.springTrailEmitter then
            trail.springTrailEmitter:Stop()
            trail.springTrailEmitter:Hide()
        end
    end,

    enableStarDust = function(trail)
        if trail.starDustEmitter then
            trail.starDustEmitter:Stop()
            trail.starDustEmitter:Hide()
        end
    end,

    enableStarEmbers = EasyCursorTrails.ClearStarEmbersEffect,

    enableStaticArc = EasyCursorTrails.ClearStaticArcEffect,

    enableTrailShadows = function(trail)
        if trail.shadowEmitter then
            trail.shadowEmitter:Stop()
            trail.shadowEmitter:Hide()
        end
    end,

    enableTwinkleStars = function(trail)
        if trail.twinkleEmitter then
            if type(trail.twinkleEmitter.Stop) == "function" then
                trail.twinkleEmitter:Stop()
            end
            trail.twinkleEmitter:Hide()
        end
    end,

    -- 🌟 Optional: connectTrails cleanup (if visual emitters exist)
    connectTrails = function(trail)
        if trail.connectEmitter then
            trail.connectEmitter:Stop()
            trail.connectEmitter:Hide()
        end
    end,
}


function EasyCursorTrails.CleanupTrail(trail)
    if not trail then return end

    -- 🧹 Registry-driven effect cleanup
    for effectKey, cleanupFunc in pairs(EasyCursorTrails.effectCleanupRegistry or {}) do
        if type(cleanupFunc) == "function" then
            cleanupFunc(trail)
        end
    end

    -- 🌠 Glow Layers
    if trail.glowLayers then
        for _, glow in ipairs(trail.glowLayers) do
            if glow.texture then
                glow.texture:Hide()
                glow.texture:SetTexture(nil)
                glow.texture:SetParent(nil)
            end
            glow:Hide()
            glow:SetParent(nil)
        end
        trail.glowLayers = nil
    end

    -- ✨ Sparkle Pool (if any active sparkles are attached)
    if trail.sparkles then
        for _, sparkle in ipairs(trail.sparkles) do
            if sparkle.animationGroup then sparkle.animationGroup:Stop() end
            sparkle:Hide()
            sparkle:SetParent(nil)
        end
        trail.sparkles = nil
    end

    -- 🎨 Texture
    if trail.texture then
        trail.texture:Hide()
        trail.texture:SetTexture(nil)
        trail.texture:SetParent(nil)
    end

    -- 🧽 Frame
    trail:Hide()
    trail:ClearAllPoints()
    trail:SetParent(nil)
end


function EasyCursorTrails.ApplyStarEmbersIfEnabled()
    local profile = EasyCursorTrails.GetCurrentProfile()
    if not profile or not profile.enableStarEmbers then return end

    if EasyCursorTrails.StarDustTicker then
        EasyCursorTrails.StarDustTicker()
    end

    if EasyCursorTrails.SpawnSparkles and EasyCursorTrails.trailPool then
        for _, pool in pairs(EasyCursorTrails.trailPool) do
            for _, trail in ipairs(pool) do
                EasyCursorTrails.SpawnSparkles(trail)
            end
        end
    end
end

EasyCursorTrails.sparkleFrames = EasyCursorTrails.sparkleFrames or {}

function EasyCursorTrails.ClearSparkles()
    for _, sparkle in ipairs(EasyCursorTrails.sparkleFrames) do
        if sparkle:IsShown() then
            sparkle:Hide()
        end
        if sparkle.texture then
            sparkle.texture:SetTexture(nil)
            sparkle.texture:SetParent(nil)
        end
        sparkle:SetParent(nil)
        sparkle:ClearAllPoints()
    end
    wipe(EasyCursorTrails.sparkleFrames)
end

EasyCursorTrails.movementEffects = {
    -- 1: No Effect
    [1] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        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)
        return {offsetX, offsetY}
    end,

    -- 3: Spiral Expansion
    [3] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local spiralSpeed = 20 * math.pi * separationFactor
        local radius = offsetDistance * separationFactor
        local offsetX = radius * math.cos(spiralSpeed + movementAngle)
        local offsetY = radius * math.sin(spiralSpeed + movementAngle)
        return {offsetX, offsetY}
    end,

    -- 4: Zig‑Zag
    [4] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local zigzagFactor = 25 * math.sin(separationFactor * 10 * math.pi)
        local offsetX = offsetDistance * math.cos(movementAngle) + zigzagFactor
        local offsetY = offsetDistance * math.sin(movementAngle)
        return {offsetX, offsetY}
    end,

    -- 5: Wave Oscillation
    [5] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local waveAmplitude = 25 * math.sin(2 * math.pi * separationFactor)
        local offsetX = offsetDistance * math.cos(movementAngle)
        local offsetY = offsetDistance * math.sin(movementAngle) + waveAmplitude
        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)
        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
        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)
        return {offsetX, offsetY}
    end,

    -- 9: Spiral (Existing Example)
    [9] = function(layerDirection, separationFactor, offsetDistance, profile, trailIndex, movementAngle, maximumOffset)
        local cursorSize = (profile.cursorSize or 80)
        local baseFrac = 0.2
        local maxFrac  = 0.5
        local radius = cursorSize * (baseFrac + (maxFrac - baseFrac) * separationFactor)
        local spinSpeed = 5
        -- Here, you expect the caller to pass trailIndex (or use f) to distinguish layers.
        local effectiveDirection = (trailIndex % 1 == 0) and -1 or 1
        local baseAngle = movementAngle or 0
        local timeAngle = baseAngle + (GetTime() * spinSpeed * effectiveDirection) + (trailIndex * 0.6)
        local offsetX = radius * math.cos(timeAngle)
        local offsetY = radius * math.sin(timeAngle)
        return { offsetX, offsetY }
    end,

    -- New Effects (Indices 10 to 19)
    -- 10: Radial Burst
    [10] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local burstSpeed = 10
        local angle = movementAngle + math.sin(GetTime() * burstSpeed + separationFactor * 2 * math.pi)
        local offsetX = offsetDistance * math.cos(angle)
        local offsetY = offsetDistance * math.sin(angle)
        return { offsetX, offsetY }
    end,

    -- 11: Vortex Spiral
    [11] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local vortexSpeed = 10
        local angle = movementAngle + (GetTime() * vortexSpeed * layerDirection) + (separationFactor * math.pi)
        local factor = 1 - separationFactor * 1.5
        local offsetX = offsetDistance * factor * math.cos(angle)
        local offsetY = offsetDistance * factor * math.sin(angle)
        return { offsetX, offsetY }
    end,

    -- 12: Oscillating Swirl
    [12] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local oscillation = math.sin(GetTime() * 3 + separationFactor * 2 * math.pi)
        local angle = movementAngle + layerDirection * oscillation * 0.5
        local offsetX = offsetDistance * math.cos(angle)
        local offsetY = offsetDistance * math.sin(angle)
        return { offsetX, offsetY }
    end,

    -- 13: Drifting Fog
    [13] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local driftAngle = movementAngle + math.sin(GetTime() + separationFactor * 2 * math.pi) * 0.9
        local offsetX = offsetDistance * math.cos(driftAngle)
        local offsetY = offsetDistance * math.sin(driftAngle)
        return { offsetX, offsetY }
    end,

    -- 14: Counter Wave
    [14] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local waveSpeed = 2
        local frequency = 4
        local waveOffset = math.sin(GetTime() * waveSpeed + separationFactor * frequency * math.pi)
        local offsetX = offsetDistance * math.cos(movementAngle) + waveOffset * (maximumOffset or 15)
        local offsetY = offsetDistance * math.sin(movementAngle) + waveOffset * (maximumOffset or 15)
        return { offsetX, offsetY }
    end,

    -- 15: Chaotic Jab
    [15] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local chaos = math.sin(GetTime() * 10 + separationFactor * 10)
        local offsetX = offsetDistance * math.cos(movementAngle) + chaos * (maximumOffset or 10)
        local offsetY = offsetDistance * math.sin(movementAngle) + chaos * (maximumOffset or 10)
        return { offsetX, offsetY }
    end,

    -- 16: Heartbeat Pulse
    [16] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local pulse = (math.sin(GetTime() * 2 * math.pi) + 1) / 2  -- cycles between 0 and 1
        local offsetX = offsetDistance * pulse * math.cos(movementAngle)
        local offsetY = offsetDistance * pulse * math.sin(movementAngle)
        return { offsetX, offsetY }
    end,

    -- 17: Pendulum Swing
    [17] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local swing = math.sin(GetTime() * 1.5 + separationFactor * math.pi)
        local angle = movementAngle + swing * 0.5
        local offsetX = offsetDistance * math.cos(angle)
        local offsetY = offsetDistance * math.sin(angle)
        return { offsetX, offsetY }
    end,




    -- 18: Ring Fire with chaotic flame tongues
    [18] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local angle = separationFactor * 2 * math.pi

        -- 🔥 Add angular chaos
        local chaos = (math.random() - 0.5) * 0.4 -- ±0.2 radians
        local flameAngle = angle + chaos

        local radius = offsetDistance
        local offsetX = math.cos(flameAngle) * radius
        local offsetY = math.sin(flameAngle) * radius

        return { offsetX, offsetY }
    end,


    -- 19: Lightning — jagged, chaotic bursts
    [19] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local time = GetTime()

        -- ⚡ Base angle with chaotic jitter
        local baseAngle = separationFactor * 2 * math.pi
        local jitter = (math.random() - 0.5) * math.pi * 0.6 -- ±~108° randomness
        local strikeAngle = baseAngle + jitter

        -- ⚡ Jagged burst offset
        local burstLength = offsetDistance * (0.8 + math.random() * 0.4)
        local offsetX = math.cos(strikeAngle) * burstLength
        local offsetY = math.sin(strikeAngle) * burstLength

        return { offsetX, offsetY }
    end,



    -- 20: Cosmic Ripple
    [20] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        -- Use the provided movement angle or default to 0.
        local baseAngle = movementAngle or 0
        -- Define a ripple frequency in radians per second (2π gives roughly one pulse per second).
        local rippleFrequency = 2 * math.pi  
        -- Calculate the ripple value. We include layerDirection and separationFactor in the phase so
        -- that different layers (or segments) will pulse a bit differently.
        local ripple = math.sin(GetTime() * rippleFrequency + separationFactor * math.pi * layerDirection)
        -- Modulate the base offsetDistance by up to ±30% (adjust 0.3 for higher/lower amplitude).
        local modulatedDistance = offsetDistance * (1 + 0.3 * ripple)
        -- Calculate final offsets along the base movement angle.
        local offsetX = modulatedDistance * math.cos(baseAngle)
        local offsetY = modulatedDistance * math.sin(baseAngle)
        return { offsetX, offsetY }
    end,

    [21] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local angle = math.random() * 2 * math.pi
        local radius = offsetDistance * (0.5 + math.random())
        return { math.cos(angle) * radius, math.sin(angle) * radius }
    end,

    [22] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local angle = math.random() * 2 * math.pi
        local sparkle = math.random(0.2, 1.2)
        return { math.cos(angle) * offsetDistance * sparkle, math.sin(angle) * offsetDistance * sparkle }
    end,

    [23] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local time = GetTime()
        local fallSpeed = 4
        local angle = separationFactor * 2 * math.pi
        local offsetX = math.cos(angle) * offsetDistance
        local offsetY = math.sin(angle) * offsetDistance - (time % 1) * fallSpeed
        return { offsetX, offsetY }
    end,

    [23] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local time = GetTime()
        local fallSpeed = 4
        local angle = separationFactor * 2 * math.pi
        local offsetX = math.cos(angle) * offsetDistance
        local offsetY = math.sin(angle) * offsetDistance - (time % 1) * fallSpeed
        return { offsetX, offsetY }
    end,

    [24] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local rise = math.sin(GetTime() * 3 + separationFactor * 2) * offsetDistance * 0.4
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance, math.sin(angle) * offsetDistance + rise }
    end,

    [25] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local wave = math.sin(GetTime() * 2 + separationFactor * 3) * offsetDistance * 0.3
        local angle = movementAngle or 0
        return { math.cos(angle) * offsetDistance, math.sin(angle) * offsetDistance + wave }
    end,

    [26] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local pulse = math.sin(GetTime() * 6 + separationFactor * math.pi) * 0.4
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance * (1 + pulse), math.sin(angle) * offsetDistance * (1 + pulse) }
    end,


    [27] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local driftX = math.sin(GetTime() * 1.5 + separationFactor * 2) * offsetDistance * 0.5
        local driftY = math.cos(GetTime() * 1.2 + separationFactor * 1.5) * offsetDistance * 0.5
        return { driftX, driftY }
    end,

    [28] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local surge = math.sin(GetTime() * 4 + separationFactor * 2) * offsetDistance * 0.4
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance + surge, math.sin(angle) * offsetDistance + surge }
    end,

    [29] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local flicker = (math.random() - 0.5) * offsetDistance * 0.6
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance + flicker, math.sin(angle) * offsetDistance + flicker }
    end,

    [30] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local flare = math.sin(GetTime() * 8 + separationFactor * 4) * offsetDistance * 0.5
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance + flare, math.sin(angle) * offsetDistance + flare }
    end,

    [31] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local echo = math.sin(GetTime() * 2 + separationFactor * 2) * offsetDistance * 0.3
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance, math.sin(angle) * offsetDistance + echo }
    end,

    [32] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local cascade = (GetTime() % 1) * offsetDistance * 0.8
        local angle = separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance, math.sin(angle) * offsetDistance - cascade }
    end,

    [33] = function(layerDirection, separationFactor, offsetDistance, profile, f, movementAngle, maximumOffset)
        local spinSpeed = 5
        local angle = GetTime() * spinSpeed + separationFactor * 2 * math.pi
        return { math.cos(angle) * offsetDistance, math.sin(angle) * offsetDistance }
    end,



}


    

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

-- 🔄 Cursor tracking
EasyCursorTrails.previousCursorX = nil
EasyCursorTrails.previousCursorY = nil

-- ⏱ Ring buffer setup
EasyCursorTrails.headIndex     = 0
EasyCursorTrails.bufferSize    = 200
EasyCursorTrails.cursorHistory = {}

-- 💡 Prefill buffer to avoid nil access
for i = 1, EasyCursorTrails.bufferSize do
    EasyCursorTrails.cursorHistory[i] = { x = 0, y = 0 }
end

-- 🧭 Warm-up logic
EasyCursorTrails._initTime = GetTime()

-- 🌀 Movement timing
local handleTrailMovementTimer    = 10
local handleTrailMovementInterval = 0.02

function EasyCursorTrails.HandleTrailMovement(elapsed)

    handleTrailMovementTimer = (handleTrailMovementTimer or 0) + elapsed
    if handleTrailMovementTimer < (handleTrailMovementInterval or 0.016) then return end
    handleTrailMovementTimer = 0

    local profile = EasyCursorTrails.currentProfileTable
    if not profile or not profile.enableTrails then return end

    local trailPool = EasyCursorTrails.trailPool
    if not trailPool then return end

    local cursorX, cursorY = GetCursorPosition()
    local scale = UIParent:GetEffectiveScale()
    cursorX, cursorY = cursorX / scale, cursorY / scale
    if EasyCursorTrails.UpdateCustomCursorPosition then EasyCursorTrails.UpdateCustomCursorPosition() end

    local bufferSize = EasyCursorTrails.bufferSize or 100
    EasyCursorTrails.cursorHistory = EasyCursorTrails.cursorHistory or {}
    EasyCursorTrails.headIndex = EasyCursorTrails.headIndex or 0

    local dx, dy = cursorX - (EasyCursorTrails.previousCursorX or cursorX), cursorY - (EasyCursorTrails.previousCursorY or cursorY)
    local distSq = dx * dx + dy * dy
    local moved = distSq >= 0.01
    local chainSegment = profile.chainSegment or 10

    if moved then
        local dist = math.sqrt(distSq)
        local steps = math.max(1, math.floor(dist / chainSegment))
        for s = 1, steps do
            local t = s / steps
            local x = EasyCursorTrails.previousCursorX + dx * t
            local y = EasyCursorTrails.previousCursorY + dy * t
            EasyCursorTrails.headIndex = (EasyCursorTrails.headIndex % bufferSize) + 1
            EasyCursorTrails.cursorHistory[EasyCursorTrails.headIndex] = { x = x, y = y }
        end
    else
        local mult = profile.trailUpdateMultiplier or 1
        local iterations = math.min(math.max(1, math.floor(mult / 8 + 0.02)), 10)
        for _ = 1, iterations do
            local nextIndex = (EasyCursorTrails.headIndex % bufferSize) + 1
            local prevIndex = nextIndex - 1 < 1 and bufferSize or nextIndex - 1
            local prev = EasyCursorTrails.cursorHistory[prevIndex] or { x = cursorX, y = cursorY }
            EasyCursorTrails.cursorHistory[nextIndex] = {
                x = prev.x + 0.5 * (cursorX - prev.x),
                y = prev.y + 0.5 * (cursorY - prev.y)
            }
            EasyCursorTrails.headIndex = nextIndex
        end
    end

    EasyCursorTrails.previousCursorX = cursorX
    EasyCursorTrails.previousCursorY = cursorY

    local layerCount = math.floor(profile.trailLayerCount or 1)
    local trailCount = math.floor(profile.trailCount or 10)
    local initialSeparation = profile.trailInitialSeparation or 30
    local maxOffset = profile.trailLayerSpacingSlider or 30
    local offsetX = profile.trailOffsetX or 0
    local offsetY = profile.trailOffsetY or 0
    local connectTrails = profile.connectTrails
    local movementFunc = EasyCursorTrails.movementEffects and EasyCursorTrails.movementEffects[profile.trailMovementEffect or 1]
        or function() return {0, 0} end

    local layerAngles = {}
    for layer = 1, layerCount do
        layerAngles[layer] = (layerCount > 1) and (((layer - 1) / (layerCount - 1)) * 2 * math.pi) or 0
    end

    local separationFactors, offsetDistances = {}, {}
    for i = 1, trailCount do
        local frac = (i - 1) / math.max(trailCount - 1, 1)
        separationFactors[i] = frac
        offsetDistances[i] = initialSeparation + frac * (maxOffset - initialSeparation)
    end

    for layer = 1, layerCount do
        local trails = trailPool[layer]
        local angle = layerAngles[layer]
        if not trails then break end

        for i = 1, trailCount do
            local trail = trails[i]
            if not trail then break end

            local index = EasyCursorTrails.headIndex - i
            if index < 1 then index = index + bufferSize end
            local pos = EasyCursorTrails.cursorHistory[index]
            local prevIndex = index - 1 < 1 and bufferSize or index - 1
            local prev = EasyCursorTrails.cursorHistory[prevIndex]

            if not pos or not prev or (pos.x == 0 and pos.y == 0) or (GetTime() - (EasyCursorTrails._initTime or 0) < 0.3) then
                trail:Hide()
            else
                local dx, dy = pos.x - prev.x, pos.y - prev.y
                local trailAngle = math.atan2(dy, dx)
                trail.texture:SetRotation(trailAngle)

                local frac = separationFactors[i]
                local dist = offsetDistances[i]
                local offset = movementFunc(angle, frac, dist, profile, i, trailAngle, maxOffset)
                local fx = offset[1] or 0
                local fy = offset[2] or 0

                local finalX = pos.x + offsetX + fx + dist * math.cos(angle)
                local finalY = pos.y + offsetY + fy + dist * math.sin(angle)

                trail:ClearAllPoints()
                trail:SetPoint("CENTER", UIParent, "BOTTOMLEFT", finalX, finalY)

                if EasyCursorTrails.ApplyColorEffectTrail then
                    EasyCursorTrails.ApplyColorEffectTrail(trail, i)
                end

                local distSqToCursor = (pos.x - cursorX)^2 + (pos.y - cursorY)^2
                if connectTrails and distSqToCursor < 25 then
                    trail:Hide()
                else
                    trail:Show()
                end
            end
        end
    end

    if not connectTrails and not moved then
        for layer = 1, layerCount do
            for _, trail in ipairs(trailPool[layer] or {}) do
                trail:Hide()
            end
        end
    end
end




-- Function to sort textures alphabetically by name within each category
local function SortTrailTextures()
    for category, textures in pairs(EasyCursorTrails.trailTextures) do
        table.sort(textures, function(a, b)
            return a.name < b.name
        end)
        --print(string.format("EasyCursorTrails: Sorted trailTextures[%d] alphabetically by name.", category))
    end
end

function EasyCursorTrails:OnEnable()
    C_Timer.NewTicker(0.15, function()
        local profile = EasyCursorTrails.currentProfileTable
        if not (profile and profile.enableStaticArc) then return end

        -- Defensive initialization
        local trailPool = EasyCursorTrails.trailPool
        if type(trailPool) ~= "table" or #trailPool < 1 then return end

        EasyCursorTrails.lastArcTime = EasyCursorTrails.lastArcTime or {}

        local now = GetTime()
        for _ = 1, 2 do
            local layerIndex = math.random(1, #trailPool)
            local pool = trailPool[layerIndex]

            if type(pool) == "table" and #pool > 1 then
                local i = math.random(1, #pool)
                local trail = pool[i]

                if trail then
                    local lastTime = EasyCursorTrails.lastArcTime[trail]
                    if not lastTime or (now - lastTime > 0.25) then
                        local arcColor = profile.staticArcColor or { r = 1, g = 1, b = 1, a = 1 }
                        EasyCursorTrails.ApplyStaticArcEffect(trail, i, arcColor)
                        EasyCursorTrails.lastArcTime[trail] = now
                    end
                end
            end
        end
    end)
end


function EasyCursorTrails.InitializeAddon()
    -- 1️⃣ Ensure DB structure and defaults
    EasyCursorTrails.InitializeEasyCursorTrailsDB()
    EasyCursorTrailsDB = EasyCursorTrailsDB or {}
    EasyCursorTrails:MergeDefaults(EasyCursorTrailsDB, EasyCursorTrails.defaults)

    -- 2️⃣ Profile setup
    EasyCursorTrails.InitializeProfile()
    EasyCursorTrails.LoadCurrentProfile()

    -- 3️⃣ Initialize rainbow timer registry
    EasyCursorTrails.rainbowTimers = EasyCursorTrails.rainbowTimers or {}

    -- 4️⃣ Settings menu
    if EasyCursorTrails.InitializeSettingsMenu then
        EasyCursorTrails.InitializeSettingsMenu()
    end

    -- 🛡️ Sync UI controls (after UI is built)
    EasyCursorTrails.isSyncingUI = true
    if EasyCursorTrails.RefreshSettingsUI then
        EasyCursorTrails.RefreshSettingsUI()
    end
    EasyCursorTrails.isSyncingUI = false

    -- 5️⃣ Custom cursor
    if EasyCursorTrails.InitializeCustomCursor then
        EasyCursorTrails.InitializeCustomCursor()
    end

    -- 6️⃣ Glow position
    if EasyCursorTrails.UpdateGlowBelowCursor then
        EasyCursorTrails.UpdateGlowBelowCursor()
    end

    -- 7️⃣ Pulse defaults
    EasyCursorTrails.pulseValueTrail     = 0.5
    EasyCursorTrails.pulseDirectionTrail = 1
    EasyCursorTrailsDB.pulseStep         = EasyCursorTrailsDB.pulseStep or 0.02
    EasyCursorTrailsDB.pulseMin          = EasyCursorTrailsDB.pulseMin  or 0.3
    EasyCursorTrailsDB.pulseMax          = EasyCursorTrailsDB.pulseMax  or 1.0

    -- 8️⃣ Animation & color update ticker
    if not EasyCursorTrails.animationUpdateFrame then
        EasyCursorTrails.animationUpdateFrame = CreateFrame("Frame")
        EasyCursorTrails.animationUpdateFrame:SetScript("OnUpdate", function(_, elapsed)
            EasyCursorTrails.colorIndexTrail = (EasyCursorTrails.colorIndexTrail or 0) + (elapsed * 300)
            if EasyCursorTrails.colorIndexTrail >= 360 then
                EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail - 360
            end

            if EasyCursorTrails.UpdatePulseValue then
                EasyCursorTrails.UpdatePulseValue()
            end

            for _, layer in pairs(EasyCursorTrails.trailPool or {}) do
                for _, trail in ipairs(layer) do
                    if trail and trail.index then
                        EasyCursorTrails.ApplyColorEffectTrail(trail, trail.index)
                    end
                end
            end
        end)
    end

    -- 8️⃣ Static Arc Effect ticker
    if type(EasyCursorTrails.OnEnable) == "function" then
        EasyCursorTrails:OnEnable()
    end

    -- 9️⃣ Normalize trail textures after reload
    C_Timer.After(0.5, function()
        for _, layer in pairs(EasyCursorTrails.trailPool or {}) do
            for _, trail in ipairs(layer) do
                if trail then
                    EasyCursorTrails.ResetTrailTexture(trail)
                end
            end
        end
    end)

    -- 🔁 Reapply Twinkle Stars color after reload
    C_Timer.After(0.6, function()
        local profile = EasyCursorTrails.GetCurrentProfile()
        if profile and profile.enableTwinkleStars and not profile.randomTwinkleStarsColor then
            if type(EasyCursorTrails.UpdateTwinkleTrailColors) == "function" then
                EasyCursorTrails.UpdateTwinkleTrailColors()
            elseif EasyCursorTrails.debugSave then
                -- print("[EasyCursorTrails] Warning: UpdateTwinkleTrailColors is not defined.")
            end
        end
    end)
end


-- 🔄 ADDON_LOADED Event Handler
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:SetScript("OnEvent", function(_, event, addonName)
    if event == "ADDON_LOADED" and addonName == "EasyCursorTrails" then
        if EasyCursorTrails.InitializeAddon then
            EasyCursorTrails.InitializeAddon()
        end
    end
end)


-- 🎨 Cursor Color Update Ticker
local cursorUpdateFrame = CreateFrame("Frame")
local cursorUpdateInterval = 0.05
local cursorAccumulatedTime = 0
cursorUpdateFrame:SetScript("OnUpdate", function(_, elapsed)
    cursorAccumulatedTime = cursorAccumulatedTime + elapsed
    if cursorAccumulatedTime >= cursorUpdateInterval then
        if EasyCursorTrails.ApplyColorEffectCursor then
            EasyCursorTrails.ApplyColorEffectCursor(cursorAccumulatedTime)
        end
        cursorAccumulatedTime = cursorAccumulatedTime % cursorUpdateInterval
    end
end)

-- 🌈 Trail Animation & Color Update Frame
local trailUpdateFrame = CreateFrame("Frame")
trailUpdateFrame:SetScript("OnUpdate", function(_, elapsed)
    EasyCursorTrails.colorIndexTrail = (EasyCursorTrails.colorIndexTrail or 0) + (elapsed * 60)
    if EasyCursorTrails.colorIndexTrail >= 360 then
        EasyCursorTrails.colorIndexTrail = EasyCursorTrails.colorIndexTrail - 360
    end

    if EasyCursorTrails.UpdatePulseValue then
        EasyCursorTrails.UpdatePulseValue()
    end

    if EasyCursorTrails.HandleTrailMovement then
        EasyCursorTrails.HandleTrailMovement(elapsed)
    end

    for _, trailLayer in pairs(EasyCursorTrails.trailPool or {}) do
        for _, trail in ipairs(trailLayer) do
            if trail and trail.index and trail.texture then
                local hue = (EasyCursorTrails.colorIndexTrail + (trail.index * 15)) % 360 / 360
                local r, g, b = EasyCursorTrails.HSVToRGB(hue * 360, 1, 1)
                trail.texture:SetVertexColor(r, g, b, 1)
                trail.texture:Show()
                trail:SetAlpha(1)
                trail:SetFrameStrata(EasyCursorTrails.currentProfileTable.trailFrameStrata or "TOOLTIP")

                if EasyCursorTrails.cursorHistory and EasyCursorTrails.cursorHistory[EasyCursorTrails.headIndex] then
                    local cursorPos = EasyCursorTrails.cursorHistory[EasyCursorTrails.headIndex]
                    local dx = trail:GetLeft() - cursorPos.x
                    local dy = trail:GetTop() - cursorPos.y
                    local distanceSquared = dx * dx + dy * dy

                    if EasyCursorTrailsDB.connectTrails and distanceSquared < 100 then
                        trail:Hide()
                    else
                        trail:Show()
                    end
                end
            end
        end
    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())
    end
end
