Quantcast
local addon = CreateFrame'Frame'
local addonname = ...

local origs = {}
local origname = ""

UnitPopupButtons["BN_RENAME"] = { text = PET_RENAME, dist = 0 }
table.insert(UnitPopupMenus["BN_FRIEND"], 7, "BN_RENAME")
table.insert(UnitPopupMenus["BN_FRIEND_OFFLINE"], 2, "BN_RENAME")

local function UpdateName(origname, name)
	if name == origname or #name == 0 then
		MonikerDB[origname] = nil
	else
		MonikerDB[origname] = name
	end

	FriendsFrame_Update()
end

local function GetNickname(origname)
	return MonikerDB[origname] or origname
end

local function ConvertLink(text)
	return text:gsub("|HBNplayer:(.-):(.-):(.-):(.-):(.-)|h%[(.+)%]|h", function(a1, a2, a3, a4, a5, a6)
		return ("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h"):format(a1, a2, a3, a4, a5, GetNickname(a6))
	end)
end

local function ReplaceText(frame)
	if frame and frame.GetText and frame.SetText then
		local text = frame:GetText()
		if not text then return end

		for orig, nick in pairs(MonikerDB) do
			if text:find(orig) then
				return frame:SetText(text:replace(orig, nick))
			end
		end
	end
end

local function AddMessage(self, text, ...)
	if text:find"You are now in a conversation with" then
		for orig, nick in pairs(MonikerDB) do
			if text:find(orig) then
				text = text:replace(orig, nick)
			end
		end
	end

	return origs[self](self, ConvertLink(text), ...)
end

local function HookChatFrame(cf)
	if not origs[cf] then
		origs[cf] = cf.AddMessage
		cf.AddMessage = AddMessage
	end
end

StaticPopupDialogs["BN_RENAME_FRIEND"] = {
	text = "Enter desired name of RealID friend or leave it empty if you want to use the original name",
	button1 = ACCEPT,
	button2 = CANCEL,
	hasEditBox = 1,
	hideOnEscape = 1,
	timeout = 0,
	exclusive = 1,
	whileDead = 1,

	OnAccept = function(self)
		local name = self.editBox:GetText()
		UpdateName(origname, name)
	end,

	EditBoxOnEnterPressed = function(self)
		local parent = self:GetParent()
		local name = parent.editBox:GetText()

		UpdateName(origname, name)
		parent:Hide()
	end,

	EditBoxOnEscapePressed = function(self)
		self:GetParent():Hide()
	end,

	OnShow = function(self)
		local name = MonikerDB[origname] or ""
		self.editBox:SetText(name)
		self.editBox:SetFocus()
	end,
}

addon:RegisterEvent"ADDON_LOADED"
addon:SetScript("OnEvent", function(self, e, addon)
	if addon ~= addonname then return end

	MonikerDB = MonikerDB or {}

	-- Hook tooltips
	FriendsTooltip:HookScript("OnShow", function(self)
		ReplaceText(FriendsTooltipHeader)
	end)

	BNToastFrame:HookScript("OnShow", function(self)
		ReplaceText(BNToastFrameTopLine)
	end)

	hooksecurefunc("FriendsFrameTooltip_Show", function(self)
		ReplaceText(FriendsTooltipHeader)
	end)


	-- Hook friends frame and it's subframes
	hooksecurefunc("FriendsFrame_SetButton", function(button, index, firstbutton)
		if button.buttonType == FRIENDS_BUTTON_TYPE_BNET then
			ReplaceText(button.name)
		end
	end)

	hooksecurefunc(FriendsFrameFriendsScrollFrame, "buttonFunc", function(button, index, firstbutton)
		if button.buttonType == FRIENDS_BUTTON_TYPE_BNET then
			ReplaceText(button.name)
		end
	end)

	hooksecurefunc("FriendsFriendsList_Update", function()
		ReplaceText(FriendsFriendsFrameTitle)

		for i = 1, FRIENDS_FRIENDS_TO_DISPLAY do
			local frame = _G["FriendsFriendsButton"..i]
			if frame then
				ReplaceText(frame.name)
			end
		end
	end)

	hooksecurefunc("BNConversationInvite_Update", function()
		for i = 1, BN_CONVERSATION_INVITE_NUM_DISPLAYED do
			local frame = _G["BNConversationInviteDialogListFriend"..i]
			if frame then
				ReplaceText(frame.name)
			end
		end
	end)

	hooksecurefunc(StaticPopupDialogs["SET_BNFRIENDNOTE"], "OnShow", function(self)
		ReplaceText(self.text)
	end)


	-- Chat related hooks
	hooksecurefunc("FCF_SetWindowName", function(frame, name, ...)
		HookChatFrame(frame)
		ReplaceText(_G[frame:GetName().."Tab"])
	end)

	hooksecurefunc("ChatEdit_UpdateHeader", function(editbox)
		local event = editbox:GetAttribute"chatType"
		local header = _G[editbox:GetName().."Header"]

		if event == "BN_WHISPER" then
			header:SetFormattedText(CHAT_BN_WHISPER_SEND, GetNickname(editbox:GetAttribute"tellTarget"))
			editbox:SetTextInsets(15 + header:GetWidth(), 13, 0, 0)
		end
	end)

	for i = 1, NUM_CHAT_WINDOWS do
		HookChatFrame(_G['ChatFrame'..i])
	end

	-- Handle right click menu
	hooksecurefunc("UnitPopup_OnClick", function(self)
		local dropdown = UIDROPDOWNMENU_INIT_MENU
		local button = self.value

		if button == "BN_RENAME" then
			local pid, firstname, lastname = BNGetFriendInfoByID(dropdown.presenceID)
			local name = firstname.." "..lastname

			origname = name

			StaticPopup_Show"BN_RENAME_FRIEND"
		end
	end)
end)