-- Cadence: Media.lua -- the bundled voice pack and per-spell sound lookup.
--
-- Every file lives under Interface\AddOns\Cadence\Sounds\, shipped with the
-- addon. No external libraries, no other addons required.
--
-- Voice: Piper neural TTS, en-US "Ryan", OGG Vorbis, -16 LUFS.
-- Spell names are English. On non-enUS clients the lookup still works because
-- Cadence matches by spell ID first and falls back to whatever label is on the
-- reminder -- so a plan built on an enUS machine is portable.

local ADDON, ns = ...

ns.Media = {}
local M = ns.Media

local BASE = "Interface\\AddOns\\Cadence\\Sounds\\"

--------------------------------------------------------------------------------
-- Voice pack: spell name -> path
--------------------------------------------------------------------------------
--
-- Grouped by spec folder to make the source easy to maintain. Paths use the
-- same folder structure that ships in the zip, so adding a new file is:
-- 1. Drop it in the right Sounds subfolder.
-- 2. Add a line here.

M.VOICEPACK = {
    -- Druid Restoration
    ["Tranquility"]                         = BASE .. "Druid_Restoration\\Tranquility.ogg",
    ["Ironbark"]                            = BASE .. "Druid_Restoration\\Ironbark.ogg",
    ["Flourish"]                            = BASE .. "Druid_Restoration\\Flourish.ogg",
    ["Incarnation: Tree of Life"]           = BASE .. "Druid_Restoration\\IncarnationTreeOfLife.ogg",
    ["Convoke the Spirits"]                 = BASE .. "Druid_Restoration\\ConvokeTheSpirits.ogg",
    ["Nature's Swiftness"]                  = BASE .. "Druid_Restoration\\NaturesSwiftness.ogg",
    ["Overgrowth"]                          = BASE .. "Druid_Restoration\\Overgrowth.ogg",
    ["Nature's Vigil"]                      = BASE .. "Druid_Restoration\\NaturesVigil.ogg",
    ["Cenarion Ward"]                       = BASE .. "Druid_Restoration\\CenarionWard.ogg",
    ["Barkskin"]                            = BASE .. "Druid_Restoration\\Barkskin.ogg",
    ["Innervate"]                           = BASE .. "Druid_Restoration\\Innervate.ogg",
    ["Grove Guardians"]                     = BASE .. "Druid_Restoration\\GroveGuardians.ogg",
    ["Efflorescence"]                       = BASE .. "Druid_Restoration\\Efflorescence.ogg",
    ["Wild Growth"]                         = BASE .. "Druid_Restoration\\WildGrowth.ogg",
    ["Stampeding Roar"]                     = BASE .. "Druid_Restoration\\StampedingRoar.ogg",

    -- Priest Discipline
    ["Power Word: Barrier"]                 = BASE .. "Priest_Discipline\\PowerWordBarrier.ogg",
    ["Rapture"]                             = BASE .. "Priest_Discipline\\Rapture.ogg",
    ["Evangelism"]                          = BASE .. "Priest_Discipline\\Evangelism.ogg",
    ["Pain Suppression"]                    = BASE .. "Priest_Discipline\\PainSuppression.ogg",
    ["Luminous Barrier"]                    = BASE .. "Priest_Discipline\\LuminousBarrier.ogg",
    ["Spirit Shell"]                        = BASE .. "Priest_Discipline\\SpiritShell.ogg",
    ["Shadow Covenant"]                     = BASE .. "Priest_Discipline\\ShadowCovenant.ogg",
    ["Power Word: Life"]                    = BASE .. "Priest_Discipline\\PowerWordLife.ogg",

    -- Priest Holy
    ["Divine Hymn"]                         = BASE .. "Priest_Holy\\DivineHymn.ogg",
    ["Holy Word: Salvation"]                = BASE .. "Priest_Holy\\HolyWordSalvation.ogg",
    ["Apotheosis"]                          = BASE .. "Priest_Holy\\Apotheosis.ogg",
    ["Symbol of Hope"]                      = BASE .. "Priest_Holy\\SymbolOfHope.ogg",
    ["Guardian Spirit"]                     = BASE .. "Priest_Holy\\GuardianSpirit.ogg",
    ["Divine Word"]                         = BASE .. "Priest_Holy\\DivineWord.ogg",
    ["Holy Word: Serenity"]                 = BASE .. "Priest_Holy\\HolyWordSerenity.ogg",
    ["Holy Word: Sanctify"]                 = BASE .. "Priest_Holy\\HolyWordSanctify.ogg",
    ["Circle of Healing"]                   = BASE .. "Priest_Holy\\CircleOfHealing.ogg",

    -- Priest Shared
    ["Desperate Prayer"]                    = BASE .. "Priest_Shared\\DesperatePrayer.ogg",
    ["Mass Dispel"]                         = BASE .. "Priest_Shared\\MassDispel.ogg",
    ["Vampiric Embrace"]                    = BASE .. "Priest_Shared\\VampiricEmbrace.ogg",
    ["Fade"]                                = BASE .. "Priest_Shared\\Fade.ogg",
    ["Leap of Faith"]                       = BASE .. "Priest_Shared\\LeapOfFaith.ogg",
    ["Power Infusion"]                      = BASE .. "Priest_Shared\\PowerInfusion.ogg",
    ["Dispersion"]                          = BASE .. "Priest_Shared\\Dispersion.ogg",

    -- Paladin Holy
    ["Aura Mastery"]                        = BASE .. "Paladin_Holy\\AuraMastery.ogg",
    ["Avenging Wrath"]                      = BASE .. "Paladin_Holy\\AvengingWrath.ogg",
    ["Avenging Crusader"]                   = BASE .. "Paladin_Holy\\AvengingCrusader.ogg",
    ["Divine Toll"]                         = BASE .. "Paladin_Holy\\DivineToll.ogg",
    ["Blessing of Sacrifice"]               = BASE .. "Paladin_Holy\\BlessingOfSacrifice.ogg",
    ["Blessing of Protection"]              = BASE .. "Paladin_Holy\\BlessingOfProtection.ogg",
    ["Blessing of Spellwarding"]            = BASE .. "Paladin_Holy\\BlessingOfSpellwarding.ogg",
    ["Lay on Hands"]                        = BASE .. "Paladin_Holy\\LayOnHands.ogg",
    ["Tyr's Deliverance"]                   = BASE .. "Paladin_Holy\\TyrsDeliverance.ogg",
    ["Beacon of Virtue"]                    = BASE .. "Paladin_Holy\\BeaconOfVirtue.ogg",
    ["Divine Favor"]                        = BASE .. "Paladin_Holy\\DivineFavor.ogg",
    ["Holy Prism"]                          = BASE .. "Paladin_Holy\\HolyPrism.ogg",
    ["Daybreak"]                            = BASE .. "Paladin_Holy\\Daybreak.ogg",
    ["Divine Protection"]                   = BASE .. "Paladin_Holy\\DivineProtection.ogg",
    ["Barrier of Faith"]                    = BASE .. "Paladin_Holy\\BarrierOfFaith.ogg",
    ["Light's Hammer"]                      = BASE .. "Paladin_Holy\\LightsHammer.ogg",
    ["Divine Shield"]                       = BASE .. "Paladin_Holy\\DivineShield.ogg",
    ["Blessing of Freedom"]                 = BASE .. "Paladin_Holy\\BlessingOfFreedom.ogg",

    -- Shaman Restoration
    ["Healing Tide Totem"]                  = BASE .. "Shaman_Restoration\\HealingTideTotem.ogg",
    ["Spirit Link Totem"]                   = BASE .. "Shaman_Restoration\\SpiritLinkTotem.ogg",
    ["Ascendance"]                          = BASE .. "Shaman_Restoration\\Ascendance.ogg",
    ["Ancestral Guidance"]                  = BASE .. "Shaman_Restoration\\AncestralGuidance.ogg",
    ["Mana Tide Totem"]                     = BASE .. "Shaman_Restoration\\ManaTideTotem.ogg",
    ["Cloudburst Totem"]                    = BASE .. "Shaman_Restoration\\CloudburstTotem.ogg",
    ["Earthen Wall Totem"]                  = BASE .. "Shaman_Restoration\\EarthenWallTotem.ogg",
    ["Ancestral Protection Totem"]          = BASE .. "Shaman_Restoration\\AncestralProtectionTotem.ogg",
    ["Spiritwalker's Grace"]                = BASE .. "Shaman_Restoration\\SpiritwalkersGrace.ogg",
    ["Wellspring"]                          = BASE .. "Shaman_Restoration\\Wellspring.ogg",
    ["Downpour"]                            = BASE .. "Shaman_Restoration\\Downpour.ogg",
    ["Healing Stream Totem"]                = BASE .. "Shaman_Restoration\\HealingStreamTotem.ogg",
    ["Ancestral Swiftness"]                 = BASE .. "Shaman_Restoration\\AncestralSwiftness.ogg",
    ["Unleash Life"]                        = BASE .. "Shaman_Restoration\\UnleashLife.ogg",
    ["Primordial Wave"]                     = BASE .. "Shaman_Restoration\\PrimordialWave.ogg",
    ["Earth Shield"]                        = BASE .. "Shaman_Restoration\\EarthShield.ogg",
    ["Astral Shift"]                        = BASE .. "Shaman_Restoration\\AstralShift.ogg",
    ["Spirit Wolf"]                         = BASE .. "Shaman_Restoration\\SpiritWolf.ogg",
    ["Tremor Totem"]                        = BASE .. "Shaman_Restoration\\TremorTotem.ogg",
    ["Wind Rush Totem"]                     = BASE .. "Shaman_Restoration\\WindRushTotem.ogg",

    -- Monk Mistweaver
    ["Revival"]                             = BASE .. "Monk_Mistweaver\\Revival.ogg",
    ["Life Cocoon"]                         = BASE .. "Monk_Mistweaver\\LifeCocoon.ogg",
    ["Invoke Yu'lon, the Jade Serpent"]     = BASE .. "Monk_Mistweaver\\InvokeYulonTheJadeSerpent.ogg",
    ["Invoke Chi-Ji, the Red Crane"]        = BASE .. "Monk_Mistweaver\\InvokeChiJiTheRedCrane.ogg",
    ["Fortifying Brew"]                     = BASE .. "Monk_Mistweaver\\FortifyingBrew.ogg",
    ["Diffuse Magic"]                       = BASE .. "Monk_Mistweaver\\DiffuseMagic.ogg",
    ["Zen Meditation"]                      = BASE .. "Monk_Mistweaver\\ZenMeditation.ogg",
    ["Thunder Focus Tea"]                   = BASE .. "Monk_Mistweaver\\ThunderFocusTea.ogg",
    ["Sheilun's Gift"]                      = BASE .. "Monk_Mistweaver\\SheilunsGift.ogg",
    ["Refreshing Jade Wind"]                = BASE .. "Monk_Mistweaver\\RefreshingJadeWind.ogg",
    ["Celestial Conduit"]                   = BASE .. "Monk_Mistweaver\\CelestialConduit.ogg",
    ["Jadefire Stomp"]                      = BASE .. "Monk_Mistweaver\\JadefireStomp.ogg",
    ["Dampen Harm"]                         = BASE .. "Monk_Mistweaver\\DampenHarm.ogg",
    ["Ring of Peace"]                       = BASE .. "Monk_Mistweaver\\RingOfPeace.ogg",
    ["Restoral"]                            = BASE .. "Monk_Mistweaver\\Restoral.ogg",

    -- Evoker Preservation
    ["Rewind"]                              = BASE .. "Evoker_Preservation\\Rewind.ogg",
    ["Dream Flight"]                        = BASE .. "Evoker_Preservation\\DreamFlight.ogg",
    ["Emerald Communion"]                   = BASE .. "Evoker_Preservation\\EmeraldCommunion.ogg",
    ["Time Dilation"]                       = BASE .. "Evoker_Preservation\\TimeDilation.ogg",
    ["Stasis"]                              = BASE .. "Evoker_Preservation\\Stasis.ogg",
    ["Zephyr"]                              = BASE .. "Evoker_Preservation\\Zephyr.ogg",
    ["Rescue"]                              = BASE .. "Evoker_Preservation\\Rescue.ogg",
    ["Dream Breath"]                        = BASE .. "Evoker_Preservation\\DreamBreath.ogg",
    ["Spiritbloom"]                         = BASE .. "Evoker_Preservation\\Spiritbloom.ogg",
    ["Verdant Embrace"]                     = BASE .. "Evoker_Preservation\\VerdantEmbrace.ogg",
    ["Renewing Blaze"]                      = BASE .. "Evoker_Preservation\\RenewingBlaze.ogg",
    ["Obsidian Scales"]                     = BASE .. "Evoker_Preservation\\ObsidianScales.ogg",
    ["Emerald Blossom"]                     = BASE .. "Evoker_Preservation\\EmeraldBlossom.ogg",
    ["Temporal Anomaly"]                    = BASE .. "Evoker_Preservation\\TemporalAnomaly.ogg",
    ["Tip the Scales"]                      = BASE .. "Evoker_Preservation\\TipTheScales.ogg",
    ["Cauterizing Flame"]                   = BASE .. "Evoker_Preservation\\CauterizingFlame.ogg",
    ["Time Spiral"]                         = BASE .. "Evoker_Preservation\\TimeSpiral.ogg",
    ["Nullifying Shroud"]                   = BASE .. "Evoker_Preservation\\NullifyingShroud.ogg",

    -- Other raid cooldowns
    ["Rallying Cry"]                        = BASE .. "Raid_Cooldowns_Other\\RallyingCry.ogg",
    ["Anti-Magic Zone"]                     = BASE .. "Raid_Cooldowns_Other\\AntiMagicZone.ogg",
    ["Darkness"]                            = BASE .. "Raid_Cooldowns_Other\\Darkness.ogg",
    ["Smoke Bomb"]                          = BASE .. "Raid_Cooldowns_Other\\SmokeBomb.ogg",
    ["Demoralizing Shout"]                  = BASE .. "Raid_Cooldowns_Other\\DemoralizingShout.ogg",
    ["Void Shift"]                          = BASE .. "Raid_Cooldowns_Other\\VoidShift.ogg",

    -- Generic alerts (assignable to any reminder by typing the key as the label)
    ["Healing cooldown ready"]              = BASE .. "Generic_Alerts\\HealingCooldownReady.ogg",
    ["Cooldown ready"]                      = BASE .. "Generic_Alerts\\CooldownReady.ogg",
    ["No cooldowns left"]                   = BASE .. "Generic_Alerts\\NoCooldownsLeft.ogg",
    ["Use it now"]                          = BASE .. "Generic_Alerts\\UseItNow.ogg",
    ["Incoming damage"]                     = BASE .. "Generic_Alerts\\IncomingDamage.ogg",
    ["Save your cooldown"]                  = BASE .. "Generic_Alerts\\SaveYourCooldown.ogg",
    ["Rotate cooldowns"]                    = BASE .. "Generic_Alerts\\RotateCooldowns.ogg",
    ["Damage reduction active"]             = BASE .. "Generic_Alerts\\DamageReductionActive.ogg",
    ["Barrier down"]                        = BASE .. "Generic_Alerts\\BarrierDown.ogg",
    ["Tranquility incoming"]                = BASE .. "Generic_Alerts\\TranquilityIncoming.ogg",
}

-- The path for a given spell, or nil when no clip exists.
-- Tries the reminder's resolved label first; if nothing matches, falls back to
-- the client's raw spell name. That covers labels set by SPELL_LABELS overrides
-- while still resolving the usual case.
function M:ClipForReminder(reminder)
    if not reminder then return nil end

    local label = reminder.label
    if label and label ~= "" then
        local p = M.VOICEPACK[label]
        if p then return p end
    end

    if reminder.spellID then
        local name = ns.GetSpellName(reminder.spellID)
        if name then
            local p = M.VOICEPACK[name]
            if p then return p end
        end
    end

    return nil
end

--------------------------------------------------------------------------------
-- Grouped list for the sound picker
--------------------------------------------------------------------------------

-- Returns { { label = "...", entries = { { name, path }, ... } }, ... }
-- The groups mirror the folder layout so the picker reads like a spec sheet.
function M:GetSoundGroups()
    local GROUPS = {
        { label = "Druid — Restoration",   prefix = BASE .. "Druid_Restoration\\" },
        { label = "Priest — Discipline",   prefix = BASE .. "Priest_Discipline\\" },
        { label = "Priest — Holy",         prefix = BASE .. "Priest_Holy\\" },
        { label = "Priest — Shared",       prefix = BASE .. "Priest_Shared\\" },
        { label = "Paladin — Holy",        prefix = BASE .. "Paladin_Holy\\" },
        { label = "Shaman — Restoration",  prefix = BASE .. "Shaman_Restoration\\" },
        { label = "Monk — Mistweaver",     prefix = BASE .. "Monk_Mistweaver\\" },
        { label = "Evoker — Preservation", prefix = BASE .. "Evoker_Preservation\\" },
        { label = "Other raid cooldowns",  prefix = BASE .. "Raid_Cooldowns_Other\\" },
        { label = "Generic alerts",        prefix = BASE .. "Generic_Alerts\\" },
    }

    local byPrefix = {}
    for _, entry in pairs(M.VOICEPACK) do
        for _, g in ipairs(GROUPS) do
            if entry:sub(1, #g.prefix) == g.prefix then
                byPrefix[g.prefix] = byPrefix[g.prefix] or {}
                byPrefix[g.prefix][#byPrefix[g.prefix] + 1] = entry
                break
            end
        end
    end

    -- Build name -> path for display in the picker.
    local nameFor = {}
    for name, path in pairs(M.VOICEPACK) do nameFor[path] = name end

    local out = {}
    for _, g in ipairs(GROUPS) do
        local entries = byPrefix[g.prefix]
        if entries and #entries > 0 then
            table.sort(entries, function(a, b) return (nameFor[a] or a) < (nameFor[b] or b) end)
            local list = {}
            for _, path in ipairs(entries) do
                list[#list + 1] = { name = nameFor[path] or path, path = path }
            end
            out[#out + 1] = { label = g.label, entries = list }
        end
    end
    return out
end

function M:CountSounds()
    local n = 0
    for _ in pairs(M.VOICEPACK) do n = n + 1 end
    return n
end
