SUF.PartyTarget = { xPos = 172 }

function PartyTargetFrame_SetUnitWatch(frame, show)
	if frame.enable ~= show then

		if show then
			RegisterUnitWatch(frame)
			frame:Show()
		else
			UnregisterUnitWatch(frame)
			frame:Hide()
		end

		frame.enable = show
	end
end

function PartyTargetFrame_OnLoad()
	local id = this:GetID()
	local prefix = "PartyTargetFrame"..id

	this.unit = "party"..id.."target"
	this.classicon = getglobal(this:GetName().."ClassIcon")

	UnitFrame_Initialize(this, this.unit,
	getglobal(prefix.."Name"),
	getglobal(prefix.."Portrait"),
	getglobal(prefix.."HealthBar"),
	getglobal(prefix.."HealthBarText"), 
	getglobal(prefix.."ManaBar"),
	getglobal(prefix.."ManaBarText"))

	SetTextStatusBarTextZeroText(getglobal(prefix.."HealthBar"), TEXT(DEAD))

	this:SetAttribute("unit", this.unit)
	this:SetAttribute("type", this.unit)

	if (SMART_PARTY_Config.target == false or
		(HIDE_PARTY_INTERFACE == "1" and GetNumRaidMembers() > 0)) then
		PartyTargetFrame_SetUnitWatch(this, false)
	else
		PartyTargetFrame_SetUnitWatch(this, true)
	end

	this:SetScale(.80)
	this:SetMovable(true)
	this:SetHitRectInsets(0, 8, 4, 4)

	this.statusCounter = 0
	this.statusSign = -1
	this.unitHPPercent = 1

	PartyTargetFrame_UpdateMember(this)
	this:RegisterEvent("PLAYER_ENTERING_WORLD")
	this:RegisterEvent("PARTY_MEMBERS_CHANGED")
	this:RegisterEvent("PARTY_LEADER_CHANGED")
	this:RegisterEvent("PARTY_MEMBER_ENABLE")
	this:RegisterEvent("PARTY_MEMBER_DISABLE")
	this:RegisterEvent("UNIT_FACTION")
	this:RegisterEvent("UNIT_AURA")
	this:RegisterEvent("VARIABLES_LOADED")
	--this:RegisterEvent("PARTY_LOOT_METHOD_CHANGED")
	--This should fix a few "sync" bugs
	this:RegisterEvent("UNIT_TARGET")
	this:RegisterEvent("UNIT_PVP_UPDATE")
	this:RegisterEvent("UNIT_HEALTH")
	this:RegisterEvent("UNIT_MAXHEALTH")
	this:RegisterEvent("UNIT_MANA")
	this:RegisterEvent("UNIT_RAGE")
	this:RegisterEvent("UNIT_FOCUS")
	this:RegisterEvent("UNIT_ENERGY")

	local showmenu = function()
		ToggleDropDownMenu(1, nil, getglobal(this:GetName().."DropDown"), this:GetName(), 120, 10)
	end
	SecureUnitButton_OnLoad(this, this.unit, showmenu)
end

function PartyTargetFrameDropDown_OnLoad()
	UIDropDownMenu_Initialize(this, PartyTargetFrameDropDown_Initialize, "MENU");
end

local dropdownMenu = nil
local dropdownUnit = nil

function PartyTargetFrameDropDown_Initialize()
	if this.unit then
		local menu;
		local name;
		local id = nil;
		local unit = this.unit

		if (UnitIsUnit(unit, "pet")) then
			menu = "PET";
		elseif (UnitIsPlayer(unit)) then
			id = UnitInRaid(unit);
			if (id) then
				menu = "RAID_PLAYER";
			elseif (UnitInParty(unit)) then
				menu = "PARTY";
			else
				menu = "PLAYER";
			end
		else
			menu = "RAID_TARGET_ICON";
			name = RAID_TARGET_ICON;
		end

		if (menu) then
			dropdownMenu = getglobal(this:GetName().."DropDown")

			if unit then
				dropdownUnit = this.unit
			end

			if dropdownMenu then
				UnitPopup_ShowMenu(dropdownMenu, menu, unit, name, id);
			end
		end
	else
		if dropdownMenu and dropdownUnit then
			UnitPopup_ShowMenu(dropdownMenu, "RAID_TARGET_ICON", dropdownUnit, RAID_TARGET_ICON, nil);
		end
	end
end

function PartyTargetFrame_UpdateMember(button)
	if (SMART_PARTY_Config.target == false or
		(HIDE_PARTY_INTERFACE == "1" and GetNumRaidMembers() > 0)) then
		PartyTargetFrame_SetUnitWatch(this, false)
		return;
	else
		PartyTargetFrame_SetUnitWatch(this, true)
	end

	local id = button:GetID()

	if (GetPartyMember(id) and UnitExists(button.unit)) then
		UnitFrame_UpdateManaType()
		UnitFrame_Update()
	end

	PartyTargetFrame_UpdatePvPStatus(button)
end

function PartyTargetFrame_UpdateMemberHealth(elapsed)
	if ((this.unitHPPercent > 0) and (this.unitHPPercent <= 0.2)) then
		local alpha = 255
		local counter = this.statusCounter + elapsed
		local sign = this.statusSign

		if (counter > 0.5) then
			sign = -sign
			this.statusSign = sign
		end

		counter = mod(counter, 0.5)
		this.statusCounter = counter

		if (sign == 1) then
			alpha = (127  + (counter * 256)) / 255
		else
			alpha = (255 - (counter * 256)) / 255
		end

		getglobal(this:GetName().."Portrait"):SetAlpha(alpha)
	end
end

function PartyTargetFrame_UpdatePvPStatus(button)
	if not button then
		button = this
	end

	local id = button:GetID();
	local icon = getglobal("PartyTargetFrame"..id.."PVPIcon")
	local factionGroup = UnitFactionGroup(button.unit)

	if (UnitIsPVPFreeForAll(button.unit)) then
		icon:SetTexture("Interface\\TargetingFrame\\UI-PVP-FFA")
		icon:Show()
	elseif ( factionGroup and UnitIsPVP(button.unit) ) then
		icon:SetTexture("Interface\\GroupFrame\\UI-Group-PVP-"..factionGroup)
		icon:Show()
	else
		icon:Hide()
	end
end

function PartyTargetFrame_OnEvent(event, unit)
	UnitFrame_OnEvent(event);

	if (event == "PLAYER_ENTERING_WORLD") then
		if (GetPartyMember(this:GetID())) then
			PartyTargetFrame_UpdateMember(this);
			return
		end
	end

	if (event == "PARTY_MEMBERS_CHANGED" or event == "PARTY_LEADER_CHANGED" or event == "UNIT_TARGET") then
		PartyTargetFrame_UpdateMember(this);
		return;
	end

	if (event == "UNIT_PVP_UPDATE") then
		if (arg1 == this.unit) then
			PartyTargetFrame_UpdatePvPStatus()
		end
		return;
	end

	if (event == "UNIT_FACTION") then
		if ( arg1 == unit ) then
			PartyTargetFrame_UpdatePvPStatus()
		end
		return;
	end

	if (event == "VARIABLES_LOADED") then
		if not UnitExists(this.unit) then
			this:Hide()
		end
	end

	if (unit) then
		local i
		for i = 1, MAX_PARTY_MEMBERS do
			if (unit == "party"..i and UnitExists("party"..i.."target")) then
				PartyTargetFrame_UpdateMember(getglobal("PartyTargetFrame"..i))
			end
		end
	else
		PartyTargetFrame_UpdateMember(this)
	end
end

function PartyTargetFrame_HealthCheck()
	local portrait = getglobal(this:GetParent():GetName().."Portrait")

	unitHPMin, unitHPMax = this:GetMinMaxValues()

	-- Handle disconnected state
	if (not UnitIsConnected(this:GetParent().unit)) then
		this:SetValue(unitHPMax);
		this:SetStatusBarColor(0.5, 0.5, 0.5);
		SetDesaturation(portrait, 1);
		getglobal(this:GetParent():GetName().."Disconnect"):Show()
		return;
	end

	local unitMinHP, unitMaxHP, unitCurrHP

	SetDesaturation(portrait, nil)
	getglobal(this:GetParent():GetName().."Disconnect"):Hide()

	unitCurrHP = this:GetValue();

	if (unitHPMax > 0) then
		this:GetParent().unitHPPercent = unitCurrHP / unitHPMax;
	else
		this:GetParent().unitHPPercent = 0;
	end

	if (UnitIsDead(this:GetParent().unit)) then
		portrait:SetVertexColor(0.35, 0.35, 0.35, 1.0)
	elseif (UnitIsGhost(this:GetParent().unit)) then
		portrait:SetVertexColor(0.2, 0.2, 0.75, 1.0)
	elseif ((this:GetParent().unitHPPercent > 0) and (this:GetParent().unitHPPercent <= 0.2)) then
		portrait:SetVertexColor(1.0, 0.0, 0.0)
	else
		portrait:SetVertexColor(1.0, 1.0, 1.0, 1.0)
	end
end

function SmartPartyTarget_OnLoad()
	this.unit = this:GetParent().unit
	this:SetAttribute("unit", this.unit)
	this:SetAttribute("type", this.unit)
	PartyTargetFrame_SetUnitWatch(this, true)
	this:RegisterEvent("UNIT_TARGET")
	SmartParty_OnLoad()
end

function SmartPartyTarget_OnEvent(event)
	if event == "UNIT_TARGET" then
		-- 파티원이 타겟을 바꿨을 때 UNIT_TARGET의 arg1은 party#이다.
		-- 하지만 이 프레임은 파티원의 타겟 프레임이므로 this.unit(party#target)과 비교하면 안된다.
		if (arg1 == "party"..this:GetID()) then
			SmartParty_UpdateMember(this)
		end
	end
	--[[
	if (arg1 and UnitIsUnit(this.unit, arg1)) then
		DEFAULT_CHAT_FRAME:AddMessage(this:GetName().." "..event.." arg1 "..arg1)
	end
	]]
	SmartParty_OnEvent(event)
end

function SmartPartyTarget_ResetPosition(force)
	local i

	for i = 1, MAX_PARTY_MEMBERS do
		local frame = getglobal("PartyTargetFrame"..i)

		if force or not frame:IsUserPlaced() then
			frame:ClearAllPoints()
			frame:SetPoint("TOPLEFT", getglobal("PartyMemberFrame"..i), "TOPRIGHT", SUF.PartyTarget.xPos, 0)

			frame:SetUserPlaced(false)
		end
	end
end 

