Quantcast

local addonName, XSM = ...

local BarWidth = 200
local BarHeight = 10
local ShieldSpell = 17   -- Priest Power Word: Shield
local FontSize = 8

XSM = XSM or {}
XSM.Events = CreateFrame("Frame","XShieldMonitor_Events",UIParent)

XSM.CreateFrames = function(self)

	-- Create the Main Bar
	XSM.Bar = CreateFrame("Frame","XShieldMonitor_Bar",UIParent)
	XSM.Bar:SetWidth(BarWidth)
	XSM.Bar:SetHeight(BarHeight * 3)
	XSM.Bar:EnableMouse(true)
	XSM.Bar:SetMovable(true)
	if ( not XSM.Bar:IsUserPlaced() ) then
		XSM.Bar:SetPoint("CENTER")
	end
	XSM.Bar:SetUserPlaced(true)
	XSM.Bar:RegisterForDrag("LeftButton")
	XSM.Bar:SetScript("OnDragStart",function(self) self:StartMoving() end)
	XSM.Bar:SetScript("OnDragStop",function(self) self:StopMovingOrSizing() end)
	XSM.Bar:Show()


	-- create the Spell Icon for the Cooldown Animation
	XSM.Icon = CreateFrame("Frame","XShieldMonitor_Icon",XSM.Bar)
	XSM.Icon:SetWidth(BarHeight * 3)
	XSM.Icon:SetHeight(BarHeight * 3)
	XSM.Icon:SetPoint("TOPLEFT")
	XSM.Icon.Texture = XSM.Icon:CreateTexture(nil,"ARTWORK")
	XSM.Icon.Texture:SetTexture(GetSpellTexture(ShieldSpell))
	XSM.Icon.Texture:SetAllPoints()
	XSM.Icon.Texture:Show()
	XSM.Icon.Caption = XSM.Icon:CreateFontString(nil,"OVERLAY","GameFontNormal")
	XSM.Icon.Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE")
	XSM.Icon.Caption:SetJustifyV("CENTER")
	XSM.Icon.Caption:SetJustifyH("MIDDLE")
	XSM.Icon.Caption:SetAllPoints()
	XSM.Icon.Caption:Show()
	XSM.Icon.Cooldown = CreateFrame("Cooldown","XShieldMonitor_Icon_Cooldown",XSM.Icon,"CooldownFrameTemplate")
	XSM.Icon.Duration = CreateFrame("Cooldown","XShieldMonitor_Icon_Duration",XSM.Icon,"CooldownFrameTemplate")
	XSM.Icon:Show()


	-- the Cooldown Bar
	XSM.Cooldown = CreateFrame("StatusBar","XShieldMonitor_Cooldown",XSM.Bar)
	XSM.Cooldown.Background = XSM.Cooldown:CreateTexture(nil,"BACKGROUND")
	XSM.Cooldown.Background:SetTexture(0,0,0)
	XSM.Cooldown.Background:SetAllPoints()
	XSM.Cooldown.Background:Show()
	XSM.Cooldown.Caption = XSM.Cooldown:CreateFontString(nil,"OVERLAY","GameFontNormal")
	XSM.Cooldown.Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE")
	XSM.Cooldown.Caption:SetJustifyV("CENTER")
	XSM.Cooldown.Caption:SetJustifyH("MIDDLE")
	XSM.Cooldown.Caption:SetAllPoints()
	XSM.Cooldown.Caption:Show()
	XSM.Cooldown:SetWidth(BarWidth - (BarHeight * 3))
	XSM.Cooldown:SetHeight(BarHeight)
	XSM.Cooldown:SetOrientation("HORIZONTAL")
	XSM.Cooldown:SetMinMaxValues(0,100)
	XSM.Cooldown:SetStatusBarColor(0,0,1,1)
	XSM.Cooldown:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	XSM.Cooldown:SetValue(0)
	XSM.Cooldown:SetPoint("TOPLEFT",XSM.Icon,"TOPRIGHT",0,0)
	XSM.Cooldown:SetPoint("RIGHT")
	XSM.Cooldown:SetScript("OnUpdate",function(self,elapsed)
		if not XSM.CDActivated then return end
		XSM.CDCounter = XSM.CDCounter + elapsed
		XSM.CDLeft = XSM.CDDuration - XSM.CDCounter
		XSM.Cooldown.Caption:SetText(string.format("%0.2d",XSM.CDLeft))
		local percLeft = (( XSM.CDLeft / XSM.CDDuration ) * 100 )
		XSM.Cooldown:SetValue(percLeft)
		if ( XSM.CDCounter and XSM.CDCounter >= XSM.CDDuration ) then
			XSM.CDActivated = false
		end
	end)
	XSM.Cooldown:Show()

	-- The Shield Status Bar
	XSM.Status = CreateFrame("StatusBar","XShieldMonitor_Status",XSM.Bar)
	XSM.Status.Background  = XSM.Status:CreateTexture(nil,"BACKGROUND")
	XSM.Status.Background:SetTexture(0,0,0)
	XSM.Status.Background:SetAllPoints()
	XSM.Status.Background:Show()
	XSM.Status.Caption = XSM.Status:CreateFontString(nil,"OVERLAY","GameFontNormal")
	XSM.Status.Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE")
	XSM.Status.Caption:SetJustifyV("CENTER")
	XSM.Status.Caption:SetJustifyH("MIDDLE")
	XSM.Status.Caption:SetAllPoints()
	XSM.Status.Caption:Show()
	XSM.Status:SetWidth(BarWidth - (BarHeight * 3))
	XSM.Status:SetHeight(BarHeight)
	XSM.Status:SetOrientation("HORIZONTAL")
	XSM.Status:SetMinMaxValues(0,100)
	XSM.Status:SetStatusBarColor(0,1,0,1)
	XSM.Status:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	XSM.Status:SetValue(0)
	XSM.Status:SetPoint("TOPLEFT",XSM.Cooldown,"BOTTOMLEFT",0,0)
	XSM.Status:SetPoint("RIGHT")
	XSM.Status:Show()

	-- The Aura duration Bar
	XSM.Timer = CreateFrame("StatusBar","XShieldMonitor_Timer",XSM.Bar)
	XSM.Timer.Background = XSM.Timer:CreateTexture(nil,"BACKGROUND")
	XSM.Timer.Background:SetTexture(0,0,0)
	XSM.Timer.Background:SetAllPoints()
	XSM.Timer.Background:Show()
	XSM.Timer.Caption = XSM.Timer:CreateFontString(nil,"OVERLAY","GameFontNormal")
	XSM.Timer.Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE")
	XSM.Timer.Caption:SetJustifyV("CENTER")
	XSM.Timer.Caption:SetJustifyH("MIDDLE")
	XSM.Timer.Caption:SetAllPoints()
	XSM.Timer.Caption:Show()
	XSM.Timer:SetWidth(BarWidth - (BarHeight * 3))
	XSM.Timer:SetHeight(BarHeight)
	XSM.Timer:SetOrientation("HORIZONTAL")
	XSM.Timer:SetMinMaxValues(0,100)
	XSM.Timer:SetStatusBarColor(1.0,0.0,0.0,1.0)
	XSM.Timer:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	XSM.Timer:SetValue(0)
	XSM.Timer:SetPoint("TOPLEFT",XSM.Status,"BOTTOMLEFT",0,0)
	XSM.Timer:SetPoint("RIGHT")
	XSM.Timer:SetScript("OnUpdate",function(self,elapsed)
		if not XSM.AuraActivated then return end
		XSM.AuraCounter = XSM.AuraCounter + elapsed
		XSM.AuraLeft = XSM.AuraDuration - XSM.AuraCounter
		XSM.Timer.Caption:SetText(string.format("%0.2d",XSM.AuraLeft))
		local percLeft = (( XSM.AuraLeft / XSM.AuraDuration ) * 100 )
		XSM.Timer:SetValue(percLeft)
		if ( XSM.AuraCounter and XSM.AuraCounter >= XSM.AuraDuration ) then
			XSM.AuraActivated = false
		end
	end)
	XSM.Timer:Show()
end

-- Check the Aura Duration for the Shield Spell and update the timers accordingly
XSM.CheckAura = function(self,...)
	if ( XSM.AuraActivated ) then return end
	XSM.AuraStart, XSM.AuraDuration, XSM.AuraCounter, XSM.AuraEnabled,XSM.AuraActivated = nil,nil,nil,nil,false
	XSM.AuraActivated = false
	for i = 1,40 do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, canStealOrPurge, shouldConsolidate, spellId, canApplyAura, isBossDebuff, isCastByPlayer, auraData = UnitAura("player",i,"HELPFUL PLAYFUL")
		if ( not name ) then break end
		if ( spellId == ShieldSpell ) then
			XSM.AuraStart = GetTime()
			XSM.AuraDuration = duration
			XSM.AuraEnabled = true
			XSM.AuraCounter = 0
			XSM.AuraActivated = true
			break
		end
	end
	CooldownFrame_SetTimer(XSM.Icon.Duration,XSM.AuraStart,XSM.AuraDuration,XSM.AuraEnabled)
end

-- Check the Absorb Value as this will affect the shield status
XSM.CheckAbsorbs = function(self,...)
	local args = { ... }
	XSM.MaxAbsorb = XSM.MaxAbsorb or UnitGetTotalAbsorbs(args[1])
	XSM.CurrAbsorb = UnitGetTotalAbsorbs(args[1])
	XSM.PercAbsorb = ((XSM.CurrAbsorb / XSM.MaxAbsorb) * 100)
	if XSM.PercAbsorb < 0 then XSM.MaxAbsorb = 0 end
	XSM.Status:SetValue( XSM.PercAbsorb )
	XSM.Status.Caption:SetText(XSM.CurrAbsorb .. "/" .. XSM.MaxAbsorb .. " (" .. string.format("%0.2d",XSM.PercAbsorb) .. "% )")
end

-- Check the shield spell cooldown
XSM.CheckCooldowns = function(self,...)
	if XSM.CDActivated then return end
	XSM.CDStart, XSM.CDDuration, XSM.CDEnabled, XSM.CDActivated = nil,nil,nil,false
	XSM.CDStart, XSM.CDDuration, XSM.CDEnabled = GetSpellCooldown(ShieldSpell)
	if not XSM.CDEnabled then return end
	if ( XSM.CDDuration ~= nil and XSM.CDDuration > 2 ) then
		XSM.CDCounter = 0
		XSM.CDActivated = true
	end
	if XSM.CDActivated then CooldownFrame_SetTimer(XSM.Icon.Cooldown,XSM.CDStart,XSM.CDDuration,XSM.CDEnabled) end
end

-- 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()
	elseif ( event == "UNIT_AURA" ) then
		XSM:CheckAura(...)
	elseif ( event == "UNIT_ABSORB_AMOUNT_CHANGED" ) then
		XSM:CheckAbsorbs(...)
	elseif ( event == "SPELL_UPDATE_COOLDOWN" ) then
		XSM:CheckCooldowns(...)
	end
end)

XSM.Events:RegisterEvent("ADDON_LOADED")
XSM.Events:RegisterUnitEvent("UNIT_AURA","player")
XSM.Events:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED","player")
XSM.Events:RegisterEvent("SPELL_UPDATE_COOLDOWN")