----------------------
-- Loading Function --
----------------------

-- XPerl_TargetTarget_OnLoad
function XPerl_TargetTarget_OnLoad(self)

	self.optPrefix = "Target"

	-- Events
	self:RegisterEvent("RAID_TARGET_UPDATE")
	if (self == XPerl_TargetTarget) then
		self:RegisterEvent("UNIT_TARGET")
		self:SetScript("OnUpdate", XPerl_TargetTarget_OnUpdate)
	else
		self:SetScript("OnUpdate", XPerl_TargetTargetTarget_OnUpdate)
	end

	self.time = 0
	self.targetname = ""
	self.targethp = 0
	self.targetmana = 0
	self.lastUpdate = 0

	self.SubFrame = function(self, a)
		return getglobal(self:GetName().."_"..a)
	end

	--XPerl_InitFadeFrame(self)
	XPerl_RegisterHighlight(getglobal(self:GetName().."_CastClickOverlay"), 2)
	XPerl_RegisterPerlFrames(self, {"NameFrame", "StatsFrame", "LevelFrame"})

	XPerl_RegisterClickCastFrame(getglobal(self:GetName().."_CastClickOverlay"))
end

-------------------------
-- The Update Function --
-------------------------
function XPerl_TargetTarget_UpdatePVP(self)
	local partyid = self:GetAttribute("unit")
        local targetrankname, targetrank=GetPVPRankInfo(UnitPVPRank(partyid), partyid)
        if (targetrank and XPerlConfig.ShowTargetPVPRank==1 and UnitIsPlayer(partyid)) then
                self:SubFrame("NameFrame_PVPRankIcon"):Show()
		if (targetrank==0) then
                        self:SubFrame("NameFrame_PVPRankIcon"):Hide()
		else
			self:SubFrame("NameFrame_PVPRankIcon"):SetTexture(string.format("Interface\\PVPRankBadges\\PVPRank%02d", targetrank))
		end
	else
                self:SubFrame("NameFrame_PVPRankIcon"):Hide()
	end
        if (XPerlConfig.ShowTargetPVP == 1 and UnitIsPVP(partyid)) then
		self:SubFrame("NameFrame_PVPStatus"):SetTexture("Interface\\TargetingFrame\\UI-PVP-"..(UnitFactionGroup(partyid) or "FFA"))
                self:SubFrame("NameFrame_PVPStatus"):Show()
	else
                self:SubFrame("NameFrame_PVPStatus"):Hide()
	end
end

-- XPerl_TargetTarget_Buff_UpdateAll
local function XPerl_TargetTarget_Buff_UpdateAll(self)
	local show
	if (self == XPerl_TargetTarget) then
		show = XPerlConfig.TargetTargetBuffs
	else
		show = XPerlConfig.TargetTargetTargetBuffs
	end

	if (show == 1) then
		self:SubFrame("BuffFrame"):Show()
		XPerl_Targets_BuffUpdate(self, self:GetName().."_")
	else
		self:SubFrame("BuffFrame"):Hide()
	end
end

-- XPerl_TargetTarget_RaidIconUpdate
local function XPerl_TargetTarget_RaidIconUpdate(unitid, frameRaidIcon, frameNameFrame)
	XPerl_Update_RaidIcon(unitid, frameRaidIcon)

	frameRaidIcon:ClearAllPoints()
	if (XPerlConfig.AlternateRaidIcon == 1) then
		frameRaidIcon:SetHeight(16)
		frameRaidIcon:SetWidth(16)
		frameRaidIcon:SetPoint("CENTER", frameNameFrame, "TOPRIGHT", -5, -4)
	else
		frameRaidIcon:SetHeight(32)
		frameRaidIcon:SetWidth(32)
		frameRaidIcon:SetPoint("CENTER", frameNameFrame, "CENTER", 0, 0)
	end
end

-- XPerl_TargetTarget_UpdateDisplay
function XPerl_TargetTarget_UpdateDisplay(self,force)

	local show
	if (self == XPerl_TargetTarget) then
		show = XPerlConfig.ShowTargetTarget
	else
		show = XPerlConfig.ShowTargetTargetTarget
		if (show == 1 and XPerlConfig.ShowTargetTarget == 0) then
			show = 0
		end
	end

	local partyid = self:GetAttribute("unit")
	if (UnitExists("target") and show == 1 and UnitIsConnected(partyid)) then		-- (UnitName("target")~=nil) and (show==1) and (UnitIsConnected(self.unitid))) then
		self.targetname = UnitName(partyid)
		if (self.targetname ~= nil) then
			local t = GetTime()
			if (not force and t < self.lastUpdate + 0.3) then
				return
			end
			self.lastUpdate = t

	                XPerl_TargetTarget_UpdatePVP(self)

			-- Save these 2, so we know whether to update the frame later
			self.targethp = UnitHealth(partyid)
			self.targetmana = UnitMana(partyid)

                        XPerl_SetUnitNameColor(partyid, self:SubFrame("NameFrame_NameBarText"))

                        if (XPerlConfig.ShowTargetTargetLevel == 1) then
				local TargetTargetlevel = UnitLevel(partyid)
	                        local color = GetDifficultyColor(TargetTargetlevel)

				if (TargetTargetLevel == -1) then
					if (UnitClassification(partyid) == "worldboss") then
						TargetTargetLevel = "Boss"
					end
				elseif (UnitIsPlusMob(partyid) or UnitClassification(partyid) == "elite") then
                                        TargetTargetlevel = TargetTargetlevel.."+"
                                        self:SubFrame("LevelFrame"):SetWidth(33)
                                else
                                        self:SubFrame("LevelFrame"):SetWidth(27)
                                end

				self:SubFrame("LevelFrameText"):SetText(TargetTargetlevel)

				if (TargetTargetLevel == "Boss") then
                                        self:SubFrame("LevelFrame"):SetWidth(self:SubFrame("LevelFrameText"):GetStringWidth() + 6)
					color = {r = 1, g = 0, b = 0}
				end

        	                self:SubFrame("LevelFrameText"):SetTextColor(color.r, color.g, color.b)
                        end

			-- Set name - Must do after level as the NameFrame can change size just above here.
			local TargetTargetname = self.targetname
			self:SubFrame("NameFrame_NameBarText"):SetText(TargetTargetname)

			-- Set health
			XPerl_Target_SetHealth(self, XPerlConfig.ShowTargetTargetPercent)

			-- Set mana
			XPerl_Target_SetManaType(self)
			XPerl_Target_SetMana(self)

			if (XPerlConfig.ShowTargetTargetValues == 1) then
				self:SubFrame("StatsFrame_HealthBarText"):Show()
				self:SubFrame("StatsFrame_ManaBarText"):Show()
			else
				self:SubFrame("StatsFrame_HealthBarText"):Hide()
				self:SubFrame("StatsFrame_ManaBarText"):Hide()
			end

			XPerl_TargetTarget_RaidIconUpdate(partyid, self:SubFrame("NameFrame_RaidIcon"), self:SubFrame("NameFrame"))

			XPerl_Targets_BuffPositions(self)
			XPerl_TargetTarget_Buff_UpdateAll(self)

			return
		else
			self.targetname = ""
		end
	else
		self.targetname = ""
	end
end

-- XPerl_TargetTarget_Update_Control
local function XPerl_TargetTarget_Update_Control(self)
	local partyid = self:GetAttribute("unit")
        if (UnitIsVisible(partyid) and UnitIsCharmed(partyid)) then
		self:SubFrame("NameFrame_Warning"):Show()
	else
		self:SubFrame("NameFrame_Warning"):Hide()
	end
end

-- XPerl_TargetTarget_Update_Combat
local function XPerl_TargetTarget_Update_Combat(self)
	local partyid = self:GetAttribute("unit")
        if (UnitAffectingCombat(partyid)) then
                self:SubFrame("NameFrame_ActivityStatus"):Show()
        else
                self:SubFrame("NameFrame_ActivityStatus"):Hide()
        end
end

-- XPerl_TargetTarget_OnUpdate
function XPerl_TargetTarget_OnUpdate(self, elapsed)

	local partyid = self:GetAttribute("unit")
	local newHP = UnitHealth(partyid)
	local newMana = UnitMana(partyid)

	if ((newHP ~= self.targethp) or (newMana ~= self.targetmana)) then
		XPerl_TargetTarget_UpdateDisplay(self)
	else
		self.time = elapsed + self.time
        	if (self.time >= 0.3) then
		        XPerl_TargetTarget_Update_Combat(self)
			XPerl_TargetTarget_Update_Control(self)
		        XPerl_TargetTarget_UpdatePVP(self)
			XPerl_TargetTarget_Buff_UpdateAll(self)
			XPerl_SetUnitNameColor(partyid, self:SubFrame("NameFrame_NameBarText"))

			self.time = 0
		end
	end
end

-- XPerl_TargetTargetTarget_OnUpdate
function XPerl_TargetTargetTarget_OnUpdate(self, elapsed)

	local partyid = self:GetAttribute("unit")
	local newName = UnitName(partyid)
	local newHP = UnitHealth(partyid)
	local newMana = UnitMana(partyid)

	if (not newName) then
		newName = ""
		newHP = 0
		newMana = 0
	end

	if (self == XPerl_TargetTargetTarget and newName ~= self.targetname) then
		XPerl_NoFadeBars(true)
		XPerl_TargetTarget_UpdateDisplay(self,true)
		XPerl_NoFadeBars()

	elseif ((newHP ~= self.targethp) or (newMana ~= self.targetmana)) then
		XPerl_TargetTarget_UpdateDisplay(self)

	else
		self.time = elapsed + self.time
        	if (self.time >= 0.3) then
		        XPerl_TargetTarget_Update_Combat(self)
			XPerl_TargetTarget_Update_Control(self)
		        XPerl_TargetTarget_UpdatePVP(self)
			XPerl_TargetTarget_Buff_UpdateAll(self)
			XPerl_SetUnitNameColor(partyid, self:SubFrame("NameFrame_NameBarText"))

			self.time = 0
		end
	end
end

-------------------
-- Event Handler --
-------------------
function XPerl_TargetTarget_OnEvent(self, event)

	if (event == "RAID_TARGET_UPDATE") then
		XPerl_TargetTarget_RaidIconUpdate(self:GetAttribute("unit"), getglobal(self:GetName().."_NameFrame_RaidIcon"), getglobal(self:GetName().."_NameFrame"))

	elseif (event == "UNIT_TARGET") then
		if (arg1 == "target") then
			XPerl_NoFadeBars(true)
			XPerl_TargetTarget_UpdateDisplay(this,true)
			XPerl_NoFadeBars()
		end
	end
end

--------------------
-- Target history --
--------------------

-- XPerl_TargetTarget_Update
function XPerl_TargetTarget_Update()

	local alpha = XPerlConfig.Transparency
	local time = GetTime()

	local offset = -3
	if (XPerlConfig.TargetTargetBuffs == 1) then
		if (UnitExists("targettarget")) then
			if (XPerl_UnitBuff("targettarget", 1)) then
				if (offset == -3) then
					offset = 0
				end
				offset = offset + 20
				if (UnitBuff("targettarget", 9)) then
					offset = offset + 20
				end
			end
			if (XPerl_UnitDebuff("targettarget", 1)) then
				if (offset == -3) then
					offset = 0
				end
				offset = offset + 24
			end
		end
	end
end

-- EnableDisable
local function EnableDisable(self)

	local opt
	if (self == XPerl_TargetTarget) then
		opt = XPerlConfig.ShowTargetTarget
	else
		opt = XPerlConfig.ShowTargetTargetTarget
	end

	if (opt == 1) then
		RegisterUnitWatch(self)
	else
		UnregisterUnitWatch(self)
		self:Hide()
	end
end

-- XPerl_TargetTarget_Set_Bits
function XPerl_TargetTarget_Set_Bits()
	if (not XPerl_TargetTarget) then
		return
	end

	local function Set(self)
		local statsFrame = getglobal(self:GetName().."_StatsFrame")
		local statsFrameHealthBarPercent = getglobal(statsFrame:GetName().."_HealthBarPercent")
		local statsFrameManaBarPercent = getglobal(statsFrame:GetName().."_ManaBarPercent")
		local nameFrame = getglobal(self:GetName().."_NameFrame")
		local levelFrame = getglobal(self:GetName().."_LevelFrame")

		if (XPerlConfig.ShowTargetTargetLevel==0) then
			levelFrame:Hide()
		else
			levelFrame:Show()
			levelFrame:SetWidth(27)
		end

		if (XPerlConfig.ShowTargetTargetPercent == 0) then
			nameFrame:SetWidth(128)
			statsFrame:SetWidth(128)
			statsFrameHealthBarPercent:Hide()
			statsFrameManaBarPercent:Hide()
		else
			nameFrame:SetWidth(160)
			statsFrame:SetWidth(160)
			statsFrameHealthBarPercent:Show()
			statsFrameManaBarPercent:Show()
		end

		XPerlConfig.TargetBuffSize = tonumber(XPerlConfig.TargetBuffSize) or 20
		XPerl_SetBuffSize(self:GetName().."_", XPerlConfig.TargetBuffSize, XPerlConfig.TargetBuffSize * 1.2)

		XPerl_ProtectedCall(EnableDisable, self)
	end

	if (XPerlConfig.ShowTargetTargetTarget == 1) then
		if (not XPerl_TargetTargetTarget) then
			local ttt = CreateFrame("Frame", "XPerl_TargetTargetTarget", UIParent, "XPerl_TargetTarget_Template")

			ttt:SetAttribute("unit", "targettargettarget")
			getglobal(ttt:GetName().."_CastClickOverlay"):SetAttribute("unit", "targettargettarget")

			ttt:SetPoint("BOTTOMLEFT", XPerl_TargetTarget_StatsFrame, "BOTTOMRIGHT", 5, 0)
			XPerl_RestorePosition(ttt)
		end
	end

	Set(XPerl_TargetTarget)
	if (XPerl_TargetTargetTarget) then
		Set(XPerl_TargetTargetTarget)
	end
end

-- XPerl_ScaleTargetTarget
function XPerl_ScaleTargetTarget(num)
	if (XPerl_TargetTarget) then
		XPerl_TargetTarget:SetScale(num)
		if (XPerl_TargetTargetTarget) then
			XPerl_TargetTargetTarget:SetScale(num)
		end
	end
end
