SUF = {}

SmartManaBarColor = {}
SmartManaBarColor[0] = { r = 0.00, g = 0.82, b = 1.00, prefix = TEXT(MANA) }
SmartManaBarColor[1] = { r = 1.00, g = 0.41, b = 0.41, prefix = TEXT(RAGE) }
SmartManaBarColor[2] = { r = 1.00, g = 0.50, b = 0.25, prefix = TEXT(FOCUS) }
SmartManaBarColor[3] = { r = 1.00, g = 0.82, b = 0.00, prefix = TEXT(ENERGY) }
SmartManaBarColor[4] = { r = 0.00, g = 1.00, b = 0.82, prefix = TEXT(HAPPINESS) }

SmartEliteText = {boss="보스",rareelite="희귀정예",elite="정예",rare="희귀"}

-------------------------------------------------------
--
-- SMART - Common Library
--
-------------------------------------------------------
function SMART_PortraitCheck(elapsed)
	if UnitExists(this.unit) and UnitIsConnected(this.unit) then
		local unitHPPercent = (UnitHealth(this.unit) / UnitHealthMax(this.unit))

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

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

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

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

			this.portrait:SetAlpha(alpha)
		else
			this.portrait:SetAlpha(1)
		end
	end
end

local hpColorRed = { r = 1, g = 0, b = 0 }
local hpColorNormal = { r = 1, g = 1, b = 1 }

function SMART_HealthColor(smartUnit)
	if (UnitHealth(smartUnit) / UnitHealthMax(smartUnit)) < 0.2 then
		return hpColorRed
	else
		return hpColorNormal
	end
end

function SMART_PortraitColor(smartFrame,smartUnit)
	local hpColor = SMART_HealthColor(smartUnit)
	smartFrame:SetVertexColor(hpColor.r, hpColor.g, hpColor.b)
end

function SMART_HealthPercent(smartFrame,smartUnit)
	if UnitIsConnected(smartUnit) then
		local hpColor = SMART_HealthColor(smartUnit)
		smartFrame:SetText(string.format("%d%%", floor((UnitHealth(smartUnit) / UnitHealthMax(smartUnit)) * 100)))
		smartFrame:SetTextColor(hpColor.r, hpColor.g, hpColor.b)
		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_ManaPercent(smartFrame,smartUnit)
	if UnitIsConnected(smartUnit) then
		if UnitManaMax(smartUnit) > 0 then
			smartFrame:SetText(string.format("%d%%",floor((UnitMana(smartUnit) / UnitManaMax(smartUnit))*100)))
		else
			smartFrame:SetText(string.format("%d%%",0))
		end
		SMART_ManaType(smartFrame, smartUnit)
		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_HealthUpdate(smartFrame,smartUnit,checkPercent)
	if UnitIsConnected(smartUnit) then
		local txt, per, cur, max
		cur, max = UnitHealth(smartUnit), UnitHealthMax(smartUnit)
		txt = string.format("%d / %d", cur, max)

		if checkPercent then
			per = floor((cur / max) * 100)
			txt = txt.." ("..per.."%)"
		end

		smartFrame:SetText(txt)

		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_MH3HealthUpdate(smartFrame,smartUnit,checkPercent)
	if UnitIsConnected(smartUnit) then
		local txt, per, cur, max
	 	if MobHealth3 and (UnitCanAttack(smartUnit,"player") or UnitCanAttack("player",smartUnit)) then
		 	local name, level = UnitName(smartUnit), UnitLevel(smartUnit)
	 		cur, max, _ = MobHealth3:GetUnitHealth(smartUnit, UnitHealth(smartUnit), UnitHealthMax(smartUnit), name, level)
			if max > 100000 then
			-- Display numbers in K notation
				txt = string.format("%dK / %dK", cur/1000, max/1000)
			else
				txt = string.format("%d / %d", cur, max)
			end
	 	else
	 		cur, max = UnitHealth(smartUnit), UnitHealthMax(smartUnit)
	 		txt = string.format("%d / %d", cur, max)
	 	end
	 	if checkPercent then
		 	per = floor((cur/max)*100)
		 	txt = txt.." ("..per.."%)"
	 	end
	 	smartFrame:SetText(txt)
		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_HealthLoss(smartFrame,smartUnit)
	if UnitIsConnected(smartUnit) and (not UnitIsDeadOrGhost(smartUnit)) and ( UnitIsUnit(smartUnit,"player") or UnitIsUnit(smartUnit,"pet") or UnitInParty(smartUnit) or UnitInRaid(smartUnit) or UnitPlayerOrPetInParty(smartUnit) or UnitPlayerOrPetInRaid(smartUnit) ) then
		local smartLoss = (UnitHealthMax(smartUnit) - UnitHealth(smartUnit))
		if (smartLoss > 0) then
			smartFrame:SetText("-"..smartLoss)
			if not smartFrame:IsShown() then
				smartFrame:Show()
			end
			local hpColor = SMART_HealthColor(smartUnit)
			smartFrame:SetTextColor(hpColor.r, hpColor.g, hpColor.b)
		else
			if smartFrame:IsShown() then
				smartFrame:Hide()
			end
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_ManaUpdate(frame, unit)
	if (unit == "target") or (unit == "player") or (unit == "pet") or (unit == "focus") then
		frame:SetTextColor(1, 1, 1)
	else
		SMART_ManaType(frame, unit)
	end

	if UnitIsConnected(unit) then
		frame:SetText(UnitMana(unit).." / "..UnitManaMax(unit))
		frame:Show()
	else
		frame:Hide()
	end
end

function SMART_ManaType(smartFrame, smartUnit)
	local powerType = UnitPowerType(smartUnit)

	if SmartManaBarColor[powerType] then
		smartFrame:SetTextColor(SmartManaBarColor[powerType].r, SmartManaBarColor[powerType].g, SmartManaBarColor[powerType].b)
	end
end

local nameColor = { r = 1, g = 0.82, b = 0 }

function SMART_ColorName(smartFrame,smartUnit)
	if (UnitPlayerControlled(smartUnit)) then
		if (UnitCanAttack(smartUnit, "player")) then
			nameColor.r = FACTION_BAR_COLORS[2].r
			nameColor.g = FACTION_BAR_COLORS[2].g
			nameColor.b = FACTION_BAR_COLORS[2].b
		elseif ( UnitCanAttack("player", smartUnit)) then
			nameColor.r = FACTION_BAR_COLORS[4].r
			nameColor.g = FACTION_BAR_COLORS[4].g
			nameColor.b = FACTION_BAR_COLORS[4].b
		elseif ( UnitIsPVP(smartUnit) ) then
			nameColor.r = FACTION_BAR_COLORS[6].r
			nameColor.g = FACTION_BAR_COLORS[6].g
			nameColor.b = FACTION_BAR_COLORS[6].b
		else
			nameColor.r = 1
			nameColor.g = 0.82
			nameColor.b = 0
		end
	elseif (UnitIsTapped(smartUnit) and not UnitIsTappedByPlayer(smartUnit)) then
		nameColor.r = 0.35
		nameColor.g = 0.35
		nameColor.b = 0.35
	else
		local reaction = UnitReaction("player", smartUnit)
		if (reaction) then
			nameColor.r = FACTION_BAR_COLORS[reaction].r
			nameColor.g = FACTION_BAR_COLORS[reaction].g
			nameColor.b = FACTION_BAR_COLORS[reaction].b
		else
			nameColor.r = 1
			nameColor.g = 0.82
			nameColor.b = 0
		end
	end

	smartFrame:SetTextColor(nameColor.r, nameColor.g, nameColor.b)
	smartFrame:SetText(GetUnitName(smartUnit, true))

	if not smartFrame:IsShown() then
		smartFrame:Show()
	end
end

function SMART_CheckElite(smartFrame,smartUnit)
	local classification = UnitClassification(smartUnit)
	local chkElite

	if ( classification == "worldboss" ) then
		chkElite = SmartEliteText.boss
	elseif ( classification == "rareelite"  ) then
		chkElite = SmartEliteText.rareelite
	elseif ( classification == "elite"  ) then
		chkElite = SmartEliteText.elite
	elseif ( classification == "rare"  ) then
		chkElite = SmartEliteText.rare
	else
		chkElite = ""
	end

	smartFrame:SetText(chkElite)

	if not smartFrame:IsShown() then
		smartFrame:Show()
	end
end

function SMART_CheckLevel(smartFrame, smartUnit)
	local chkLevel = UnitLevel(smartUnit)

	if (UnitCanAttack("player", smartUnit)) then
		local color = GetDifficultyColor(chkLevel)
		smartFrame:SetTextColor(color.r, color.g, color.b)
	else
		smartFrame:SetTextColor(1, 0.82, 0)
	end

	if (chkLevel <= 0) then
		chkLevel = "??"
	end

	smartFrame:SetText(chkLevel)

	if not smartFrame:IsShown() then
		smartFrame:Show()
	end
end

function SMART_ClassIcons(smartFrame,smartUnit)
	local _, englishClass = UnitClass(smartUnit)

	if englishClass and UnitIsPlayer(smartUnit) then
		smartFrame:SetTexture("Interface\\AddOns\\SmartUnitFrame\\Icons\\"..englishClass)
		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_PVPRank(smartUnit)
	local unitRank
	local unitRankTexture, unitRankName, unitRankNumber

	if UnitIsUnit(smartUnit,"player") then
		_, unitRank = GetPVPLifetimeStats()
	else
		unitRank = UnitPVPRank(smartUnit)
	end

	unitRankName, unitRankNumber = GetPVPRankInfo(UnitPVPRank(unitRank))

	if (unitRankNumber > 0) then
		unitRankTexture = format.string("%s%02d", "Interface\\PvPRankBadges\\PvPRank", unitRankNumber)
	end

	return unitRankTexture, unitRankName, unitRankNumber
end

function SMART_RaidTargetCheck(smartFrame, smartUnit)
	if GetRaidTargetIndex(smartUnit) then
		SetRaidTargetIconTexture(smartFrame, GetRaidTargetIndex(smartUnit))
		if not smartFrame:IsShown() then
			smartFrame:Show()
		end
	else
		if smartFrame:IsShown() then
			smartFrame:Hide()
		end
	end
end

function SMART_CheckFeign(smartUnit)
	local _, class = UnitClass(smartUnit)
	if class ~= "HUNTER" then return false end

	local num = 1
	local buff = UnitBuff(smartUnit, num)

	while (buff) do
		if (buff == "Interface\\Icons\\Ability_Rogue_FeignDeath") then
			return true
		end
		num = num + 1
		buff = UnitBuff(smartUnit, num)
	end

	return false
end

function SMART_FactionGroupCheck(smartFrame, smartUnit)
	if not smartFrame then
		return
	end

	if ( UnitIsPVPFreeForAll(smartUnit) ) then
		smartFrame:SetTexture("Interface\\TargetingFrame\\UI-PVP-FFA")
		smartFrame:Show()
	elseif ( UnitFactionGroup(smartUnit) and UnitIsPVP(smartUnit) ) then
		smartFrame:SetTexture("Interface\\TargetingFrame\\UI-PVP-"..UnitFactionGroup(smartUnit))
		smartFrame:Show()
	else
		smartFrame:Hide()
	end
end

function SMART_IsToTShown()
	if SMART_TOT_Config.enable then
		return SmartToTFrame:IsShown()
	else
		return TargetofTargetFrame:IsShown()
	end
end

