local _
local _G = _G

--=============================================================================================================

local addonName, FriendsInfo = ...
--FRIENDSINFO_VERSION = GetAddOnMetadata(addonName, "Version")

--=============================================================================================================

local REALM = GetRealmName()
local FRIENDSINFO_PLAYER_PATTERN = "(%u[a-ý]+)" --KOLLA "Êva"
--local MARKER = "|T1121272:16:16:0:0:512:512:66:98:406:438|t"
--local MARKER = "|TInterface/COMMON/FavoritesIcon.blp:16:16|t"
local MARKER = "|T1121272:16:16:0:0:512:512:202:234:440:472|t"
FriendsInfo_Data = FriendsInfo_Data or { }

--=============================================================================================================

local function FriendsInfo_ReturnClassColoredText(class, text)
	if class and class ~= "" then
		local classColor = RAID_CLASS_COLORS[string.upper(class)]
		return string.format("|cFF%02x%02x%02x%s|r",  classColor.r * 255,  classColor.g * 255,  classColor.b * 255, text)
	else
		return string.format("|cFF888888%s|r", text)
	end
end

--=============================================================================================================

local function FriendsInfo_GetSex(sex)
	return sex == 2 and "Male" or sex == 3 and "Female" or "Unknown"
end

--=============================================================================================================

local function FriendsInfo_ShowTooltip(self)
	if not (self and FriendsInfo_Data) then return end

	local playerInfo = FriendsInfo_Data[REALM] and
													(
													FriendsInfo_Data[REALM][self.PlayerName] or 
													(self.GetUnit and FriendsInfo_Data[REALM][strupper(self:GetUnit())])
													)

	if not playerInfo then return end

	local text = playerInfo.Info
	local name = strlower(self.PlayerName or self:GetUnit()):gsub("^%l", string.upper)

	if self:GetParent() == ChannelFrameScrollChild then

		GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 45, -40)
		GameTooltip:SetText(name)
		GameTooltip:AddLine(" ")

	elseif self:GetParent() == IgnoreListFrame then

		--GameTooltip:SetOwner(IgnoreListFrame, "ANCHOR_RIGHT", 0, -200)
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 50, -40)
		GameTooltip:SetText(name)
		GameTooltip:AddLine(" ")
	
	elseif self:GetParent() == WhoFrame or self:GetParent() == GuildPlayerStatusFrame then

		GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 55, -35)
		GameTooltip:SetText(name)
		GameTooltip:AddLine(" ")

	elseif self:GetParent() == FriendsFrameFriendsScrollFrameScrollChild then

		GameTooltip:SetOwner(FriendsTooltip, "ANCHOR_NONE")
		GameTooltip:SetPoint("TOPLEFT", FriendsTooltip, "BOTTOMLEFT", 2, 0)

	else --if self:GetParent() == UIParent then
		GameTooltip:AddLine(" ")
		PlaySoundFile("Sound/interface/AuctionWindowOpen.ogg")
		UIFrameFlash(_G["GameTooltipTextLeft" .. GameTooltip:NumLines()+1], 0.05, 0.05, 0.7, true, 0.05, 0.05)

	end

	text = string.gsub(text, "\\n", "\n")
	text = string.gsub(text, ";", "\n")
	text = MARKER .. text
	GameTooltip:AddLine(text, 1.00, 0.47, 0.04) --0.69, 0.40, 1.00
	if playerInfo.Class or playerInfo.Race or playerInfo.Sex then
		GameTooltip:AddLine(format("\n%s %s %s", FriendsInfo_GetSex(playerInfo.Sex), playerInfo.Race, FriendsInfo_ReturnClassColoredText(playerInfo.Class, playerInfo.Class)), 0.5, 0.5, 0.5) --0.69, 0.40, 1.00)
	end
--	GameTooltip:AddLine(text, 0.77, 0.12, 0.23)
--	GameTooltip:AddTexture("Interface/Minimap/Ping/ping6")
--	GameTooltipTexture1:SetBlendMode("ADD")
	GameTooltip:Show()
end

--=============================================================================================================

local function FriendsInfo_Save(button, name, text)
	if (not FriendsInfo_Data[REALM]) then
		FriendsInfo_Data[REALM] = { }
	end

	local class, race, sex = "", "", 0

	if (text == "") then
		FriendsInfo_Data[REALM][name] = nil
	else


		if FriendsInfo_Data[REALM][name] then
			class, race, sex = FriendsInfo_Data[REALM][name].Class, FriendsInfo_Data[REALM][name].Race, FriendsInfo_Data[REALM][name].Sex
		end

		if button and button.unit then
			local guid = UnitGUID(button.unit)
			class, _, race, _, sex = GetPlayerInfoByGUID(guid)
		elseif C_FriendList.GetNumWhoResults() > 0 then
			local who_info = C_FriendList.GetWhoInfo(1)
			if who_info then
				class, race, sex = who_info.classStr, who_info.raceStr, who_info.gender
			end
		end

		FriendsInfo_Data[REALM][name] = {
			["Info"] = text,
			["Class"] = class,
			["Race"] = race,
			["Sex"] = sex
		}

	end

	BasicMessageDialogButton:Click()
	name = strlower(name):gsub("^%l", string.upper)
	message(format("%s   %s\n|cffFFFF00%s|r|r", text == "" and "|c00FF0000DELETED|r" or "|c0000FF00SAVED|r", FriendsInfo_ReturnClassColoredText(class, name), tostring(text)))
	
	if (FriendsListFrame:IsVisible()) then FriendsList_Update() end
	if (IgnoreListFrame:IsVisible()) then IgnoreList_Update() end
	if (WhoFrame:IsVisible()) then WhoList_Update() end
	if (GuildFrame:IsVisible()) then GuildStatus_Update() end
	if (ChannelFrame.ChannelRoster:IsVisible()) then ChannelFrame.ChannelRoster:UpdateRosterList() end
	GameTooltip:Hide()
	FriendsInfo_ShowTooltip(button)
end

--=============================================================================================================

local function FriendsInfo_FriendsInfo_Edit(name, button, console)
	if GetMouseButtonClicked() ~= "LeftButton" and not console then return end

	local friendlyName = strlower(name):gsub("^%l", string.upper)
	name = strupper(name)

	StaticPopupDialogs["FRIENDSINFO_EDIT"] = {
		text = "Edit information for: |cff00FF00" .. friendlyName .. "|r\n|cffFFFF00Tip:|r  (semicolon) or \\n = newline",
		button1 = ACCEPT,
		button2 = CANCEL,
		hasEditBox = 1,
		maxLetters = 128,
		wide = false,
		editBoxWidth = 350,
		timeout = 0,
		exclusive = 1,
		whileDead = 1,
		hideOnEscape = 1,
		OnAccept = function(self)
			FriendsInfo_Save(button, name, self.editBox:GetText())
		end,
		OnShow = function(self)
			C_FriendList.SendWho(friendlyName)
			self.editBox:SetText(FriendsInfo_Data[REALM] and FriendsInfo_Data[REALM][name] and FriendsInfo_Data[REALM][name].Info or "")
			local icon = _G[self:GetName().."AlertIcon"]
			icon:Show()
			icon:SetTexture("Interface\\Minimap\\Ping\\ping6")
			icon:SetBlendMode("ADD")
			self.editBox:SetFocus()
		end,
		EditBoxOnEnterPressed = function(self)
			FriendsInfo_Save(button, name, self:GetText())
			self:GetParent():Hide()
		end,
		EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end
	}

	StaticPopup_Show("FRIENDSINFO_EDIT")
end

--=============================================================================================================

local function FriendsInfo_UpdateButton(button, name)
	if not name:GetText() then return end

	if (not button.PlayerName and button.buttonType ~= 2) then
		button:HookScript("OnDoubleClick", function(self, button) FriendsInfo_FriendsInfo_Edit(self.PlayerName, self) end)
		button:HookScript("OnEnter", function(self, motion) FriendsInfo_ShowTooltip(self) end)
		button:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
		if button:GetParent() == WhoFrame then
			button:HookScript("OnMouseUp", function(self, button)	name:SetText(strlower(self.PlayerName):gsub("^%l", string.upper))	end)
			button:HookScript("OnClick", function(self, button)	if button == "RightButton" then FriendsInfo_UpdateButton(self, name) end end)
		end
	end

	button.PlayerName = strmatch(name:GetText() or "", FRIENDSINFO_PLAYER_PATTERN) or ""
	button.PlayerName = strupper(button.PlayerName)

	local text = FriendsInfo_Data[REALM] and FriendsInfo_Data[REALM][button.PlayerName] and FriendsInfo_Data[REALM][button.PlayerName].Info

	if text then
		if button:GetParent() == ChannelFrameScrollChild and button.Rank:IsShown() then
			text = "     " .. text
		end
			--name:SetText(format("|cffFF0000*|r %s |c00FF0000%s|r", name:GetText(), text))
			--name:SetText(format("%s  |C00A330C9%s|r", name:GetText(), text))
			name:SetText(format("%s%s  |c00C41E3A%s|r", MARKER, name:GetText(), text))
	end

	local hasInfo, name, _, level, class =  name:GetText():match("(.-)(%a*), (%a+) (%d+) (%a+)")
	class = class or (FriendsInfo_Data[REALM] and FriendsInfo_Data[REALM][button.PlayerName] and FriendsInfo_Data[REALM][button.PlayerName].Class) or ""
	local classColor = RAID_CLASS_COLORS[string.upper(class)]
	if classColor and button.name then
		button.name:SetTextColor(classColor.r, classColor.g, classColor.b)
	end

end

--=============================================================================================================

--hooksecurefunc("FriendsFrame_UpdateFriendButton", 
--	function(button)
--		if button.buttonType == 2 then
--			--BNGetFriendInfo(button.index)
--		elseif button.buttonType == 3 then
--			local info = C_FriendList.GetFriendInfoByIndex(button.index)
--			if info then
--				local classColor = RAID_CLASS_COLORS[string.upper(info.className)]
--				--local colorCode = string.format("|cFF%02x%02x%02x",  classColor.r*255,  classColor.g*255,  classColor.b*255)
--				if classColor then
--					--print(button.buttonType, classColor, info.className, string.upper(info.className), info.name, info.level, classColor and classColor.colorStr)
--					button.name:SetText(format("|c%s%s (%s)|r  |c00FF0000%s|r", classColor.colorStr, info.name, info.level, text or ""))
--					--button.name:SetTextColor(classColor.r, classColor.g, classColor.b)
--				end
--			end
--		end
--	end
--)

--=============================================================================================================

local function FriendsInfo_Update(buttonName, count)
	local button, name
	for i=1, count do
		button = _G[buttonName .. i]
		name = _G[buttonName .. i .. "Name"]
		FriendsInfo_UpdateButton(button, name)
	end
end

--=============================================================================================================

local function FriendsInfo_UpdateChannelList()
	local buttons = HybridScrollFrame_GetButtons(ChannelFrameScrollChild:GetParent())
	if not buttons then return end
	for i, button in ipairs(buttons) do
		FriendsInfo_UpdateButton(button, button.Name)
	end
end

--=============================================================================================================

local function FriendsInfo_SlashHandler(msg)
	if (msg and msg ~= "") then
		FriendsInfo_FriendsInfo_Edit(msg, nil, true)
	end
end

--=============================================================================================================

local function FriendsInfo_Init()
	SLASH_FRIENDSINFO1 = "/friendsinfo"
	SLASH_FRIENDSINFO2 = "/fi"
	SlashCmdList["FRIENDSINFO"] = function(msg) FriendsInfo_SlashHandler(msg) end

	hooksecurefunc(FriendsFrameFriendsScrollFrame, "update", function() FriendsInfo_Update("FriendsFrameFriendsScrollFrameButton",	FRIENDS_TO_DISPLAY) end)
	hooksecurefunc("FriendsFrame_UpdateFriends", FriendsFrameFriendsScrollFrame.update)

	hooksecurefunc("IgnoreList_Update", function() FriendsInfo_Update("FriendsFrameIgnoreButton",	IGNORES_TO_DISPLAY) end)
	hooksecurefunc("WhoList_Update", function() FriendsInfo_Update("WhoFrameButton", WHOS_TO_DISPLAY) end)
--	hooksecurefunc("FriendsFrameWhoButton_OnClick", function(self, button) if button == "RightButton" then WhoList_Update() end	end)
	hooksecurefunc("GuildStatus_Update", function() FriendsInfo_Update("GuildFrameButton", GUILDMEMBERS_TO_DISPLAY) end)
	hooksecurefunc(ChannelFrame.ChannelRoster, "UpdateRosterList", FriendsInfo_UpdateChannelList)
	TargetFrame:HookScript("OnDoubleClick", function(self, button) FriendsInfo_FriendsInfo_Edit(TargetFrame.name:GetText(), self) end)
	GameTooltip:HookScript("OnTooltipSetUnit", function(self) FriendsInfo_ShowTooltip(self) end)

	for i=1, 4 do
		_G["PartyMemberFrame" .. i]:HookScript("OnDoubleClick", function(self, button) FriendsInfo_FriendsInfo_Edit(UnitName(self.unit), self) end)
	end

	hooksecurefunc(C_FriendList, "SendWho", 
		function(name)
			print(format("|c00008899Sending /who for:|r |c00FF5C1A%s|r", name))
			if StaticPopup1:IsShown() and StaticPopup1.which == "FRIENDSINFO_EDIT" then return end
			--name = name:gsub("%-.+", "")
			--name = strupper(name):gsub("^(.%-)", "")
			--name = strupper(name):match("[xX]?[%-]?(.+)%-")
			name = strupper(name)
			name = select(2, strsplit("-", name)) or name
			local REALM = GetRealmName()
			local playerInfo = FriendsInfo_Data[REALM] and FriendsInfo_Data[REALM][name]
			if playerInfo then
				PlaySoundFile("Sound/interface/AuctionWindowOpen.ogg")
				print(format("\n%s|c00FF5C1A%s|r   |c00888888%s %s|r %s", MARKER, playerInfo.Info, FriendsInfo_GetSex(playerInfo.Sex), playerInfo.Race, FriendsInfo_ReturnClassColoredText(playerInfo.Class, playerInfo.Class)))
			end
		end
	)
end

--=============================================================================================================

FriendsInfo_Init()

--C_Timer.After(2, ToggleFriendsFrame)
