--- Class Resource Information
--
local ClassResources = {}
local AddOnName, nsVars = ...
local ss = nsVars.SS

local strlower, pairs = strlower, pairs

ClassResources.classModes =  {
  deathknight = {
    ["1"] = { --blood
      ["default"] = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
    },
    ["2"] = { --frost
      ["default"] = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
    },
    ["3"] = { --unholy
      ["default"] = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("deathknight")}, ss.ClassResourceData.resourceInfo("runic power"), },
    },
  },
  demonhunter = {
    ["1"] = { --havoc
      ["default"] = { {0, ss.ClassResourceData.classColor("demonhunter")}, ss.ClassResourceData.resourceInfo("fury"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("demonhunter")}, ss.ClassResourceData.resourceInfo("fury"), },
    },
    ["2"] = { --vengeance
      ["default"] = { {0, ss.ClassResourceData.classColor("demonhunter")}, ss.ClassResourceData.resourceInfo("pain"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("demonhunter")}, ss.ClassResourceData.resourceInfo("pain"), },
    },
  },
  druid = {
    ["1"] = { --balance
      ["default"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("lunar power"),
      },
      ["combat"]  = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("lunar power"),
      },
      ["bear"]    = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("rage"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["cat"]     = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("lunar power"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["moonkin"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("lunar power"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
    },
    ["2"] = { --feral
      ["default"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
      },
      ["combat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
      },
      ["bear"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("rage"),
        ss.ClassResourceData.resourceInfo("energy"),
      },
      ["cat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["moonkin"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("lunar power"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
    },
    ["3"] = { --guardian
      ["default"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("rage"),
      },
      ["combat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("rage"),
      },
      ["bear"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("rage"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["cat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("rage"),
      },
      ["moonkin"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("lunar power"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("rage"),
      },
    },
    ["4"] = { --restoration
      ["default"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
      },
      ["combat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("mana"),
        ss.ClassResourceData.resourceInfo("energy"),
      },
      ["bear"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("rage"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["cat"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
      ["moonkin"] = {
        {0, ss.ClassResourceData.classColor("druid")},
        ss.ClassResourceData.resourceInfo("lunar power"),
        ss.ClassResourceData.resourceInfo("energy"),
        ss.ClassResourceData.resourceInfo("mana"),
      },
    },
  },
  hunter = {
    ["1"] = { --beast mastery
      ["default"] = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
    },
    ["2"] = { --marksmanship
      ["default"] = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
    },
    ["3"] = { --survival
      ["default"] = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("hunter")}, ss.ClassResourceData.resourceInfo("focus"), },
    },
  },
  mage = {
    ["1"] = { --arcane
      ["default"] = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["2"] = { --fire
      ["default"] = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --frost
      ["default"] = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("mage")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
  },
  monk = {
    ["1"] = { --brewmaster
      ["default"] = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("energy"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("energy"), },
    },
    ["2"] = { -- mistweaver
      ["default"] = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --windwalker
      ["default"] = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("energy"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("monk")}, ss.ClassResourceData.resourceInfo("energy"), },
    },
  },
  paladin = {
    ["1"] = { --holy
      ["default"] = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["2"] = { --protection
      ["default"] = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --retribution
      ["default"] = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("paladin")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
  },
  priest = {
    ["1"] = { -- discipline
      ["default"] = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["2"] = { --holy
      ["default"] = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --shadow
      ["default"] = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("insanity"), ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("priest")}, ss.ClassResourceData.resourceInfo("insanity"), ss.ClassResourceData.resourceInfo("mana"), },
    },
  },
  rogue = {
    ["1"] = { --assassination
      ["default"] = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
    },
    ["2"] = { --outlaw
      ["default"] = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
    },
    ["3"] = { --subtlety
      ["default"] = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("rogue")}, ss.ClassResourceData.resourceInfo("energy"), },
    },
  },
  shaman = {
    ["1"] = { --elemental
      ["default"] = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("maelstrom"), ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("maelstrom"), ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["2"] = { --enhancement
      ["default"] = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("maelstrom"), ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("maelstrom"), ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --restoration
      ["default"] = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("shaman")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
  },
  warlock = {
    ["1"] = { --affliction
      ["default"] = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["2"] = { --demonology
      ["default"] = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
    ["3"] = { --destruction
      ["default"] = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warlock")}, ss.ClassResourceData.resourceInfo("mana"), },
    },
  },
  warrior = {
    ["1"] = { --arms
      ["default"] = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
    },
    ["2"] = { --fury
      ["default"] = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
    },
    ["3"] = { --protection
      ["default"] = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
      ["combat"]  = { {0, ss.ClassResourceData.classColor("warrior")}, ss.ClassResourceData.resourceInfo("rage"), },
    },
  },
}

--- Provides a basic list of modes for a class.
-- @param self A reference to the object.
-- @param class The class identifier.
-- @return The mode information.
--
function ClassResources:getModes(class)
  return self.classModes[strlower(class)]
end

--- Verifies if the player has a secondary resource.
-- @return The default mode for the secondary resource.
--
function ClassResources.hasSecondaryResource()
  return ss.pVars.spheres["SSProfile_Default"].additionalResource.modes[ss.curSpec]
          and ss.pVars.spheres["SSProfile_Default"].additionalResource.modes[ss.curSpec]["default"]
          or false
end

--- Retrieves the stored unitId for a resource mdoe.
-- @param dbConfig The configuration table index.
-- @return The unitId(s).
--
function ClassResources.modeResourceUnitId(dbConfig, preview)
  local mode = (ss.curShapeshift and ss.curShapeshift ~= "travel") and ss.curShapeshift or "default"

  if dbConfig == "mainResource" then
    local resource = ClassResources.classModes[ss.curClass][strlower(ss.curSpec)][preview or mode]

    return (resource and resource[2]) and resource[2][1] or 0
  elseif dbConfig == "additionalResource" then
    local resource = ClassResources.classModes[ss.curClass][strlower(ss.curSpec)][preview or mode]

    return ((resource and resource[3]) and resource[3][1] or nil), ((resource and resource[4]) and resource[4][1] or nil)
  else
    return 0, 0
  end
end

--- Initializes the player's profile metatables.
--
function ClassResources.initMetaModes()
  local metas = ss.Utils.tcopy(ss.pVars.spheres["SSProfile_Default"], true)
  metas.health.modes             = {};
  metas.mainResource.modes       = {};
  metas.additionalResource.modes = {};
  
  local classModeData = ss.ClassResources:getModes(ss.curClass)
  local i = 1
  
  for spec,modeList in pairs(classModeData) do
    for mode,resourceList in pairs(modeList) do
      for k,resourceData in pairs(resourceList) do
        if i < 4 then
          ss.ClassResources.registerMetaMode(
            metas,
            ss.private.layout.frameList[i],
            spec,
            mode,
            resourceData,
            resourceData[2],
            { {r=1,g=1,b=1,a=1}, {r=1,g=1,b=1,a=1}, },
            { id = "galaxy", groupId = "swirl", speed = 5, },
            { ["fillGroup"] = ss.FillTextures.defaultGroup, ["fillId"] = ss.FillTextures.defaultId },
            ss.FillTextures.defaultTexture)
        elseif i == 4 then
          ss.ClassResources.registerMetaMode(
            metas,
            ss.private.layout.frameList[i],
            spec,
            mode,
            resourceData,
            resourceData[2],
            { {r=1,g=1,b=1,a=1}, {r=1,g=1,b=1,a=1}, },
            { id = "galaxy", groupId = "swirl", speed = 5, },
            { ["fillGroup"] = "split", ["fillId"] = 1 },
            ss.FillTextures.get("split", 1))
        end
        i = i + 1
      end
      i = 1
    end
  end
  
  local localP = ss.Utils.tcopy(ss.pVars.spheres, true)
  localP["SSProfile_Default"] = metas
  
  ss.db            = ss.Utils:SetMetatables(ss.global[ss.profile.profileName], localP["SSProfile_Default"])
  ss.private       = ss.Utils:SetMetatables(ss.Utils.tcopy(ss.private, true), localP)
  ss.pVars.spheres = localP
end

--- Creates and stores a configured mode.
-- @param db The resource configuration.
-- @param resource The resource configuration index.
-- @param specialization The specialization identifier.
-- @param label The mode label.
-- @param fillColor The fill texture color. (Includes unitId)
-- @param swirlColor The swirl texture color.
-- @param fontColor The font colors.
-- @param swirl The swirl details.
-- @param fillInfo The fill texture information.
-- @param fillTexture The fill texture.
-- @param monitorValue The resource monitor value.
--
function ClassResources.registerMetaMode(db, resource, specialization, label, fillColor, swirlColor, fontColor, swirl, fillInfo, fillTexture, monitorValue)
  if db[resource] and db[resource].modes then
    db[resource].modes[specialization] = db[resource].modes[specialization] or {};

    if db[resource].modes[specialization][label] then
      db[resource].modes[specialization][label]["fillColor"][2] = fillColor
      db[resource].modes[specialization][label]["fillInfo"]     = fillInfo
      db[resource].modes[specialization][label]["fillTexture"]  = fillTexture
    else
      db[resource].modes[specialization][label] = {
        ["fillColor"] = {
          fillColor,
        },
        ["swirlColor"] = {
          swirlColor,
        },
        ["fontColor"]   = fontColor,
        ["fillInfo"]    = fillInfo,
        ["fillTexture"] = {
          fillTexture,
        },
        ["monitorValue"] = monitorValue or 0,
        ["swirl"] = swirl,
      }
    end
  end
end

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