--- Spell Charge Information for Micro Spheres
--
local SpellChargeData = {}
local AddOnName, nsVars = ...
local ss = nsVars.SS

local strlower, string, select = strlower, string, select
local UnitBuff = ss.APIUtils.UnitBuff
local GetSpellCooldown, GetSpellCharges = GetSpellCooldown, GetSpellCharges

--- Provides spell charge information.
-- @param spell The spell identifier.
-- @return The spell information.
-- @see GetSpellCharges().
--
local function getMinMax(spell)
  local curRes, maxRes, start, duration, r = GetSpellCharges(spell)
  if not curRes then
    curRes, maxRes, start, duration, r = 0, 0, 0, 0, 0
  end

  return spell, curRes, maxRes, start, duration, r
end

--- Provides "Stormstrike" charge information, including "Stormbringer" procs.
-- @param spell The spell identifier.
-- @return The spell charge information.
-- @see UnitBuff().
-- @see GetSpellCooldown().
--
local function getStormBringerMinMax(spell)
  -- Stormstrike may have 2 stacks with the Stormbringer buff
  local max = 2
  local buffDetails = { UnitBuff("player", "Stormbringer") }
  
  if next(buffDetails) ~= nil then
    local min = select(3, unpack(buffDetails))-- or 0
    return spell, min + 1, max
  else
    local start, dur = GetSpellCooldown(17364)

    if dur < max then
      return spell, 1, max
    else
      return spell, 0, max, start, dur
    end
  end
end

SpellChargeData.demonhunter = {
    ["throwglaive"]    = { 185123, { r=0.227, g=0.788, b=0.533, a=1 }, getMinMax = getMinMax, name = "Throw Glaive",},
    ["demonspikes"]    = { 203720, { r=0.784, g=0.725, b=0.000, a=1 }, getMinMax = getMinMax, name = "Demon Spikes",},
    ["infernalstrike"] = { 189110, { r=0.549, g=0.784, b=0.275, a=1 }, getMinMax = getMinMax, name = "Infernal Strike",},
    ["felrush"]        = { 195072, { r=0.176, g=0.569, b=0.353, a=1 }, getMinMax = getMinMax, name = "Fel Rush",},
}

SpellChargeData.warrior = {
    ["charge"]      = { 100,    { r=0.784, g=0.176, b=0.118, a=1 }, getMinMax = getMinMax, name = "Charge", },
    ["shieldblock"] = { 2565,   { r=0.294, g=0.549, b=0.784, a=1 }, getMinMax = getMinMax, name = "Shield Block",},
    ["intercept"]   = { 198304, { r=0.922, g=0.804, b=0.137, a=1 }, getMinMax = getMinMax, name = "Intercept",},
}

SpellChargeData.paladin = {
    ["divinesteed"]          = { 190784, { r=0.588, g=0.824, b=0.961, a=1 }, getMinMax = getMinMax, name = "Divine Steed",},
    ["shieldoftherighteous"] = { 53600,  { r=0.471, g=0.137, b=0.627, a=1 }, getMinMax = getMinMax, name = "Shield of the Righteous",},
    ["blessedhammer"]        = { 204019, { r=0.549, g=0.255, b=0.509, a=1 }, getMinMax = getMinMax, name = "Blessed Hammer",},
    ["judgment"]             = { 20271,  { r=0.843, g=0.627, b=0.098, a=1 }, getMinMax = getMinMax, name = "Judgement",},
    ["crusaderstrike"]       = { 35395,  { r=1.000, g=0.863, b=0.431, a=1 }, getMinMax = getMinMax, name = "Crusader Strike",},
    ["zeal"]                 = { 217020, { r=0.941, g=0.902, b=0.588, a=1 }, getMinMax = getMinMax, name = "Zeal",},
}

SpellChargeData.mage = {
    ["phoenixsflames"] = { 194466, { r=0.941, g=0.529, b=0.098, a=1 }, getMinMax = getMinMax, name = "Phoenix's Flames",},
    ["fireblast"]      = { 108853, { r=1.000, g=0.686, b=0.471, a=1 }, getMinMax = getMinMax, name = "Fire Blast",},
    ["shimmer"]        = { 212653, { r=0.706, g=0.549, b=1.000, a=1 }, getMinMax = getMinMax, name = "Shimmer",},
    ["icefloes"]       = { 108839, { r=0.333, g=0.627, b=0.804, a=1 }, getMinMax = getMinMax, name = "Ice Floes",},
    ["runeofpower"]    = { 116011, { r=0.451, g=0.863, b=1.000, a=1 }, getMinMax = getMinMax, name = "Rune of Power",},
    ["frostnova"]      = { 122,    { r=0.431, g=0.686, b=1.000, a=1 }, getMinMax = getMinMax, name = "Frost Nova",},
}

SpellChargeData.shaman = {
    ["boulderfist"]        = { 201897, { r=0.588, g=0.333, b=0.118, a=1 }, getMinMax = getMinMax,             name = "Boulderfist",},
    ["healingstreamtotem"] = { 5394,   { r=0.510, g=0.882, b=1.000, a=1 }, getMinMax = getMinMax,             name = "Healing Stream Totem",},
    ["riptide"]            = { 61295,  { r=0.157, g=0.392, b=0.569, a=1 }, getMinMax = getMinMax,             name = "Riptide",},
    ["lavaburst"]          = { 51505,  { r=1.000, g=0.373, b=0.059, a=1 }, getMinMax = getMinMax,             name = "Lava Burst",},
    ["stormstrike"]        = { 17364,  { r=0.686, g=0.843, b=1.000, a=1 }, getMinMax = getStormBringerMinMax, name = "Stormstrike",},
}

SpellChargeData.priest = {
    ["angelicfeather"]  = { 121536, { r=1.000, g=0.737, b=0.318, a=1 }, getMinMax = getMinMax, name = "Angelic Feather",},
    ["shadowworddeath"] = { 199911, { r=1.000, g=0.392, b=0.000, a=1 }, getMinMax = getMinMax, name = "Shadow Word: Death",},
}

SpellChargeData.druid = {
    ["frenziedregeneration"] = { 22842,  { r=0.588, g=0.353, b=0.157, a=1 }, getMinMax = getMinMax, name = "Frenzied Regeneration", },
    ["survivalinstincts"]    = { 61336,  { r=0.863, g=0.529, b=0.294, a=1 }, getMinMax = getMinMax, name = "Survival Instincts", },
    ["newmoon"]              = { 202768, { r=0.235, g=0.706, b=1.000, a=1 }, getMinMax = getMinMax, name = "New Moon", },
    ["swiftmend"]            = { 18562,  { r=0.196, g=0.314, b=0.549, a=1 }, getMinMax = getMinMax, name = "Swiftmend", },
    ["brutalslash"]          = { 202028, { r=1.00, g=0.373, b=0.196, a=1 },  getMinMax = getMinMax, name = "Brutal Slash", },
}

SpellChargeData.hunter = {
    ["mongoosebite"] = { 190928, { r=0.804, g=0.157, b=0.098, a=1 }, getMinMax = getMinMax, name = "Mongoose Bite", },
    ["sidewinders"]  = { 214579, { r=1.000, g=0.765, b=0.549, a=1 }, getMinMax = getMinMax, name = "Sidewinders", },
    ["butchery"]     = { 212436, { r=170, g=100, b=75, a=1 },        getMinMax = getMinMax, name = "Butchery", },
    ["direbeast"]    = { 120679, { r=252, g=184, b=64, a=1 },        getMinMax = getMinMax, name = "Dire Beast", },
    ["aimedshot"]    = { 19434,  { r=75, g=130, b=165, a=1 },        getMinMax = getMinMax, name = "Aimed Shot", },
    ["throwingaxes"] = { 200163, { r=0.137, g=0.490, b=0.824, a=1 }, getMinMax = getMinMax, name = "Throwing Axes", },
}

SpellChargeData.monk = {
    ["roll"]              = { 109132, { r=0.451, g=1.000, b=0.275, a=1 }, getMinMax = getMinMax, name = "Roll", },
    ["mistwalk"]          = { 197945, { r=0.294, g=1.000, b=0.490, a=1 }, getMinMax = getMinMax, name = "Mistwalk", },
    ["stormearthandfire"] = { 137639, { r=0.922, g=0.420, b=0.725, a=1 }, getMinMax = getMinMax, name = "Storm, Earth, and Fire", },
    ["healingelixir"]     = { 122281, { r=0.863, g=0.863, b=0.275, a=1 }, getMinMax = getMinMax, name = "Healing Elixir", },
    ["ironskinbrew"]      = { 115308, { r=0.529, g=1.000, b=0.843, a=1 }, getMinMax = getMinMax, name = "Ironskin Brew", },
    ["purifyingbrew"]     = { 119582, { r=0.392, g=0.882, b=0.510, a=1 }, getMinMax = getMinMax, name = "Purifying Brew", },
}

SpellChargeData.deathknight = {
    ["bloodtap"]  = { 221699, { r=0.804, g=0.078, b=0.157, a=1 }, getMinMax = getMinMax, name = "Blood Tap", },
    ["bloodboil"] = { 50842,  { r=1.000, g=0.235, b=0.175, a=1 }, getMinMax = getMinMax, name = "Blood Boil", },
    ["epidemic"]  = { 207317, { r=0.686, g=0.882, b=0.294, a=1 }, getMinMax = getMinMax, name = "Epidemic", },
}

SpellChargeData.rogue = {
    ["shadowdance"] = { 185313, { r=0.784, g=0.980, b=0.784, a=1 }, getMinMax = getMinMax, name = "Shadow Dance", },
    ["bladeflurry"] = { 13877,  { r=1.000, g=0.765, b=0.588, a=1 }, getMinMax = getMinMax, name = "Blade Flurry", },
}

SpellChargeData.warlock = {
    ["shadowflame"]      = { 205181,             { r=1.000, g=0.567, b=0.980, a=1 },  getMinMax = getMinMax, name = "Shadowflame", },
    ["conflagrate"]      = { 17962,              { r=0.647, g=0.882, b=0.059, a=1 },  getMinMax = getMinMax, name = "Conflagrate", },
    ["shadowburn"]       = { 17877,              { r=0.431, g=0.490, b=0.667, a=1 },  getMinMax = getMinMax, name = "Shadowburn", },
    ["dimensionalrift"]  = { "Dimensional Rift", { r=0.729, g=0.121, b=0.788, a=1 },  getMinMax = getMinMax, name = "Dimensional Rift", },
  }

--- Provides resource details.
-- @param class The class identifier.
-- @param spell The buff identifier.
-- @return The resource data.
--
function SpellChargeData.get(class, spell)
  local res = SpellChargeData[strlower(class)][strlower(spell)]

  if SpellChargeData[strlower(class)][strlower(spell)] then
    res.ssClass = "SpellChargeData"
    return res
  else
    return nil
  end
end

--- Returns a reference to the data function.
-- @return The function reference.
--
function SpellChargeData.getFunction()
  return getMinMax
end

--- Initializes a stored resource with actual values.
-- @param resource The resource to initialize.
--
function SpellChargeData.init(resource)
  local index = strlower(string.gsub(resource.name, "[ :',]", ""))

  if SpellChargeData[ss.curClass][index] then
    -- update identifier, color and getMinMax functions.
    resource[1]        = SpellChargeData[ss.curClass][index][1]
    resource[2]        = SpellChargeData[ss.curClass][index][2]
    resource.getMinMax = SpellChargeData[ss.curClass][index].getMinMax
  else
    resource.getMinMax = function() return "",0,0,0,0 end
  end
end

ss.Utils.addModule("SpellChargeData", SpellChargeData)
