function methods.GetMessageHeight(g,w,n,a)a=a or n.AbsoluteSize.X local Q=g:GetStringTextBounds(w.Text,w.Font,w.TextSize,Vector2.new(a,1000))if Q.Y~=math.floor(Q.Y)then return Q.Y+1 end return Q.Y end function methods.GetNumberOfSpaces(g,w,n,a)local Q if typeof(w)=="\115\116\114\105\110\103"then Q=g:GetStringTextBounds(w,n,a)elseif typeof(w)=="\073\110\115\116\097\110\099\101"then Q=w.AbsoluteSize end local I=g:GetStringTextBounds(" ",n,a)return math.ceil(Q.X/I.X)end function methods.CreateBaseMessage(Q,w,n,a,g)local I=Q:GetFromObjectPool("\070\114\097\109\101")I.Selectable=false I.Size=UDim2.new(1,0,0,18)I.Visible=true I.BackgroundTransparency=1 local C=8 local W=Q:GetFromObjectPool("\084\101\120\116\076\097\098\101\108")W.Selectable=false W.Size=UDim2.new(1,-(C+6),1,0)W.Position=UDim2.new(0,C,0,0)W.BackgroundTransparency=1 W.Font=n W.TextSize=a W.TextXAlignment=Enum.TextXAlignment.Left W.TextYAlignment=Enum.TextYAlignment.Top W.TextTransparency=0 W.TextStrokeTransparency=.75 W.TextColor3=g W.TextWrapped=true W.ClipsDescendants=true W.Text=w W.Visible=true W.Parent=I return I,W end function methods.AddNameButtonToBaseMessage(Q,w,n,a,g)local I=Q:GetStringTextBounds(a,w.Font,w.TextSize)local C=Q:GetFromObjectPool("\084\101\120\116\066\117\116\116\111\110")C.Selectable=false C.Size=UDim2.new(0,I.X,0,I.Y)C.Position=UDim2.new(0,0,0,0)C.BackgroundTransparency=1 C.Font=w.Font C.TextSize=w.TextSize C.TextXAlignment=w.TextXAlignment C.TextYAlignment=w.TextYAlignment C.TextTransparency=w.TextTransparency C.TextStrokeTransparency=w.TextStrokeTransparency C.TextColor3=n C.Text=a C.Visible=true C.Parent=w local W=C.MouseButton1Click:connect(function()Q:NameButtonClicked(C,g)end)local P=nil P=C.Changed:connect(function(w)if w=="\080\097\114\101\110\116"then W:Disconnect()P:Disconnect()end end)return C end function methods.AddChannelButtonToBaseMessage(Q,w,n,a,g)local I=Q:GetStringTextBounds(a,w.Font,w.TextSize)local C=Q:GetFromObjectPool("\084\101\120\116\066\117\116\116\111\110")C.Selectable=false C.Size=UDim2.new(0,I.X,0,I.Y)C.Position=UDim2.new(0,0,0,0)C.BackgroundTransparency=1 C.Font=w.Font C.TextSize=w.TextSize C.TextXAlignment=w.TextXAlignment C.TextYAlignment=w.TextYAlignment C.TextTransparency=w.TextTransparency C.TextStrokeTransparency=w.TextStrokeTransparency C.TextColor3=n C.Text=a C.Visible=true C.Parent=w local W=C.MouseButton1Click:connect(function()Q:ChannelButtonClicked(C,g)end)local P=nil P=C.Changed:connect(function(w)if w=="\080\097\114\101\110\116"then W:Disconnect()P:Disconnect()end end)return C end function methods.AddTagLabelToBaseMessage(g,w,n,a)local Q=g:GetStringTextBounds(a,w.Font,w.TextSize)local I=g:GetFromObjectPool("\084\101\120\116\076\097\098\101\108")I.Selectable=false I.Size=UDim2.new(0,Q.X,0,Q.Y)I.Position=UDim2.new(0,0,0,0)I.BackgroundTransparency=1 I.Font=w.Font I.TextSize=w.TextSize I.TextXAlignment=w.TextXAlignment I.TextYAlignment=w.TextYAlignment I.TextTransparency=w.TextTransparency I.TextStrokeTransparency=w.TextStrokeTransparency I.TextColor3=n I.Text=a I.Visible=true I.Parent=w return I end function methods.AddIconLabelToBaseMessage(a,w,n)local g=DEFAULT_ICON_SIZE local Q=a:GetFromObjectPool("\073\109\097\103\101\076\097\098\101\108")Q.Selectable=false Q.Position=UDim2.new(0,0,0,0)Q.Size=UDim2.new(0,g.X,0,g.Y)Q.BackgroundTransparency=1 Q.Visible=true Q.ImageTransparency=0 Q.ScaleType=Enum.ScaleType.Fit Q.ImageColor3=Color3.new(1,1,1)Q.Image=n Q.Parent=w return Q end function GetWhisperChannelPrefix()if ChatConstants.WhisperChannelPrefix then return ChatConstants.WhisperChannelPrefix end return"\084\111 "end function methods.NameButtonClicked(a,w,n)if not a.ChatWindow then return end if ChatSettings.ClickOnPlayerNameToWhisper then local w=Players:FindFirstChild(n)if w and w~=LocalPlayer then local w=GetWhisperChannelPrefix()..n if a.ChatWindow:GetChannel(w)then a.ChatBar:ResetCustomState()local g=a.ChatWindow:GetTargetMessageChannel()if g~=w then a.ChatWindow:SwitchCurrentChannel(w)end local Q="\047\119 "..n a.ChatBar:SetText(Q)a.ChatBar:CaptureFocus()elseif not a.ChatBar:IsInCustomState()then local w="\047\119 "..n a.ChatBar:SetText(w)a.ChatBar:CaptureFocus()end end end end function methods.ChannelButtonClicked(a,w,n)if not a.ChatWindow then return end if ChatSettings.ClickOnChannelNameToSetMainChannel then if a.ChatWindow:GetChannel(n)then a.ChatBar:ResetCustomState()local w=a.ChatWindow:GetTargetMessageChannel()if w~=n then a.ChatWindow:SwitchCurrentChannel(n)end a.ChatBar:ResetText()a.ChatBar:CaptureFocus()end end end function methods.RegisterChatWindow(n,w)n.ChatWindow=w n.ChatBar=w:GetChatBar()end function methods.GetFromObjectPool(n,w)if n.ObjectPool==nil then return Instance.new(w)end return n.ObjectPool:GetInstance(w)end function methods.RegisterObjectPool(n,w)n.ObjectPool=w end
--// Above was taken directly from Util.GetStringTextBounds() in the old chat corescripts.

function methods:GetMessageHeight(BaseMessage, BaseFrame, xSize)
	xSize = xSize or BaseFrame.AbsoluteSize.X
	local textBoundsSize =
		self:GetStringTextBounds(BaseMessage.Text, BaseMessage.Font, BaseMessage.TextSize, Vector2.new(xSize, 1000))
	if textBoundsSize.Y ~= math.floor(textBoundsSize.Y) then
		-- HACK Alert. TODO: Remove this when we switch UDim2 to use float Offsets
		-- This is nessary due to rounding issues on mobile devices when translating between screen pixels and native pixels
		return textBoundsSize.Y + 1
	end
	return textBoundsSize.Y
end

function methods:GetNumberOfSpaces(str, font, textSize)
	local strSize
	if typeof(str) == "string" then
		strSize = self:GetStringTextBounds(str, font, textSize)
	elseif typeof(str) == "Instance" then
		strSize = str.AbsoluteSize
	end
	local singleSpaceSize = self:GetStringTextBounds(" ", font, textSize)
	return math.ceil(strSize.X / singleSpaceSize.X)
end

function methods:CreateBaseMessage(message, font, textSize, chatColor)
	local BaseFrame = self:GetFromObjectPool("Frame")
	BaseFrame.Selectable = false
	BaseFrame.Size = UDim2.new(1, 0, 0, 18)
	BaseFrame.Visible = true
	BaseFrame.BackgroundTransparency = 1

	local messageBorder = 8

	local BaseMessage = self:GetFromObjectPool("TextLabel")
	BaseMessage.Selectable = false
	BaseMessage.Size = UDim2.new(1, -(messageBorder + 6), 1, 0)
	BaseMessage.Position = UDim2.new(0, messageBorder, 0, 0)
	BaseMessage.BackgroundTransparency = 1
	BaseMessage.Font = font
	BaseMessage.TextSize = textSize
	BaseMessage.TextXAlignment = Enum.TextXAlignment.Left
	BaseMessage.TextYAlignment = Enum.TextYAlignment.Top
	BaseMessage.TextTransparency = 0
	BaseMessage.TextStrokeTransparency = 0.75
	BaseMessage.TextColor3 = chatColor
	BaseMessage.TextWrapped = true
	BaseMessage.ClipsDescendants = true
	BaseMessage.Text = message
	BaseMessage.Visible = true
	BaseMessage.Parent = BaseFrame

	return BaseFrame, BaseMessage
end

function methods:AddNameButtonToBaseMessage(BaseMessage, nameColor, formatName, playerName)
	local speakerNameSize = self:GetStringTextBounds(formatName, BaseMessage.Font, BaseMessage.TextSize)
	local NameButton = self:GetFromObjectPool("TextButton")
	NameButton.Selectable = false
	NameButton.Size = UDim2.new(0, speakerNameSize.X, 0, speakerNameSize.Y)
	NameButton.Position = UDim2.new(0, 0, 0, 0)
	NameButton.BackgroundTransparency = 1
	NameButton.Font = BaseMessage.Font
	NameButton.TextSize = BaseMessage.TextSize
	NameButton.TextXAlignment = BaseMessage.TextXAlignment
	NameButton.TextYAlignment = BaseMessage.TextYAlignment
	NameButton.TextTransparency = BaseMessage.TextTransparency
	NameButton.TextStrokeTransparency = BaseMessage.TextStrokeTransparency
	NameButton.TextColor3 = nameColor
	NameButton.Text = formatName
	NameButton.Visible = true
	NameButton.Parent = BaseMessage

	local clickedConn = NameButton.MouseButton1Click:connect(function()
		self:NameButtonClicked(NameButton, playerName)
	end)

	local changedConn = nil
	changedConn = NameButton.Changed:connect(function(prop)
		if prop == "Parent" then
			clickedConn:Disconnect()
			changedConn:Disconnect()
		end
	end)

	return NameButton
end

function methods:AddChannelButtonToBaseMessage(BaseMessage, channelColor, formatChannelName, channelName)
	local channelNameSize = self:GetStringTextBounds(formatChannelName, BaseMessage.Font, BaseMessage.TextSize)
	local ChannelButton = self:GetFromObjectPool("TextButton")
	ChannelButton.Selectable = false
	ChannelButton.Size = UDim2.new(0, channelNameSize.X, 0, channelNameSize.Y)
	ChannelButton.Position = UDim2.new(0, 0, 0, 0)
	ChannelButton.BackgroundTransparency = 1
	ChannelButton.Font = BaseMessage.Font
	ChannelButton.TextSize = BaseMessage.TextSize
	ChannelButton.TextXAlignment = BaseMessage.TextXAlignment
	ChannelButton.TextYAlignment = BaseMessage.TextYAlignment
	ChannelButton.TextTransparency = BaseMessage.TextTransparency
	ChannelButton.TextStrokeTransparency = BaseMessage.TextStrokeTransparency
	ChannelButton.TextColor3 = channelColor
	ChannelButton.Text = formatChannelName
	ChannelButton.Visible = true
	ChannelButton.Parent = BaseMessage

	local clickedConn = ChannelButton.MouseButton1Click:connect(function()
		self:ChannelButtonClicked(ChannelButton, channelName)
	end)

	local changedConn = nil
	changedConn = ChannelButton.Changed:connect(function(prop)
		if prop == "Parent" then
			clickedConn:Disconnect()
			changedConn:Disconnect()
		end
	end)

	return ChannelButton
end

function methods:AddTagLabelToBaseMessage(BaseMessage, tagColor, formatTagText)
	local tagNameSize = self:GetStringTextBounds(formatTagText, BaseMessage.Font, BaseMessage.TextSize)
	local TagLabel = self:GetFromObjectPool("TextLabel")
	TagLabel.Selectable = false
	TagLabel.Size = UDim2.new(0, tagNameSize.X, 0, tagNameSize.Y)
	TagLabel.Position = UDim2.new(0, 0, 0, 0)
	TagLabel.BackgroundTransparency = 1
	TagLabel.Font = BaseMessage.Font
	TagLabel.TextSize = BaseMessage.TextSize
	TagLabel.TextXAlignment = BaseMessage.TextXAlignment
	TagLabel.TextYAlignment = BaseMessage.TextYAlignment
	TagLabel.TextTransparency = BaseMessage.TextTransparency
	TagLabel.TextStrokeTransparency = BaseMessage.TextStrokeTransparency
	TagLabel.TextColor3 = tagColor
	TagLabel.Text = formatTagText
	TagLabel.Visible = true
	TagLabel.Parent = BaseMessage

	return TagLabel
end

function methods:AddIconLabelToBaseMessage(BaseMessage, iconAddress)
	local iconSize = DEFAULT_ICON_SIZE
	local IconLabel = self:GetFromObjectPool("ImageLabel")
	IconLabel.Selectable = false
	IconLabel.Position = UDim2.new(0, 0, 0, 0)
	IconLabel.Size = UDim2.new(0, iconSize.X, 0, iconSize.Y)
	IconLabel.BackgroundTransparency = 1
	IconLabel.Visible = true
	IconLabel.ImageTransparency = 0
	IconLabel.ScaleType = Enum.ScaleType.Fit
	IconLabel.ImageColor3 = Color3.new(1, 1, 1)
	IconLabel.Image = iconAddress
	IconLabel.Parent = BaseMessage
	return IconLabel
end

function GetWhisperChannelPrefix()
	if ChatConstants.WhisperChannelPrefix then
		return ChatConstants.WhisperChannelPrefix
	end
	return "To "
end

function methods:NameButtonClicked(nameButton, playerName)
	if not self.ChatWindow then
		return
	end

	if ChatSettings.ClickOnPlayerNameToWhisper then
		local player = Players:FindFirstChild(playerName)
		if player and player ~= LocalPlayer then
			local whisperChannel = GetWhisperChannelPrefix() .. playerName
			if self.ChatWindow:GetChannel(whisperChannel) then
				self.ChatBar:ResetCustomState()
				local targetChannelName = self.ChatWindow:GetTargetMessageChannel()
				if targetChannelName ~= whisperChannel then
					self.ChatWindow:SwitchCurrentChannel(whisperChannel)
				end

				local whisperMessage = "/w " .. playerName
				self.ChatBar:SetText(whisperMessage)

				self.ChatBar:CaptureFocus()
			elseif not self.ChatBar:IsInCustomState() then
				local whisperMessage = "/w " .. playerName
				self.ChatBar:SetText(whisperMessage)

				self.ChatBar:CaptureFocus()
			end
		end
	end
end

function methods:ChannelButtonClicked(channelButton, channelName)
	if not self.ChatWindow then
		return
	end

	if ChatSettings.ClickOnChannelNameToSetMainChannel then
		if self.ChatWindow:GetChannel(channelName) then
			self.ChatBar:ResetCustomState()
			local targetChannelName = self.ChatWindow:GetTargetMessageChannel()
			if targetChannelName ~= channelName then
				self.ChatWindow:SwitchCurrentChannel(channelName)
			end
			self.ChatBar:ResetText()
			self.ChatBar:CaptureFocus()
		end
	end
end

function methods:RegisterChatWindow(chatWindow)
	self.ChatWindow = chatWindow
	self.ChatBar = chatWindow:GetChatBar()
end

function methods:GetFromObjectPool(className)
	if self.ObjectPool == nil then
		return Instance.new(className)
	end
	return self.ObjectPool:GetInstance(className)
end

function methods:RegisterObjectPool(objectPool)
	self.ObjectPool = objectPool
end
