local EFL = unpack(select(2,...))
local _
local pairs = pairs
local format = format
local LSM = LibStub("LibSharedMedia-3.0")

function EFL:ClassColorCode(class)
	for k, v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
		if class == v then
			class = k
		end
	end
	if GetLocale() ~= "enUS" then
		for k, v in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do
			if class == v then
				class = k
			end
		end
	end
	local color = RAID_CLASS_COLORS[class]
	if not color then
		return format("|cFF%02x%02x%02x", 255, 255, 255)
	else
		return format("|cFF%02x%02x%02x", color.r*255, color.g*255, color.b*255)
	end
end

local FRIENDS_GROUP_NAME_COLOR = NORMAL_FONT_COLOR
local INVITE_RESTRICTION_NONE = 5

function EFL:BasicUpdateFriends()
	local TexturePath = EnhancedFriendsListOptions.TexturePath
	local scrollFrame = FriendsFrameFriendsScrollFrame
	local offset = HybridScrollFrame_GetOffset(scrollFrame)
	local buttons = scrollFrame.buttons
	local numButtons = #buttons
	local nameText, nameColor, infoText, broadcastText
	local hasTravelPass = HasTravelPass()
	local hasTravelPassButton
	local canInvite = FriendsFrame_HasInvitePermission()
	local FRIENDS_TEXTURE_ONLINE = TexturePath == EFL.FlatTexturePath and EFL.FlatOnline or FRIENDS_TEXTURE_ONLINE
	local FRIENDS_TEXTURE_OFFLINE = TexturePath == EFL.FlatTexturePath and EFL.FlatOffline or FRIENDS_TEXTURE_OFFLINE
	local FRIENDS_TEXTURE_AFK = TexturePath == EFL.FlatTexturePath and EFL.FlatAway or FRIENDS_TEXTURE_AFK
	local FRIENDS_TEXTURE_DND = TexturePath == EFL.FlatTexturePath and EFL.FlatDnD or FRIENDS_TEXTURE_DND
	for i = 1, numButtons do
		local Cooperate = false
		local button = buttons[i]
		hasTravelPassButton = false

		if button.buttonType == FRIENDS_BUTTON_TYPE_WOW then
			local name, level, class, area, connected, status, note = GetFriendInfo(button.id)
			broadcastText = nil
			if connected then
				button.background:SetTexture(FRIENDS_WOW_BACKGROUND_COLOR.r, FRIENDS_WOW_BACKGROUND_COLOR.g, FRIENDS_WOW_BACKGROUND_COLOR.b, FRIENDS_WOW_BACKGROUND_COLOR.a)
				if status == "" then
					button.status:SetTexture(FRIENDS_TEXTURE_ONLINE)
				elseif status == CHAT_FLAG_AFK then
					button.status:SetTexture(FRIENDS_TEXTURE_AFK)
				elseif status == CHAT_FLAG_DND then
					button.status:SetTexture(FRIENDS_TEXTURE_DND)
				end
				nameText = format('%s%s - (%s - %s %s)', EFL:ClassColorCode(class), name, class, LEVEL, level)
				nameColor = FRIENDS_WOW_NAME_COLOR
				Cooperate = true
			else
				button.background:SetTexture(FRIENDS_OFFLINE_BACKGROUND_COLOR.r, FRIENDS_OFFLINE_BACKGROUND_COLOR.g, FRIENDS_OFFLINE_BACKGROUND_COLOR.b, FRIENDS_OFFLINE_BACKGROUND_COLOR.a)
				button.status:SetTexture(FRIENDS_TEXTURE_OFFLINE)
				nameText = name
				nameColor = FRIENDS_GRAY_COLOR
			end
			infoText = area
			button.gameIcon:Hide()
			FriendsFrame_SummonButton_Update(button.summonButton)
		elseif button.buttonType == FRIENDS_BUTTON_TYPE_BNET and BNConnected() then
			local presenceID, presenceName, battleTag, isBattleTagPresence, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, messageTime, canSoR = BNGetFriendInfo(button.id)
			local realmName, realmID, faction, race, class, zoneName, level, gameText, classcolor, diff
			broadcastText = messageText
			local characterName = toonName
			if presenceName then
				nameText = presenceName
				if isOnline and not characterName and battleTag then
					characterName = battleTag
				end
			elseif givenName then
				nameText = givenName
			else
				nameText = UNKNOWN
			end

			if characterName then
				_, _, _, realmName, realmID, faction, race, class, _, zoneName, level, gameText = BNGetToonInfo(toonID)
				if client == BNET_CLIENT_WOW then
					classcolor = EFL:ClassColorCode(class)
					diff = format("|cff%02x%02x%02x", GetQuestDifficultyColor(level).r * 255, GetQuestDifficultyColor(level).g * 255, GetQuestDifficultyColor(level).b * 255)
				end
				if client == BNET_CLIENT_WOW and CanCooperateWithToon(toonID, hasTravelPass) then
					nameText = format('%s |cFFFFFFFF(|r%s%s|r - %s %s%s|r|cFFFFFFFF)|r', nameText, classcolor, characterName, LEVEL, diff, level)
					Cooperate = true
				elseif client == BNET_CLIENT_WOW and not CanCooperateWithToon(toonID, hasTravelPass) then
					nameText = format('%s |cFFFFFFFF(|r%s%s|r - %s %s%s|r|cFFFFFFFF)|r', nameText, classcolor, characterName, LEVEL, diff, level)
				elseif client == BNET_CLIENT_SC2 then
					nameText = format('|cFFC495DD%s|r |cFFFFFFFF(|r%s|r|cFFFFFFFF)|r', nameText, characterName)
				elseif client == BNET_CLIENT_D3 then
					nameText = format('|cFFC41F3B%s|r |cFFFFFFFF(|r%s|r|cFFFFFFFF)|r', nameText, characterName)
				else
					nameText = format('%s |cFFFFFFFF(|r%s|r|cFFFFFFFF)|r', nameText, characterName)
				end
			end

			if isOnline then
				button.background:SetTexture(FRIENDS_BNET_BACKGROUND_COLOR.r, FRIENDS_BNET_BACKGROUND_COLOR.g, FRIENDS_BNET_BACKGROUND_COLOR.b, FRIENDS_BNET_BACKGROUND_COLOR.a)
				if isAFK then
					button.status:SetTexture(FRIENDS_TEXTURE_AFK)
				elseif isDND then
					button.status:SetTexture(FRIENDS_TEXTURE_DND)
				else
					button.status:SetTexture(FRIENDS_TEXTURE_ONLINE)
				end
				if client == BNET_CLIENT_WOW then
					if not zoneName or zoneName == "" then
						infoText = UNKNOWN
					else
						if realmName == EFL.MyRealm then
							infoText = zoneName
						else
							infoText = format('%s - %s', zoneName, realmName)
						end
					end
					button.gameIcon:SetTexture(TexturePath..faction)
				elseif client == BNET_CLIENT_SC2 then
					button.gameIcon:SetTexture(TexturePath.."SC2")
					infoText = gameText
				elseif client == BNET_CLIENT_D3 then
					button.gameIcon:SetTexture(TexturePath.."D3")
					infoText = gameText
				elseif client == BNET_CLIENT_WTCG then
					button.gameIcon:SetTexture(TexturePath..'Hearthstone')
					infoText = gameText
				end
				button.gameIcon:Show()
				nameColor = FRIENDS_BNET_NAME_COLOR
				if hasTravelPass then
					hasTravelPassButton = true
					local restriction = FriendsFrame_GetInviteRestriction(button.id, canInvite)
					if restriction == INVITE_RESTRICTION_NONE then
						button.travelPassButton:Enable()
					else
						button.travelPassButton:Disable()
					end
				end
			else
				button.background:SetTexture(FRIENDS_OFFLINE_BACKGROUND_COLOR.r, FRIENDS_OFFLINE_BACKGROUND_COLOR.g, FRIENDS_OFFLINE_BACKGROUND_COLOR.b, FRIENDS_OFFLINE_BACKGROUND_COLOR.a)
				button.status:SetTexture(FRIENDS_TEXTURE_OFFLINE)
				nameColor = FRIENDS_GRAY_COLOR
				button.gameIcon:Hide()
				if (not lastOnline or lastOnline == 0 or time() - lastOnline >= 31104000) == 0 then
					infoText = FRIENDS_LIST_OFFLINE
				else
					infoText = format(BNET_LAST_ONLINE_TIME, FriendsFrame_GetLastOnline(lastOnline))
				end
			end
			FriendsFrame_SummonButton_Update(button.summonButton)
		end

		if hasTravelPassButton then
			button.travelPassButton:Show()
			button.gameIcon:SetPoint("TOPRIGHT", -21, -3)
		else
			button.travelPassButton:Hide()
			button.gameIcon:SetPoint("TOPRIGHT", -2, -3)
		end

		if nameText then
			button.name:SetText(nameText)
			button.name:SetTextColor(nameColor.r, nameColor.g, nameColor.b);
			button.info:SetText(infoText)
			button.info:SetTextColor(.49, .52, .54)
			if Cooperate then
				button.info:SetTextColor(1, .96, .45)
			end
			button.name:SetFont(LSM:Fetch("font", EnhancedFriendsListOptions.NameFont), EnhancedFriendsListOptions.NameFontSize, EnhancedFriendsListOptions.NameFontFlag)
			button.name:SetShadowOffset(0,0)
			button.info:SetFont(LSM:Fetch("font", EnhancedFriendsListOptions.InfoFont), EnhancedFriendsListOptions.InfoFontSize, EnhancedFriendsListOptions.InfoFontFlag)
			button.info:SetShadowOffset(0,0)
		end
	end
end

function EFL:Basic()
	hooksecurefunc("HybridScrollFrame_Update", EFL.BasicUpdateFriends)
	hooksecurefunc("FriendsFrame_UpdateFriends", EFL.BasicUpdateFriends)
end