Quantcast
phUnitFrame = {
	create = function(parent,frame)
		local config = parent.config;
        local model = phUnitFramesModels[config.model];

		if not frame then
			frame = CreateFrame("Button",nil,parent,"SecureUnitButtonTemplate");
			frame:SetPoint("CENTER",0,0);

			-- Barre

			frame.config = config;
			frame.alpha = 0.9;
			frame.order = 100;
			frame.name = "?";
			frame.disp_role = 0;
			frame.createTooltip = phUnitFrame.createTooltip;


            local bar = frame:CreateTexture();
            bar:SetTexture("Interface\\AddOns\\phUnitFrames\\uiStatusBar");
            bar:SetVertexColor(1,0,0,0.5);
			bar:SetPoint("TOPLEFT",frame,"TOPLEFT");
			bar:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT");

			frame.ibar = CreateFrame("StatusBar",nil,frame);
			frame.ibar:SetStatusBarTexture("Interface\\AddOns\\phUnitFrames\\uiStatusBar");
			frame.ibar:SetMinMaxValues(0, 100);
			frame.ibar:SetValue(0);
			frame.ibar:SetStatusBarColor(0,0.5,0.5);
			frame.ibar:SetPoint("TOPLEFT",frame,"TOPLEFT");
			frame.ibar:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT");

			frame.bar = CreateFrame("StatusBar",nil,frame);
            frame.bar:SetFrameLevel(frame.ibar:GetFrameLevel()+1);
			frame.bar:SetStatusBarTexture("Interface\\AddOns\\phUnitFrames\\uiStatusBar");
			frame.bar:SetMinMaxValues(0, 100);
			frame.bar:SetValue(100);
			frame.bar:SetStatusBarColor(0,1,0);
			frame.bar:SetPoint("TOPLEFT",frame,"TOPLEFT");
			frame.bar:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT");

			frame.licon = frame.bar:CreateTexture(nil,"OVERLAY");
			frame.licon:SetPoint("LEFT",0,0);
            frame.licon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconThreat");
			frame.licon:Hide();

			frame.icon = frame.bar:CreateTexture(nil,"OVERLAY");
			frame.icon:SetPoint("RIGHT",0,0);
			frame.icon:Hide();

			frame.loc = frame.bar:CreateFontString(nil,"ARTWORK");
			frame.loc:SetFontObject(GameFontHighlightSmall);
			frame.loc:SetPoint("BOTTOMRIGHT",0,0);
			frame.loc:SetText("Very Very Long Location Name");
            frame.loc:Hide();

			frame.text = frame.bar:CreateFontString(nil,"ARTWORK");
			frame.text:SetFontObject(GameFontHighlightSmall);
			frame.text:SetPoint("LEFT",2,0);
			frame.text:SetText("Nom");


			frame:SetScript("OnEnter",function(frame)
				frame:SetAlpha(1);
				frame.mouseover = true;
				frame:createTooltip(frame.unit);
			end);
			frame:SetScript("OnLeave",function(frame)
				frame.mouseover = false;
				frame:SetAlpha(frame.alpha);
				GameTooltip:Hide();
			end);

		--[[	frame:RegisterEvent("UNIT_HEALTH");
			frame:RegisterEvent("UNIT_MAXHEALTH");
		 	frame:RegisterEvent("UNIT_AURA");
			frame:RegisterEvent("UNIT_NAME_UPDATE");
            frame:RegisterEvent("UNIT_HEAL_PREDICTION");
            frame:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE");
			frame:SetScript("OnEvent",function(frame,event,...)
				if event == "PLAYER_TARGET_CHANGED" or "PLAYER_FOCUS_CHANGED" then
					phUnitFrame.update(frame,event);
				elseif frame.unit then
					local unit = ...;
					if UnitIsUnit(unit,frame.unit) then
						phUnitFrame.update(frame,event);
					end;
				end;
			end);--]]

            frame.auras = {};
			frame.buffs = phUnitFrame.createAuraButtons(frame,model.buffs);
			frame.debuffs = phUnitFrame.createAuraButtons(frame,model.debuffs);

            RegisterUnitWatch(frame);
			frame.changeUnit = phUnitFrame.changeUnit;
			frame.updateUnit = phUnitFrame.updateUnit;
			frame.updateBars = phUnitFrame.updateBars;
		else
			phUnitFrame.createAuraButtons(frame,model.buffs,frame.buffs);
			phUnitFrame.createAuraButtons(frame,model.debuffs,frame.debuffs);
		end;

		frame:SetWidth(config.width);
		frame:SetHeight(config.height);
		frame.text:SetFont(STANDARD_TEXT_FONT,config.fontsize);
		frame.loc:SetFont(STANDARD_TEXT_FONT,config.fontsize-3);
		frame.icon:SetWidth(config.height);
		frame.icon:SetHeight(config.height);
		frame.licon:SetWidth(config.height);
		frame.licon:SetHeight(config.height);
        phUnitFrame.createButtonAttributes(frame,model.spells);

		return frame;
	end,

	changeUnit = function(frame,unit,raidIdx)
        if unit then
            local guid = UnitGUID(unit);
            if guid then
                frame.role = phPlayerRoles[guid];
            else
                frame.role = nil;
            end;
        end;

        if frame.unit == unit then
			return;
		end;

		--[[if unit == "target" then
			frame:RegisterEvent("PLAYER_TARGET_CHANGED");
		else
			frame:UnregisterEvent("PLAYER_TARGET_CHANGED");
		end;
		if unit == "focus" then
			frame:RegisterEvent("PLAYER_FOCUS_CHANGED");
		else
			frame:UnregisterEvent("PLAYER_FOCUS_CHANGED");
		end;--]]

		frame.unit = unit;
        frame.raidIdx = raidIdx;
		frame:SetAttribute ("unit",unit);
		for i,button in pairs(frame.buffs) do
			button:SetAttribute ("unit",unit);
		end;
		for i,button in pairs(frame.debuffs) do
			button:SetAttribute ("unit",unit);
		end;
	end,

	createAuraButtons = function(frame,bconfig,list)
		if not list then
			list = {};
		end;
		local lastbutton = frame;
		local config = frame.config;
		for i=1,bconfig.max do
			local button = list[i];
			if not button then
                if i <= 2 then
				    button = CreateFrame("Button",nil,frame,"SecureUnitButtonTemplate");
                    button.isSecure = true;
                else
                    button = CreateFrame("Button",nil,frame);
                end;
				button.frame = frame;
				button.createTooltip = phUnitFrame.createTooltip;

				button.icon = button:CreateTexture(nil,"BACKGROUND");
				button.icon:SetAllPoints(button);

				button.cooldown = CreateFrame("Cooldown",nil,button,"CooldownFrameTemplate");
				button.cooldown:SetPoint("CENTER",0,0);
				button.cooldown:SetReverse(true);

				button.count = button:CreateFontString(nil,"ARTWORK");
				button.count:SetFontObject(NumberFontNormalSmall);
				button.count:SetPoint("BOTTOMRIGHT",4,0);
				button.count:SetText("99");

				button:SetScript("OnEnter",function(button)
					button:createTooltip(button.frame.unit);
				end);
				button:SetScript("OnLeave",function(button)
					GameTooltip:Hide();
				end);

				list[i] = button;
			end;

			button:SetPoint(bconfig.left,lastbutton,bconfig.right);
			button:SetWidth(config.height);
			button:SetHeight(config.height);

			if bconfig.types and bconfig.types[i] then
				button.type = bconfig.types[i];
            else
                button.type = nil;
			end

            if button.isSecure then
			    phUnitFrame.createButtonAttributes(button,bconfig.spells[i]);
            end;

			lastbutton = button;
		end
		return list;
	end,

	createButtonAttributes = function(button,spells)
		button:RegisterForClicks ("AnyUp");
		button:SetAttribute("alt-ctrl-type2","menu");
		button.menu = phUnitFrame.buttonMenu;
        button:SetAttribute("type1",nil);
        button:SetAttribute("type2",nil);
        button:SetAttribute("shift-type1",nil);
        button:SetAttribute("shift-type2",nil);
        button:SetAttribute("ctrl-type1",nil);
        button:SetAttribute("ctrl-type2",nil);
        if not spells then
		    button.tooltip = nil;
            return;
        end;
		button.tooltip = {};
		for count=1,table.getn(spells) do
			local name = "?";
			local action = "?";
			for attr,value in pairs(spells[count]) do
				button:SetAttribute(attr,value);
				if attr == "type1" then
					action = "|cff69ccf0 "..phLib.getLocale("Left click").." |r ";
				elseif attr == "type2" then
					action = "|cff69ccf0 "..phLib.getLocale("Right click").." |r ";
				elseif attr == "shift-type1" then
					action = "|cff69ccf0 Shift+"..phLib.getLocale("Left click").." |r ";
				elseif attr == "shift-type2" then
					action = "|cff69ccf0 Shift+"..phLib.getLocale("Right click").." |r ";
				elseif attr == "ctrl-type1" then
					action = "|cff69ccf0 Ctrl+"..phLib.getLocale("Left click").." |r ";
				elseif attr == "ctrl-type2" then
					action = "|cff69ccf0 Ctrl+"..phLib.getLocale("Right click").." |r ";
				elseif string.find(attr,"spell") then
					local spellname, rank, icon, cost, isFunnel, powerType, castTime, minRange, maxRange = GetSpellInfo(value);
					if rank and rank ~= "" then
						name = spellname.." ("..rank..")";
					elseif spellname then
						name = spellname;
					else
						name = "?";
					end;
					if button.icon then
						button.icon:SetTexture(icon);
					end;
				end;
				if value == "target" then
					name = phLib.getLocale("Target");
				elseif value == "assist" then
					name = phLib.getLocale("Assist");
				elseif value == "focus" then
					name = phLib.getLocale("Set focus");
				end;
			end;
			button.tooltip[count] = action..name;
        end;
	end,

	buttonMenu = function(button)
        if button.unit then
            local menu = {
                { text = phLib.getLocale("Role"), notCheckable = true, hasArrow = true, menuList = {
                        { text = phLib.getLocale("Default"), checked = (not button.role), arg1 = button, arg2 = nil, func = phUnitFrame.changeRole },
                        { text = phLib.getLocale("Tank"), checked = (button.role == 1), arg1 = button, arg2 = 1, func = phUnitFrame.changeRole },
                        { text = phLib.getLocale("Damage"),  checked = (button.role == 2), arg1 = button, arg2 = 2, func = phUnitFrame.changeRole },
                        { text = phLib.getLocale("Heal"), checked = (button.role == 3), arg1 = button, arg2 = 3, func = phUnitFrame.changeRole },
                    }
                }
            };
            EasyMenu(menu, phMenuFrame, "cursor", 0 , 0, "MENU", 5);
        end
	end,

	changeRole = function(menu,button,newrole,checked)
		button.role = newrole;
		local guid = UnitGUID(button.unit);
		if guid then
			phPlayerRoles[guid] = newrole;
		end;
		CloseDropDownMenus();
	end,

	createTooltip = function(button,unit)
		if unit and UnitExists(unit) then
			if button.auraIndex and button.auraIndex > 0 and button.filter then
			    GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT", 0, 0);
				GameTooltip:SetUnitAura(unit,button.auraIndex,button.filter);

  --              GameTooltip:AddLine(button:GetAlpha());
  --              GameTooltip:AddLine(button:IsShown());
  --              GameTooltip:AddLine(button.aura.duration);

                if button.tooltip and not InCombatLockdown() then
                    GameTooltip:AddLine (" ");
                    GameTooltip:AddLine (phLib.getLocale("Cast spells on %s",UnitName(unit)).." :",1,1,1);
                    for i,msg in pairs(button.tooltip) do
                        GameTooltip:AddLine (msg);
                    end;
                end;
                GameTooltip:Show();
			elseif not InCombatLockdown() then
			    GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT", 0, 0);
				GameTooltip:SetUnit(unit);
                if button.tooltip then
                    GameTooltip:AddLine (" ");
                    GameTooltip:AddLine (phLib.getLocale("Cast spells on %s",UnitName(unit)).." :",1,1,1);
                    for i,msg in pairs(button.tooltip) do
                        GameTooltip:AddLine (msg);
                    end;
                end;
                GameTooltip:Show();
            end;
		end;
	end,

	updateUnit = function(frame,event)
		local unit = frame.unit;

		if not frame.mouseover then
			frame:SetAlpha(frame.alpha);
		end;

	    frame.icon:SetTexCoord(0,1,0,1);
        frame.icon:SetVertexColor(1,1,1);
		frame.icon:Hide();
        frame.loc:Hide();
        frame.licon:Hide();
        frame.text:SetPoint("LEFT",2,0);

        if not unit or not UnitExists(unit) then
		    frame.text:SetTextColor(1,1,1);
			phUnitFrame.updateSimple(frame,unit);
            frame.bars = false;
			return;
		end

		local role = frame.role;
		if not role then
			local r = UnitGroupRolesAssigned(unit);
            if not r then role = 2;
            elseif r == "TANK" then role = 1;
            elseif r == "DAMAGER" then role = 2;
            elseif r == "HEALER" then role = 3;
			else role = 2;
			end;
		end;
		frame.disp_role = role;

		local _,className = UnitClass(unit);
		local c = RAID_CLASS_COLORS[className];
		if not c then
			c = { r=1,g=1,b=1 };
		end;
		frame.text:SetTextColor(c.r,c.g,c.b);

		if frame.config.showrole and role > 0 then
			frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconRoles");
			if role == 1 then
				frame.icon:SetTexCoord(0, 19/64, 22/64, 41/64);
			elseif role == 2 then
				frame.icon:SetTexCoord(20/64, 39/64, 22/64, 41/64);
			elseif role == 3 then
				frame.icon:SetTexCoord(20/64, 39/64, 1/64, 20/64);
			end;
			frame.icon:Show();
		end;

		if not UnitIsConnected(unit) then
			phUnitFrame.updateSimple(frame,UnitName(unit));
			frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconOffline");
			frame.icon:Show();
            frame.bars = false;
			return;
		end;
		if UnitIsGhost(unit) then
			phUnitFrame.updateSimple(frame,UnitName(unit));
			frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconGhost");
			frame.icon:Show();
            frame.bars = false;
			return;
		end
		if UnitIsDead(unit) then
			phUnitFrame.updateSimple(frame,UnitName(unit));
			frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconDead");
			frame.icon:Show();
            frame.bars = false;
			return;
		end
		if not UnitIsVisible(unit) then
			phUnitFrame.updateSimple(frame,UnitName(unit));
            if frame.raidIdx then
                local _,_,_,_,_,_,zone = GetRaidRosterInfo(frame.raidIdx);
                frame.loc:SetText(zone);
                frame.loc:Show();
            else
			    frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconAway");
			    frame.icon:Show();
            end;
            frame.bars = false;
			return;
		end

        frame.bars = true;


		if UnitIsFriend("player",unit) then
		    frame.bar:SetStatusBarColor(0,1,0);
            local threat = UnitThreatSituation(unit);
            if threat and threat >= 1 then
			    frame.licon:SetVertexColor(GetThreatStatusColor(threat));
			    frame.licon:Show();
                frame.text:SetPoint("LEFT",frame.licon,"RIGHT");
            end;
		else
			frame.bar:SetStatusBarColor(1,0,0);
			frame.alpha = 0.9;
		end


        if UnitIsAFK(unit) then
			frame.icon:SetTexture("Interface\\AddOns\\phUnitFrames\\iconAfk");
			frame.icon:SetTexCoord(0, 1, 0, 1);
			frame.icon:Show();
		end
		frame.name = UnitName(unit);
		frame.text:SetText(frame.name);

		frame.order = PHCLASS_ORDER[className];
		if not frame.order then
			frame.order = 100;
		end;
    end,

    updateBars = function(frame)
        local unit = frame.unit;
        if not frame.bars or not unit or not UnitExists(unit) then
			return;
		end

		if not UnitInRange(unit) then
			frame.alpha = 0.4;
		else
			frame.alpha = 0.9;
		end;

        frame.ibar:SetMinMaxValues(0,UnitHealthMax(unit));
        local ival = UnitHealth(unit);
        local x = UnitGetIncomingHeals(unit);
        if x then
            ival = ival + x;
        end
        frame.ibar:SetValue(ival);
		frame.bar:SetMinMaxValues(0,UnitHealthMax(unit));
		frame.bar:SetValue(UnitHealth(unit));

        local model = phUnitFramesModels[frame.config.model];
        phUnitFrame.updateAuras(frame,frame.buffs,model.buffs);
        phUnitFrame.updateAuras(frame,frame.debuffs,model.debuffs);
    end,

	updateSimple = function(frame,msg)
		frame.alpha = 0.5;
		frame.text:SetText(msg);
		frame.ibar:SetMinMaxValues(0, 100);
		frame.ibar:SetValue(0);
		frame.bar:SetStatusBarColor(0.5,0.5,0.5);
		frame.bar:SetMinMaxValues(0, 100);
		frame.bar:SetValue(100);
		for i,button in pairs(frame.buffs) do
            if button.isSecure then
			    button:SetAlpha(0);
            else
                button:Hide();
            end;
        end;
		for i,button in pairs(frame.debuffs) do
            if button.isSecure then
			    button:SetAlpha(0);
            else
                button:Hide();
            end;
        end;
	end,

    parseHotTooltip = function(frame,buffIndex,filter)
        if spellId == 139 then
            phTooltip:SetUnitAura(frame.unit,buffIndex,filter)
            local lt2 = phTooltip.leftTexts[2];
            print (lt2);
        end;
    end,

	updateAuras = function(frame,buttons,bconfig)
		local list = frame.auras;
        local auraCount = 0;
		for i=1,100 do
			local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId = UnitAura(frame.unit,i,bconfig.filter);
			if name == nil then
				break;
			end;
            if not list[i] then
                list[i] = {};
            end;
            if not count or count == 0 then
                count = 1;
            end;
            list[i].index = i;
            list[i].type = debuffType;
            list[i].icon = icon;
            list[i].count = count;
            list[i].caster = unitCaster;
            list[i].duration = duration;
            list[i].expirationTime = expirationTime;
            list[i].spellId = spellId;
            auraCount = i;

            if phUnitFramesConfig.showHotValues then
                phUnitFrame.parseHotTooltip(button,i,bconfig.filter);
            end;
		end;

		local b;
		for i=1,table.getn(buttons) do
			local button = buttons[i];
			if not button.type then
				b = i;
				break;
			end;
			local count = 0;
            local found;
			for j=1,auraCount do
                local aura = list[j];
				if aura.type == button.type or (aura.type == nil and button.type == "None") then
                    found = aura;
					count = count + aura.count;
                    aura.count = -1;
				end;
			end;
			if found then
				phUnitFrame.updateAura(button,bconfig.filter,found,count);
            else
                button.auraIndex = 0;
                button:SetAlpha(0);
			end;
		end

		if not buttons[b] then
			return;
		end;

		local order = bconfig.rest;
		if InCombatLockdown() then
			order = bconfig.combat;
		end;

		for i=1,table.getn(order) do
            local button = buttons[b];
            if not button then
                break;
            end;

            local count = 0;
            local found;
			local spellId = order[i];
            for j=1,auraCount do
                local aura = list[j];
                if aura.count > 0 and aura.spellId == spellId then
                    count = count + aura.count;
                    if not found or aura.caster == "player" then
                        found = aura;
                    end;
                end;
            end;

            if found then
                phUnitFrame.updateAura(button,bconfig.filter,found,count);
                b = b + 1;
            end;
		end;

		while true do
            local button = buttons[b];
            if not button then
                break;
            end;
            button.auraIndex = 0;
            if button.isSecure then
			    button:SetAlpha(0);
            else
                button:Hide();
            end;
            b = b + 1;
		end;

--[[
		local j = 1;
		for i=1,table.getn(buttons) do
			local button = buttons[i];
			if button.type == nil and list[j] ~= nil then
				phUnitFrame.updateAura(button,filter,list[j]);
				j = j + 1;
			endz
		end;

		--]]
	end,

	updateAura = function(button,filter,aura,count)
		button.filter = filter;
		button.auraIndex = aura.index;
        button.aura = aura;
		if (count > 1) then
			button.count:SetText(count);
		else
			button.count:SetText(nil);
		end
		if aura.duration and aura.duration > 0 then
			CooldownFrame_SetTimer(button.cooldown,aura.expirationTime-aura.duration,aura.duration,1);
			button.cooldown:Show();
			--button.cooldown:SetAlpha(1);
		else
			button.cooldown:Hide();
			--button.cooldown:SetAlpha(0);
		end;
		button.icon:SetTexture(aura.icon);
	    button:SetAlpha(1);
        if not button.isSecure then
            button:Show();
        end;
        if GameTooltip:IsOwned(button) then
			button:createTooltip(button.frame.unit);
		end;
	end,

}