--------------------------------------------
--
-- SMART - FOCUS
--
--------------------------------------------
SMART_FOCUS_ENABLE = true
SMART_FOCUS_Config = { ChkBuff=24, MaxBuff=24, ChkDebuff=40, MaxDebuff=40 }

local CURRENT_FOCUS = nil
local SMART_FOCUS_NUMBUFFS = 0
local SMART_FOCUS_NUMDEBUFFS = 0

function SmartFocus_BuffDebuffCreation()
	local button
	for i=1, SMART_FOCUS_Config.MaxBuff do
		button = CreateFrame("Button","SmartFocusFrameBuff"..i, SmartFocusFrame, "SmartFocusBuffButtonTemplate")
		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_FOCUS_Config.MaxDebuff do
		button = CreateFrame("Button","SmartFocusFrameDebuff"..i, SmartFocusFrame, "SmartFocusDebuffButtonTemplate")
		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
end

function SmartFocus_BuffDebuffInitialize()
	if SMART_FOCUS_Config.ChkBuff < SMART_FOCUS_Config.MaxBuff then
		for i=(SMART_FOCUS_Config.ChkBuff+1),SMART_FOCUS_Config.MaxBuff do
			getglobal("SmartFocusFrameBuff"..i):Hide()
		end
	end
	if SMART_FOCUS_Config.ChkDebuff < SMART_FOCUS_Config.MaxDebuff then
		for i=(SMART_FOCUS_Config.ChkDebuff+1), SMART_FOCUS_Config.MaxDebuff do
			getglobal("SmartFocusFrameDebuff"..i):Hide()
		end
	end
	SmartFocusBuff_BorderCheck()
end

function SmartFocusBuff_BorderCheck()
	for i=1, SMART_FOCUS_Config.MaxBuff do
		if SMART_TARGET_Config.buffborder then
			getglobal("SmartFocusFrameBuff"..i.."Border"):Show()
		else
			getglobal("SmartFocusFrameBuff"..i.."Border"):Hide()
		end
		getglobal("SmartFocusFrameBuff"..i.."Border"):SetVertexColor(0,1,0)
	end
end

function SmartFocusFrame_OnLoad(self)
	SmartFocusRelocator_Initialize()

	self.statusCounter = 0
	self.statusSign = -1
	self.unitHPPercent = 1
	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:RegisterEvent("PLAYER_FOCUS_CHANGED")
	self:RegisterEvent("UNIT_HEALTH")
	self:RegisterEvent("UNIT_MAXHEALTH")
	self:RegisterEvent("UNIT_MANA")
	self:RegisterEvent("UNIT_RAGE")
	self:RegisterEvent("UNIT_ENERGY")
	self:RegisterEvent("UNIT_FOCUS")
	self:RegisterEvent("UNIT_MAXMANA")
	self:RegisterEvent("UNIT_MAXRAGE")
	self:RegisterEvent("UNIT_MAXENERGY")
	self:RegisterEvent("UNIT_MAXFOCUS")
	self:RegisterEvent("UNIT_LEVEL")
	self:RegisterEvent("UNIT_FACTION")
	self:RegisterEvent("UNIT_CLASSIFICATION_CHANGED")
	self:RegisterEvent("UNIT_AURA")
	self:RegisterEvent("UNIT_COMBAT")
	self:RegisterEvent("PLAYER_FLAGS_CHANGED")
	self:RegisterEvent("PARTY_MEMBERS_CHANGED")
	self:RegisterEvent("RAID_ROSTER_UPDATE")
	self:RegisterEvent("RAID_TARGET_UPDATE")
	self:RegisterEvent("VARIABLES_LOADED")
	self:SetMovable(true)

	SlashCmdList["SFOCUS"] = SmartFocus_CmdHandler
	SLASH_SFOCUS1 = "/sfocus"
	SLASH_SFOCUS2 = "/스마트주시대상"

	SmartFocusFrame:SetHitRectInsets(0,36,6,22)
	SmartFocusFrameHealthBar:SetHitRectInsets(0,SmartFocusFrameHealthBar:GetWidth(),0,SmartFocusFrameHealthBar:GetHeight())
	SmartFocusFrameManaBar:SetHitRectInsets(0,SmartFocusFrameManaBar:GetWidth(),0,SmartFocusFrameManaBar:GetHeight())

	SmartFocusFrameTextureFrame:CreateTexture("SmartFocusStatusTexture","ARTWORK")
	SmartFocusStatusTexture:SetTexture("Interface\\AddOns\\SmartUnitFrame\\CircleFlash.tga")
	SmartFocusStatusTexture:SetWidth(64)
	SmartFocusStatusTexture:SetHeight(64)
	SmartFocusStatusTexture:SetTexCoordModifiesRect(false)
	SmartFocusStatusTexture:SetTexCoord(0,1,0,1)
	SmartFocusStatusTexture:SetPoint("CENTER",SmartFocusPortrait,"CENTER",0,0)
	SmartFocusStatusTexture:SetBlendMode("ADD")
	SmartFocusStatusTexture:SetVertexColor(1,0.5,0)

	SmartFocusFrameTextureFrame:CreateTexture("SmartFocusStatusTextureNameFlash","ARTWORK")
	SmartFocusStatusTextureNameFlash:SetPoint("CENTER",SmartFocusFrameNameBackground,"CENTER",0,0)
	SmartFocusStatusTextureNameFlash:SetTexture("Interface\\AddOns\\SmartUnitFrame\\NameFlash.tga")
	SmartFocusStatusTextureNameFlash:SetWidth(SmartFocusFrameNameBackground:GetWidth()-4)
	SmartFocusStatusTextureNameFlash:SetHeight(SmartFocusFrameNameBackground:GetHeight()-4)
	SmartFocusStatusTextureNameFlash:SetTexCoordModifiesRect(false)
	SmartFocusStatusTextureNameFlash:SetTexCoord(0,1,0,1)
	SmartFocusStatusTextureNameFlash:SetBlendMode("ADD")
	SmartFocusStatusTextureNameFlash:SetVertexColor(1,0.5,0)

	self.statusCounter = 0
	self.statusSign = -1

	SmartFocus_BuffDebuffCreation()
	local showmenu = function()
		ToggleDropDownMenu(1, nil, getglobal(self:GetName().."DropDown"), self:GetName(), 120, 10)
	end
	SecureUnitButton_OnLoad(self, "focus", showmenu)
	RegisterUnitWatch(self)
end


function SmartFocusFrameDropDown_OnLoad(self)
	UIDropDownMenu_Initialize(self, SmartFocusFrameDropDown_Initialize, "MENU")
end

function SmartFocusFrameDropDown_Initialize()
	local menu
	local name
	local id = nil
	if (UnitIsUnit("focus", "player")) then
		menu = "SELF"
	elseif (UnitIsUnit("focus", "pet")) then
		menu = "PET"
	elseif (UnitIsPlayer("focus")) then
		id = UnitInRaid("focus")
		if (id) then
			menu = "RAID_PLAYER"
		elseif (UnitInParty("focus")) then
			menu = "PARTY"
		else
			menu = "PLAYER"
		end
	else
		menu = "RAID_TARGET_ICON"
		name = RAID_TARGET_ICON
	end
	if (menu) then
		UnitPopup_ShowMenu(SmartFocusFrameDropDown, menu, "focus", name, id)
	end
end

function SmartFocusFrame_OnShow(self)
	if UnitExists("focus") then
		if (CURRENT_FOCUS == nil) or (CURRENT_FOCUS ~= UnitName("focus")) then
			CURRENT_FOCUS = UnitName("focus")
			SmartFocusFrame_Update(self)
		end
	end
end

function SmartFocusFrame_OnHide(self)
	CURRENT_FOCUS = nil
end

function SmartFocus_Update()
	SmartFocusFrame_ClassIndicator()
	SmartFocusFrame_GroupIndicator()
	SmartFocusFrame_CheckLevel()
	SmartFocusFrame_CheckFaction()
	SmartFocusFrame_CheckClassification()
	if (UnitIsPartyLeader("focus")) then
		SmartFocusLeaderIcon:Show()
	else
		SmartFocusLeaderIcon:Hide()
	end
	SmartFocus_AuraButtonUpdate()
	SmartFocusPortrait:SetAlpha(1.0)
	SmartFocusFrame_UpdateRaidIcon()
	SmartFocusHealthUpdate(SmartFocusHealthBarText, "focus")
	SmartFocusManaUpdate(SmartFocusManaBarText, "focus")
end

function SmartFocusFrame_Update(self)
	if UnitExists("focus") then
		UnitFrame_Update(self)
		SmartFocus_Update(self)
	end
end

function SmartFocusFrame_OnEvent(self, event, ...)

	UnitFrame_OnEvent(self, event, ...)
	if (event == "PLAYER_ENTERING_WORLD") then
		SmartFocusFrame_Update(self)
	elseif (event == "VARIABLES_LOADED") then
		SmartFocus_BuffDebuffInitialize()
	elseif (event == "PLAYER_FOCUS_CHANGED") then
		SmartFocusFrame_Update(self)
	elseif (event == "UNIT_HEALTH") or (event == "UNIT_MAXHEALTH") then
		if arg1 == "focus" then
			SmartFocusHealthUpdate(SmartFocusHealthBarText, "focus")
		end
	elseif (event == "UNIT_FOCUS") or (event == "UNIT_MANA") or (event == "UNIT_RAGE") or (event == "UNIT_ENERGY")  or (event == "UNIT_MAXFOCUS") or (event == "UNIT_MAXMANA") or (event == "UNIT_MAXRAGE") or (event == "UNIT_MAXENERGY") then
		if arg1 == "focus" then
			SmartFocusManaUpdate(SmartFocusManaBarText, "focus")
		end
	elseif (event == "UNIT_LEVEL") then
		if (arg1 == "focus") then
			SmartFocusFrame_CheckLevel()
		end
	elseif (event == "UNIT_FACTION") then
		if (arg1 == "focus" or arg1 == "player") then
			SmartFocusFrame_CheckFaction()
			SmartFocusFrame_CheckLevel()
		end
	elseif (event == "UNIT_CLASSIFICATION_CHANGED") then
		if (arg1 == "focus") then
			SmartFocusFrame_CheckClassification()
		end
	elseif (event == "UNIT_AURA") then
		if (arg1 == "focus") then
			SmartFocus_AuraButtonUpdate()
		end
	elseif (event == "PLAYER_FLAGS_CHANGED") then
		if (arg1 == "focus") then
			if (UnitIsPartyLeader("focus")) then
				SmartFocusLeaderIcon:Show()
			else
				SmartFocusLeaderIcon:Hide()
			end
		end
	elseif (event == "PARTY_MEMBERS_CHANGED") then
		SmartFocusFrame_CheckFaction()
	elseif (event == "RAID_TARGET_UPDATE") then
		SmartFocusFrame_UpdateRaidIcon()
	elseif (event == "RAID_ROSTER_UPDATE") then
		SmartFocusFrame_GroupIndicator()
	end

end

function SmartFocusFrame_ClassIndicator()
	if SMART_TARGET_Config.infomation and SMART_TARGET_Config.classinfo then
		local focusClass, englishClass = UnitClass("focus")
		local classColor = {r=1,g=1,b=1}
		if focusClass and UnitIsPlayer("focus") then
			SmartFocusFrameClassIndicatorText:SetText(focusClass)
			if englishClass then
				classColor = RAID_CLASS_COLORS[englishClass]
			end
			SmartFocusFrameClassIndicator:Show()
		else
			if UnitCreatureType("target") then
				SmartFocusFrameClassIndicatorText:SetText(UnitCreatureType("target"))
				SmartFocusFrameClassIndicator:Show()
			else
				SmartFocusFrameClassIndicator:Hide()
			end
			if not UnitIsFriend("target","player") then
				local classColor = {r=1,g=0.5,b=0}
			end
		end
		SmartFocusFrameClassIndicatorText:SetTextColor(classColor.r,classColor.g,classColor.b)
	else
		SmartFocusFrameClassIndicator:Hide()
	end
end

function SmartFocusFrame_GroupIndicator()
	if SMART_TARGET_Config.infomation and SMART_TARGET_Config.groupinfo and
		UnitIsPlayer("focus") then
		local groupColor = {r=1,g=1,b=1}

		if UnitInRaid("focus") then
			local i
			local checkNum = GetNumRaidMembers()

			for i=1, checkNum do
				local name, _, subgroup, _, _, _, _, _, _ = GetRaidRosterInfo(i)
				if name == UnitName("focus") then
					SmartFocusFrameGroupIndicatorText:SetText(GROUPS.." "..subgroup)
					break
				end
			end
		else
			local unitRace, _ = UnitRace("focus")
			if unitRace == "나이트 엘프" then
				unitRace = "나이트엘프"
			end
			if unitRace == "블러드 엘프" then
				unitRace = "블러드엘프"
			end
			SmartFocusFrameGroupIndicatorText:SetText(unitRace)
			if not UnitIsFriend("focus", "player") then
				groupColor = {r=1,g=0.5,b=0}
			end
		end

		SmartFocusFrameGroupIndicatorText:SetTextColor(groupColor.r,groupColor.g,groupColor.b)
		SmartFocusFrameGroupIndicator:Show()
	else
		SmartFocusFrameGroupIndicator:Hide()
	end
end

function SmartFocus_AuraButtonUpdate()
	local texture, count, duration, expiretime, debuffType
	local cooldown
	local numBuffs = 0

	if SMART_FOCUS_Config.ChkBuff > 0 then
		local buffButton, buffIcon, buffCount

		for i=1, SMART_FOCUS_Config.ChkBuff do
			_, _, texture, count, debuffType, duration, expiretime = UnitAura("focus", i, "HELPFUL")

			if (texture) then
				numBuffs = numBuffs + 1

				buffButton = getglobal("SmartFocusFrameBuff"..numBuffs)
				buffIcon = getglobal("SmartFocusFrameBuff"..numBuffs.."Icon")
				buffCount = getglobal("SmartFocusFrameBuff"..numBuffs.."Count")
				buffIcon:SetTexture(texture)

				if (count > 1) then
					buffCount:SetText(count)
					buffCount:Show()
				else
					buffCount:Hide()
				end

				cooldown = getglobal("SmartFocusFrameBuff"..numBuffs.."Cooldown")

				if (duration and duration > 0) then
					cooldown:Show()
					CooldownFrame_SetTimer(cooldown, GetTime(), expiretime - GetTime(), 1)
				else
					cooldown:Hide()
				end

				buffButton:Show()
				buffButton.id = i
			else
				break
			end
		end
	end

	if numBuffs < SMART_FOCUS_NUMBUFFS then
		for i = (numBuffs+1), SMART_FOCUS_NUMBUFFS do
			getglobal("SmartFocusFrameBuff"..i):Hide()
		end
	end

	SMART_FOCUS_NUMBUFFS = numBuffs

	local numDebuffs = 0

	if SMART_FOCUS_Config.ChkDebuff > 0 then
		local debuffButton, debuffIcon, debuffBorder, debuffCount, color

		for i=1, SMART_FOCUS_Config.ChkDebuff do
			_, _, texture, count, debuffType, duration, expiretime = UnitAura("focus", i, "HARMFUL")

			if (texture) then
				numDebuffs = numDebuffs + 1

				debuffButton = getglobal("SmartFocusFrameDebuff"..numDebuffs)
				debuffIcon = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Icon")
				debuffCount = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Count")
				debuffBorder = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Border")
				debuffIcon:SetTexture(texture)

				if (debuffType) then
					color = DebuffTypeColor[debuffType]
				else
					color = DebuffTypeColor["none"]
				end

				if (count > 1) then
					debuffCount:SetText(count)
					debuffCount:Show()
				else
					debuffCount:Hide()
				end

				debuffBorder:SetVertexColor(color.r, color.g, color.b)

				cooldown = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Cooldown")

				if (duration and duration > 0) then
					cooldown:Show()
					CooldownFrame_SetTimer(cooldown, GetTime(), expiretime - GetTime(), 1)
				else
					cooldown:Hide()
				end

				debuffButton:Show()
				debuffButton.id = i
			else
				break
			end
		end
	end

	if numDebuffs < SMART_FOCUS_NUMDEBUFFS then
		for i = (numDebuffs+1), SMART_FOCUS_NUMDEBUFFS do
			getglobal("SmartFocusFrameDebuff"..i):Hide()
		end
	end
	
	SMART_FOCUS_NUMDEBUFFS = numDebuffs

	local buffWrap, buffSize, buffRows, debuffRows

	buffWrap, buffSize = SmartFocusBuffDebuff_LineUp()

	buffRows = 0

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

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

	SmartFocusFrameBuff1:ClearAllPoints()
	SmartFocusFrameDebuff1:ClearAllPoints()
	if (UnitIsFriend("player", "focus")) then
		SmartFocusFrameBuff1:SetPoint("TOPLEFT",SmartFocusFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.x,SMART_BUFFDEBUFF_POSITION.y)
		if numBuffs > 0 then
			SmartFocusFrameDebuff1:SetPoint("TOPLEFT", getglobal("SmartFocusFrameBuff"..((buffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 0, -3)
		else
			SmartFocusFrameDebuff1:SetPoint("TOPLEFT",SmartFocusFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.x,SMART_BUFFDEBUFF_POSITION.y)
		end
	else
		SmartFocusFrameDebuff1:SetPoint("TOPLEFT",SmartFocusFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.x,SMART_BUFFDEBUFF_POSITION.y)
		if numDebuffs > 0 then
			SmartFocusFrameBuff1:SetPoint("TOPLEFT", getglobal("SmartFocusFrameDebuff"..((debuffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 0, -3)
		else
			SmartFocusFrameBuff1:SetPoint("TOPLEFT",SmartFocusFrame,"BOTTOMLEFT",SMART_BUFFDEBUFF_POSITION.x,SMART_BUFFDEBUFF_POSITION.y)
		end
	end
	SmartFocus_Spellbar_AdjustPosition()
end

function SmartFocusFrame_CheckLevel()
	local targetLevel = UnitLevel("focus")

	if (UnitIsCorpse("focus")) then
		SmartFocusLevelText:Hide()
		SmartFocusHighLevelTexture:Show()
	elseif (targetLevel > 0) then
		-- Normal level target
		SmartFocusLevelText:SetText(targetLevel)
		-- Color level number
		if (UnitCanAttack("player", "focus")) then
			local color = GetDifficultyColor(targetLevel)
			SmartFocusLevelText:SetVertexColor(color.r, color.g, color.b)
		else
			SmartFocusLevelText:SetVertexColor(1.0, 0.82, 0.0)
		end
		SmartFocusLevelText:Show()
		SmartFocusHighLevelTexture:Hide()
	else
		-- SmartFocus is too high level to tell
		SmartFocusLevelText:Hide()
		SmartFocusHighLevelTexture:Show()
	end
end

function SmartFocusFrame_CheckFaction()
	if (UnitPlayerControlled("focus")) then
		local r, g, b
		if (UnitCanAttack("focus", "player")) then
			-- Hostile players are red
			if (not UnitCanAttack("player", "focus")) then
				r = 0.0
				g = 0.0
				b = 1.0
			else
				r = FACTION_BAR_COLORS[2].r
				g = FACTION_BAR_COLORS[2].g
				b = FACTION_BAR_COLORS[2].b
			end
		elseif (UnitCanAttack("player", "focus")) then
			-- Players we can attack but which are not hostile are yellow
			r = FACTION_BAR_COLORS[4].r
			g = FACTION_BAR_COLORS[4].g
			b = FACTION_BAR_COLORS[4].b
		elseif (UnitIsPVP("focus") and not UnitIsPVPSanctuary("focus") and not UnitIsPVPSanctuary("player")) then
			-- Players we can assist but are PvP flagged are green
			r = FACTION_BAR_COLORS[6].r
			g = FACTION_BAR_COLORS[6].g
			b = FACTION_BAR_COLORS[6].b
		else
			-- All other players are blue (the usual state on the "blue" server)
			r = 0.0
			g = 0.0
			b = 1.0
		end
		SmartFocusFrameNameBackground:SetVertexColor(r, g, b)
		SmartFocusPortrait:SetVertexColor(1.0, 1.0, 1.0)
	elseif (UnitIsTapped("focus") and not UnitIsTappedByPlayer("focus")) then
		SmartFocusFrameNameBackground:SetVertexColor(0.5, 0.5, 0.5)
		SmartFocusPortrait:SetVertexColor(0.5, 0.5, 0.5)
	else
		local reaction = UnitReaction("focus", "player")
		if (reaction) then
			local r, g, b
			r = FACTION_BAR_COLORS[reaction].r
			g = FACTION_BAR_COLORS[reaction].g
			b = FACTION_BAR_COLORS[reaction].b
			SmartFocusFrameNameBackground:SetVertexColor(r, g, b)
		else
			SmartFocusFrameNameBackground:SetVertexColor(0, 0, 1.0)
		end
		SmartFocusPortrait:SetVertexColor(1.0, 1.0, 1.0)
	end

	local factionGroup = UnitFactionGroup("focus")
	if (UnitIsPVPFreeForAll("focus")) then
		SmartFocusPVPIcon:SetTexture("Interface\\TargetingFrame\\UI-PVP-FFA")
		SmartFocusPVPIcon:Show()
	elseif (factionGroup and UnitIsPVP("focus")) then
		SmartFocusPVPIcon:SetTexture("Interface\\TargetingFrame\\UI-PVP-"..factionGroup)
		SmartFocusPVPIcon:Show()
	else
		SmartFocusPVPIcon:Hide()
	end
end

function SmartFocusFrame_CheckClassification()
	local classification = UnitClassification("focus")
	if (classification == "worldboss") then
		SmartFocusFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite")
	elseif (classification == "rareelite") then
		SmartFocusFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite")
	elseif (classification == "elite") then
		SmartFocusFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite")
	elseif (classification == "rare") then
		SmartFocusFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Rare")
	else
		SmartFocusFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame")
	end
end

function SmartFocusFrame_HealthUpdate(self, elapsed)
	if UnitExists("focus") then
		local alpha = 255
		local counter = self.statusCounter + elapsed
		local sign = self.statusSign

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

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

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

		if UnitAffectingCombat("focus") then
			SmartFocusStatusTexture:Show()
			SmartFocusStatusTexture:SetAlpha(alpha)
			SmartFocusStatusTextureNameFlash:Show()
			SmartFocusStatusTextureNameFlash:SetAlpha(alpha)
		else
			SmartFocusStatusTexture:Hide()
			SmartFocusStatusTextureNameFlash:Hide()
		end

		if UnitIsGhost("focus") or ((self.unitHPPercent > 0) and (self.unitHPPercent < 0.2)) then
			SmartFocusPortrait:SetAlpha(alpha)
		end
	end
end

function SmartFocusManaUpdate()
	if SMART_TARGET_Config.statusbartext and SMART_TARGET_Config.statusbarmana then
		SMART_ManaUpdate(SmartFocusManaBarText,"focus")
	else
		SmartFocusManaBarText:Hide()
	end
	if SMART_TARGET_Config.percent and SMART_TARGET_Config.percentmana then
		SMART_ManaPercent(SmartFocusManaPercent,"focus")
	else
		SmartFocusManaPercent:Hide()
	end
end

function SmartFocusHealthUpdate()
	if UnitIsConnected("focus") then
		if UnitIsDead("focus") then
			SmartFocusFrameHealthBar:Hide()
			SmartFocusHealthBarText:Hide()
			SmartFocusStatusText:SetText("죽음")
			SmartFocusStatusText:Show()
		elseif UnitIsGhost("focus") then
			SmartFocusFrameHealthBar:Hide()
			SmartFocusHealthBarText:Hide()
			SmartFocusStatusText:SetText("유령")
			SmartFocusStatusText:Show()
		else
			SmartFocusStatusText:Hide()
			SmartFocusFrameHealthBar:Show()
			if SMART_TARGET_Config.statusbartext then
				if SMART_TARGET_Config.statusbarloss then
					SMART_HealthLoss(SmartFocusHealthBarText,"focus")
				else
					SMART_MH3HealthUpdate(SmartFocusHealthBarText,"focus",SMART_TARGET_Config.healthwithpercent)
				end
			else
				SmartFocusHealthBarText:Hide()
			end
		end
	else
		SmartFocusFrameHealthBar:Hide()
		SmartFocusHealthBarText:Hide()
		SmartFocusStatusText:SetText("오프라인")
		SmartFocusStatusText:Show()
	end
	if SMART_TARGET_Config.percent then
		if SMART_TARGET_Config.percenttoloss then
			SMART_HealthLoss(SmartFocusHealthPercent,"focus")
		else
			SMART_HealthPercent(SmartFocusHealthPercent,"focus")
		end
	else
		SmartFocusHealthPercent:Hide()
	end
end

function SmartFocusHealthCheck(self)
	local unitMinHP, unitMaxHP, unitCurrHP
	unitHPMin, unitHPMax = self:GetMinMaxValues()
	unitCurrHP = self:GetValue()
	self:GetParent().unitHPPercent = unitCurrHP / unitHPMax
	if (UnitIsDead("focus")) then
		SmartFocusPortrait:SetVertexColor(0.35, 0.35, 0.35)
	elseif (UnitIsGhost("focus")) then
		SmartFocusPortrait:SetVertexColor(0.2, 0.2, 0.75)
	elseif ((self:GetParent().unitHPPercent >= 0) and (self:GetParent().unitHPPercent <= 0.2)) then
		SmartFocusPortrait:SetVertexColor(1.0, 0.0, 0.0)
	else
		SmartFocusPortrait:SetVertexColor(1.0, 1.0, 1.0, 1.0)
	end
end

function SmartFocusFrame_UpdateRaidIcon()
	local index = GetRaidTargetIndex("focus")
	if (index) then
		SetRaidTargetIconTexture(SmartFocusRaidIcon, index)
		SmartFocusRaidIcon:Show()
	else
		SmartFocusRaidIcon:Hide()
	end
end

function SmartFocusHitIndicator_OnEvent(self, event)
	if (event == "PLAYER_FOCUS_CHANGED") then
		SmartFocusHitIndicator:Hide()
		return
	end
	if (event == "UNIT_COMBAT") and (arg1 == "focus") then
		if SMART_TARGET_Config.indicator then
			CombatFeedback_OnCombatEvent(self, arg2, arg3, arg4, arg5)
			return
		else
			SmartFocusHitIndicator:Hide()
			return
		end
	end
end

function SmartFocusHitIndicator_OnUpdate(self, elapsed)
	if SMART_TARGET_Config.indicator then
		CombatFeedback_OnUpdate(self, elapsed)
	end
end

function SmartFocusRelocator_Initialize()
	local frame = getglobal("SmartFocusRelocator")

	if not frame then
		frame = CreateFrame("Button", "SmartFocusRelocator", SmartFocusFrame)

		SmartFocusRelocator:SetFrameLevel(SmartFocusFrame:GetFrameLevel()+2)
		SmartFocusRelocator:SetPoint("TOPLEFT", SmartFocusFrameNameBackground, "TOPLEFT")
		SmartFocusRelocator:SetPoint("BOTTOMRIGHT", SmartFocusFrameNameBackground, "BOTTOMRIGHT")
		SmartFocusRelocator:SetHitRectInsets(0, 0, 0, 0)
		SmartFocusRelocator:SetScript("OnEnter", function(self) SmartUnitFrame_OnEnter(self) end)
		SmartFocusRelocator:SetScript("OnLeave", SmartUnitFrame_OnLeave)
		SmartFocusRelocator:SetScript("OnMouseDown", function(self, arg1) SmartUnitFrame_OnMouseDown(self, arg1) end)
		SmartFocusRelocator:SetScript("OnMouseUp", function(self) SmartUnitFrame_OnMouseUp(self) end)
	end
end

function SmartFocus_CmdHandler(msg)
	if (strlower(msg) == strlower("reset")) or ( strlower(msg) == strlower("초기화")) then
		SmartFocus_ResetPosition()
		DEFAULT_CHAT_FRAME:AddMessage("SmartFocus: 위치초기화")
	else
		DEFAULT_CHAT_FRAME:AddMessage("SmartFocus: /sfocus or /스마트주시대상")
		DEFAULT_CHAT_FRAME:AddMessage("SmartFocus: [reset 또는 초기화] 프레임 위치초기화")
	end
end

function SmartFocus_ResetPosition()
	SmartFocusFrame:ClearAllPoints()
	SmartFocusFrame:SetPoint("TOPLEFT",TargetFrame,"BOTTOMLEFT",0,-100)
	SmartFocusFrame:SetUserPlaced(false)
	if SMART_FOCUSTOT_ENABLE then
		SmartFocusToT_ResetPosition()
	end
end

function SetSmartFocusSpellbarAspect()
	local frameText = getglobal(SmartFocusFrameSpellBar:GetName().."Text")
	if (frameText) then
		frameText:SetTextHeight(10)
		frameText:ClearAllPoints()
		frameText:SetPoint("TOP", SmartFocusFrameSpellBar, "TOP", 0, 4)
	end

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

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

function SmartFocus_Spellbar_OnLoad(self)
	self:RegisterEvent("PLAYER_FOCUS_CHANGED")
	self:RegisterEvent("CVAR_UPDATE")

	CastingBarFrame_OnLoad(self, "focus", false)

	local barIcon = getglobal(self:GetName().."Icon")
	barIcon:Show()

	SetSmartFocusSpellbarAspect()

	if (GetCVar("ShowTargetCastbar") == "0") then
		self.showCastbar = false;	
	end
end

function SmartFocus_Spellbar_OnEvent(self, target)
	local newevent = event
	-- Check for target specific events
	if ((event == "CVAR_UPDATE") and (arg1 == "SHOW_TARGET_CASTBAR")) then
		if (GetCVar("ShowTargetCastbar") == "0") then
			self.showCastbar = false;
		else
			self.showCastbar = true;
		end

		if (not self.showCastbar) then
			self:Hide()
		elseif (self.casting or self.channeling) then
			self:Show()
		end
		return
	elseif (event == "PLAYER_FOCUS_CHANGED") then
		-- check if the new target is casting a spell
		local nameChannel  = UnitChannelInfo(self.unit)
		local nameSpell  = UnitCastingInfo(self.unit)
		if (nameChannel) then
			newevent = "UNIT_SPELLCAST_CHANNEL_START"
			target = "focus"
		elseif (nameSpell) then
			newevent = "UNIT_SPELLCAST_START"
			target = "focus"
		else
			self.casting = nil
			self.channeling = nil
			self:SetMinMaxValues(0, 0)
			self:SetValue(0)
			self:Hide()
			return
		end
	end

	--if (UnitIsUnit("player", "focus")) then
	--		return
	--end
	CastingBarFrame_OnEvent(self, newevent, target)
end

function SmartFocus_Spellbar_AdjustPosition()
	SmartFocusFrameSpellBar:SetWidth(116)
	SmartFocusFrameSpellBarBorder:SetWidth(156)
	SmartFocusFrameSpellBarFlash:SetWidth(156)
	SmartFocusFrameSpellBar:SetFrameStrata("LOW")
	SmartFocusFrameSpellBar:SetToplevel(true)
	if SMART_TARGET_Config.ecastbarfixed then
		SmartFocusFrameSpellBar:ClearAllPoints()
		SmartFocusFrameSpellBar:SetPoint("BOTTOMLEFT", "SmartFocusFrame", "TOPLEFT", 8, -18)
	else
		local buffWrap, buffRows, debuffRows
		buffWrap, _ = SmartFocusBuffDebuff_LineUp()

		buffRows = 0
		if SMART_FOCUS_NUMBUFFS > 0 then
			for i=1, SMART_FOCUS_NUMBUFFS do
				if (i == (buffWrap * buffRows + 1)) then
					buffRows = buffRows + 1
				end
			end
		end

		debuffRows = 0

		if SMART_FOCUS_NUMDEBUFFS > 0 then
			for i=1, SMART_FOCUS_NUMDEBUFFS do
				if (i == (buffWrap * debuffRows + 1)) then
					debuffRows = debuffRows + 1
				end
			end
		end

		SmartFocusFrameSpellBar:ClearAllPoints()

		if (UnitIsFriend("player", "focus")) then
			if debuffRows > 0 then
				SmartFocusFrameSpellBar:SetPoint("TOPLEFT", getglobal("SmartFocusFrameDebuff"..((debuffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 3, -8)
			else
				if buffRows > 0 then
					SmartFocusFrameSpellBar:SetPoint("TOPLEFT", getglobal("SmartFocusFrameBuff"..((buffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 3, -8)
				else
					SmartFocusFrameSpellBar:SetPoint("TOPLEFT",SmartFocusFrameBuff1,"TOPLEFT",3,-8)
				end
			end
		else
			if buffRows > 0 then
				SmartFocusFrameSpellBar:SetPoint("TOPLEFT", getglobal("SmartFocusFrameBuff"..((buffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 3, -8)
			else
				if debuffRows > 0 then
					SmartFocusFrameSpellBar:SetPoint("TOPLEFT", getglobal("SmartFocusFrameDebuff"..((debuffRows * buffWrap + 1) - buffWrap)), "BOTTOMLEFT", 3, -8)
				else
					SmartFocusFrameSpellBar:SetPoint("TOPLEFT",SmartFocusFrameDebuff1,"TOPLEFT",3, -8)
				end
			end
		end
	end
end

function SmartFocusBuffDebuff_LineUp()
	local focusofTarget, buffWrap, buffSize

	-- check SmartToTFrame or TargetofTargetFrame
	if SMART_TOT_Config.enable and SMART_TOT_Config.WoWToTOnOff then
		focusofTarget = SmartFocusToTFrame:IsShown()
	end

	-- set the wrap point for the rows of de/buffs.
	if (focusofTarget) then
		if SMART_FOCUS_NUMBUFFS > 25 or SMART_FOCUS_NUMDEBUFFS > 25 then
			buffWrap = 6
			buffSize = 14
		else
			if SMART_FOCUS_NUMBUFFS > 4 or SMART_FOCUS_NUMDEBUFFS > 4 then
				buffWrap = 5
				buffSize = 17
			else
				buffWrap = 4
				buffSize = 22
			end
		end
	else
		if SMART_FOCUS_NUMBUFFS > 24 or SMART_FOCUS_NUMDEBUFFS > 24 then
			buffWrap = 8
			buffSize = 13
		else
			if SMART_FOCUS_NUMBUFFS > 5 or SMART_FOCUS_NUMDEBUFFS > 5 then
				buffWrap = 6
				buffSize = 18
			else
				buffWrap = 5
				buffSize = 22
			end
		end
	end

	return buffWrap, buffSize
end

