--------------------------------------------
--
-- SMART - BUFF/DEBUFF
--
--------------------------------------------
SMART_BUFFDEBUFF_ENABLE = true;
SMART_BUFF_ChkNum = {target=24,party=24,pet=16,partypet=16};
SMART_BUFF_MaxNum = {target=24,party=24,pet=16,partypet=16};
SMART_DEBUFF_ChkNum = {target=40,party=6,pet=6,partypet=6};
SMART_DEBUFF_MaxNum = {target=40,party=16,pet=16,partypet=16};

SMART_TARGET_NUMBUFFS = 0;
SMART_TARGET_NUMDEBUFFS = 0;

function SmartTarget_BuffDebuffCreation()
	local button;
	for i=1, SMART_BUFF_MaxNum.target do
		button = getglobal("TargetFrameBuff"..i);
		if ( not button ) then
			button = CreateFrame("Button", "TargetFrameBuff"..i, TargetFrame, "TargetBuffButtonTemplate");
		end
		button:Hide();
		button:SetFrameStrata("LOW");
		button:CreateTexture(button:GetName().."Border", "OVERLAY");

		CreateFrame("Frame", button:GetName().."TextLayer", button);
		getglobal(button:GetName().."TextLayer"):SetPoint("TOPLEFT",button,"TOPLEFT");
		getglobal(button:GetName().."TextLayer"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT");
		
		getglobal(button:GetName().."Border"):SetTexture("Interface/Buttons/UI-Debuff-Overlays");
		getglobal(button:GetName().."Border"):SetPoint("CENTER",button,"CENTER",0,0);
		getglobal(button:GetName().."Border"):SetWidth(button:GetWidth()+2);
		getglobal(button:GetName().."Border"):SetHeight(button:GetHeight()+2);
		getglobal(button:GetName().."Border"):SetTexCoord(0.296875,0.5703125,0,0.515625);
		getglobal(button:GetName().."Border"):SetVertexColor(0,1,0);
		getglobal(button:GetName().."Count"):SetFontObject("TextStatusBarText");
		getglobal(button:GetName().."Count"):ClearAllPoints();
		getglobal(button:GetName().."Count"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",1,0);
		getglobal(button:GetName().."Count"):SetJustifyH("RIGHT");
		getglobal(button:GetName().."Count"):SetParent(getglobal(button:GetName().."TextLayer"));
		getglobal(button:GetName().."Cooldown"):SetPoint("CENTER",button,"CENTER",0,2);

		RaiseFrameLevel(getglobal(button:GetName().."Cooldown"));
		RaiseFrameLevel(getglobal(button:GetName().."TextLayer"));
	end
	for i=1, SMART_DEBUFF_MaxNum.target do
		button = getglobal("TargetFrameDebuff"..i)
		if ( not button ) then
			button = CreateFrame("Button", "TargetFrameDebuff"..i, TargetFrame, "TargetDebuffButtonTemplate");
		end
		button:Hide();
		button:SetFrameStrata("LOW");

		CreateFrame("Frame", button:GetName().."TextLayer", button);
		getglobal(button:GetName().."TextLayer"):SetPoint("TOPLEFT",button,"TOPLEFT");
		getglobal(button:GetName().."TextLayer"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT");

		getglobal(button:GetName().."Count"):SetFontObject("TextStatusBarText");
		getglobal(button:GetName().."Count"):ClearAllPoints();
		getglobal(button:GetName().."Count"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",1,0);
		getglobal(button:GetName().."Count"):SetJustifyH("RIGHT");
		getglobal(button:GetName().."Count"):SetParent(getglobal(button:GetName().."TextLayer"));
		getglobal(button:GetName().."Cooldown"):SetPoint("CENTER",button,"CENTER",0,2);

		RaiseFrameLevel(getglobal(button:GetName().."Cooldown"));
		RaiseFrameLevel(getglobal(button:GetName().."TextLayer"));
	end
end

function SmartParty_BuffDebuffCreation()
	for i=1, 4 do
		for j=1, SMART_BUFF_MaxNum.party do
			CreateFrame("Button","SmartPartyFrame"..i.."Buff"..j,getglobal("PartyMemberFrame"..i),"SmartPartyBuffButtonTemplate");
			if j > 1 then
				getglobal("SmartPartyFrame"..i.."Buff"..j):SetPoint("LEFT",getglobal("SmartPartyFrame"..i.."Buff"..(j-1)),"RIGHT",2,0);
			else
				getglobal("SmartPartyFrame"..i.."Buff"..j):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..i),"TOPLEFT",48,-33);
			end
			getglobal("SmartPartyFrame"..i.."Buff"..j):SetID(j);
			getglobal("SmartPartyFrame"..i.."Buff"..j).id = j;
			getglobal("SmartPartyFrame"..i.."Buff"..j):SetFrameStrata("LOW");

			CreateFrame("Frame", "SmartPartyFrame"..i.."Buff"..j.."TextLayer", getglobal("SmartPartyFrame"..i.."Buff"..j));
			getglobal("SmartPartyFrame"..i.."Buff"..j.."TextLayer"):SetPoint("TOPLEFT",getglobal("SmartPartyFrame"..i.."Buff"..j),"TOPLEFT");
			getglobal("SmartPartyFrame"..i.."Buff"..j.."TextLayer"):SetPoint("BOTTOMRIGHT",getglobal("SmartPartyFrame"..i.."Buff"..j),"BOTTOMRIGHT");
			getglobal("SmartPartyFrame"..i.."Buff"..j.."Count"):ClearAllPoints();
			getglobal("SmartPartyFrame"..i.."Buff"..j.."Count"):SetPoint("BOTTOMRIGHT",getglobal("SmartPartyFrame"..i.."Buff"..j),"BOTTOMRIGHT",1,0);
			getglobal("SmartPartyFrame"..i.."Buff"..j.."Count"):SetJustifyH("RIGHT");
			getglobal("SmartPartyFrame"..i.."Buff"..j.."Count"):SetParent(getglobal("SmartPartyFrame"..i.."Buff"..j.."TextLayer"));

			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."Buff"..j.."Cooldown"));
			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."Buff"..j.."TextLayer"));
    end
    for j=1, SMART_BUFF_MaxNum.partypet do
			CreateFrame("Button","SmartPartyFrame"..i.."PetFrameBuff"..j,getglobal("PartyMemberFrame"..i.."PetFrame"),"SmartPartyPetBuffButtonTemplate");
			if j > 1 then
				getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j):SetPoint("LEFT",getglobal("SmartPartyFrame"..i.."PetFrameBuff"..(j-1)),"RIGHT",2,0);
			else
				getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..i.."PetFrame"),"TOPLEFT",25,-20);
			end
			getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j):SetID(j);
			getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j).id = j;
			getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j):SetFrameStrata("LOW");
			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."PetFrameBuff"..j));
		end
		for j=1, SMART_DEBUFF_MaxNum.party do
			CreateFrame("Button","SmartPartyFrame"..i.."Debuff"..j,getglobal("PartyMemberFrame"..i),"SmartPartyDebuffButtonTemplate");
			if j > 1 then
				getglobal("SmartPartyFrame"..i.."Debuff"..j):SetPoint("LEFT",getglobal("SmartPartyFrame"..i.."Debuff"..(j-1)),"RIGHT",2,0);
			else
				getglobal("SmartPartyFrame"..i.."Debuff"..j):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..i),"TOPLEFT",198,-13);
			end
			getglobal("SmartPartyFrame"..i.."Debuff"..j):SetID(j);
			getglobal("SmartPartyFrame"..i.."Debuff"..j).id = j;
			getglobal("SmartPartyFrame"..i.."Debuff"..j):SetFrameStrata("LOW");

			CreateFrame("Frame", "SmartPartyFrame"..i.."Debuff"..j.."TextLayer", getglobal("SmartPartyFrame"..i.."Debuff"..j));
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."TextLayer"):SetPoint("TOPLEFT",getglobal("SmartPartyFrame"..i.."Debuff"..j),"TOPLEFT");
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."TextLayer"):SetPoint("BOTTOMRIGHT",getglobal("SmartPartyFrame"..i.."Debuff"..j),"BOTTOMRIGHT");
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."Count"):ClearAllPoints();
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."Count"):SetPoint("BOTTOMRIGHT",getglobal("SmartPartyFrame"..i.."Debuff"..j),"BOTTOMRIGHT",1,0);
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."Count"):SetJustifyH("RIGHT");
			getglobal("SmartPartyFrame"..i.."Debuff"..j.."Count"):SetParent(getglobal("SmartPartyFrame"..i.."Debuff"..j.."TextLayer"));

			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."Debuff"..j.."Cooldown"));
			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."Debuff"..j.."TextLayer"));
		end
	  for j=1, SMART_DEBUFF_MaxNum.partypet do
			CreateFrame("Button","SmartPartyFrame"..i.."PetFrameDebuff"..j,getglobal("PartyMemberFrame"..i.."PetFrame"),"SmartPartyPetDebuffButtonTemplate");
			if j > 1 then
				getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j):SetPoint("LEFT",getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..(j-1)),"RIGHT",2,0);
			else
				getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..i.."PetFrame"),"TOPLEFT",136,-4);
			end
			getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j):SetID(j);
			getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j).id = j;
			getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j):SetFrameStrata("LOW");
			RaiseFrameLevel(getglobal("SmartPartyFrame"..i.."PetFrameDebuff"..j));
		end
		getglobal("PartyMemberFrame"..i).numBuffs = 0;
		getglobal("PartyMemberFrame"..i).numDebuffs = 0;
		getglobal("PartyMemberFrame"..i.."PetFrame").numBuffs = 0;
		getglobal("PartyMemberFrame"..i.."PetFrame").numDebuffs = 0;
	end
end

function SmartPet_BuffDebuffCreation()
	local button;
	for i=1, SMART_DEBUFF_MaxNum.pet do
		button = CreateFrame("Button","SmartPetFrameBuff"..i,PetFrame,"SmartPetBuffButtonTemplate");
		if i > 1 then
			button:SetPoint("LEFT",getglobal("SmartPetFrameBuff"..(i-1)),"RIGHT",2,0);
		else
			button:SetPoint("TOPLEFT",PetFrame,"TOPLEFT",48,-42);
		end
		button:SetID(i);
		button.id = i;
		button:SetFrameStrata("LOW");

		CreateFrame("Frame", button:GetName().."TextLayer", button);
		getglobal(button:GetName().."TextLayer"):SetPoint("TOPLEFT",button,"TOPLEFT");
		getglobal(button:GetName().."TextLayer"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT");
		getglobal(button:GetName().."Count"):ClearAllPoints();
		getglobal(button:GetName().."Count"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",1,0);
		getglobal(button:GetName().."Count"):SetJustifyH("RIGHT");
		getglobal(button:GetName().."Count"):SetParent(getglobal(button:GetName().."TextLayer"));

		RaiseFrameLevel(getglobal(button:GetName().."Cooldown"));
		RaiseFrameLevel(getglobal(button:GetName().."TextLayer"));
	end
	for i=1, SMART_DEBUFF_MaxNum.pet do
		button = CreateFrame("Button","SmartPetFrameDebuff"..i,PetFrame,"SmartPetDebuffButtonTemplate");
		if i > 1 then
			button:SetPoint("LEFT",getglobal("SmartPetFrameDebuff"..(i-1)),"RIGHT",2,0);
		else
			button:SetPoint("TOPLEFT",PetFrame,"TOPLEFT",124,-25);
		end
		button:SetID(i);
		button.id = i;
		button:SetFrameStrata("LOW");

		CreateFrame("Frame", button:GetName().."TextLayer", button);
		getglobal(button:GetName().."TextLayer"):SetPoint("TOPLEFT",button,"TOPLEFT");
		getglobal(button:GetName().."TextLayer"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT");
		getglobal(button:GetName().."Count"):ClearAllPoints();
		getglobal(button:GetName().."Count"):SetPoint("BOTTOMRIGHT",button,"BOTTOMRIGHT",1,0);
		getglobal(button:GetName().."Count"):SetJustifyH("RIGHT");
		getglobal(button:GetName().."Count"):SetParent(getglobal(button:GetName().."TextLayer"));

		RaiseFrameLevel(getglobal(button:GetName().."Cooldown"));
		RaiseFrameLevel(getglobal(button:GetName().."TextLayer"));
	end
	PetFrame.numBuffs = 0;
	PetFrame.numDebuffs = 0;
end


function SmartBuffDebuff_Initial()
	-- BUFF initial
	if SMART_BUFF_ChkNum.target < SMART_BUFF_MaxNum.target then
		for i=(SMART_BUFF_ChkNum.target+1),SMART_BUFF_MaxNum.target do
			getglobal("TargetFrameBuff"..i):Hide();
		end
	end
	if SMART_BUFF_ChkNum.party < SMART_BUFF_MaxNum.party then
		for id=1,4 do
			for i=(SMART_BUFF_ChkNum.party+1),SMART_BUFF_MaxNum.party do
				getglobal("SmartPartyFrame"..id.."Buff"..i):Hide();
			end
		end
	end
	if SMART_BUFF_ChkNum.partypet < SMART_BUFF_MaxNum.partypet then
		for id=1,4 do
			for i=(SMART_BUFF_ChkNum.partypet+1),SMART_BUFF_MaxNum.partypet do
				getglobal("SmartPartyFrame"..id.."PetFrameBuff"..i):Hide();
			end
		end
	end
	if SMART_BUFF_ChkNum.pet < SMART_BUFF_MaxNum.pet then
		for i=(SMART_BUFF_ChkNum.pet+1),SMART_BUFF_MaxNum.pet do
			getglobal("SmartPetFrameBuff"..i):Hide();
		end
	end

	-- DEBUFF initial
	if SMART_DEBUFF_ChkNum.target < SMART_DEBUFF_MaxNum.target then
		for i=(SMART_DEBUFF_ChkNum.target+1),SMART_DEBUFF_MaxNum.target do
			getglobal("TargetFrameDebuff"..i):Hide();
		end
	end
	if SMART_DEBUFF_ChkNum.party < SMART_DEBUFF_MaxNum.party then
		for id=1,4 do
			for i=(SMART_DEBUFF_ChkNum.party+1),SMART_DEBUFF_MaxNum.party do
				getglobal("SmartPartyFrame"..id.."Debuff"..i):Hide();
			end
		end
	end
	if SMART_DEBUFF_ChkNum.partypet < SMART_DEBUFF_MaxNum.partypet then
		for id=1,4 do
			for i=(SMART_DEBUFF_ChkNum.partypet+1),SMART_DEBUFF_MaxNum.partypet do
				getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i):Hide();
			end
		end
	end
	if SMART_DEBUFF_ChkNum.pet < SMART_DEBUFF_MaxNum.pet then
		for i=(SMART_DEBUFF_ChkNum.pet+1),SMART_DEBUFF_MaxNum.pet do
			getglobal("SmartPetFrameDebuff"..i):Hide();
		end
	end
	SmartTargetBuff_BorderCheck();
	SmartPartyDebuff_Position();
end

function SmartPartyDebuff_Position()
	for id=1, 4 do
		if SMART_PARTY_Config.statusbartext then
			getglobal("SmartPartyFrame"..id.."Debuff"..1):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..id),"TOPLEFT",198,-13);
		else
			getglobal("SmartPartyFrame"..id.."Debuff"..1):SetPoint("TOPLEFT",getglobal("PartyMemberFrame"..id),"TOPLEFT",124,-13);
		end
	end
end

function SmartTargetBuff_BorderCheck()
	for i=1, SMART_BUFF_MaxNum.target do
		if SMART_TARGET_Config.buffborder then
			getglobal("TargetFrameBuff"..i.."Border"):Show();
		else
			getglobal("TargetFrameBuff"..i.."Border"):Hide();
		end
	end
end

function SmartTargetBuffDebuff_Update()
	local duration, timeLeft, buffCooldown, debuffCooldown, startCooldownTime;
	local numBuffs = 0;
	if SMART_BUFF_ChkNum.target > 0 then
		local buff, buffStack;
		local buffButton, buffIcon, buffCount;
		for i=1, SMART_BUFF_ChkNum.target do
			_, _, buff, buffStack, duration, timeLeft = UnitBuff("target", i);
			if ( buff ) then
				numBuffs = numBuffs + 1;
				buffButton = getglobal("TargetFrameBuff"..numBuffs);
				buffIcon = getglobal("TargetFrameBuff"..numBuffs.."Icon");
				buffCount = getglobal("TargetFrameBuff"..numBuffs.."Count");
				buffIcon:SetTexture(buff);
				if ( buffStack > 1 ) then
					buffCount:SetText(buffStack);
					buffCount:Show();
				else
					buffCount:Hide();
				end

				buffCooldown = getglobal("TargetFrameBuff"..numBuffs.."Cooldown");
				if (duration) then
					if (duration > 0) then
						buffCooldown:Show();
						startCooldownTime = GetTime()-(duration-timeLeft);
						CooldownFrame_SetTimer(buffCooldown, startCooldownTime, duration, 1);
					else
						buffCooldown:Hide();
					end
				else
					buffCooldown:Hide();
				end
				
				buffButton:Show();
				buffButton.id = numBuffs;
			else
				break;
			end
		end
	end
	if numBuffs < SMART_TARGET_NUMBUFFS then
		for i = (numBuffs+1), SMART_TARGET_NUMBUFFS do
			getglobal("TargetFrameBuff"..i):Hide();
		end
	end
	SMART_TARGET_NUMBUFFS = numBuffs;

	local numDebuffs = 0;
	if SMART_DEBUFF_ChkNum.target > 0 then
		local debuff, debuffStack, debuffType;
		local debuffButton, debuffIcon, debuffBorder, debuffCount, debuffColor;
		for i=1, SMART_DEBUFF_ChkNum.target do
			_, _, debuff, debuffStack, debuffType, duration, timeLeft = UnitDebuff("target", i);
			if ( debuff ) then
				numDebuffs = numDebuffs + 1;
				debuffButton = getglobal("TargetFrameDebuff"..numDebuffs);
				debuffIcon = getglobal("TargetFrameDebuff"..numDebuffs.."Icon");
				debuffCount = getglobal("TargetFrameDebuff"..numDebuffs.."Count");
				debuffBorder = getglobal("TargetFrameDebuff"..numDebuffs.."Border");
				debuffIcon:SetTexture(debuff);
				if ( debuffType ) then
					debuffColor = DebuffTypeColor[debuffType];
				else
					debuffColor = DebuffTypeColor["none"];
				end
				if ( debuffStack > 1 ) then
					debuffCount:SetText(debuffStack);
					debuffCount:Show();
				else
					debuffCount:Hide();
				end
				debuffBorder:SetVertexColor(debuffColor.r, debuffColor.g, debuffColor.b);

				debuffCooldown = getglobal("TargetFrameDebuff"..numDebuffs.."Cooldown")
				if (duration) then
					if (duration > 0) then
						debuffCooldown:Show();
						startCooldownTime = GetTime()-(duration-timeLeft);
						CooldownFrame_SetTimer(debuffCooldown, startCooldownTime, duration, 1);
					else
						debuffCooldown:Hide()
					end
				else
					debuffCooldown:Hide()
				end

				debuffButton:Show();
				debuffButton.id = i;
			else
	--[[
				numDebuffs = numDebuffs + 1;
				debuffButton = getglobal("TargetFrameDebuff"..numDebuffs);
				debuffIcon = getglobal("TargetFrameDebuff"..numDebuffs.."Icon");
				debuffCount = getglobal("TargetFrameDebuff"..numDebuffs.."Count");
				debuffBorder = getglobal("TargetFrameDebuff"..numDebuffs.."Border");
				debuff = "Interface\\Icons\\Temp.blp";
				debuffIcon:SetTexture(debuff);
				debuffCount:SetText("");
				debuffCount:Show();
				debuffBorder:SetVertexColor(1, 1, 1);
				debuffButton:Show();
				debuffButton.id = i;
	--]]
				break;
			end
		end
	else
	end
	if numDebuffs < SMART_TARGET_NUMDEBUFFS then
		for i = (numDebuffs+1), SMART_TARGET_NUMDEBUFFS do
			getglobal("TargetFrameDebuff"..i):Hide();
		end
	end
	SMART_TARGET_NUMDEBUFFS = numDebuffs;

	local buffWrap, buffSize, buffRows, debuffRows;

	buffWrap, buffSize = SmartTargetBuffDebuff_LineUp();

	buffRows = 0;
	if numBuffs > 0 then
		for i=1, numBuffs do
			getglobal("TargetFrameBuff"..i):ClearAllPoints();
			if i == 1 then
				getglobal("TargetFrameBuff"..i):SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",5,32);
				buffRows = buffRows + 1;
			elseif (i == (buffWrap * buffRows + 1)) and (i ~= 1) then
				getglobal("TargetFrameBuff"..i):SetPoint("TOPLEFT",getglobal("TargetFrameBuff"..(i-buffWrap)),"BOTTOMLEFT",0,-3);
				buffRows = buffRows + 1;
			else
				getglobal("TargetFrameBuff"..i):SetPoint("LEFT",getglobal("TargetFrameBuff"..(i-1)),"RIGHT",2,0);
			end
			getglobal("TargetFrameBuff"..i):SetWidth(buffSize);
			getglobal("TargetFrameBuff"..i):SetHeight(buffSize);
			getglobal("TargetFrameBuff"..i.."Border"):SetWidth(buffSize+2);
			getglobal("TargetFrameBuff"..i.."Border"):SetHeight(buffSize+2);
		end
	end

	debuffRows = 0;
	if numDebuffs > 0 then
		for i=1, numDebuffs do
			getglobal("TargetFrameDebuff"..i):ClearAllPoints();
			if i == 1 then
				getglobal("TargetFrameDebuff"..i):SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",5,32);
				debuffRows = debuffRows + 1;
			elseif (i == (buffWrap * debuffRows + 1)) and (i ~= 1) then
				getglobal("TargetFrameDebuff"..i):SetPoint("TOPLEFT",getglobal("TargetFrameDebuff"..(i-buffWrap)),"BOTTOMLEFT",0,-3);
				debuffRows = debuffRows + 1;
			else
				getglobal("TargetFrameDebuff"..i):SetPoint("LEFT",getglobal("TargetFrameDebuff"..(i-1)),"RIGHT",2,0);
			end
			getglobal("TargetFrameDebuff"..i):SetWidth(buffSize);
			getglobal("TargetFrameDebuff"..i):SetHeight(buffSize);
			getglobal("TargetFrameDebuff"..i.."Border"):SetWidth(buffSize+2);
			getglobal("TargetFrameDebuff"..i.."Border"):SetHeight(buffSize+2);
		end
	end

	TargetFrameBuff1:ClearAllPoints();
	TargetFrameDebuff1:ClearAllPoints();
	if ( UnitIsFriend("player", "target") ) then
		TargetFrameBuff1:SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.xOfs,SMART_BUFFDEBUFF_POSITION.yOfs);
		if numBuffs > 0 then
			TargetFrameDebuff1:SetPoint("TOPLEFT", getglobal("TargetFrameBuff"..((buffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 0, -3);
		else
			TargetFrameDebuff1:SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.xOfs,SMART_BUFFDEBUFF_POSITION.yOfs);
		end
	else
		TargetFrameDebuff1:SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.xOfs,SMART_BUFFDEBUFF_POSITION.yOfs);
		if numDebuffs > 0 then
			TargetFrameBuff1:SetPoint("TOPLEFT", getglobal("TargetFrameDebuff"..((debuffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 0, -3);
		else
			TargetFrameBuff1:SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.xOfs,SMART_BUFFDEBUFF_POSITION.yOfs);
		end
	end

	Target_Spellbar_AdjustPosition();
end

function SmartTargetBuffDebuff_LineUp()
	local targetofTarget, buffWrap, buffSize;
	-- check SmartToTFrame or TargetofTargetFrame
	if SMART_TOT_Config.enable and SMART_TOT_Config.WoWToTOnOff then
		targetofTarget = SmartToTFrame:IsShown();
	end
	-- set the wrap point for the rows of de/buffs.
	if ( targetofTarget ) then
		if SMART_TARGET_NUMBUFFS > 25 or SMART_TARGET_NUMDEBUFFS > 25 then
			buffWrap = 6;
			buffSize = 14;
		else
			if SMART_TARGET_NUMBUFFS > 4 or SMART_TARGET_NUMDEBUFFS > 4 then
				buffWrap = 5;
				buffSize = 17;
			else
				buffWrap = 4;
				buffSize = 22;
			end
		end
	else
		if SMART_TARGET_NUMBUFFS > 24 or SMART_TARGET_NUMDEBUFFS > 24 then
			buffWrap = 8;
			buffSize = 13;
		else
			if SMART_TARGET_NUMBUFFS > 5 or SMART_TARGET_NUMDEBUFFS > 5 then
				buffWrap = 6;
				buffSize = 18;
			else
				buffWrap = 5;
				buffSize = 22;
			end
		end
	end
	return buffWrap, buffSize;
end

local existingRefreshBuffs = RefreshBuffs;
function RefreshBuffs(frame, param2, param3)
	local id = frame:GetID();
	local checkUnit, chkBuff, chkDebuff, maxBuff, maxDebuff, buffFilter, debuffFilter;
	if ( frame == getglobal("PartyMemberFrame"..id) ) then
		checkUnit = "party"..id;
		chkBuff = SMART_BUFF_ChkNum.party;
		chkDebuff = SMART_DEBUFF_ChkNum.party;
		maxBuff = SMART_BUFF_MaxNum.party;
		maxDebuff = SMART_DEBUFF_MaxNum.party;
		buffFilter = SMART_PARTY_Config.bufffilter;
		debuffFilter = SMART_PARTY_Config.debufffilter;
	elseif ( frame == PetFrame ) then
		checkUnit = "pet";
		chkBuff = SMART_BUFF_ChkNum.pet;
		chkDebuff = SMART_DEBUFF_ChkNum.pet;
		maxBuff = SMART_BUFF_MaxNum.pet;
		maxDebuff = SMART_DEBUFF_MaxNum.pet;
		buffFilter = false;
		debuffFilter = false;
	else
		return existingRefreshBuffs(frame, param2, param3);
	end

	-- Buff Refresh Check
	-- If buffFilter is true, repeat CheckBuff until maxBuff
	-- But buffFilter is false, repeat CheckBuff until Exsist buffImage
	-- This rule apply only PartyMemberFrame
	local duration, timeLeft, cooldown, startCooldownTime;
	local idxBuff = 0;
	if chkBuff > 0 then
		local buffImage, buffButton, buffIcon, buffCount, buffStack;
		for i=1, maxBuff do
			_, _, buffImage, buffStack, duration, timeLeft = UnitBuff(checkUnit, i, buffFilter);
			if ( buffImage ) then
				idxBuff = idxBuff + 1;
				if ( checkUnit == ("party"..id) ) then
					buffButton = getglobal("SmartPartyFrame"..id.."Buff"..idxBuff);
					buffIcon = getglobal("SmartPartyFrame"..id.."Buff"..idxBuff.."Icon");
					buffCount = getglobal("SmartPartyFrame"..id.."Buff"..idxBuff.."Count");
					cooldown = getglobal("SmartPartyFrame"..id.."Buff"..idxBuff.."Cooldown");
				elseif ( checkUnit == "pet" ) then
					buffButton = getglobal("SmartPetFrameBuff"..idxBuff);
					buffIcon = getglobal("SmartPetFrameBuff"..idxBuff.."Icon");
					buffCount = getglobal("SmartPetFrameBuff"..idxBuff.."Count");
					cooldown = getglobal("SmartPetFrameBuff"..idxBuff.."Cooldown");
				end

				if (duration) then
					if (duration > 0) then
						cooldown:Show();
						startCooldownTime = GetTime()-(duration-timeLeft);
						CooldownFrame_SetTimer(cooldown, startCooldownTime, duration, 1);
					else
						cooldown:Hide();
					end
				else
					cooldown:Hide();
				end

				buffIcon:SetTexture(buffImage);
				buffButton:SetID(idxBuff);
				buffButton.id = idxBuff;
				buffButton:Show();
				if ( buffStack > 1 ) then
					buffCount:SetText(buffStack);
					buffCount:Show();
				else
					buffCount:Hide();
				end
				if idxBuff == chkBuff then
					break;
				end
			else
				if not buffFilter then
					break;
				end
			end
		end
	end
	if idxBuff < frame.numBuffs then
		for i = (idxBuff+1), frame.numBuffs do
			if ( checkUnit == ("party"..id) ) then
				getglobal("SmartPartyFrame"..id.."Buff"..i):Hide();
			elseif ( checkUnit == "pet" ) then
				getglobal("SmartPetFrameBuff"..i):Hide();
			end
		end
	end
	frame.numBuffs = idxBuff;

	-- Debuff Refresh Check
	-- If debuffFilter is true, repeat CheckDebuff until maxBuff
	-- But debuffFilter is false, repeat CheckDebuff until Exsist debuffImage
	-- This rule apply only PartyMemberFrame
	local idxDebuff = 0;
	if chkDebuff > 0 then
		local debuffImage, debuffStack, debuffType;
		local debuffButton, debuffIcon, debuffBorder, debuffCount, debuffColor;
		for i=1, maxDebuff do
			_, _, debuffImage, debuffStack, debuffType, duration, timeLeft = UnitDebuff(checkUnit, i, debuffFilter);
			if ( debuffImage ) then
				idxDebuff = idxDebuff + 1;
				if ( checkUnit == ("party"..id) ) then
					debuffButton = getglobal("SmartPartyFrame"..id.."Debuff"..idxDebuff);
					debuffIcon = getglobal("SmartPartyFrame"..id.."Debuff"..idxDebuff.."Icon");
					debuffBorder = getglobal("SmartPartyFrame"..id.."Debuff"..idxDebuff.."Border");
					debuffCount = getglobal("SmartPartyFrame"..id.."Debuff"..idxDebuff.."Count");
					cooldown = getglobal("SmartPartyFrame"..id.."Debuff"..idxDebuff.."Cooldown");
				elseif ( checkUnit == "pet" ) then
					debuffButton = getglobal("SmartPetFrameDebuff"..idxDebuff);
					debuffIcon = getglobal("SmartPetFrameDebuff"..idxDebuff.."Icon");
					debuffBorder = getglobal("SmartPetFrameDebuff"..idxDebuff.."Border");
					debuffCount = getglobal("SmartPetFrameDebuff"..idxDebuff.."Count");
					cooldown = getglobal("SmartPetFrameDebuff"..idxDebuff.."Cooldown");
				end

				if (duration) then
					if (duration > 0) then
						cooldown:Show();
						startCooldownTime = GetTime()-(duration-timeLeft);
						CooldownFrame_SetTimer(cooldown, startCooldownTime, duration, 1);
					else
						cooldown:Hide();
					end
				else
					cooldown:Hide();
				end
				
				if ( debuffType ) then
					debuffColor = DebuffTypeColor[debuffType];
				else
					debuffColor = DebuffTypeColor["none"];
				end
				debuffBorder:SetVertexColor(debuffColor.r, debuffColor.g, debuffColor.b);
				if ( debuffStack > 1 ) then
					debuffCount:SetText(debuffStack);
					debuffCount:Show();
				else
					debuffCount:Hide();
				end
				debuffIcon:SetTexture(debuffImage);
				debuffButton:SetID(idxDebuff);
				debuffButton.id = idxDebuff;
				debuffButton:Show();

				if idxDebuff == chkDebuff then
					break;
				end
			else
				if not debuffFilter then
					break;
				end
			end
		end
	end
	if idxDebuff < frame.numDebuffs then
		for i = (idxDebuff+1), frame.numDebuffs do
			if ( checkUnit == ("party"..id) ) then
				getglobal("SmartPartyFrame"..id.."Debuff"..i):Hide();
			elseif ( checkUnit == "pet" ) then
				getglobal("SmartPetFrameDebuff"..i):Hide();
			end
		end
	end
	frame.numDebuffs = idxDebuff;
end

function PartyMemberFrame_RefreshPetBuffs(id)
	if ( not id ) then
		id = this:GetID();
	end
	local checkFrame, checkUnit, maxBuff, maxDebuff;
	checkFrame = getglobal("PartyMemberFrame"..id.."PetFrame");
	checkUnit = "partypet"..id;
	chkBuff = SMART_BUFF_ChkNum.partypet;
	chkDebuff = SMART_DEBUFF_ChkNum.partypet;
	maxBuff = SMART_BUFF_MaxNum.partypet;
	maxDebuff = SMART_DEBUFF_MaxNum.partypet;

-- Buff Refresh Check
	local idxBuff = 0;
	if chkBuff > 0 then
		local buffImage, buffButton, buffIcon;
		for i=1, maxBuff do
			_, _, buffImage, _, _, _ = UnitBuff(checkUnit, i, SMART_PARTY_Config.bufffilter);
			if ( buffImage ) then
				idxBuff = idxBuff + 1;
				buffButton = getglobal("SmartPartyFrame"..id.."PetFrameBuff"..idxBuff);
				buffIcon = getglobal("SmartPartyFrame"..id.."PetFrameBuff"..idxBuff.."Icon");
				buffIcon:SetTexture(buffImage);
				buffButton:SetID(idxBuff);
				buffButton.id = idxBuff;
				buffButton:Show();
				if idxBuff == chkBuff then
					break;
				end
			else
				break;
			end
		end
	end
	if idxBuff < checkFrame.numBuffs then
		for i = (idxBuff+1), checkFrame.numBuffs do
			getglobal("SmartPartyFrame"..id.."PetFrameBuff"..i):Hide();
		end
	end
	checkFrame.numBuffs = idxBuff;

-- Debuff Refresh Check
	local idxDebuff = 0;
	if chkDebuff > 0 then
		local debuffImage, debuffStack, debuffType;
		local debuffButton, debuffIcon, debuffBorder, debuffCount, debuffColor;
		for i=1, maxDebuff do
			_, _, debuffImage, debuffStack, debuffType, _, _ = UnitDebuff(checkUnit, i, SMART_PARTY_Config.debufffilter);
			if ( debuffImage ) then
				idxDebuff = idxDebuff + 1;
				debuffButton = getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i);
				debuffIcon = getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i.."Icon");
				debuffBorder = getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i.."Border");
				debuffCount = getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i.."Count");
				if ( debuffType ) then
					debuffColor = DebuffTypeColor[debuffType];
				else
					debuffColor = DebuffTypeColor["none"];
				end
				debuffBorder:SetVertexColor(debuffColor.r, debuffColor.g, debuffColor.b);
				if ( debuffStack > 1 ) then
					debuffCount:SetText(debuffStack);
					debuffCount:Show();
				else
					debuffCount:Hide();
				end
				debuffIcon:SetTexture(debuffImage);
				debuffButton:SetID(idxDebuff);
				debuffButton.id = idxDebuff;
				debuffButton:Show();
				if idxDebuff == chkDebuff then
					break;
				end
			else
				break;
			end
		end
	end
	if idxDebuff < checkFrame.numDebuffs then
		for i = (idxDebuff+1), checkFrame.numDebuffs do
			getglobal("SmartPartyFrame"..id.."PetFrameDebuff"..i):Hide();
		end
	end
	checkFrame.numDebuffs = idxDebuff;
end

function PartyMemberBuffTooltip_Update(isPet)
-- Intentionally empty: Since we already have a more advanced buff/debuff
-- display than the tooltip, the tooltip doesn't make much sense to show.
end
