Quantcast
local f  = CreateFrame("frame",nil,UIParent);
HealerManaWatchSaved = {}


local watching = {}
local bars = {}
local modactive = false
--changes the bar size
local barsize = {["width"]=50,["height"]=20}


f:SetWidth(barsize.width)

function f:OnLoad()
    f:SetScript("OnEvent",f.EventHandler);
	f:RegisterEvent("RAID_ROSTER_UPDATE");
	f:RegisterEvent("PARTY_MEMBERS_CHANGED");
	f:RegisterEvent("ADDON_LOADED");
end

function f:CreateOrReturnBar(pos,playername,playercolor,online,isdead)
	if(not bars[pos]) then

		local d = CreateFrame("StatusBar",nil,f)
		d:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
		d:GetStatusBarTexture():SetHorizTile(false)
		d:SetOrientation("HORIZONTAL")
		d:SetMinMaxValues(0,100)
		d:SetValue(100)
		d:SetWidth(barsize.width)
		d:SetHeight(barsize.height)
		d:SetBackdrop({bgFile = "Interface/RAIDFRAME/UI-RaidFrame-GroupBg"});
		d.mtext = d:CreateFontString(nil, "OVERLAY", "TextStatusBarText");
		d.mtext:SetPoint("CENTER", d);
		d.mtext:SetWidth(barsize.width)
		d.playername = d:CreateFontString(nil, "OVERLAY", "TextStatusBarText");

		bars[pos] = d
	end
		if(online==nil or isdead==1) then
			f:SetDeadOrOffline(pos,online,isdead)
		else
			f:SetAlive(pos);
		end

		f:ShortenName(playername,bars[pos].playername);
		bars[pos].playername:SetWidth(barsize.width)
		bars[pos].playername:SetTextColor(playercolor.r,playercolor.g,playercolor.b);
		local textheight = bars[pos].playername:GetStringHeight()
		bars[pos].playername:SetWidth(barsize.width)
		bars[pos].playername:SetPoint("TOP",bars[pos],0,textheight);
		if(pos==1) then
			bars[pos]:SetPoint("TOPLEFT",f,0,-(textheight));
		else
			bars[pos]:SetPoint("BOTTOM",bars[pos-1],0,-(bars[pos]:GetHeight()+textheight));
		end
	f:SetHeight(pos*(textheight+barsize.height))
	return bars[pos]
end

function f:SetAlive(pos)
	bars[pos]:SetStatusBarColor(0.0,0.0,1.0);
end

function f:SetDeadOrOffline(pos,online,isdead)
	bars[pos]:SetStatusBarColor(0.7,0.7,0.7);
	if(online==nil) then
		bars[pos].mtext:SetText("offline");
	elseif(isdead==1) then
		bars[pos].mtext:SetText("dead");
	end
end

function f:ShortenName(name,obj)
	obj:SetText(name);
	if(obj:GetStringWidth()>barsize.width) then
		for i=strlen(name),1,-1 do
			obj:SetText(strsub(name,1,i).."...")
			if(obj:GetStringWidth()<=barsize.width) then
				return;
			end
		end

	end

end

function f:EventHandler(event,...)
	if(event=="RAID_ROSTER_UPDATE") then
		if not(UnitInRaid("player")) then
			f:DisableMod();
			f:RegisterEvent("PARTY_MEMBERS_CHANGED"); --reactive party watching on raid leave
			return;
		end
		local _,name,class,role
		watching = {}
		f:HideBars();
		local run =1
		for i=1,GetNumRaidMembers() do
			name,_,_,_,_,class,_,online,_,_,_,role = GetRaidRosterInfo(i);
			if(role=="HEALER") then
				watching["raid"..i]=run;
				isdead = UnitIsDeadOrGhost("raid"..i)
				local mb = f:CreateOrReturnBar(run,name,RAID_CLASS_COLORS[class],online,isdead)
				if(online==1 and isdead==nil) then
					f:UpdateMana("raid"..i,"MANA");
				end
				mb:Show()
				run=run+1;
			end
		end
		if (modactive==false) then
			f:EnableMod()
		end
	elseif(event=="PARTY_MEMBERS_CHANGED") then

		if UnitInRaid("player") then
			f:UnregisterEvent("PARTY_MEMBERS_CHANGED"); --no need to use this if in raid
			return
		elseif not(UnitInParty("player")) then
			f:DisableMod();
			return
		end

		watching = {}
		f:HideBars();
		local unittowatch;
		if(UnitGroupRolesAssigned("player")=="HEALER") then
			unittowatch = "player";
		else
			for i=1,GetNumPartyMembers() do
				if(UnitGroupRolesAssigned("party"..i) == "HEALER") then
					unittowatch = "party"..i;
				end
			end
		end
		if(unittowatch == nil) then
			if (modactive==true) then
				f:DisableMod();
				modactive=false;
			end
			return; --no healer in party currently
		end


		local _,isdead,online,name,class;
		watching[unittowatch]=1;
		isdead = UnitIsDeadOrGhost(unittowatch);
		name = UnitName(unittowatch);
		online = UnitIsConnected(unittowatch);
		_,class = UnitClass(unittowatch);

		local mb = f:CreateOrReturnBar(1,name,RAID_CLASS_COLORS[class],online,isdead)
		if(online==1 and isdead==nil) then
			f:UpdateMana(unittowatch,"MANA");
		end
		mb:Show()


		if (modactive==false) then
			f:EnableMod()
		end

	elseif(event=="UNIT_POWER" or event=="UNIT_MAXPOWER") then
		local unitid,powertype = ...;
		f:UpdateMana(unitid,powertype);
	elseif(event=="UNIT_FLAGS") then
		local unitid = ...;
		if(watching[unitid]) then
			f:UpdateMana(unitid,"MANA");
		end
	elseif(event=="UNIT_CONNECTION") then
		local unitid = ...;
		if(watching[unitid]) then
			f:SetDeadOrOffline(watching[unitid],nil,nil)
		end
	elseif(event=="ADDON_LOADED") then
		local addonname = ...;
		if(addonname=="HealerManaWatch") then
			if not(HealerManaWatchSaved.points) then
				f:SetPoint("CENTER",UIParent);
			else
				f:SetPoint(unpack(HealerManaWatchSaved.points))
			end
		end

	end
end

function f:EnableMod()
	f:RegisterEvent("UNIT_POWER")
	f:RegisterEvent("UNIT_MAXPOWER")
	f:RegisterEvent("UNIT_CONNECTION")
	f:RegisterEvent("UNIT_FLAGS")
	f:Show();
	modactive=true;
end

function f:DisableMod()
	f:UnregisterEvent("UNIT_POWER")
	f:UnregisterEvent("UNIT_MAXPOWER")
	f:UnregisterEvent("UNIT_CONNECTION")
	f:UnregisterEvent("UNIT_FLAGS")
	modactive=false
	f:Hide();
end

function f:HideBars()
	for _,v in pairs(bars) do
		v:Hide();
	end
end

function f:UpdateMana(unitid,powertype)
	if(watching[unitid] and powertype=="MANA") then
		if(UnitIsDeadOrGhost(unitid)) then
			f:SetDeadOrOffline(watching[unitid],1,1)
		elseif(UnitIsConnected(unitid)==1) then
			f:SetAlive(watching[unitid]);
			local curmana = ceil(UnitPower(unitid)/UnitPowerMax(unitid) * 100);
			bars[watching[unitid]]:SetValue(curmana);
			bars[watching[unitid]].mtext:SetText(curmana.."%");
		end
	end
end
f:Hide();
f:EnableMouse(true)
f:RegisterForDrag("LeftButton");
f:SetMovable(true);
f:SetScript("OnDragStart", function(self) if IsShiftKeyDown() then self:StartMoving() end end)
f:SetScript("OnDragStop", function(self) self:StopMovingOrSizing(); local a,b,c,d,e = self:GetPoint(); if(b~=nil) then b=b:GetName(); end; HealerManaWatchSaved.points = {a,b,c,d,e} end);
f:OnLoad();