local AddName, Ns = ...
local L = Ns.L

------------------------------
--		Options Equates		--
------------------------------

local Season, World, Equipped, Percentage, BNet = 1, 1, 1, 1, 1
local Expansion, Realm, Max, Rating = 2, 2, 2, 2
local Both = 3

----------------------
--		Misc		--
----------------------

-- Target Speed
function Ns.FunctionList.TargetSpeed(HUD, data, options, ...)

	local speedColor = ""
	local targetSpeed = GetUnitSpeed("target") / 7 * 100

	if targetSpeed == 0 or targetSpeed == 100 then speedColor = ""
	elseif targetSpeed < 100 then speedColor = "|cffC41E3A"
	elseif targetSpeed > 100 then speedColor = "|cff71FFC9" end

	HUD:UpdateText(data, speedColor .. string.format("%.0f%%", targetSpeed))
end
------------------------------------------------

-- Durability
function Ns.FunctionList.Durability(HUD, data, options, ...)
	local Durability, Current, Full, Percent
	local LowestCurrent, LowestFull, t1, t2, t3 = 500, 0, 0, 0, 100
	local statusbar

	for i=1,19 do
		Current, Full = GetInventoryItemDurability(i)
		if Current and Full then
			Percent = floor(100*Current/Full + 0.5)
			if (Percent < t3) then
				t3 = Percent
			end
			if (Current < LowestCurrent) then
				LowestCurrent = Current
				LowestFull = Full
			end
			t1 = t1 + Current
			t2 = t2 + Full
		end
	end
	if t2 == 0 then
		Durability = "N/A"
	else
		Durability = floor(t1 * 100 / t2)
	end
	local Text = ""
	if type(Durability) == "number" then
		if not options.AutoColorOff then
			if Durability > 50 then
				Text = string.format("|cff%2xff00", ((Durability > 50) and (255 - 2.55*Durability) or (2.55*Durability)), Durability) .. Text
			else
				Text = string.format("|cffff%2x00", (2.55*Durability), Durability) .. Text
			end
		end
		Text = Text..Durability.."%"
		statusbar = Durability
	end

	HUD:UpdateText(data, Text)
	HUD:UpdateBar(data, statusbar)
end
------------------------------------------------

-- Repair Cost
-- function Ns.FunctionList.RepairCost(HUD, data, options, ...)

-- 	local repairCost = GetRepairAllCost()
-- 	local returnText = "0"

-- 	if repairCost and repairCost > 0 then
-- 		local gold = floor(repairCost / 1e4)
-- 		if options.Display_Gold then
-- 			returnText = Ns.DecimalNumber(options.Decimals_Default, gold)
-- 		else
-- 			returnText = C_CurrencyInfo.GetCoinTextureString(repairCost)
-- 		end
-- 	end

-- 	HUD:UpdateText(data, returnText)
-- end
------------------------------------------------

-- Item Level
function Ns.FunctionList.ItemLevel(HUD, data, options, ...)

	local EB = options.Equipped_Overall
	local overall, equipped = GetAverageItemLevel()
	local returnText, decimals

	decimals = Ns.DecimalFormat(options.Decimals_Two)

	if Ns.Band(EB, Equipped) then returnText = (decimals):format(equipped) end
	if Ns.Band(EB, Max) then returnText = (decimals):format(overall) end
	if Ns.Band(EB, Both) then returnText = (decimals):format(equipped) .. "/" .. (decimals):format(overall) end
	if returnText == nil then returnText = 0 end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- PvP iLvl
function Ns.FunctionList.PvPiLvl(HUD, data, options, ...)

	local pvp = select(3, GetAverageItemLevel())
	local decimals

	decimals = Ns.DecimalFormat(options.Decimals_Two)

	HUD:UpdateText(data, (decimals):format(pvp))
end
------------------------------------------------

-- Global Cooldown
local gcd, oldgcd = 0, 0
function Ns.FunctionList.GlobalCD(HUD, data, options, ...)

	local _, gcd = C_Spell.GetSpellCooldown(61304) or 0
	local display = 0
	if gcd then display = gcd.duration end
	local decimals

	if gcd == 0 then display = oldgcd
	else oldgcd = gcd end

	decimals = Ns.DecimalFormat(options.Decimals_Two)

	HUD:UpdateText(data, (decimals):format(display))
end
------------------------------------------------

-- Ping
function Ns.FunctionList.Lag(HUD, data, options, ...)

	local EB = options.World_Realm
	local _, _, lagRealm, lagWorld = GetNetStats()
	local lagColor = ""
	local returnText

	if lagWorld <= 90 or lagRealm <= 90 then lagColor = "|cff71FFC9"
	elseif (lagWorld >= 90 and lagWorld < 200) or  (lagRealm >= 90 and lagRealm < 200) then lagColor = "|cffFF7C0A"
	elseif lagWorld >= 200 or lagRealm >= 200 then lagColor = "|cffC41E3A" end

	if Ns.Band(EB, World) then returnText = lagColor .. floor(lagWorld) end
	if  Ns.Band(EB, Realm) then returnText = lagColor .. floor(lagRealm) end
	if  Ns.Band(EB, Both) then returnText = lagColor .. floor(lagWorld) .. "/" .. floor(lagRealm) end
	if returnText == nil then returnText = 0 end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- FPS
function Ns.FunctionList.FPS(HUD, data, options, ...)

	local framerate = GetFramerate()
	local fpsColor = ""
	local returnText

	if framerate < 30 then fpsColor = "|cffC41E3A"
	elseif framerate > 30 and framerate < 50 then fpsColor = "|cffFF7C0A"
	elseif framerate > 50 then fpsColor = "|cff71FFC9" end
	if returnText == nil then returnText = 0 end

	HUD:UpdateText(data, fpsColor .. floor(framerate))
end
------------------------------------------------

-- Coordinates
function Ns.FunctionList.Coordinates(HUD, data, options, ...)

	local mapID = C_Map.GetBestMapForUnit("player")
	local returnText = "--"

	if mapID then
		local pos = C_Map.GetPlayerMapPosition(mapID, "player")
		if pos then
			local x, y = pos:GetXY()
			local fmt = Ns.DecimalFormat(options.Decimals_One)
			local decimals = fmt .. ", " .. fmt

			returnText = (decimals):format(x * 100, y * 100)
		end
	end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Renown Factions
local function RenownFaction(factionId)
	return function(HUD, data, options, ...)
		local renown = C_MajorFactions.GetMajorFactionData(factionId)
		local returnText

		if renown == nil then renown = 0 end

		local percent = renown.renownReputationEarned

		percent = (percent * 0.04)
		returnText = renown.renownLevel

		if options.Display_Percentage then returnText = renown.renownLevel .. " (" .. ("%.0f%%"):format(percent) .. ")" end

		HUD:UpdateText(data, returnText)

		if type(renown) == "table" then
			local barMode = options.JourneyBarMode or 1
			if barMode == 2 then
				local levels = C_MajorFactions.GetRenownLevels(factionId)
				local maxLevel = levels and #levels or 1
				HUD:UpdateBar(data, renown.renownLevel, maxLevel)
			else
				HUD:UpdateBar(data, renown.renownReputationEarned, renown.renownLevelThreshold or 2500)
			end
		end
	end
end

for name, factionId in pairs(Ns.RenownData) do
	Ns.FunctionList[name] = RenownFaction(factionId)
end
------------------------------------------------

-- Mythic Plus rating
function Ns.FunctionList.MythicPlus(HUD, data, options, ...)

	local EB = options.Season_Exp
	local expRating = C_MythicPlus.GetSeasonBestMythicRatingFromThisExpansion()
	local rating = C_ChallengeMode.GetOverallDungeonScore()
	local color = C_ChallengeMode.GetDungeonScoreRarityColor(rating)
	local colorBest = C_ChallengeMode.GetDungeonScoreRarityColor(expRating)
	local coloredRating, coloredBest = "", ""
	local returnText

	if color then coloredRating = color:WrapTextInColorCode(rating) end
	if colorBest then coloredBest = colorBest:WrapTextInColorCode(expRating) end

	if Ns.Band(EB, Season) then returnText = coloredRating end
	if Ns.Band(EB, Expansion) then returnText = coloredBest end
	if Ns.Band(EB, Both) then returnText = coloredRating .. "|r/" .. coloredBest end

	if returnText == nil then returnText = 0 end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Great Vault
function Ns.FunctionList.GreatVault(HUD, data, options, ...)

	local filled = 0
	local total = 0
	local types = { 2, 3, 1, 4 } -- MythicPlus, Raid, RankedPvP, World

	for i = 1, #types do
		local activities = C_WeeklyRewards.GetActivities(types[i])
		if activities then
			for j = 1, #activities do
				total = total + 1
				if activities[j].progress >= activities[j].threshold then
					filled = filled + 1
				end
			end
		end
	end

	local returnText = filled .. "/" .. total
	if filled == total and total > 0 then
		returnText = "|cff71FFC9" .. returnText
	end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Delves
function Ns.FunctionList.Delves(HUD, data, options, ...)

	local entry = options.Editbox_D or 0
	local delves = C_WeeklyRewards.GetActivities(6)
	local tier = 0
	local tier8 = options.Display_Delves

	for i=1,3 do
		if tier8 then
			if delves[i] and delves[i].level >= 8 then
				tier = delves[i].progress
			end
		else
			if delves[i] and delves[i].level == entry then
				tier = delves[i].progress
			end
		end
	end

	HUD:UpdateText(data, tier)
end
------------------------------------------------

-- Threat
function Ns.FunctionList.Threat(HUD, data, options, ...)

	local EB = options.Percent_Rating
	local _, _, threatpct, _, threatvalue = UnitDetailedThreatSituation("player", "target")
	local returnText, statusbar
	local threatColor = ""

	if threatpct == nil then threatpct = 0 end
	if threatvalue == nil then threatvalue = 0 end

	if threatpct <= 59 then threatColor = Ns.greenText
	elseif threatpct >= 60 and threatpct < 100 then threatColor = Ns.orangeText
	elseif threatpct == 100 then threatColor = Ns.redText end

	threatvalue = BreakUpLargeNumbers(threatvalue)

	if Ns.Band(EB, Percentage) then returnText = threatColor .. ("%.0f%%"):format(threatpct); statusbar = threatpct end
	if Ns.Band(EB, Rating) then returnText = threatColor .. ("%.0f"):format(threatvalue); statusbar = threatvalue end
	if Ns.Band(EB, Both) then returnText = threatColor .. ("%.0f%%"):format(threatpct) .. " |r(" .. ("%.0f"):format(threatvalue) .. ")"; statusbar = threatpct end

	if returnText == nil then returnText = "" end

	HUD:UpdateText(data, returnText)
	HUD:UpdateBar(data, statusbar)
end
------------------------------------------------

-- Guild
function Ns.FunctionList.Guild(HUD, data, options, ...)

	local totalMembers, numOnline = GetNumGuildMembers()
	local returnText

	if not IsInGuild() then
		HUD:UpdateText(data, "0")
		return
	end

	if options.Display_Total then
		returnText = numOnline .. "/" .. totalMembers
	else
		returnText = tostring(numOnline)
	end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Friends
function Ns.FunctionList.Friends(HUD, data, options, ...)

	local EB = options.BNet_Realm
	local bnetTotal, bnetOnline = BNGetNumFriends()
	local realmOnline = C_FriendList.GetNumOnlineFriends()
	local returnText

	if Ns.Band(EB, BNet) then returnText = tostring(bnetOnline) end
	if Ns.Band(EB, Realm) then returnText = tostring(realmOnline) end
	if Ns.Band(EB, Both) then returnText = bnetOnline .. "/" .. realmOnline end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------
