--------------------------------------------
--
-- SMART - PARTY
--
--------------------------------------------
SMART_PARTY_ENABLE = true
SMART_PARTY_Config = {statusbartext=true,percent=false,loss=true,losstopercent=false,level=true,color=true,namewithserver=true,bufffilter=false,debufffilter=false,groupicon=true,movable=false,movablegroup=false,castingbar=false}

function SmartParty_OnLoad()
	this:RegisterEvent("PLAYER_ENTERING_WORLD")
	this:RegisterEvent("UNIT_FACTION")
	this:RegisterEvent("UNIT_LEVEL")
	this:RegisterEvent("UNIT_HEALTH")
	this:RegisterEvent("UNIT_MANA")
	this:RegisterEvent("UNIT_RAGE")
	this:RegisterEvent("UNIT_ENERGY")
	this:RegisterEvent("UNIT_MAXHEALTH")
	this:RegisterEvent("UNIT_MAXMANA")
	this:RegisterEvent("UNIT_MAXRAGE")
	this:RegisterEvent("UNIT_MAXENERGY")
	this:RegisterEvent("UNIT_DISPLAYPOWER")
	this:RegisterEvent("PARTY_MEMBERS_CHANGED")
	this:RegisterEvent("PARTY_MEMBER_ENABLE")
	this:RegisterEvent("PARTY_MEMBER_DISABLE")
	this:RegisterEvent("PARTY_LEADER_CHANGED")
	this:RegisterEvent("VARIABLES_LOADED")
	this:SetFrameLevel((this:GetParent():GetFrameLevel())+2)
	this:GetParent():SetMovable(true)
	this:GetParent():SetHitRectInsets(0,8,4,4)
	getglobal(this:GetParent():GetName().."HealthBar"):SetHitRectInsets(0,getglobal(this:GetParent():GetName().."HealthBar"):GetWidth(),0,getglobal(this:GetParent():GetName().."HealthBar"):GetHeight())
	getglobal(this:GetParent():GetName().."ManaBar"):SetHitRectInsets(0,getglobal(this:GetParent():GetName().."ManaBar"):GetWidth(),0,getglobal(this:GetParent():GetName().."ManaBar"):GetHeight())
	getglobal(this:GetParent():GetName().."HealthBarText"):SetAlpha(0)
	getglobal(this:GetParent():GetName().."ManaBarText"):SetAlpha(0)

	this.unit = this:GetParent().unit
	this.statusCounter = 0
	this.statusSign = -1

	this:GetParent():CreateTexture(this:GetParent():GetName().."StatusTexture","OVERLAY")
	getglobal(this:GetParent():GetName().."StatusTexture"):SetPoint("TOPLEFT",getglobal(this:GetParent():GetName().."Portrait"),"TOPLEFT",0,0)
	getglobal(this:GetParent():GetName().."StatusTexture"):SetPoint("BOTTOMRIGHT",getglobal(this:GetParent():GetName().."Portrait"),"BOTTOMRIGHT",0,0)
	getglobal(this:GetParent():GetName().."StatusTexture"):SetTexture("Interface\\AddOns\\SmartUnitFrame\\CircleFlash.tga")
	getglobal(this:GetParent():GetName().."StatusTexture"):SetTexCoordModifiesRect(false)
	getglobal(this:GetParent():GetName().."StatusTexture"):SetTexCoord(0,1,0,1)
	getglobal(this:GetParent():GetName().."StatusTexture"):SetBlendMode("ADD")
	getglobal(this:GetParent():GetName().."StatusTexture"):SetVertexColor(1,0.5,0)
end

function SmartParty_AffectingCombatOnUpdate(elapsed)
	if UnitAffectingCombat(this.unit) then
		if not getglobal(this:GetParent():GetName().."StatusTexture"):IsShown() then
			getglobal(this:GetParent():GetName().."StatusTexture"):Show()
		end

		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 = (55  + (counter * 400)) / 255
		else
			alpha = (255 - (counter * 400)) / 255
		end
		getglobal(this:GetParent():GetName().."StatusTexture"):SetAlpha(alpha)

	else
		if getglobal(this:GetParent():GetName().."StatusTexture"):IsShown() then
			getglobal(this:GetParent():GetName().."StatusTexture"):Hide()
		end
	end
end

function SmartParty_ResetPosition()
	if PartyMemberFrame1:IsUserPlaced() then
		PartyMemberFrame1:ClearAllPoints()
		if SMART_GROUPICON_ENABLE or SMART_PVPICON_ENABLE then
			PartyMemberFrame1:SetPoint("TOPLEFT", "PlayerFrame", "TOPLEFT", 40, -180)
		else
			PartyMemberFrame1:SetPoint("TOPLEFT", "PlayerFrame", "TOPLEFT", 24, -180)
		end
	else
		local _, _, _, _, yOfs = PartyMemberFrame1:GetPoint()
		PartyMemberFrame1:ClearAllPoints()
		if SMART_GROUPICON_ENABLE or SMART_PVPICON_ENABLE then
			PartyMemberFrame1:SetPoint("TOPLEFT", "PlayerFrame", "TOPLEFT", 40, yOfs)
		else
			PartyMemberFrame1:SetPoint("TOPLEFT", "PlayerFrame", "TOPLEFT", 24, yOfs)
		end
	end
	PartyMemberFrame1:SetUserPlaced(false)
end

function SmartParty_GroupCheck(groupCheck)
	if SMART_PARTY_Config.movablegroup or groupCheck then
		for id=2,4 do
			if getglobal("PartyMemberFrame"..id):IsUserPlaced() then
				getglobal("PartyMemberFrame"..id):ClearAllPoints()
				getglobal("PartyMemberFrame"..id):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..(id-1).."PetFrame"),"BOTTOMLEFT",-23,-10)
				getglobal("PartyMemberFrame"..id):SetUserPlaced(false)
			end
		end
	end
end

function SmartParty_MemberEnableCheck(id)
	--	Check : Dead or Ghost / Offline
	local deadText = getglobal("SmartPartyFrame"..id.."DeadText")
	if UnitIsConnected("party"..id) then
		if UnitIsDead("party"..id) then
			local deadStatus = "죽음"
			if SMART_CheckFeign("party"..id) then
				deadStatus = "죽은척하기"
			end
			deadText:SetText(deadStatus)
			deadText:Show()
		elseif UnitIsGhost("party"..id) then
			deadText:SetText("유령")
			deadText:Show()
		else
			deadText:SetText("")
			deadText:Hide()
		end
	else
		deadText:SetText("오프라인")
		deadText:Show()
	end
end

function SmartParty_HealthUpdate(id)
	--	Check : HP/MP Percent or HP/MaxHP MP/MaxMP
	if SMART_PARTY_Config.statusbartext then
		if SMART_PARTY_Config.percent then
			getglobal("SmartPartyFrame"..id.."HealthBarText"):Hide()
			SMART_HealthPercent(getglobal("SmartPartyFrame"..id.."HealthPercent"),"party"..id)
		else
			getglobal("SmartPartyFrame"..id.."HealthPercent"):Hide()
			SMART_HealthUpdate(getglobal("SmartPartyFrame"..id.."HealthBarText"),"party"..id)
		end
	else
		getglobal("SmartPartyFrame"..id.."HealthBarText"):Hide()
		getglobal("SmartPartyFrame"..id.."HealthPercent"):Hide()
	end
	--	Check : Health Loss SHOW/HIDE
	if SMART_PARTY_Config.loss then
		if SMART_PARTY_Config.losstopercent then
			SMART_HealthPercent(getglobal("SmartPartyFrame"..id.."HealthLoss"),"party"..id)
		else
			SMART_HealthLoss(getglobal("SmartPartyFrame"..id.."HealthLoss"),"party"..id)
		end
	else
		getglobal("SmartPartyFrame"..id.."HealthLoss"):Hide()
	end
end

function SmartParty_ManaUpdate(id)
	--	Check : HP/MP Percent or HP/MaxHP MP/MaxMP
	if SMART_PARTY_Config.statusbartext then
		if SMART_PARTY_Config.percent then
			getglobal("SmartPartyFrame"..id.."ManaBarText"):Hide()
			SMART_ManaPercent(getglobal("SmartPartyFrame"..id.."ManaPercent"),"party"..id)
		else
			getglobal("SmartPartyFrame"..id.."ManaPercent"):Hide()
			SMART_ManaUpdate(getglobal("SmartPartyFrame"..id.."ManaBarText"),"party"..id)
		end
	else
		getglobal("SmartPartyFrame"..id.."ManaBarText"):Hide()
		getglobal("SmartPartyFrame"..id.."ManaPercent"):Hide()
	end
end

function SmartParty_LevelUpdate(id)
	if SMART_PARTY_Config.level and UnitIsConnected("party"..id) then
		local levelText = getglobal("SmartPartyFrame"..id.."LevelText")
		levelText:SetText(UnitLevel("party"..id))
		levelText:Show()
		if UnitCanAttack("party"..id, "player") or UnitCanAttack("player", "party"..id) then
			levelText:SetTextColor(1,0,0)
		else
			levelText:SetTextColor(1,0.82,0)
		end
	else
		getglobal("SmartPartyFrame"..id.."LevelText"):Hide()
	end
end

function SmartParty_ColorName(id)
	--	Check : Member's name is colored by class
	local colorName = getglobal("PartyMemberFrame"..id.."Name")
	if UnitIsConnected("party"..id) then
		if UnitCanAttack("party"..id, "player") or UnitCanAttack("player", "party"..id) then
			colorName:SetTextColor(1,0,0)
		else
			if SMART_PARTY_Config.color then
				local _, englishClass = UnitClass("party"..id)
				if ( englishClass ) then
					local classColor = RAID_CLASS_COLORS[englishClass]
					colorName:SetTextColor(classColor.r,classColor.g,classColor.b)
				else
					colorName:SetTextColor(1,0.82,0)
				end
			else
				colorName:SetTextColor(1,0.82,0)
			end
		end
	else
		colorName:SetTextColor(0.75,0.75,0.75)
	end
	colorName:SetText(GetUnitName("party"..id, SMART_PARTY_Config.namewithserver))
end

function SmartParty_MemberUpdate(id)
	SmartParty_MemberEnableCheck(id)
	SmartParty_HealthUpdate(id)
	SmartParty_ManaUpdate(id)
	SmartParty_LevelUpdate(id)
	SmartParty_ColorName(id)
	RefreshBuffs(getglobal("PartyMemberFrame"..id), 0, "party"..id)
	SetPortraitTexture(getglobal("PartyMemberFrame"..id.."Portrait"),"party"..id)
end

function SmartParty_OnEvent(event)
	local id = this:GetID()
	if (event == "VARIABLES_LOADED") then
		getglobal("PartyMemberFrame"..id.."MasterIcon"):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..id.."MasterIcon"):GetParent(),"TOPLEFT",29,-31)
		getglobal("PartyMemberFrame"..id.."PVPIcon"):ClearAllPoints()
		getglobal("PartyMemberFrame"..id.."PVPIcon"):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..id.."Portrait"),"TOPLEFT",-15,-5)
		if (SMART_CLASSICON_ENABLE and SMART_CLASSICON_PARTY) or (IsAddOnLoaded("ClassIcons")) then
			getglobal("SmartPartyFrame"..id.."LevelText"):ClearAllPoints()
			getglobal("SmartPartyFrame"..id.."LevelText"):SetPoint("BOTTOMLEFT",getglobal("PartyMemberFrame"..id.."Portrait"),"BOTTOMLEFT",2,-2)
			getglobal("SmartPartyFrame"..id.."LevelText"):SetJustifyH("LEFT")
		end
--		RegisterUnitWatch(getglobal("PartyMemberFrame"..id))
--		RegisterUnitWatch(getglobal("PartyMemberFrame"..id.."PetFrame"))
		PartyMemberFrame_UpdatePet = Smart_PartyMemberFrame_UpdatePet
		Smart_PartyMemberFrame_UpdatePet(id)
		return
	end
	if UnitExists("party"..id) then
		if (event == "PLAYER_ENTERING_WORLD") or (event == "PARTY_MEMBERS_CHANGED") or (event == "PARTY_LEADER_CHANGED") then
			SmartParty_MemberUpdate(id)
		elseif (event == "PARTY_MEMBER_DISABLE") or (event == "PARTY_MEMBER_ENABLE") then
			if arg1 == ("party"..id) then
				SmartParty_MemberUpdate(id)
			end
		elseif (event == "UNIT_HEALTH") or (event == "UNIT_MAXHEALTH") then
			if arg1 == ("party"..id) then
				SmartParty_HealthUpdate(id)
				SmartParty_MemberEnableCheck(id)
			end
		elseif (event == "UNIT_DISPLAYPOWER") or (event == "UNIT_MANA") or (event == "UNIT_RAGE") or (event == "UNIT_ENERGY") or (event == "UNIT_MAXMANA") or (event == "UNIT_MAXRAGE") or (event == "UNIT_MAXENERGY") then
			if arg1 == ("party"..id) then
				SmartParty_ManaUpdate(id)
			end
		elseif (event == "UNIT_FACTION") then
			if arg1 == ("party"..id) or (arg1 == "player") then
				SmartParty_ColorName(id)
				SmartParty_LevelUpdate(id)
			end
		elseif (event == "UNIT_LEVEL") then
			if arg1 == ("party"..id) then
				SmartParty_LevelUpdate(id)
			end
		elseif (event == "UNIT_AURA") then
			if arg1 == ("party"..id) then
				RefreshBuffs(getglobal("PartyMemberFrame"..id), 0, "party"..id)
			end
		end
	end
end

function SmartPartyPet_OnEvent(event)
	local id = this:GetID()
	if (event == "PLAYER_ENTERING_WORLD") or (event == "PARTY_MEMBERS_CHANGED") or (event == "PARTY_MEMBER_ENABLE") or (event == "PARTY_MEMBER_DISABLE") or (event == "PARTY_LEADER_CHANGED") then
		SmartPartyPet_HealthUpdate(id)
	elseif (event == "UNIT_PET") then
		if (arg1 == "party"..id) then
			SmartPartyPet_HealthUpdate(id)
		end
	elseif (event == "UNIT_HEALTH") or (event == "UNIT_MAXHEALTH") then
		if (arg1 == "partypet"..id) then
			SmartPartyPet_HealthUpdate(id)
		end
	end
end

function SmartPartyPet_HealthUpdate(id)
	if UnitExists("partypet"..id) and SMART_PARTY_Config.statusbartext then
		if SMART_PARTY_Config.percent then
			SMART_HealthPercent(getglobal("SmartPartyFrame"..id.."PetFrameHealthBarText"),"partypet"..id)
		else
			SMART_HealthUpdate(getglobal("SmartPartyFrame"..id.."PetFrameHealthBarText"),"partypet"..id)
		end
	else
		getglobal("SmartPartyFrame"..id.."PetFrameHealthBarText"):Hide()
	end
end

function SmartPartyPet_OnLoad()
	this:RegisterEvent("PLAYER_ENTERING_WORLD")
	this:RegisterEvent("PARTY_MEMBERS_CHANGED")
	this:RegisterEvent("PARTY_MEMBER_ENABLE")
	this:RegisterEvent("PARTY_MEMBER_DISABLE")
	this:RegisterEvent("PARTY_LEADER_CHANGED")
	this:RegisterEvent("UNIT_PET")
	this:RegisterEvent("UNIT_HEALTH")
	this:RegisterEvent("UNIT_MAXHEALTH")
	this:GetParent():SetMovable(true)
	this:GetParent():SetHitRectInsets(3,3,3,3)
	getglobal(this:GetParent():GetName().."HealthBar"):SetHitRectInsets(0,getglobal(this:GetParent():GetName().."HealthBar"):GetWidth(),0,getglobal(this:GetParent():GetName().."HealthBar"):GetHeight())
--	getglobal(this:GetParent():GetName().."HealthBarText"):SetAlpha(0)
end


function SetSmartPartySpellbarAspect()
	local spellBar = getglobal("SmartPartyFrame"..this:GetID().."SpellBar")
	local frameText = getglobal(spellBar:GetName().."Text")
	if ( frameText ) then
		frameText:SetTextHeight(10)
		frameText:ClearAllPoints()
		frameText:SetPoint("TOP", spellBar, "TOP", 0, 4)
	end

	local frameBorder = getglobal(spellBar:GetName().."Border")
	if ( frameBorder ) then
		frameBorder:SetTexture("Interface\\CastingBar\\UI-CastingBar-Border-Small")
		frameBorder:SetWidth(156)
		frameBorder:SetHeight(49)
		frameBorder:ClearAllPoints()
		frameBorder:SetPoint("TOP", spellBar, "TOP", 0, 20)
	end

	local frameFlash = getglobal(spellBar:GetName().."Flash")
	if ( frameFlash ) then
		frameFlash:SetTexture("Interface\\CastingBar\\UI-CastingBar-Flash-Small")
		frameFlash:SetWidth(156)
		frameFlash:SetHeight(49)
		frameFlash:ClearAllPoints()
		frameFlash:SetPoint("TOP", spellBar, "TOP", 0, 20)
	end
end

function SmartParty_Spellbar_OnLoad()
	this:RegisterEvent("PARTY_MEMBERS_CHANGED")
	this:RegisterEvent("PARTY_MEMBER_ENABLE")
	this:RegisterEvent("PARTY_MEMBER_DISABLE")
	this:RegisterEvent("PARTY_LEADER_CHANGED")
	this:RegisterEvent("CVAR_UPDATE")

	this:SetID(this:GetParent():GetID())
	this.unit = "party"..this:GetID()

	this:SetFrameStrata("HIGH")
	RaiseFrameLevel(this)
	this:ClearAllPoints()
	--this:SetPoint("TOPLEFT",getglobal(this:GetParent():GetParent():GetName().."ManaBar"),"BOTTOMLEFT",2,-6)
	this:SetPoint("BOTTOMLEFT",getglobal(this:GetParent():GetParent():GetName().."Name"),"BOTTOMLEFT")

	CastingBarFrame_OnLoad(this.unit, false)

	local barIcon = getglobal(this:GetName().."Icon")
	barIcon:Hide()

	SetSmartPartySpellbarAspect()
end

function SmartParty_Spellbar_OnEvent()
	local newevent = event
	local newarg1 = arg1

	this.showCastbar = SMART_PARTY_Config.castingbar

	if (event == "CVAR_UPDATE" and this.showCastbar) then
		if (this.casting or this.channeling) then
			this:Show()
		else
			this:Hide()
		end
		return
	elseif (event == "PARTY_MEMBERS_CHANGED") or (event == "PARTY_MEMBER_ENABLE") or (event == "PARTY_MEMBER_DISABLE") or (event == "PARTY_LEADER_CHANGED") then
		-- check if the new target is casting a spell
		local nameChannel  = UnitChannelInfo(this.unit)
		local nameSpell  = UnitCastingInfo(this.unit)

		if (nameChannel) then
			newevent = "UNIT_SPELLCAST_CHANNEL_START"
			newarg1 = "party"..this:GetID()
		elseif (nameSpell) then
			newevent = "UNIT_SPELLCAST_START"
			newarg1 = "party"..this:GetID()
		else
			this.casting = nil
			this.channeling = nil
			this:SetMinMaxValues(0, 0)
			this:SetValue(0)
			this:Hide()
			return
		end
	end
	CastingBarFrame_OnEvent(newevent, newarg1)
end

function Smart_PartyMemberFrame_UpdatePet(id)
	if (not id) then
		id = this:GetID()
	end

	local frameName = "PartyMemberFrame"..id
	local petFrame = getglobal("PartyMemberFrame"..id.."PetFrame")

	if ( UnitIsConnected("party"..id) and UnitExists("partypet"..id) and SHOW_PARTY_PETS == "1" ) then
		petFrame:Show()
		petFrame:SetPoint("TOPLEFT", frameName, "TOPLEFT", 23, -56)
	else
		petFrame:Hide()
		petFrame:SetPoint("TOPLEFT", frameName, "TOPLEFT", 23, -40)
	end

	PartyMemberFrame_RefreshPetBuffs(id)
	UpdatePartyMemberBackground()
end

