Quantcast
--[[--------------------------------------------------------------------
	oUF_Phanx/Elements/AuraStack.lua
	Element to track stacking self-(de)buffs like combo points.
	Copyright (c) 2008-2015 Phanx <addons@phanx.net>. All rights reserved.

	You may embed this module in your own layout, but please do not
	distribute it as a standalone plugin.

	Modified for oUF Stardust:
	- Added .spec key to hide in wrong specs
------------------------------------------------------------------------
	Usage:

	self.AuraStack = {
		aura = GetSpellInfo(53817) -- Localized spell name for Maelstrom Weapon
		filter = "HELPFUL", -- Optional filter to pass to UnitAura, defaults to "HELPFUL"
	}
	for i = 1, 5 do
		self.AuraStack[i] = CreateTexture(nil, "OVERLAY")
		self.AuraStack[i]:SetSize(20, 20)
		if i == 1 then
			self.AuraStack[i]:SetPoint("LEFT", self, "BOTTOMLEFT", 5, 0)
		else
			self.AuraStack[i]:SetPoint("LEFT", self.AuraStack[i-1], "RIGHT", 0, 0)
		end
	end
------------------------------------------------------------------------
	Notes:

	Only supports one aura per frame.

	Supports Override or PreUpdate/PostUpdate.

	Does not support spell IDs, as the WoW API cannot look up a buff
	directly by its ID and looping is not desirable here.

	The buff to track can be changed dynamically (for example, when
	the player's spec changes) by the layout.

	The individual objects do not have to be textures. They can be
	frames, fontstrings, or even basic tables, as long as they have
	Show, Hide, SetAlpha, and IsObjectType methods.
----------------------------------------------------------------------]]

local _, ns = ...
local oUF = ns.oUF or oUF
assert(oUF, "AuraStack element requires oUF")

local UnitBuff = UnitBuff

local UpdateVisibility, Update, Path, ForceUpdate, Enable, Disable

function UpdateVisibility(self, event)
	local element = self.AuraStack

	if UnitHasVehicleUI(self.unit) or (element.spec and element.spec ~= GetSpecialization()) then
		element.__disabled = true
		for i = 1, #element do
			element[i]:Hide()
		end
		return self:UnregisterEvent("UNIT_AURA", Path)
	end

	element.__disabled = false
	self:RegisterEvent("UNIT_AURA", Path)
	return Path(self, "UpdateVisibility", self.unit)
end

function Update(self, event, unit)
	if unit ~= self.unit then return end
	local element = self.AuraStack
	if element.__disabled or not element.aura then return end

	local _, _, _, count = UnitAura(unit, element.aura, nil, element.filter or "HELPFUL")
	count = count or 0

	if count == element.__count then return end

	if element.PreUpdate then
		element:PreUpdate()
	end

	element.__count = count

	for i = 1, #element do
		local obj = element[i]
		obj:SetShown(count > 0 and i <= element.__max)
	end

	if element.PostUpdate then
		element:PostUpdate(count)
	end
end

function Path(self, ...)
	return (self.AuraStack.Override or Update)(self, ...)
end

function ForceUpdate(element)
	return Path(element.__owner, "ForceUpdate", element.__owner.unit)
end

function Enable(self)
	local element = self.AuraStack
	if not element then return end

	element.__name = "AuraStack"
	element.__owner = self
	element.ForceUpdate = ForceUpdate

	if not element.__max then
		element.__max = #element
	end

	for i = 1, #element do
		local obj = element[i]
		obj.__owner = self
		if obj:IsObjectType("Texture") and not obj:GetTexture() then
			obj:SetTexture([[Interface\ComboFrame\ComboPoint]])
			obj:SetTexCoord(0, 0.375, 0, 1)
		end
	end

	self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED", UpdateVisibility)
	self:RegisterEvent("UNIT_ENTERING_VEHICLE", UpdateVisibility)
	self:RegisterEvent("UNIT_EXITED_VEHICLE", UpdateVisibility)

	UpdateVisibility(self, "Enable")

	return true
end

function Disable(self)
	local element = self.AuraStack
	if not element then return end

	self:UnregisterEvent("UNIT_AURA", Path)
	self:UnregisterEvent("UNIT_ENTERING_VEHICLE", UpdateVisibility)
	self:UnregisterEvent("UNIT_EXITED_VEHICLE", UpdateVisibility)

	for i = 1, #element do
		element[i]:Hide()
	end
	if element.SetShown then
		element:SetShown(false)
	end
end

oUF:AddElement("AuraStack", Path, Enable, Disable)