function methods.GetMessageHeight(T,x,N,J)J=J or N.AbsoluteSize.X local X=T:GetStringTextBounds(x.Text,x.Font,x.TextSize,Vector2.new(J,1000))return X.Y end function methods.GetNumberOfSpaces(T,x,N,J)local X=T:GetStringTextBounds(x,N,J)local h=T:GetStringTextBounds(" ",N,J)return math.ceil(X.X/h.X)end function methods.CreateBaseMessage(X,x,N,J,T)local h=X:GetFromObjectPool("\070\114\097\109\101")h.Selectable=false h.Size=UDim2.new(1,0,0,18)h.Visible=true h.BackgroundTransparency=1 local g=8 local j=X:GetFromObjectPool("\084\101\120\116\076\097\098\101\108")j.Selectable=false j.Size=UDim2.new(1,-(g+6),1,0)j.Position=UDim2.new(0,g,0,0)j.BackgroundTransparency=1 j.Font=N j.TextSize=J j.TextXAlignment=Enum.TextXAlignment.Left j.TextYAlignment=Enum.TextYAlignment.Top j.TextTransparency=0 j.TextStrokeTransparency=.75 j.TextColor3=T j.TextWrapped=true j.Text=x j.Visible=true j.Parent=h return h,j end function methods.AddNameButtonToBaseMessage(X,x,N,J,T)local h=X:GetStringTextBounds(J,x.Font,x.TextSize)local g=X:GetFromObjectPool("\084\101\120\116\066\117\116\116\111\110")g.Selectable=false g.Size=UDim2.new(0,h.X,0,h.Y)g.Position=UDim2.new(0,0,0,0)g.BackgroundTransparency=1 g.Font=x.Font g.TextSize=x.TextSize g.TextXAlignment=x.TextXAlignment g.TextYAlignment=x.TextYAlignment g.TextTransparency=x.TextTransparency g.TextStrokeTransparency=x.TextStrokeTransparency g.TextColor3=N g.Text=J g.Visible=true g.Parent=x local j=g.MouseButton1Click:connect(function()X:NameButtonClicked(g,T)end)local z=nil z=g.Changed:connect(function(x)if x=="\080\097\114\101\110\116"then j:Disconnect()z:Disconnect()end end)return g end function methods.AddPrefixLabelToBaseMessage(T,x,N,J)local X=T:GetStringTextBounds(J,x.Font,x.TextSize)local h=T:GetFromObjectPool("\084\101\120\116\076\097\098\101\108")h.Selectable=false h.Size=UDim2.new(0,X.X,0,X.Y)h.Position=UDim2.new(0,0,0,0)h.BackgroundTransparency=1 h.Font=x.Font h.TextSize=x.TextSize h.TextXAlignment=x.TextXAlignment h.TextYAlignment=x.TextYAlignment h.TextTransparency=x.TextTransparency h.TextStrokeTransparency=x.TextStrokeTransparency h.TextColor3=N h.Text=J h.Visible=true h.Parent=x return h end function methods.AddChannelButtonToBaseMessage(X,x,N,J,T)local h=X:GetStringTextBounds(J,x.Font,x.TextSize)local g=X:GetFromObjectPool("\084\101\120\116\066\117\116\116\111\110")g.Selectable=false g.Size=UDim2.new(0,h.X,0,h.Y)g.Position=UDim2.new(0,0,0,0)g.BackgroundTransparency=1 g.Font=x.Font g.TextSize=x.TextSize g.TextXAlignment=x.TextXAlignment g.TextYAlignment=x.TextYAlignment g.TextTransparency=x.TextTransparency g.TextStrokeTransparency=x.TextStrokeTransparency g.TextColor3=N g.Text=J g.Visible=true g.Parent=x local j=g.MouseButton1Click:connect(function()X:ChannelButtonClicked(g,T)end)local z=nil z=g.Changed:connect(function(x)if x=="\080\097\114\101\110\116"then j:Disconnect()z:Disconnect()end end)return g end function GetWhisperChannelPrefix()if ChatConstants.WhisperChannelPrefix then return ChatConstants.WhisperChannelPrefix end return"\084\111 "end function methods.NameButtonClicked(J,x,N)if not J.ChatWindow then return end if ChatSettings.ClickOnPlayerNameToWhisper then local x=Players:FindFirstChild(N)if x and x~=LocalPlayer then local x=GetWhisperChannelPrefix()..N if J.ChatWindow:GetChannel(x)then J.ChatBar:ResetCustomState()local N=J.ChatWindow:GetTargetMessageChannel()if N~=x then J.ChatWindow:SwitchCurrentChannel(x)end J.ChatBar:ResetText()J.ChatBar:CaptureFocus()elseif not J.ChatBar:IsInCustomState()then local x="\047\119 "..N J.ChatBar:CaptureFocus()J.ChatBar:SetText(x)end end end end function methods.ChannelButtonClicked(J,x,N)if not J.ChatWindow then return end if ChatSettings.ClickOnChannelNameToSetMainChannel then if J.ChatWindow:GetChannel(N)then J.ChatBar:ResetCustomState()local x=J.ChatWindow:GetTargetMessageChannel()if x~=N then J.ChatWindow:SwitchCurrentChannel(N)end J.ChatBar:ResetText()J.ChatBar:CaptureFocus()end end end function methods.RegisterChatWindow(N,x)N.ChatWindow=x N.ChatBar=x:GetChatBar()end function methods.GetFromObjectPool(N,x)if N.ObjectPool==nil then return Instance.new(x)end return N.ObjectPool:GetInstance(x)end function methods.RegisterObjectPool(N,x)N.ObjectPool=x end


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))
	return textBoundsSize.Y
end

function methods:GetNumberOfSpaces(str, font, textSize)
	local strSize = self:GetStringTextBounds(str, font, textSize)
	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.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:AddPrefixLabelToBaseMessage(BaseMessage, prefixColor, formatPrefix)
	local speakerNameSize = self:GetStringTextBounds(formatPrefix, BaseMessage.Font, BaseMessage.TextSize)
	local PrefixLabel = self:GetFromObjectPool("TextLabel")
	PrefixLabel.Selectable = false
	PrefixLabel.Size = UDim2.new(0, speakerNameSize.X, 0, speakerNameSize.Y)
	PrefixLabel.Position = UDim2.new(0, 0, 0, 0)
	PrefixLabel.BackgroundTransparency = 1
	PrefixLabel.Font = BaseMessage.Font
	PrefixLabel.TextSize = BaseMessage.TextSize
	PrefixLabel.TextXAlignment = BaseMessage.TextXAlignment
	PrefixLabel.TextYAlignment = BaseMessage.TextYAlignment
	PrefixLabel.TextTransparency = BaseMessage.TextTransparency
	PrefixLabel.TextStrokeTransparency = BaseMessage.TextStrokeTransparency
	PrefixLabel.TextColor3 = prefixColor
	PrefixLabel.Text = formatPrefix
	PrefixLabel.Visible = true
	PrefixLabel.Parent = BaseMessage

	return PrefixLabel
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 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
				self.ChatBar:ResetText()
				self.ChatBar:CaptureFocus()
			elseif not self.ChatBar:IsInCustomState() then
				local whisperMessage = "/w " ..playerName
				self.ChatBar:CaptureFocus()
				self.ChatBar:SetText(whisperMessage)
			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
