Quantcast

local addonName, XSM = ...

local BarWidth = 200
local BarHeight = 15
local FontSize = 10

XSM = XSM or {}

XSM.ShieldSpells = {

	17, 	-- Power Word: Shield 	-- Regular Ability
	123258, -- Power Word: Shield 	-- Modified by Angelic Bulwhark (108946), Divine Insight (123266)
	47753, 	-- Divine Aegis (1) 	-- Modified by Angelic Bulwhark (108946)
	114908,	-- Spirit Shell
	77613,	-- Grace
	59889,	-- Borrowed Time
}

XSM.PlayerSpells = {
	17, 	-- Power Word: Shield 	-- Regular Ability
	123258, -- Power Word: Shield 	-- Modified by Angelic Bulwhark (108946), Divine Insight (123266)
	47753, 	-- Divine Aegis (1) 	-- Modified by Angelic Bulwhark (108946)
	114908,	-- Spirit Shell
	--	47517,	-- Grace				-- Modifies Flash Heal, Greater Heal, Penance
	77613,	-- Grace
	59889,	-- Borrowed Time

	109175, -- Divine Insight (75) 	-- Applies Aura Divine Insight (124430/123266/123267)
	123266, -- Divine Insight 		-- Modifies Power Word Shield (17)
	123267,	-- Divine Insight
	124430,	-- Divine Insight

	108946, -- Angelic Bulwhark 	-- Modifies Power Word: Shield (17), Spirit Shell (109964)
	114214, -- Angelic Bulwhark (1)	-- Regular Ability ?

}

XSM.PlayerCooldowns = {
	109964, -- Spirit Shell (28) 	-- Modifies Heals to absorb - Modified By Angelic Bulwhark (108946)
	47750,	-- Penance
	47540,	-- Penance (Discipline)
	52798,	-- Borrowed Time ( Discipline )		-- Applies Aura 59889
}

XSM.SetMovable = function(self,frame)
	if not frame then return end
	frame:EnableMouse(true)
	frame:SetMovable(true)
	frame:RegisterForDrag("LeftButton")
	frame:SetScript("OnDragStart",function(self)
		self:StartMoving()
	end)

	frame:SetScript("OnDragStop",function(self)
		self:StopMovingOrSizing()
		self:SetUserPlaced(true)
		self:SetClampedToScreen(true)
	end)

	frame:SetScript("OnHide",function(self)
		self:StopMovingOrSizing()
		self:SetUserPlaced(true)
		self:SetClampedToScreen(true)
	end)

end

XSM.CreateShieldFrame = function(self,unit)
	local f = CreateFrame("Frame","XSM_"..unit.."ShieldMonitor",UIParent,"SecureHandlerStateTemplate")
	f.unit = unit
	f:SetWidth(BarWidth)
	f:SetHeight(BarHeight * 3)

	self:SetMovable(f)
	if ( not f:IsUserPlaced() ) then
		f:SetPoint("CENTER")
	end

	f:SetBackdrop(self.Backdrop["Tooltip4"])
	f:SetBackdropColor(self.BackdropColor["Tooltip4"])

	f.Name = f:CreateFontString(nil,"OVERLAY")
	f.Name:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"THICKOUTLINE")
	f.Name:SetPoint("TOP",f,"TOP",0,-5)
	f.Name:SetJustifyV("CENTER")
	f.Name:SetJustifyH("MIDDLE")
	f.Name:SetText(unit)
	f.Name:SetHeight(BarHeight)

	f.Shield = CreateFrame("StatusBar","$parentShield",f)
	f.Shield:SetWidth(BarWidth - 10)
	f.Shield:SetHeight(BarHeight)
	f.Shield:SetOrientation("HORIZONTAL")
	f.Shield:SetMinMaxValues(0,100)
	f.Shield:SetStatusBarColor(0,1,0,1)
	f.Shield:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	f.Shield:SetValue(0)
	f.Shield:SetPoint("BOTTOMLEFT",f,"BOTTOMLEFT",5,5)

	f.Shield.Background  = f.Shield:CreateTexture(nil,"BACKGROUND")
	f.Shield.Background:SetAllPoints()
	f.Shield.Background:Show()

	f.Shield.Text = f.Shield:CreateFontString(nil,"OVERLAY")
	f.Shield.Text:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"THICKOUTLINE")
	f.Shield.Text:SetHeight(BarHeight - 5)
	f.Shield.Text:SetWidth(BarWidth - 5)
	f.Shield.Text:SetJustifyV("CENTER")
	f.Shield.Text:SetJustifyH("MIDDLE")
	f.Shield.Text:SetAllPoints()
	f.Shield.Text:SetText("Test")
	f.Shield.Text:Show()

	f.Shield:Show()

	f.Icons = {}
	local firstIcon,lastIcon = nil,nil
	for i,v in pairs(f.unit == "player" and XSM.PlayerSpells or XSM.ShieldSpells) do
		f.Icons[v] = CreateFrame("Frame","$parent_Icon_"..v,f)
		f.Icons[v]:SetWidth(32)
		f.Icons[v]:SetHeight(32)
		if i == 1 then
			f.Icons[v]:SetPoint("TOPLEFT",f,"BOTTOMLEFT",5,-5)
			lastLineIcon = v
		elseif math.fmod(i,6) == 1 then
			f.Icons[v]:SetPoint("TOPLEFT",f.Icons[lastLineIcon],"BOTTOMLEFT",0,0)
			lastLineIcon = v
		else
			f.Icons[v]:SetPoint("TOPLEFT",f.Icons[lastIcon],"TOPRIGHT",0,0)
		end

		f.Icons[v]:SetScript("OnEnter",function(self)
			GameTooltip:SetOwner(self,"ANCHOR_CURSOR")
			GameTooltip:SetSpellByID(v)
			GameTooltip:AddLine(string.format("Spell ID: %d",v),1.0,1.0,1.0,1.0)
			GameTooltip:Show()
		end)

		f.Icons[v]:SetScript("OnLeave",function(self)
			GameTooltip:Hide()
		end)

		f.Icons[v].Texture = f.Icons[v]:CreateTexture(nil,"ARTWORK")
		f.Icons[v].Texture:SetTexture(GetSpellTexture(v))
		f.Icons[v].Texture:SetAllPoints()
		f.Icons[v].Texture:Show()

		f.Icons[v].Caption = f.Icons[v]:CreateFontString(nil,"OVERLAY","GameFontNormal")
		f.Icons[v].Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE")
		f.Icons[v].Caption:SetJustifyV("CENTER")
		f.Icons[v].Caption:SetJustifyH("MIDDLE")
		f.Icons[v].Caption:SetAllPoints()
		f.Icons[v].Caption:Show()

		f.Icons[v].Cooldown = CreateFrame("Cooldown","$parent_Cooldown",f.Icons[v],"CooldownFrameTemplate")

		f.Icons[v].Duration = CreateFrame("Cooldown","$parent_Duration",f.Icons[v],"CooldownFrameTemplate")
		f.Icons[v].Duration:SetScript("OnUpdate",function(self,elapsed)
			local spellName = GetSpellInfo(v)
			if not f.Icons[v].AuraActivated then return end
			f.Icons[v].AuraCounter = f.Icons[v].AuraCounter + elapsed
			f.Icons[v].AuraLeft = f.Icons[v].AuraDuration - f.Icons[v].AuraCounter
			if f.Icons[v].LastAuraLeft and f.Icons[v].AuraLeft > f.Icons[v].LastAuraLeft then
				CooldownFrame_SetTimer(self,f.Icons[v].AuraStart,f.Icons[v].AuraDuration,true)
				f.Icons[v].DurationStarted = true
			end
			f.Icons[v].Caption:SetText(string.format("%0.2d",f.Icons[v].AuraLeft))
			local percLeft = (( f.Icons[v].AuraLeft / f.Icons[v].AuraDuration ) * 100 )
			local auraName = UnitAura(f.unit or unit,spellName,"PLAYER HELPFUL")
			if ( not auraName and spellId == v or f.Icons[v].AuraLeft < 0 ) then
				f.Icons[v].AuraActivated = false
				f.Icons[v].Caption:SetText("")
				f.Icons[v].DurationStarted = false
				f.Icons[v]:SetAlpha(0.25)
			end
			f.Icons[v].LastAuraLeft = f.Icons[v].AuraLeft
		end)

		f.Icons[v]:SetAlpha(0.25)

		f.Icons[v]:Show()

		lastIcon = v
	end

	f.RefreshAbsorb = function(self)
		if f.Shield then
			f.MaxAbsorb = f.MaxAbsorb or UnitGetTotalAbsorbs(f.unit) or 0
			f.CurrAbsorb = UnitGetTotalAbsorbs(f.unit) or 0
			if ( f.CurrAbsorb > f.MaxAbsorb ) then f.MaxAbsorb = f.CurrAbsorb end
			f.PercAbsorb = f.MaxAbsorb > 0 and ((f.CurrAbsorb / f.MaxAbsorb) * 100) or 0
			if f.PercAbsorb < 0 then f.MaxAbsorb = 0 f.CurrAbsorb = 0 f.PercAbsorb = 0 end
			f.Shield:SetValue( f.PercAbsorb )
			HealthBar_OnValueChanged(f.Shield,f.PercAbsorb,true)
			f.Shield.Text:SetText(AbbreviateLargeNumbers(f.CurrAbsorb) .. " / " .. AbbreviateLargeNumbers(f.MaxAbsorb) .. " (" .. string.format("%0.2d",f.PercAbsorb) .. "% )")
			f.Shield.TextString = f.Shield.Text:GetText()
			f.LastAbsorb = f.CurrAbsorb
		end
	end

	f.RefreshName = function(self)
		local name = GetUnitName(f.unit) or ""
		local unitText = "(" .. f.unit ..")"
		f.Name:SetText(name .. unitText)
	end

	f.RefreshAuras = function(self)
		for i = 1,40 do
			local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, canStealOrPurge, shouldConsolidate, spellId, canApplyAura, isBossDebuff, isCastByPlayer, auraData1,auraData2,auraData3 = UnitAura(f.unit,i,"PLAYER HELPFUL")
			if name and name == "Divine Insight" then
				print(name,spellId)
			end
			if tContains(XSM.ShieldSpells,spellId) and name then
				f.Icons[tonumber(spellId)].AuraStart = GetTime()
				f.Icons[tonumber(spellId)].AuraDuration = expirationTime - f.Icons[tonumber(spellId)].AuraStart
				f.Icons[tonumber(spellId)].AuraCounter = 0
				f.Icons[tonumber(spellId)].AuraEnabled = true
				f.Icons[tonumber(spellId)].AuraActivated = true
				if ( not f.Icons[tonumber(spellId)].DurationStarted ) then
					CooldownFrame_SetTimer(f.Icons[tonumber(spellId)].Duration,f.Icons[tonumber(spellId)].AuraStart,f.Icons[tonumber(spellId)].AuraDuration,true)
					f.Icons[tonumber(spellId)].DurationStarted = true
				end
				f.Icons[tonumber(spellId)]:SetAlpha(1)
			end
		end
	end

	f.RefreshUnit = function(self)
		f.RefreshName()
		f.RefreshAbsorb()
		f.RefreshAuras()
	end

	RegisterStateDriver(f,"visibility","[@"..unit..",exists] show;hide")
	f:SetShown(UnitExists(unit))

	f:RegisterUnitEvent("UNIT_AURA",unit)
	f:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED",unit)
	f:RegisterUnitEvent("UNIT_TARGET",unit)
	f:RegisterEvent("PLAYER_ENTERING_WORLD")

	f:SetScript("OnEvent",function(self,event,...)
		if event == "UNIT_TARGET" and f.unit == "player" then
			if UnitExists("target") then
				f.TargetFrame:RefreshUnit()
			end

		elseif event == "UNIT_TARGET" and f.unit == "target" then
			if UnitExists("targettarget") then
				f.TargetFrame:RefreshUnit()
			end

		elseif event == "UNIT_TARGET" and f.unit == "focus" then
			if UnitExists("focustarget") then
				f.TargetFrame:RefreshUnit()
			end

		elseif event == "UNIT_FOCUS" and  f.unit == "player" then
			if UnitExists("focus") then
				f.FocusFrame:RefreshUnit()
			end

		elseif event == "UNIT_ABSORB_AMOUNT_CHANGED" and f.unit == ... then
			f:RefreshAbsorb()

		elseif event == "UNIT_AURA" and ... == f.unit then
			f:RefreshAuras()

		elseif event == "PLAYER_ENTERING_WORLD" then
			f.MaxAbsorb = 0
			f.CurrAbsorb = 0
			f.PercAbsorb = 0
			f.LastAbsorb = 0
			f:RefreshUnit()
			if f.TargetFrame and UnitExists(f.TargetFrame.unit) then
				f.TargetFrame:RefreshUnit()
				f.TargetFrame.TargetFrame:RefreshUnit()
			end
			if f.FocusFrame and UnitExists(f.FocusFrame.unit) then
				f.FocusFrame:RefreshUnit()
				f.FocusFrame.TargetFrame:RefreshUnit()
			end

		end
	end)

	return f
end

XSM.Events = CreateFrame("Frame")

-- check any events and deal with accordingly
XSM.Events:SetScript("OnEvent",function(self,event,...)
	local args = { ... }
	if ( event == "ADDON_LOADED" and args[1] == addonName ) then
		--XSM:CreateFrames()
		XSM.PlayerFrame = XSM:CreateShieldFrame("player")
		XSM.TargetFrame = XSM:CreateShieldFrame("target")
		XSM.PlayerFrame.TargetFrame = XSM.TargetFrame
		XSM.FocusFrame = XSM:CreateShieldFrame("focus")
		XSM.PlayerFrame.FocusFrame = XSM.FocusFrame
	end
end)

XSM.Events:RegisterEvent("ADDON_LOADED")