--------------------------------------------
--
-- 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()
	this.statusCounter = 0
	this.statusSign = -1
	this.unitHPPercent = 1
	this:RegisterEvent("PLAYER_ENTERING_WORLD")
	this:RegisterEvent("PLAYER_FOCUS_CHANGED")
	this:RegisterEvent("UNIT_HEALTH")
	this:RegisterEvent("UNIT_MAXHEALTH")
	this:RegisterEvent("UNIT_MANA")
	this:RegisterEvent("UNIT_RAGE")
	this:RegisterEvent("UNIT_ENERGY")
	this:RegisterEvent("UNIT_FOCUS")
	this:RegisterEvent("UNIT_MAXMANA")
	this:RegisterEvent("UNIT_MAXRAGE")
	this:RegisterEvent("UNIT_MAXENERGY")
	this:RegisterEvent("UNIT_MAXFOCUS")
	this:RegisterEvent("UNIT_LEVEL")
	this:RegisterEvent("UNIT_FACTION")
	this:RegisterEvent("UNIT_CLASSIFICATION_CHANGED")
	this:RegisterEvent("UNIT_AURA")
	this:RegisterEvent("UNIT_COMBAT")
	this:RegisterEvent("PLAYER_FLAGS_CHANGED")
	this:RegisterEvent("PARTY_MEMBERS_CHANGED")
	this:RegisterEvent("RAID_ROSTER_UPDATE")
	this:RegisterEvent("RAID_TARGET_UPDATE")
	this:RegisterEvent("VARIABLES_LOADED")
	this: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())

	SmartFocusRelocator_Initialize()

	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)

	this.statusCounter = 0
	this.statusSign = -1

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


function SmartFocusFrameDropDown_OnLoad()
	UIDropDownMenu_Initialize(this, 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()
	if UnitExists("focus") then
		if (CURRENT_FOCUS == nil) or (CURRENT_FOCUS ~= UnitName("focus")) then
			CURRENT_FOCUS = UnitName("focus")
			SmartFocusFrame_Update()
		end
	end
end

function SmartFocusFrame_OnHide()
	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_DebuffButtonUpdate()
	SmartFocusPortrait:SetAlpha(1.0)
	SmartFocusFrame_UpdateRaidIcon()
	SmartFocusHealthUpdate(SmartFocusHealthBarText, "focus")
	SmartFocusManaUpdate(SmartFocusManaBarText, "focus")
end

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

function SmartFocusFrame_OnEvent(event)

	UnitFrame_OnEvent(event)
	if (event == "PLAYER_ENTERING_WORLD") then
		SmartFocusFrame_Update()
	elseif (event == "VARIABLES_LOADED") then
		SmartFocus_BuffDebuffInitialize()
	elseif (event == "PLAYER_FOCUS_CHANGED") then
		SmartFocusFrame_Update()
	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_DebuffButtonUpdate()
		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_DebuffButtonUpdate()
	local duration, timeLeft, cooldown, startCooldownTime
	local numBuffs = 0

	if SMART_FOCUS_Config.ChkBuff > 0 then
		local buff, buffButton, buffIcon, buffCount, buffStack
		for i=1, SMART_FOCUS_Config.ChkBuff do
			_, _, buff, buffStack, duration, timeLeft = UnitBuff("focus", i)
			if (buff) then
				numBuffs = numBuffs + 1
				buffButton = getglobal("SmartFocusFrameBuff"..numBuffs)
				buffIcon = getglobal("SmartFocusFrameBuff"..numBuffs.."Icon")
				buffCount = getglobal("SmartFocusFrameBuff"..numBuffs.."Count")
				buffIcon:SetTexture(buff)
				if (buffStack > 1) then
					buffCount:SetText(buffStack)
					buffCount:Show()
				else
					buffCount:Hide()
				end

				cooldown = getglobal("SmartFocusFrameBuff"..numBuffs.."Cooldown")
				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

				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 debuff, debuffButton, debuffIcon, debuffBorder, debuffStack, debuffType, color
		local debuffCount
		for i=1, SMART_FOCUS_Config.ChkDebuff do
			_, _, debuff, debuffStack, debuffType, duration, timeLeft = UnitDebuff("focus", i)
			if (debuff) 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(debuff)
				if (debuffType) then
					color = DebuffTypeColor[debuffType]
				else
					color = DebuffTypeColor["none"]
				end
				if (debuffStack > 1) then
					debuffCount:SetText(debuffStack)
					debuffCount:Show()
				else
					debuffCount:Hide()
				end
				debuffBorder:SetVertexColor(color.r, color.g, color.b)

				cooldown = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Cooldown")
				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

				debuffButton:Show()
				debuffButton.id = i
			else
				--[[
				numDebuffs = numDebuffs + 1
				debuffButton = getglobal("SmartFocusFrameDebuff"..numDebuffs)
				debuffIcon = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Icon")
				debuffCount = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Count")
				debuffBorder = getglobal("SmartFocusFrameDebuff"..numDebuffs.."Border")
				debuff = "Interface\\Icons\\Temp.blp"
				debuffIcon:SetTexture(debuff)
				debuffCount:SetText("")
				debuffCount:Show()
				debuffBorder:SetVertexColor(1, 1, 1)
				debuffButton:Show()
				debuffButton:SetID(i)
				debuffButton.id = i
				--]]
				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 = UnitReactionColor[2].r
				g = UnitReactionColor[2].g
				b = UnitReactionColor[2].b
			end
		elseif (UnitCanAttack("player", "focus")) then
			-- Players we can attack but which are not hostile are yellow
			r = UnitReactionColor[4].r
			g = UnitReactionColor[4].g
			b = UnitReactionColor[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 = UnitReactionColor[6].r
			g = UnitReactionColor[6].g
			b = UnitReactionColor[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 = UnitReactionColor[reaction].r
			g = UnitReactionColor[reaction].g
			b = UnitReactionColor[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(elapsed)
	if UnitExists("focus") 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

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

		if UnitIsGhost("focus") or ((this.unitHPPercent > 0) and (this.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()
	local unitMinHP, unitMaxHP, unitCurrHP
	unitHPMin, unitHPMax = this:GetMinMaxValues()
	unitCurrHP = this:GetValue()
	this: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 ((this:GetParent().unitHPPercent >= 0) and (this: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(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(arg2, arg3, arg4, arg5)
			return
		else
			SmartFocusHitIndicator:Hide()
			return
		end
	end
end

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

function SmartFocusRelocator_Initialize()
	local frame
	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() SmartFocus_DragEnter() end)
	SmartFocusRelocator:SetScript("OnLeave", function() SmartFocus_DragLeave() end)
	SmartFocusRelocator:SetScript("OnMouseDown", function() SmartFocus_DragStart(arg1) end)
	SmartFocusRelocator:SetScript("OnMouseUp", function() SmartFocus_DragStop() end)
end

function SmartFocus_DragEnter()
	if SMART_TARGET_Config.movable then
		GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT")
		GameTooltip:AddLine("프레임 이동가능")
		GameTooltip:AddLine("알트키와 함께 왼쪽 또는 오른쪽 마우스버튼으로 프레임 이동",1,1,1)
		GameTooltip:Show()
	end
end

function SmartFocus_DragLeave()
	GameTooltip:Hide()
end

function SmartFocus_DragStart(button)
	if SMART_TARGET_Config.movable and IsAltKeyDown() then
		if (button == "LeftButton") or (button == "RightButton") then
			if (this:GetParent():IsMovable()) then
				this:GetParent():StartMoving()
			end
		end
	end
end

function SmartFocus_DragStop()
	if (this:GetParent():IsMovable()) then
		this:GetParent():StopMovingOrSizing()
	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()
	this:RegisterEvent("PLAYER_FOCUS_CHANGED")
	this:RegisterEvent("CVAR_UPDATE")

	CastingBarFrame_OnLoad("focus", false)

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

	SetSmartFocusSpellbarAspect()

	-- check to see if the castbar should be shown
--	if (GetCVar( UIOptionsFrameCheckButtons["SHOW_TARGET_CASTBAR"].cvar) == "0") then
	if (GetCVar( "ShowTargetCastbar" ) == "0") then
		this.showCastbar = false
	end
end

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

		if (not this.showCastbar) then
			this:Hide()
		elseif (this.casting or this.channeling) then
			this:Show()
		end
		return
	elseif (event == "PLAYER_FOCUS_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 = "focus"
		elseif (nameSpell) then
			newevent = "UNIT_SPELLCAST_START"
			newarg1 = "focus"
		else
			this.casting = nil
			this.channeling = nil
			this:SetMinMaxValues(0, 0)
			this:SetValue(0)
			this:Hide()
			return
		end
	end

	--if (UnitIsUnit("player", "focus")) then
	--		return
	--end
	CastingBarFrame_OnEvent(newevent, newarg1)
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

