----------------------------------------
-- Buff Information for Micro Spheres --
----------------------------------------
local AddOnName, nsVars = ...
local ss = nsVars.SS

local setmetatable = setmetatable
local UnitBuff, UnitStagger, UnitHealthMax = UnitBuff, UnitStagger, UnitHealthMax
local string, GetTime, tonumber, strlower, select = string, GetTime, tonumber, strlower, select

local timeBuffer = 0.05

-- Global Cooldown
local getGCD = function(spell)
  local duration = ss.gcdWatch.max and ss.gcdWatch.max or 1
  local expires = (ss.gcdWatch.start and ss.gcdWatch.max) and (ss.gcdWatch.start + ss.gcdWatch.max) or 1

  if ss.gcdWatch.start and GetTime() >= expires - timeBuffer then
    ss.gcdWatch.start = nil
  end

  return spell, (duration ~= expires) and 1 or 0, 1, duration, expires
end

-- Incanters Flow
local getIncantersFlowMinMax = function(buff)
  local cur, max, prog = select(3, UnitIncantersFlow())
  return buff, (cur and 1 or 0), 1, (max or 1), (prog and (GetTime() + (max * prog) + timeBuffer) or 1)
end

-- Standard generic function to get buff data.
local getMinMax = function(buff)
  local duration, expires = select(6, UnitBuff("player", buff))
  return buff, (duration and 1 or 0), 1, (duration or 1), (expires or 1)
end

-- Used for buffs that have stacks.
local getStackingMinMax = function(spell)
  local buffName = string.gsub(spell, "%d", "")
  local index = strlower(string.gsub(spell, "[ :'%(%)%d]", ""))

  local stacks, _, duration, expires = select(4, UnitBuff("player", buffName))

  if stacks then
    local buffStack = string.gsub(spell, "[^%d]", "")
    buffStack = (buffStack and buffStack ~= "") and tonumber(buffStack) or 1

    duration = (stacks >= buffStack) and duration or nil
    expires = (stacks >= buffStack) and expires or nil
  end

  return index, (duration and 1 or 0), 1, (duration or 1), (expires or 1)
end

-- Used for buffs that have stacks but no expiration.
local getStacks = function(spell)
  local buffName = string.gsub(spell, "%d", "")
  local index = strlower(string.gsub(spell, "[ :'%(%)%d]", ""))
  local stacks, _, duration = select(4, UnitBuff("player", buffName))

  if stacks then
    local buffStack = string.gsub(spell, "[^%d]", "")
    buffStack = (buffStack and buffStack ~= "") and tonumber(buffStack) or 1

    duration = (stacks >= buffStack) and duration or nil
  end

  return index, (duration and 1 or 0), 1, 1, (GetTime() + 1)
end

-- Stagger
local getStaggerMinMax = function()
  local min, max = UnitStagger("player"), UnitHealthMax("player")
  return "Stagger", min, max
end

local getShieldBlockMinMax = function(buff)
  local duration, expires = select(6, UnitBuff("player", buff))
  duration = duration or 1
  expires  = expires or 1

  if duration == 0 and expires == 0 then
    -- Need to find the "real" data. with the T19 2 piece bonus, there are two "Shield Block" buffs.
    for i = 0, 20 do
      -- Possible memory leak?
      local buffDetails = { UnitBuff("player", i) }
      
      if buffDetails and buffDetails[1] == "Shield Block" and buffDetails[7] > 0 then
        -- Real Shield Block.
        return buff, (buffDetails[6] and 1 or 0), 1, (buffDetails[6] or 1), (buffDetails[7] or 1)
      end
    end
  end
  
  return buff, (duration ~= expires and 1 or 0), 1, duration, expires
end

-- Pet buffs
local getPetBuffMinMax = function(buff)
  local duration, expires = select(6, UnitBuff("pet", buff))
  return buff, (duration and 1 or 0), 1, (duration or 1), (expires or 1)
end

local mtBuffData = {
  demonhunter = {
    ["momentum"]       = { "Momentum",        { r=0.824, g=0.526, b=0.157, a=1 }, getMinMax = getMinMax, name = "Momentum", },
    ["empowerwards"]   = { "Empower Wards",   { r=0.471, g=0.784, b=0.294, a=1 }, getMinMax = getMinMax, name = "Empower Wards", },
    ["demonspikes"]    = { "Demon Spikes",    { r=0.784, g=0.725, b=0.000, a=1 }, getMinMax = getMinMax, name = "Demon Spikes", },
    ["soulbarrier"]    = { "Soul Barrier",    { r=0.392, g=0.529, b=0.137, a=1 }, getMinMax = getMinMax, name = "Soul Barrier", },
    ["immolationaura"] = { "Immolation Aura", { r=0.863, g=0.941, b=0.275, a=1 }, getMinMax = getMinMax, name = "Immolation Aura", },
    ["globalcooldown"] = { "Global Cooldown", { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,    name = "Global Cooldown",},
  },
  druid = {
    ["dirgeofangerboda"]     = { "Dirge of Angerboda",    { r=150, g=215, b=55, a=1 },        getMinMax = getMinMax,         name = "Dirge of Angerboda",},
    ["wailofsvala"]          = { "Wail of Svala",         { r=135, g=140, b=225, a=1 },       getMinMax = getMinMax,         name = "Wail of Svala",},
    ["howlofingvar"]         = { "Howl of Ingvar",        { r=205, g=135, b=110, a=1 },       getMinMax = getMinMax,         name = "Howl of Ingvar",},
    ["guardianofelune"]      = { "Guardian of Elune",     { r=0.451, g=0.039, b=0.725, a=1 }, getMinMax = getMinMax,         name = "Guardian of Elune",},
    ["ironfur"]              = { "Ironfur",               { r=0.529, g=0.686, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Ironfur", },
    ["frenziedregeneration"] = { "Frenzied Regeneration", { r=0.588, g=0.353, b=0.157, a=1 }, getMinMax = getMinMax,         name = "Frenzied Regeneration", },
    ["souloftheforest"]      = { "Soul of the Forest",    { r=0.196, g=0.314, b=0.431, a=1 }, getMinMax = getMinMax,         name = "Soul of the Forest", },
    ["pulverize"]            = { "Pulverize",             { r=0.196, g=0.784, b=0.784, a=1 }, getMinMax = getMinMax,         name = "Pulverize", },
    ["tigersfury"]           = { "Tiger's Fury",          { r=0.961, g=0.804, b=0.431, a=1 }, getMinMax = getMinMax,         name = "Tiger's Fury", },
    ["savageroar"]           = { "Savage Roar",           { r=1.000, g=0.667, b=0.039, a=1 }, getMinMax = getMinMax,         name = "Savage Roar", },
    ["warriorofelune"]       = { "Warrior of Elune",      { r=0.153, g=0.216, b=0.471, a=1 }, getMinMax = getStacks,         name = "Warrior of Elune", },
    ["warriorofelune2"]      = { "Warrior of Elune2",     { r=0.153, g=0.216, b=0.471, a=1 }, getMinMax = getStacks,         name = "Warrior of Elune", },
    ["warriorofelune3"]      = { "Warrior of Elune3",     { r=0.153, g=0.216, b=0.471, a=1 }, getMinMax = getStacks,         name = "Warrior of Elune", },
    ["earthwarden"]          = { "Earthwarden",           { r=0.471, g=0.961, b=0.725, a=1 }, getMinMax = getStacks,         name = "Earthwarden", },
    ["earthwarden2"]         = { "Earthwarden2",          { r=0.471, g=0.961, b=0.725, a=1 }, getMinMax = getStacks,         name = "Earthwarden", },
    ["earthwarden3"]         = { "Earthwarden3",          { r=0.471, g=0.961, b=0.725, a=1 }, getMinMax = getStacks,         name = "Earthwarden", },
    ["clearcasting"]         = { "Clearcasting",          { r=0.118, g=0.608, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Clearcasting", },
    ["clearcasting2"]        = { "Clearcasting2",         { r=0.118, g=0.608, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Clearcasting", },
    ["clearcasting3"]        = { "Clearcasting3",         { r=0.118, g=0.608, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Clearcasting", },
    ["bloodtalons"]          = { "Bloodtalons",           { r=0.706, g=0.098, b=0.000, a=1 }, getMinMax = getStackingMinMax, name = "Bloodtalons", },
    ["bloodtalons2"]         = { "Bloodtalons2",          { r=0.706, g=0.098, b=0.000, a=1 }, getMinMax = getStackingMinMax, name = "Bloodtalons", },
    ["globalcooldown"]       = { "Global Cooldown",       { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown",},
  },
  mage = {
    ["norgannonsforesight"]      = { "Norgannon's Foresight", { r=0.000, g=0.922, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Norgannon's Foresight", },
    ["kaelthassultimateability"] = { "Kael'thas's Ultimate Ability", { r=0.647, g=0.294, b=0.765, a=1 }, getMinMax = getMinMax,              name = "Kael'thas's Ultimate Ability",},
    ["freneticspeed"]            = { "Frenetic Speed",               { r=1.000, g=0.784, b=0.294, a=1 }, getMinMax = getMinMax,              name = "Frenetic Speed",},
    ["chronoshift"]              = { "Chrono Shift",                 { r=0.882, g=0.686, b=0.451, a=1 }, getMinMax = getMinMax,              name = "Chrono Shift",},
    ["incantersflow"]            = { "Incanter's Flow",              { r=0.824, g=0.157, b=0.196, a=1 }, getMinMax = getIncantersFlowMinMax, name = "Incanter's Flow",},
    ["globalcooldown"]           = { "Global Cooldown",              { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,                 name = "Global Cooldown",},
  },
  monk = {
    ["stagger"]                  = { "Stagger",                      ss.ClassResourceData.resourceColor("chi"), getMinMax = getStaggerMinMax,  name = "Stagger", },
    ["hitcombo"]                 = { "Hit Combo",                    { r=1.000, g=0.686, b=0.157, a=1 },        getMinMax = getMinMax,         name = "Hit Combo", },
    ["thunderfocustea"]          = { "Thunder Focus Tea",            { r=0.490, g=0.667, b=0.941, a=1 },        getMinMax = getStackingMinMax, name = "Thunder Focus Tea", },
    ["thunderfocustea2"]         = { "Thunder Focus Tea2",           { r=0.490, g=0.667, b=0.941, a=1 },        getMinMax = getStackingMinMax, name = "Thunder Focus Tea", },
    ["lifecyclesvivify"]         = { "Lifecycles (Vivify)",          { r=0.196, g=0.824, b=0.490, a=1 },        getMinMax = getMinMax,         name = "Lifecycles (Vivify)", },
    ["lifecyclesenvelopingmist"] = { "Lifecycles (Enveloping Mist)", { r=0.863, g=0.824, b=0.529, a=1 },        getMinMax = getMinMax,         name = "Lifecycles (Enveloping Mist)", },
    ["ironskinbrew"]             = { "Ironskin Brew",                { r=0.529, g=1.000, b=0.843, a=1 },        getMinMax = getMinMax,         name = "Ironskin Brew", },
    ["elusivedance"]             = { "Elusive Dance",                { r=0.392, g=0.882, b=0.510, a=1 },        getMinMax = getMinMax,         name = "Elusive Dance", },
    ["globalcooldown"]           = { "Global Cooldown",              { r=0.482, g=1.000, b=0.827, a=1 },        getMinMax = getGCD,            name = "Global Cooldown",},
  },
  shaman = {
    ["boulderfist"]                  = { "Boulderfist",                      { r=0.588, g=0.333, b=0.118, a=1 }, getMinMax = getMinMax,         name = "Boulderfist",},
    ["lightningcrash"]               = { "Lightning Crash",                  { r=82, g=154, b=206, a=1 },        getMinMax = getMinMax,         name = "Lightning Crash",},
    ["flametongue"]                  = { "Flametongue",                      { r=1.000, g=0.725, b=0.451, a=1 }, getMinMax = getMinMax,         name = "Flametongue",},
    ["crashlightning"]               = { "Crash Lightning",                  { r=0.098, g=0.588, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Crash Lightning",},
    ["doomwinds"]                    = { "Doom Winds",                       { r=0.471, g=0.882, b=0.353, a=1 }, getMinMax = getMinMax,         name = "Doom Winds",},
    ["windsong"]                     = { "Windsong",                         { r=0.510, g=0.784, b=0.824, a=1 }, getMinMax = getMinMax,         name = "Windsong",},
    ["landslide"]                    = { "Landslide",                        { r=0.627, g=0.176, b=0.176, a=1 }, getMinMax = getMinMax,         name = "Landslide",},
    ["elementalblastcriticalstrike"] = { "Elemental Blast: Critical Strike", { r=0.804, g=0.745, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Elemental Blast: Critical Strike",},
    ["elementalblasthaste"]          = { "Elemental Blast: Haste",           { r=0.647, g=0.333, b=0.686, a=1 }, getMinMax = getMinMax,         name = "Elemental Blast: Haste",},
    ["elementalblastmastery"]        = { "Elemental Blast: Mastery",         { r=1.000, g=0.706, b=0.000, a=1 }, getMinMax = getMinMax,         name = "Elemental Blast: Mastery",},
    ["icefury"]                      = { "Icefury",                          { r=0.682, g=0.549, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Icefury",},
    ["icefury2"]                     = { "Icefury2",                         { r=0.682, g=0.549, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Icefury",},
    ["icefury3"]                     = { "Icefury3",                         { r=0.682, g=0.549, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Icefury",},
    ["icefury4"]                     = { "Icefury4",                         { r=0.682, g=0.549, b=1.000, a=1 }, getMinMax = getStackingMinMax, name = "Icefury",},
    ["shockofthetwistingnether"]     = { "Shock of the Twisting Nether",     { r=0.608, g=1.000, b=0.529, a=1 }, getMinMax = getMinMax,         name = "Shock of the Twisting Nether",},
    ["chillofthetwistingnether"]     = { "Chill of the Twisting Nether",     { r=0.608, g=0.882, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Chill of the Twisting Nether",},
    ["fireofthetwistingnether"]      = { "Fire of the Twisting Nether",      { r=0.843, g=0.176, b=0.000, a=1 }, getMinMax = getMinMax,         name = "Fire of the Twisting Nether",},
    ["globalcooldown"]               = { "Global Cooldown",                  { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown",},
  },
  warrior = {
    ["enrage"]              = { "Enrage",                 { r=1.000, g=0.215, b=0.000, a=1 }, getMinMax = getMinMax,            name = "Enrage",},
    ["enragedregeneration"] = { "Enraged Regeneration",   { r=0.804, g=0.255, b=0.137, a=1 }, getMinMax = getMinMax,            name = "Enraged Regeneration",},
    ["meatcleaver"]         = { "Meat Cleaver",           { r=0.314, g=0.608, b=0.765, a=1 }, getMinMax = getMinMax,            name = "Meat Cleaver",},
    ["shieldblock"]         = { "Shield Block",           { r=0.294, g=0.549, b=0.784, a=1 }, getMinMax = getShieldBlockMinMax, name = "Shield Block",},
    ["ignorepain"]          = { "Ignore Pain",            { r=1.000, g=0.647, b=0.020, a=1 }, getMinMax = getMinMax,            name = "Ignore Pain",},
    ["frothingberserker"]   = { "Frothing Berserker",     { r=1.000, g=0.549, b=0.000, a=1 }, getMinMax = getMinMax,            name = "Frothing Berserker",},
    ["dragonroar"]          = { "Dragon Roar",            { r=0.392, g=0.177, b=0.177, a=1 }, getMinMax = getMinMax,            name = "Dragon Roar",},
    ["bloodbath"]           = { "Bloodbath",              { r=1.000, g=0.275, b=0.020, a=1 }, getMinMax = getMinMax,            name = "Bloodbath",},
    ["berserkerrage"]       = { "Berserker Rage",         { r=0.922, g=0.490, b=0.196, a=1 }, getMinMax = getMinMax,            name = "Berserker Rage",},
    ["renewedfury"]         = { "Renewed Fury",           { r=0.812, g=0.294, b=0.275, a=1 }, getMinMax = getMinMax,            name = "Renewed Fury",},
    ["vengeancerevenge"]    = { "Vengeance: Revenge",     { r=1.000, g=0.706, b=0.314, a=1 }, getMinMax = getMinMax,            name = "Vengeance: Revenge",},
    ["vengeanceignorepain"] = { "Vengeance: Ignore Pain", { r=1.000, g=0.706, b=0.314, a=1 }, getMinMax = getMinMax,            name = "Vengeance: Ignore Pain",},
    ["juggernaut"]          = { "Juggernaut",             { r=0.922, g=0.824, b=0.510, a=1 }, getMinMax = getMinMax,            name = "Juggernaut",},
    ["warmachine"]          = { "War Machine",            { r=1.000, g=0.196, b=0.216, a=1 }, getMinMax = getMinMax,            name = "War Machine",},
    ["shattereddefenses"]   = { "Shattered Defenses",     { r=170, g=90, b=30, a=1 },         getMinMax = getMinMax,            name = "Shattered Defenses",},
    ["frenzy"]              = { "Frenzy",                 { r=0.549, g=0.451, b=0.294, a=1 }, getMinMax = getStackingMinMax,    name = "Frenzy",},
    ["frenzy2"]             = { "Frenzy2",                { r=0.549, g=0.451, b=0.294, a=1 }, getMinMax = getStackingMinMax,    name = "Frenzy",},
    ["frenzy3"]             = { "Frenzy3",                { r=0.549, g=0.451, b=0.294, a=1 }, getMinMax = getStackingMinMax,    name = "Frenzy",},
    ["focusedrage"]         = { "Focused Rage",           { r=0.843, g=0.196, b=0.078, a=1 }, getMinMax = getStackingMinMax,    name = "Focused Rage",},
    ["focusedrage2"]        = { "Focused Rage2",          { r=0.843, g=0.196, b=0.078, a=1 }, getMinMax = getStackingMinMax,    name = "Focused Rage",},
    ["focusedrage3"]        = { "Focused Rage3",          { r=0.843, g=0.196, b=0.078, a=1 }, getMinMax = getStackingMinMax,    name = "Focused Rage",},
    ["globalcooldown"]      = { "Global Cooldown",        { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,               name = "Global Cooldown",},
  },
  deathknight = {
    ["soulgorge"]      = { "Soulgorge",       { r=0.490, g=0.039, b=0.353, a=1 }, getMinMax = getMinMax,         name = "Soulgorge",},
    ["gravewarden"]    = { "Gravewarden",     { r=148, g=127, b=33, a=1 },        getMinMax = getMinMax,         name = "Gravewarden",},
    ["unholyfrenzy"]   = { "Unholy Frenzy",   { r=0.902, g=0.784, b=0.922, a=1 }, getMinMax = getMinMax,         name = "Unholy Frenzy",},
    ["icytalons"]      = { "Icy Talons",      { r=0.373, g=0.412, b=0.667, a=1 }, getMinMax = getStackingMinMax, name = "Icy Talons",},
    ["icytalons2"]     = { "Icy Talons2",     { r=0.373, g=0.412, b=0.667, a=1 }, getMinMax = getStackingMinMax, name = "Icy Talons",},
    ["icytalons3"]     = { "Icy Talons3",     { r=0.373, g=0.412, b=0.667, a=1 }, getMinMax = getStackingMinMax, name = "Icy Talons",},
    ["boneshield"]     = { "Bone Shield",     { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield2"]    = { "Bone Shield2",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield3"]    = { "Bone Shield3",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield4"]    = { "Bone Shield4",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield5"]    = { "Bone Shield5",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield6"]    = { "Bone Shield6",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield7"]    = { "Bone Shield7",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield8"]    = { "Bone Shield8",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield9"]    = { "Bone Shield9",    { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["boneshield10"]   = { "Bone Shield10",   { r=0.498, g=0.686, b=0.118, a=1 }, getMinMax = getStackingMinMax, name = "Bone Shield",},
    ["globalcooldown"] = { "Global Cooldown", { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown",},
  },
  hunter = {
    ["mongoosefury"]      = { "Mongoose Fury",       { r=0.804, g=0.157, b=0.098, a=1 }, getMinMax = getMinMax,         name = "Mongoose Fury",},
    ["steadyfocus"]       = { "Steady Focus",        { r=1.000, g=0.922, b=0.000, a=1 }, getMinMax = getMinMax,         name = "Steady Focus",},
    ["bombardment"]       = { "Bombardment",         { r=0.961, g=0.804, b=0.000, a=1 }, getMinMax = getMinMax,         name = "Bombardment",},
    ["lockandload"]       = { "Lock and Load",       { r=0.961, g=0.000, b=0.000, a=1 }, getMinMax = getStackingMinMax, name = "Lock and Load",},
    ["lockandload2"]      = { "Lock and Load2",      { r=0.961, g=0.000, b=0.000, a=1 }, getMinMax = getStackingMinMax, name = "Lock and Load",},
    ["moknathaltactics"]  = { "Mok'Nathal Tactics",  { r=0.765, g=0.529, b=0.349, a=1 }, getMinMax = getStackingMinMax, name = "Mok'Nathal Tactics",},
    ["moknathaltactics2"] = { "Mok'Nathal Tactics2", { r=0.765, g=0.529, b=0.349, a=1 }, getMinMax = getStackingMinMax, name = "Mok'Nathal Tactics",},
    ["moknathaltactics3"] = { "Mok'Nathal Tactics3", { r=0.765, g=0.529, b=0.349, a=1 }, getMinMax = getStackingMinMax, name = "Mok'Nathal Tactics",},
    ["moknathaltactics4"] = { "Mok'Nathal Tactics4", { r=0.765, g=0.529, b=0.349, a=1 }, getMinMax = getStackingMinMax, name = "Mok'Nathal Tactics",},
    ["mendpet"]           = { "Mend Pet",            { r=230, g=125, b=10, a=1 },        getMinMax = getPetBuffMinMax,  name = "Mend Pet",},
    ["beastcleave"]       = { "Beast Cleave",        { r=65, g=110, b=120, a=1 },        getMinMax = getPetBuffMinMax,  name = "Beast Cleave",},
    ["bestialtenacity"]   = { "Bestial Tenacity",    { r=165, g=55, b=40, a=1 },         getMinMax = getPetBuffMinMax,  name = "Bestial Tenacity",},
    ["globalcooldown"]    = { "Global Cooldown",     { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown",},
  },
  paladin = {
    ["zeal"]           = { "Zeal",            { r=0.941, g=0.902, b=0.588, a=1 }, getMinMax = getMinMax, name = "Zeal",},
    ["seraphim"]       = { "Seraphim",        { r=0.569, g=0.451, b=0.137, a=1 }, getMinMax = getMinMax, name = "Seraphim",},
    ["globalcooldown"] = { "Global Cooldown", { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,    name = "Global Cooldown",},
  },
  priest = {
    ["norgannonsforesight"] = { "Norgannon's Foresight", { r=0.000, g=0.922, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Norgannon's Foresight", },
    ["twistoffate"]         = { "Twist of Fate",         { r=0.451, g=0.333, b=0.843, a=1 }, getMinMax = getMinMax,         name = "Twist of Fate",},
    ["voidray"]             = { "Void Ray",              { r=0.804, g=0.275, b=0.804, a=1 }, getMinMax = getStackingMinMax, name = "Void Ray",},
    ["voidray2"]            = { "Void Ray2",             { r=0.804, g=0.275, b=0.804, a=1 }, getMinMax = getStackingMinMax, name = "Void Ray",},
    ["voidray3"]            = { "Void Ray3",             { r=0.804, g=0.275, b=0.804, a=1 }, getMinMax = getStackingMinMax, name = "Void Ray",},
    ["voidray4"]            = { "Void Ray4",             { r=0.804, g=0.275, b=0.804, a=1 }, getMinMax = getStackingMinMax, name = "Void Ray",},
    ["surgeoflight"]        = { "Surge of Light",        { r=0.902, g=0.569, b=0.294, a=1 }, getMinMax = getStackingMinMax, name = "Surge of Light",},
    ["surgeoflight2"]       = { "Surge of Light2",       { r=0.902, g=0.569, b=0.294, a=1 }, getMinMax = getStackingMinMax, name = "Surge of Light",},
    ["globalcooldown"]      = { "Global Cooldown",       { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown",},
  },
  rogue = {
    ["truebearing"]         = { "True Bearing",          { r=1.000, g=0.824, b=0.373, a=1 }, getMinMax = getMinMax, name = "True Bearing",},
    ["sharkinfestedwaters"] = { "Shark Infested Waters", { r=0.333, g=0.550, b=0.725, a=1 }, getMinMax = getMinMax, name = "Shark Infested Waters",},
    ["broadsides"]          = { "Broadsides",            { r=1.000, g=0.627, b=0.059, a=1 }, getMinMax = getMinMax, name = "Broadsides",},
    ["grandmelee"]          = { "Grand Melee",           { r=0.725, g=0.333, b=0.176, a=1 }, getMinMax = getMinMax, name = "Grand Melee",},
    ["jollyroger"]          = { "Jolly Roger",           { r=0.725, g=0.686, b=0.686, a=1 }, getMinMax = getMinMax, name = "Jolly Roger",},
    ["buriedtreasure"]      = { "Buried Treasure",       { r=1.000, g=0.843, b=0.000, a=1 }, getMinMax = getMinMax, name = "Buried Treasure",},
    ["envenom"]             = { "Envenom",               { r=0.431, g=1.000, b=0.255, a=1 }, getMinMax = getMinMax, name = "Envenom",},
    ["shivarransymmetry"]   = { "Shivarran Symmetry",    { r=1.000, g=0.765, b=0.588, a=1 }, getMinMax = getMinMax, name = "Shivarran Symmetry",},
    ["alacrity"]            = { "Alacrity",              { r=1.000, g=1.000, b=0.392, a=1 }, getMinMax = getMinMax, name = "Alacrity",},
    ["sliceanddice"]        = { "Slice and Dice",        { r=1.000, g=0.294, b=0.000, a=1 }, getMinMax = getMinMax, name = "Slice and Dice",},
    ["elaborateplanning"]   = { "Elaborate Planning",    { r=0.941, g=0.784, b=0.078, a=1 }, getMinMax = getMinMax, name = "Elaborate Planning",},
    ["subterfuge"]          = { "Subterfuge",            { r=0.882, g=0.843, b=1.000, a=1 }, getMinMax = getMinMax, name = "Subterfuge",},
    ["symbolsofdeath"]      = { "Symbols of Death",      { r=1.000, g=0.216, b=0.980, a=1 }, getMinMax = getMinMax, name = "Symbols of Death",},
    ["envelopingshadows"]   = { "Enveloping Shadows",    { r=0.882, g=0.451, b=0.882, a=1 }, getMinMax = getMinMax, name = "Enveloping Shadows",},
    ["globalcooldown"]      = { "Global Cooldown",       { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,    name = "Global Cooldown",},
  },
  warlock = {
    ["empoweredlifetap"]   = { "Empowered Life Tap",  { r=0.686, g=0.217, b=1.000, a=1 }, getMinMax = getMinMax,         name = "Empowered Life Tap", },
    ["deadwindharvester"]  = { "Deadwind Harvester",  { r=16,    g=154,   b=140,   a=1 }, getMinMax = getMinMax,         name = "Deadwind Harvester", },
    ["backdraft"]          = { "Backdraft",           { r=1.000, g=0.726, b=0.235, a=1 }, getMinMax = getStackingMinMax, name = "Backdraft", },
    ["backdraft2"]         = { "Backdraft2",          { r=1.000, g=0.726, b=0.235, a=1 }, getMinMax = getStackingMinMax, name = "Backdraft", },
    ["backdraft3"]         = { "Backdraft3",          { r=1.000, g=0.726, b=0.235, a=1 }, getMinMax = getStackingMinMax, name = "Backdraft", },
    ["backdraft4"]         = { "Backdraft4",          { r=1.000, g=0.726, b=0.235, a=1 }, getMinMax = getStackingMinMax, name = "Backdraft", },
    ["demonicempowerment"] = { "Demonic Empowerment", { r=105, g=235, b=15, a=1 },        getMinMax = getPetBuffMinMax,  name = "Demonic Empowerment",},
    ["globalcooldown"]     = { "Global Cooldown",     { r=0.482, g=1.000, b=0.827, a=1 }, getMinMax = getGCD,            name = "Global Cooldown", },
  },
};

mtBuffData.get = function(class, buff)
  local res = mtBuffData[strlower(class)][strlower(buff)]
  res.ssClass = "BuffData"
  return res
end

mtBuffData.init = function(resource)
  local index = strlower(string.gsub(resource[1], "[ :'%(%)]", ""))

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

ss["BuffData"] = setmetatable({}, { __index = mtBuffData });
