local MicroSphereContainer = {}
local AddOnName, nsVars = ...
local ss = nsVars.SS

local math = math

--- Updates a fill texture and it's gradient data.
-- @param self A reference to the fill texture.
-- @param targetHeight The target height
-- @param color The target color.
-- @param maxAlpha The alpha limit.
--
local function updateGradientFilling(self, targetHeight, color, maxAlpha)
  if self and ss.global.show.gradient then
    if color and maxAlpha and self.gradient then
      local r,g,b = ss.Utils:GetRGBAValues(color)
      self.gradient:SetGradientAlpha("VERTICAL",r,g,b,maxAlpha,r,g,b,0)
    end
    
    self._gradT = targetHeight / self._maxH
    self._gradT = self._gradT > 1 and 1 or self._gradT -- ensure value isnt greater than 1 when resource changes
    
    local textCoordTop = (self._gradT - ss.gradientScale)
    local newHeight    = targetHeight - (self._maxH * ss.gradientScale)
    textCoordTop = textCoordTop < 0 and 0 or textCoordTop
    
    if self._gradT < 0 then
      self._gradT = 0
    end
    
    newHeight = newHeight < 1 and 1 or newHeight
    
    self:SetHeight  (newHeight)
    self:SetTexCoord(0,1,math.abs(textCoordTop - 1),1)
    
    self._gradB = 1 - (self._gradT - ss.gradientScale)
    self._gradH      = self._maxH * ss.gradientScale
    
    self._gradB = self._gradB < 0 and 0 or self._gradB
    self._gradB = self._gradB > 1 and 1 or self._gradB
    
    self._newY = (self._maxH * (1 - self._gradB)) - self._gradH
    
    if self._updateSplitValues then
      self:_updateSplitValues(textCoordTop, newHeight)
    end
  end
end

--- Updates a texture gradient.
-- @param self The texture reference.
--
local function updateGradient(self)
  if self and ss.global.show.gradient then
    self.gradient:SetHeight  (self._gradH)
    self.gradient:SetTexCoord(0, 1, math.abs(self._gradT - 1), math.abs(self._gradB))
    self.gradient:SetPoint   ("BOTTOM", self._newX, self._newY)
    
    -- Clear temp values.
    self._maxH = nil
    self._newY = nil
    self._newX = nil
    self._gradH = nil
    self._gradT = nil
    self._gradB = nil
  end
end

local function initTextures(container)
  container.filling._updateValues   = updateGradientFilling
  container.filling._updateGradient = updateGradient
  
  function container.filling:UpdateGradient(targetHeight, maxHeight, color, maxAlpha)
    self._maxH = maxHeight
    self._newX = 0
    self:_updateValues(targetHeight, color, maxAlpha)
    self:_updateGradient()
  end
end

local function setTextures(container, color, fillIndex)
  -- Set textures
  local texture = ss.FillTextures.get(ss.profile.microResourceFillTextureGroups[fillIndex], ss.profile.microResourceFillTextures[fillIndex])

  if texture[2] then
    texture = ss.FillTextures.defaultTexture
  end
  
  container.filling:SetTexture(texture)
  container.filling:SetAlpha(1)
  container.filling:SetVertColor(color)
  
  if ss.global.show.gradient then
    -- Set gradient color.
    local r,g,b,a = container.filling:GetVertexColor()
    container.fillingGradient:SetTexture(texture)
    container.fillingGradient:SetAlpha(1)
    container.fillingGradient:SetGradientAlpha("VERTICAL",r,g,b,0,r,g,b,0)
  else
    container.fillingGradient:SetAlpha(0)
    container.fillingGradient:SetGradientAlpha("VERTICAL",0,0,0,0,0,0,0,0)
  end
end

local function initAnimation(container)
  local size = container:GetWidth() * 2.172
  container.animation:ClearAllPoints()
  container.animation:SetPoint      ("CENTER", 0, 0.075)
  container.animation:SetHeight     (size)
  container.animation:SetWidth      (size)
  container.animation:SetFrameLevel (4)
  container.animation:SetAlpha      (0.3)
  container.animation:SetDisplayInfo(ss.Animations.get("orbtacular", "pearl"))
  container.animation:SetCamDistanceScale(1.85)
  container.animation:SetPosition   (0,0,0.075)
  
  function container.animation:UpdateAnimation()
    self:SetAlpha           (0.3)
    self:SetDisplayInfo     (ss.Animations.get("orbtacular", "pearl"))
    self:SetCamDistanceScale(1.85)
    self:Show()
  end
end

function MicroSphereContainer:GetTooltipLabel()
  return self.tooltipLabel
end

function MicroSphereContainer:Init(resource, fillIndex)
  self:SetScale (1)
  self:SetHeight(30 / ss.db[self:GetParent().configName].general.scale)
  self:SetWidth (30 / ss.db[self:GetParent().configName].general.scale)
  self:SetAllPoints  (self:GetParent())
  self:SetFrameStrata(self:GetParent():GetFrameStrata() or "HIGH")
  self.displayMode = "preview"
  
  initTextures(self)
  setTextures(self, resource[2], fillIndex)

  initAnimation(self)
  self:Show()

  self.resourceAnimation:Init()
end

rawset(_G, "MicroSphereContainer_OnLoad", function(self)
  ss.Extentions:DelegateVertexColor(
    self.filling,
    self.fillingGradient)

  self.filling.gradient = self.fillingGradient

  for k,v in pairs(MicroSphereContainer) do
    self[k] = v
  end
end)
