function methods.GetMessageModeTextLabel(w)return w:GetMessageModeTextButton()end function methods.IsFocused(w)if w.UserHasChatOff then return false end return(w:GetTextBox()):IsFocused()end function methods.GetVisible(w)return w.GuiObject.Visible end function methods.CaptureFocus(w)if not w.UserHasChatOff then(w:GetTextBox()):CaptureFocus()end end function methods.ReleaseFocus(j,w)(j:GetTextBox()):ReleaseFocus(w)end function methods.ResetText(w)(w:GetTextBox()).Text=""end function methods.SetText(j,w)(j:GetTextBox()).Text=w end function methods.GetEnabled(w)return w.GuiObject.Visible end function methods.SetEnabled(j,w)if j.UserHasChatOff then j.GuiObject.Visible=true else j.GuiObject.Visible=w end end function methods.SetTextLabelText(j,w)if not j.UserHasChatOff then j.TextLabel.Text=w end end function methods.SetTextBoxText(j,w)j.TextBox.Text=w end function methods.GetTextBoxText(w)return w.TextBox.Text end function methods.ResetSize(w)w.TargetYSize=0 w:TweenToTargetYSize()end local function w(w)return TextService:GetTextSize(w.Text,w.TextSize,w.Font,Vector2.new(w.AbsoluteSize.X,10000))end function methods.CalculateSize(j)if j.CalculatingSizeLock then return end j.CalculatingSizeLock=true local A=nil local H=nil if j:IsFocused()or j.TextBox.Text~=""then A=j.TextBox.TextSize H=(w(j.TextBox)).Y else A=j.TextLabel.TextSize H=(w(j.TextLabel)).Y end local G=H-A if j.TargetYSize~=G then j.TargetYSize=G j:TweenToTargetYSize()end j.CalculatingSizeLock=false end function methods.TweenToTargetYSize(w)local j=UDim2.new(1,0,1,w.TargetYSize)local A=w.GuiObject.Size local H=w.GuiObject.AbsoluteSize.Y w.GuiObject.Size=j local G=w.GuiObject.AbsoluteSize.Y w.GuiObject.Size=A local x=math.abs(G-H)local R=math.min(1,x*(1/w.TweenPixelsPerSecond))local c=pcall(function()w.GuiObject:TweenSize(j,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,R,true)end)if not c then w.GuiObject.Size=j end end function methods.SetTextSize(j,w)if not j:IsInCustomState()then if j.TextBox then j.TextBox.TextSize=w end if j.TextLabel then j.TextLabel.TextSize=w end end end function methods.GetDefaultChannelNameColor(w)if ChatSettings.DefaultChannelNameColor then return ChatSettings.DefaultChannelNameColor end return Color3.fromRGB(35,76,142)end function methods.SetChannelTarget(j,w)local A=j.GuiObjects.MessageModeTextButton local H=j.TextBox local G=j.TextLabel j.TargetChannel=w if not j:IsInCustomState()then if w~=ChatSettings.GeneralChannelName then A.Size=UDim2.new(0,1000,1,0)local x=w if ChatLocalization.tryLocalize then x=ChatLocalization:tryLocalize(w)end A.Text=string.format("\091\037\115\093 ",x)local R=j:GetChannelNameColor(w)if R then A.TextColor3=R else A.TextColor3=j:GetDefaultChannelNameColor()end local c=A.TextBounds.X A.Size=UDim2.new(0,c,1,0)H.Size=UDim2.new(1,-c,1,0)H.Position=UDim2.new(0,c,0,0)G.Size=UDim2.new(1,-c,1,0)G.Position=UDim2.new(0,c,0,0)else A.Text=""A.Size=UDim2.new(0,0,0,0)H.Size=UDim2.new(1,0,1,0)H.Position=UDim2.new(0,0,0,0)G.Size=UDim2.new(1,0,1,0)G.Position=UDim2.new(0,0,0,0)end end end function methods.IsInCustomState(w)return w.InCustomState end function methods.ResetCustomState(w)if w.InCustomState then w.CustomState:Destroy()w.CustomState=nil w.InCustomState=false w.ChatBarParentFrame:ClearAllChildren()w:CreateGuiObjects(w.ChatBarParentFrame)w:SetTextLabelText(ChatLocalization:Get("\071\097\109\101\067\104\097\116\095\067\104\097\116\077\097\105\110\095\067\104\097\116\066\097\114\084\101\120\116","\084\111 \099\104\097\116 \099\108\105\099\107 \104\101\114\101 \111\114 \112\114\101\115\115 \"\047\" \107\101\121"))end end function methods.EnterWhisperState(j,w)j:ResetCustomState()j:CaptureFocus()if WhisperModule.CustomStateCreator then j.CustomState=WhisperModule.CustomStateCreator(w,j.ChatWindow,j,ChatSettings)j.InCustomState=true else j:SetText("\047\119 "..w.Name)end end function methods.GetCustomMessage(w)if w.InCustomState then return w.CustomState:GetMessage()end return nil end function methods.CustomStateProcessCompletedMessage(j,w)if j.InCustomState then return j.CustomState:ProcessCompletedMessage()end return false end function methods.FadeOutBackground(j,w)j.AnimParams.Background_TargetTransparency=1 j.AnimParams.Background_NormalizedExptValue=CurveUtil:NormalizedDefaultExptValueInSeconds(w)j:FadeOutText(w)end function methods.FadeInBackground(j,w)j.AnimParams.Background_TargetTransparency=.6 j.AnimParams.Background_NormalizedExptValue=CurveUtil:NormalizedDefaultExptValueInSeconds(w)j:FadeInText(w)end function methods.FadeOutText(j,w)j.AnimParams.Text_TargetTransparency=1 j.AnimParams.Text_NormalizedExptValue=CurveUtil:NormalizedDefaultExptValueInSeconds(w)end function methods.FadeInText(j,w)j.AnimParams.Text_TargetTransparency=.4 j.AnimParams.Text_NormalizedExptValue=CurveUtil:NormalizedDefaultExptValueInSeconds(w)end function methods.AnimGuiObjects(w)w.GuiObject.BackgroundTransparency=w.AnimParams.Background_CurrentTransparency w.GuiObjects.TextBoxFrame.BackgroundTransparency=w.AnimParams.Background_CurrentTransparency w.GuiObjects.TextLabel.TextTransparency=w.AnimParams.Text_CurrentTransparency w.GuiObjects.TextBox.TextTransparency=w.AnimParams.Text_CurrentTransparency w.GuiObjects.MessageModeTextButton.TextTransparency=w.AnimParams.Text_CurrentTransparency end function methods.InitializeAnimParams(w)w.AnimParams.Text_TargetTransparency=.4 w.AnimParams.Text_CurrentTransparency=.4 w.AnimParams.Text_NormalizedExptValue=1 w.AnimParams.Background_TargetTransparency=.6 w.AnimParams.Background_CurrentTransparency=.6 w.AnimParams.Background_NormalizedExptValue=1 end function methods.Update(j,w)j.AnimParams.Text_CurrentTransparency=CurveUtil:Expt(j.AnimParams.Text_CurrentTransparency,j.AnimParams.Text_TargetTransparency,j.AnimParams.Text_NormalizedExptValue,w)j.AnimParams.Background_CurrentTransparency=CurveUtil:Expt(j.AnimParams.Background_CurrentTransparency,j.AnimParams.Background_TargetTransparency,j.AnimParams.Background_NormalizedExptValue,w)j:AnimGuiObjects()end function methods.SetChannelNameColor(A,w,j)A.ChannelNameColors[w]=j if A.GuiObjects.MessageModeTextButton.Text==w then A.GuiObjects.MessageModeTextButton.TextColor3=j end end function methods.GetChannelNameColor(j,w)return j.ChannelNameColors[w]end

function methods:GetMessageModeTextLabel()
	return self:GetMessageModeTextButton()
end

function methods:IsFocused()
	if self.UserHasChatOff then
		return false
	end

	return self:GetTextBox():IsFocused()
end

function methods:GetVisible()
	return self.GuiObject.Visible
end

function methods:CaptureFocus()
	if not self.UserHasChatOff then
		self:GetTextBox():CaptureFocus()
	end
end

function methods:ReleaseFocus(didRelease)
	self:GetTextBox():ReleaseFocus(didRelease)
end

function methods:ResetText()
	self:GetTextBox().Text = ""
end

function methods:SetText(text)
	self:GetTextBox().Text = text
end

function methods:GetEnabled()
	return self.GuiObject.Visible
end

function methods:SetEnabled(enabled)
	if self.UserHasChatOff then
		-- The chat bar can not be removed if a user has chat turned off so that
		-- the chat bar can display a message explaining that chat is turned off.
		self.GuiObject.Visible = true
	else
		self.GuiObject.Visible = enabled
	end
end

function methods:SetTextLabelText(text)
	if not self.UserHasChatOff then
		self.TextLabel.Text = text
	end
end

function methods:SetTextBoxText(text)
	self.TextBox.Text = text
end

function methods:GetTextBoxText()
	return self.TextBox.Text
end

function methods:ResetSize()
	self.TargetYSize = 0
	self:TweenToTargetYSize()
end

local function measureSize(textObj)
	return TextService:GetTextSize(
		textObj.Text,
		textObj.TextSize,
		textObj.Font,
		Vector2.new(textObj.AbsoluteSize.X, 10000)
	)
end

function methods:CalculateSize()
	if self.CalculatingSizeLock then
		return
	end
	self.CalculatingSizeLock = true

	local textSize = nil
	local bounds = nil

	if self:IsFocused() or self.TextBox.Text ~= "" then
		textSize = self.TextBox.TextSize
		bounds = measureSize(self.TextBox).Y
	else
		textSize = self.TextLabel.TextSize
		bounds = measureSize(self.TextLabel).Y
	end

	local newTargetYSize = bounds - textSize
	if (self.TargetYSize ~= newTargetYSize) then
		self.TargetYSize = newTargetYSize
		self:TweenToTargetYSize()
	end

	self.CalculatingSizeLock = false
end

function methods:TweenToTargetYSize()
	local endSize = UDim2.new(1, 0, 1, self.TargetYSize)
	local curSize = self.GuiObject.Size

	local curAbsoluteSizeY = self.GuiObject.AbsoluteSize.Y
	self.GuiObject.Size = endSize
	local endAbsoluteSizeY = self.GuiObject.AbsoluteSize.Y
	self.GuiObject.Size = curSize

	local pixelDistance = math.abs(endAbsoluteSizeY - curAbsoluteSizeY)
	local tweeningTime = math.min(1, (pixelDistance * (1 / self.TweenPixelsPerSecond))) -- pixelDistance * (seconds per pixels)

	local success = pcall(function() self.GuiObject:TweenSize(endSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweeningTime, true) end)
	if (not success) then
		self.GuiObject.Size = endSize
	end
end

function methods:SetTextSize(textSize)
	if not self:IsInCustomState() then
		if self.TextBox then
			self.TextBox.TextSize = textSize
		end
		if self.TextLabel then
			self.TextLabel.TextSize = textSize
		end
	end
end

function methods:GetDefaultChannelNameColor()
	if ChatSettings.DefaultChannelNameColor then
		return ChatSettings.DefaultChannelNameColor
	end
	return Color3.fromRGB(35, 76, 142)
end

function methods:SetChannelTarget(targetChannel)
	local messageModeTextButton = self.GuiObjects.MessageModeTextButton
	local textBox = self.TextBox
	local textLabel = self.TextLabel

	self.TargetChannel = targetChannel

	if not self:IsInCustomState() then
		if targetChannel ~= ChatSettings.GeneralChannelName then
			messageModeTextButton.Size = UDim2.new(0, 1000, 1, 0)
			local localizedTargetChannel = targetChannel
			if ChatLocalization.tryLocalize then
				localizedTargetChannel = ChatLocalization:tryLocalize(targetChannel)
			end
			messageModeTextButton.Text = string.format("[%s] ", localizedTargetChannel)

			local channelNameColor = self:GetChannelNameColor(targetChannel)
			if channelNameColor then
				messageModeTextButton.TextColor3 = channelNameColor
			else
				messageModeTextButton.TextColor3 = self:GetDefaultChannelNameColor()
			end

			local xSize = messageModeTextButton.TextBounds.X
			messageModeTextButton.Size = UDim2.new(0, xSize, 1, 0)
			textBox.Size = UDim2.new(1, -xSize, 1, 0)
			textBox.Position = UDim2.new(0, xSize, 0, 0)
			textLabel.Size = UDim2.new(1, -xSize, 1, 0)
			textLabel.Position = UDim2.new(0, xSize, 0, 0)
		else
			messageModeTextButton.Text = ""
			messageModeTextButton.Size = UDim2.new(0, 0, 0, 0)
			textBox.Size = UDim2.new(1, 0, 1, 0)
			textBox.Position = UDim2.new(0, 0, 0, 0)
			textLabel.Size = UDim2.new(1, 0, 1, 0)
			textLabel.Position = UDim2.new(0, 0, 0, 0)
		end
	end
end

function methods:IsInCustomState()
	return self.InCustomState
end

function methods:ResetCustomState()
	if self.InCustomState then
		self.CustomState:Destroy()
		self.CustomState = nil
		self.InCustomState = false

		self.ChatBarParentFrame:ClearAllChildren()
		self:CreateGuiObjects(self.ChatBarParentFrame)
		self:SetTextLabelText(
			ChatLocalization:Get(
				"GameChat_ChatMain_ChatBarText",
				'To chat click here or press "/" key'
			)
		)
	end
end

function methods:EnterWhisperState(player)
	self:ResetCustomState()
	self:CaptureFocus()
	if WhisperModule.CustomStateCreator then
		self.CustomState = WhisperModule.CustomStateCreator(
			player,
			self.ChatWindow,
			self,
			ChatSettings
		)
		self.InCustomState = true
	else
		self:SetText("/w " .. player.Name)
	end
end

function methods:GetCustomMessage()
	if self.InCustomState then
		return self.CustomState:GetMessage()
	end
	return nil
end

function methods:CustomStateProcessCompletedMessage(message)
	if self.InCustomState then
		return self.CustomState:ProcessCompletedMessage()
	end
	return false
end

function methods:FadeOutBackground(duration)
	self.AnimParams.Background_TargetTransparency = 1
	self.AnimParams.Background_NormalizedExptValue = CurveUtil:NormalizedDefaultExptValueInSeconds(duration)
	self:FadeOutText(duration)
end

function methods:FadeInBackground(duration)
	self.AnimParams.Background_TargetTransparency = 0.6
	self.AnimParams.Background_NormalizedExptValue = CurveUtil:NormalizedDefaultExptValueInSeconds(duration)
	self:FadeInText(duration)
end

function methods:FadeOutText(duration)
	self.AnimParams.Text_TargetTransparency = 1
	self.AnimParams.Text_NormalizedExptValue = CurveUtil:NormalizedDefaultExptValueInSeconds(duration)
end

function methods:FadeInText(duration)
	self.AnimParams.Text_TargetTransparency = 0.4
	self.AnimParams.Text_NormalizedExptValue = CurveUtil:NormalizedDefaultExptValueInSeconds(duration)
end

function methods:AnimGuiObjects()
	self.GuiObject.BackgroundTransparency = self.AnimParams.Background_CurrentTransparency
	self.GuiObjects.TextBoxFrame.BackgroundTransparency = self.AnimParams.Background_CurrentTransparency

	self.GuiObjects.TextLabel.TextTransparency = self.AnimParams.Text_CurrentTransparency
	self.GuiObjects.TextBox.TextTransparency = self.AnimParams.Text_CurrentTransparency
	self.GuiObjects.MessageModeTextButton.TextTransparency = self.AnimParams.Text_CurrentTransparency
end

function methods:InitializeAnimParams()
	self.AnimParams.Text_TargetTransparency = 0.4
	self.AnimParams.Text_CurrentTransparency = 0.4
	self.AnimParams.Text_NormalizedExptValue = 1

	self.AnimParams.Background_TargetTransparency = 0.6
	self.AnimParams.Background_CurrentTransparency = 0.6
	self.AnimParams.Background_NormalizedExptValue = 1
end

function methods:Update(dtScale)
	self.AnimParams.Text_CurrentTransparency = CurveUtil:Expt(
			self.AnimParams.Text_CurrentTransparency,
			self.AnimParams.Text_TargetTransparency,
			self.AnimParams.Text_NormalizedExptValue,
			dtScale
	)
	self.AnimParams.Background_CurrentTransparency = CurveUtil:Expt(
			self.AnimParams.Background_CurrentTransparency,
			self.AnimParams.Background_TargetTransparency,
			self.AnimParams.Background_NormalizedExptValue,
			dtScale
	)

	self:AnimGuiObjects()
end

function methods:SetChannelNameColor(channelName, channelNameColor)
	self.ChannelNameColors[channelName] = channelNameColor
	if self.GuiObjects.MessageModeTextButton.Text == channelName then
		self.GuiObjects.MessageModeTextButton.TextColor3 = channelNameColor
	end
end

function methods:GetChannelNameColor(channelName)
	return self.ChannelNameColors[channelName]
end
