
Chat = {}

-- Create some client convars that we'll need.
CreateClientConVar("chat_radio", "1", true, true)
CreateClientConVar("chat_ooc", "1", true, true)
CreateClientConVar("chat_ic", "1", true, true)
CreateClientConVar("chat_advert", "1", true, true)
CreateClientConVar("chat_joinleave", "1", true, true)

-- Create Font.
surface.CreateFont("Tahoma", 14, 600, true, false, "Chat_MainText")

-- Emoticons.
Chat.Messages = {}
Chat.Derma = {}

-- History.
Chat.History = {}
Chat.History.Messages = {}
Chat.History.Position = 0

-- Hook.
usermessage.Hook("Chat_Player_Message", function(Message)
	local Player = Message:ReadEntity()
	local Filter = Message:ReadString()
	local Text = Message:ReadString()
	
	-- Check Is Player.
	if ( !Player:IsPlayer() ) then
		print("ERROR: Trying to do a player message with chat filter "..Filter.." ("..Text..") and the entity isn't a player!")
	end
	
	-- Chat Text.
	Chat.ChatText(Player:EntIndex(), Player:Name(), Text, Filter)
end)

-- Hook.
usermessage.Hook("Chat_Message", function(Message)
	local Filter = Message:ReadString()
	local Text = Message:ReadString()
	
	-- Chat Text.
	Chat.ChatText(nil, nil, Text, Filter)
end)


-- Get Position.
function Chat.GetPosition()
	local X, Y = 9, ScrH() - (ScrH() / 4)
	
	-- Check Position.
	if (Chat.Position) then Y = Chat.Position end
	
	-- Return X.
	return X, Y
end

-- Get X.
function Chat.GetX()
	local X, Y = Chat.GetPosition()
	
	-- Return X.
	return X
end

-- Get Y.
function Chat.GetY()
	local X, Y = Chat.GetPosition()
	
	-- Return Y.
	return Y
end

-- Get Spacing.
function Chat.GetSpacing(Message)
	if (Message) then
		return 20
	else
		return 20
	end
end

-- Create Derma All.
function Chat.CreateDermaAll()
	Chat.CreateDermaPanel()
	Chat.CreateDermaCheckBoxes()
	Chat.CreateDermaButtons()
	Chat.CreateDermaFilters()
	Chat.CreateDermaTextEntry()

	-- Hide.
	Chat.Derma.Panel.Hide()
end

-- Create Derma Buttons.
function Chat.CreateDermaButtons()
	if (!Chat.Derma.Buttons) then
		Chat.Derma.Buttons = {}
		
		-- Create Derma Button.
		Chat.CreateDermaButton("Up", "+", 434, 16, "Scroll up the message area.", function()
			Chat.History.Position = Chat.History.Position - 1
		end, function(self)
			if (Chat.History.Messages[Chat.History.Position - 5]) then
				self:SetDisabled(false)
			else
				self:SetDisabled(true)
			end
		end)
		Chat.CreateDermaButton("Down", "-", 454, 16, "Scroll down the message area.", function()
			Chat.History.Position = Chat.History.Position + 1
		end, function(self)
			if (Chat.History.Messages[Chat.History.Position + 1]) then
				self:SetDisabled(false)
			else
				self:SetDisabled(true)
			end
		end)
		Chat.CreateDermaButton("Bottom", "*", 474, 16, "Goto the bottom of the message area.", function()
			Chat.History.Position = #Chat.History.Messages
		end, function(self)
			if (Chat.History.Position < #Chat.History.Messages) then
				self:SetDisabled(false)
			else
				self:SetDisabled(true)
			end
		end)
		Chat.CreateDermaButton("Filters", "Filters", 494, 80, "Enable or disable message filters.", function()
			local IsVisible = Chat.Derma.Filters:IsVisible()
			
			-- Check Is Visible.
			if (IsVisible) then
				Chat.Derma.Filters:SetVisible(false)
			else
				Chat.Derma.Filters:SetVisible(true)
			end
		end, function(self) end)
	end
end
	
-- Create Derma Button.
function Chat.CreateDermaButton(Name, Text, X, Width, ToolTip, DoClick, Think)
	if (!Chat.Derma.Buttons[Name]) then
		Chat.Derma.Buttons[Name] = vgui.Create("DButton", Chat.Derma.Panel)
		Chat.Derma.Buttons[Name]:SetText(Text)
		Chat.Derma.Buttons[Name]:SetSize(Width, 16)
		Chat.Derma.Buttons[Name]:SetPos(X, 4)
		Chat.Derma.Buttons[Name]:SetToolTip(ToolTip)
		Chat.Derma.Buttons[Name].DoClick = DoClick
		Chat.Derma.Buttons[Name].Think = Think
	end
end

-- Create Derma Check Boxes.
function Chat.CreateDermaCheckBoxes()
	if (!Chat.Derma.CheckBoxes) then Chat.Derma.CheckBoxes = {} end
end

-- Create Derma Check Box.
function Chat.CreateDermaCheckBox(Name, ConVar, X, ToolTip, Label, Parent, Y)
	if (!Chat.Derma.CheckBoxes[Name]) then
		Parent = Parent or Chat.Derma.Panel
		Y = Y or 4
		
		-- Check Label.
		if (Label) then
			Chat.Derma.CheckBoxes[Name] = vgui.Create("DCheckBoxLabel", Parent)
			Chat.Derma.CheckBoxes[Name]:SetText(Label)
		else
			Chat.Derma.CheckBoxes[Name] = vgui.Create("DCheckBox", Parent)
		end
		
		-- Set Pos.
		Chat.Derma.CheckBoxes[Name]:SetPos(X, Y)
		Chat.Derma.CheckBoxes[Name]:SetToolTip(ToolTip)
		Chat.Derma.CheckBoxes[Name]:SetConVar(ConVar)
		
		-- Check Label.
		if (Label) then
			Chat.Derma.CheckBoxes[Name]:SizeToContents()
		else
			Chat.Derma.CheckBoxes[Name]:SetSize(16, 16)
		end
	end
end

-- Create Derma Text Entry.
function Chat.CreateDermaTextEntry()
	if (!Chat.Derma.TextEntry) then
		Chat.Derma.TextEntry = vgui.Create("DTextEntry", Chat.Derma.Panel)
		Chat.Derma.TextEntry:SetPos(34, 4)
		Chat.Derma.TextEntry:SetSize(396, 16)
		Chat.Derma.TextEntry.OnEnter = function()
			local Message = Chat.Derma.TextEntry:GetValue()
			LocalPlayer( ):ConCommand( "rp_closedchat" );
			-- Check Message.
			if (Message and Message != "") then
				Chat.History.Position = #Chat.History.Messages
				
				-- Message.
				Message = string.Replace(Message, '"', '\"')
				
				-- Check Say Team.
				if (Chat.SayTeam) then
					LocalPlayer():ConCommand("say_team \""..Message.."\"\n")
				else
					LocalPlayer():ConCommand("say \""..Message.."\"\n")
				end
				
				-- Set Text.
				Chat.Derma.TextEntry:SetText("")
			end
			
			-- Hide.
			Chat.Derma.Panel.Hide()
		end
		
		-- Think.
		function Chat.Derma.TextEntry:Think()
			local Message = self:GetValue()
			
			-- Check Len.
			if (string.len(Message) > 126) then
				self:SetValue(string.sub(Message, 1, 126))
				self:SetCaretPos(126)
				
				-- Play Sound.
				surface.PlaySound("common/talk.wav")
			end
		end
	end
end

-- Create Derma Filters.
function Chat.CreateDermaFilters()
	if (!Chat.Derma.Filters) then
		Chat.Derma.Filters = vgui.Create("EditablePanel")
		Chat.Derma.Filters:SetSize(116, 112)
		
		-- Paint.
		function Chat.Derma.Filters:Paint()
			local BackgroundColor = Color(0, 0, 0, 150)
			local CornerSize = 4
			local TitleColor = Color(50, 255, 50, 255)
			local TextColor = Color(255, 255, 255, 255)
			
			-- Rounded Box.
			draw.RoundedBox(CornerSize, 0, 0, self:GetWide(), self:GetTall(), BackgroundColor)
		end
		
		-- Think.
		function Chat.Derma.Filters:Think()
			local X = Chat.Derma.Panel.x + Chat.Derma.Panel:GetWide() + 4
			local Y = Chat.Derma.Panel.y + Chat.Derma.Panel:GetTall() - self:GetTall()
			
			-- Set Pos.
			self:SetPos(X, Y)
		end
		
		-- Create Derma Check Box.
		Chat.CreateDermaCheckBox("Radio", "chat_radio", 8, "Filter radio messages.", "Filter Radio", Chat.Derma.Filters, 8)
		Chat.CreateDermaCheckBox("OOC", "chat_ooc", 8, "Filter out-of-character messages.", "Filter OOC", Chat.Derma.Filters, 28)
		Chat.CreateDermaCheckBox("IC", "chat_ic", 8, "Filter in-character messages.", "Filter IC", Chat.Derma.Filters, 48)
		Chat.CreateDermaCheckBox("advert", "chat_advert", 8, "Filter advert messages.", "Filter Adverts", Chat.Derma.Filters, 68)
		Chat.CreateDermaCheckBox("Join/Leave", "chat_joinleave", 8, "Filter join/leave messages.", "Filter Join/Leave", Chat.Derma.Filters, 88)
	end
end

-- Create Derma Panel.
function Chat.CreateDermaPanel()
	if (!Chat.Derma.Panel) then
		Chat.Derma.Panel = vgui.Create("EditablePanel")
		Chat.Derma.Panel:SetSize(576, 24)
		Chat.Derma.Panel.Show = function()
			Chat.Derma.Panel:SetKeyboardInputEnabled(true)
			Chat.Derma.Panel:SetMouseInputEnabled(true)
			
			-- Set Visible.
			Chat.Derma.Scroll:SetVisible(true)
			Chat.Derma.Panel:SetVisible(true)
			Chat.Derma.Panel:MakePopup()
			
			-- Position.
			Chat.History.Position = #Chat.History.Messages
			
			-- Request Focus.
			Chat.Derma.TextEntry:RequestFocus()
		end
		Chat.Derma.Panel.Hide = function()
			Chat.Derma.Panel:SetKeyboardInputEnabled(false)
			Chat.Derma.Panel:SetMouseInputEnabled(false)
			
			-- Set Text.
			Chat.Derma.TextEntry:SetText("")
			
			-- Set Visible.
			Chat.Derma.Panel:SetVisible(false)
			Chat.Derma.Scroll:SetVisible(false)
			Chat.Derma.Filters:SetVisible(false)
		end
		
		-- Paint.
		function Chat.Derma.Panel:Paint()
			local BackgroundColor = Color(0, 0, 0, 150)
			local CornerSize = 4
			local TitleColor = Color(50, 255, 50, 255)
			local TextColor = Color(255, 255, 255, 255)
			
			-- Rounded Box.
			draw.RoundedBox(CornerSize, 0, 0, self:GetWide(), self:GetTall(), BackgroundColor)
			
			-- Set Font.
			surface.SetFont("Chat_MainText")
			
			-- Width.
			local Width = surface.GetTextSize("Say")
			
			-- Check Say Team.
			if (Chat.SayTeam) then
				Width = surface.GetTextSize("Say Team")
				
				-- Simple Text.
				draw.SimpleText("Say Team", "Chat_MainText", 5, 13, Color(0, 0, 0, 255), 0, 1)
				draw.SimpleText("Say Team", "Chat_MainText", 4, 12, TitleColor, 0, 1)
				
				-- Text Entry.
				Chat.Derma.TextEntry:SetPos(74, 4)
				Chat.Derma.TextEntry:SetSize(356, 16)
			else
				draw.SimpleText("Say", "Chat_MainText", 5, 13, Color(0, 0, 0, 255), 0, 1)
				draw.SimpleText("Say", "Chat_MainText", 4, 12, TitleColor, 0, 1)
				
				-- Text Entry.
				Chat.Derma.TextEntry:SetPos(34, 4)
				Chat.Derma.TextEntry:SetSize(396, 16)
			end
			
			-- Simple Text.
			draw.SimpleText(":", "Chat_MainText", 5 + Width, 13, Color(0, 0, 0, 255), 0, 1)
			draw.SimpleText(":", "Chat_MainText", 4 + Width, 12, TextColor, 0, 1)
		end
		
		-- Think.
		function Chat.Derma.Panel:Think()
			local X, Y = Chat.GetPosition()
			
			-- Set Pos.
			Chat.Derma.Panel:SetPos(X, Y + 6)
			
			-- Check Is Visible.
			if (self:IsVisible() and input.IsKeyDown(KEY_ESCAPE)) then Chat.Derma.Panel.Hide() end
		end
		
		-- Scroll.
		Chat.Derma.Scroll = vgui.Create("Panel")
		Chat.Derma.Scroll:SetPos(0, 0)
		Chat.Derma.Scroll:SetSize(0, 0)
		
		-- On Mouse Wheeled.
		function Chat.Derma.Scroll:OnMouseWheeled(Delta)
			local IsVisible = Chat.Derma.Panel:IsVisible()
			
			-- Check Is Visible.
			if (IsVisible) then
				if (Delta > 0) then
					if (Chat.History.Messages[Chat.History.Position - 1]) then
						Chat.History.Position = Chat.History.Position - 1
					end
				else
					if (Chat.History.Messages[Chat.History.Position + 1]) then
						Chat.History.Position = Chat.History.Position + 1
					end
				end
			end
		end
	end
end

-- Player Bind Press.
function Chat.PlayerBindPress(Player, Bind, Press)
	if (Bind == "toggleconsole") then
		Chat.Derma.Panel.Hide()
	elseif (Bind == "messagemode" and Press) then
		LocalPlayer( ):ConCommand( "rp_openedchat" );
		Chat.Derma.Panel.Show()
		Chat.SayTeam = false
		
		-- Return True.
		return true
	elseif (Bind == "messagemode2" and Press) then
		LocalPlayer( ):ConCommand( "rp_openedchat" );
		Chat.Derma.Panel.Show()
		Chat.SayTeam = false -- (normally true).
		
		-- Return True.
		return true
	end
end

-- Add.
hook.Add("PlayerBindPress", "Chat.PlayerBindPress", Chat.PlayerBindPress)

-- Message Add.
function Chat.MessageAdd(Title, Name, Text, Filtered)
	local Message = {}
	
	-- Check Title.
	if (Title) then
		Message.Title = {}
		Message.Title.Text = Title[1]
		Message.Title.Color = Title[2] or Color(255, 255, 255, 255)
	end
	
	-- Check Name.
	if (Name) then
		Message.Name = {}
		Message.Name.Text = Name[1]
		Message.Name.Color = Name[2] or Color(255, 255, 255, 255)
	end
	
	-- Time Start.
	Message.TimeStart = CurTime()
	Message.TimeFade = Message.TimeStart + 10
	Message.TimeFinish = Message.TimeFade + 1
	Message.Spacing = 0
	Message.Blocks = {}
	Message.Color = Text[2] or Color(255, 255, 255, 255)
	Message.Alpha = 255
	Message.Lines = 1
	Message.Text = string.Explode(" ", Text[1])
	
	-- Extract Types.
	Chat.ExtractTypes(Message)
	Chat.PrintConsole(Message)
	
	-- Check Filtered.
	if (Filtered) then return end
	
	-- Check Position.
	if (Chat.History.Position == #Chat.History.Messages) then
		Chat.History.Position = #Chat.History.Messages + 1
	end
	
	-- Check Messages.
	if (#Chat.Messages == 20) then table.remove(Chat.Messages, 20) end
	
	-- Copy.
	local Copy = table.Copy(Message)
	
	-- Insert.
	table.insert(Chat.Messages, 1, Message)
	table.insert(Chat.History.Messages, Copy)
	
	-- Play Sound.
	surface.PlaySound("common/talk.wav")
end

-- Print Console.
function Chat.PrintConsole(Message)
	local String = ""
	
	-- Check Title.
	if (Message.Title) then String = String..Message.Title.Text.." " end
	if (Message.Name) then String = String..Message.Name.Text..": " end
	
	-- For Loop.
	for K, V in pairs(Message.Blocks) do
		local Space = " "
		
		-- Check K.
		if (K == #Message.Blocks) then Space = "" end
		
		-- Check Break.
		if (V.Break) then Space = "" end
		
		-- Check Type.
		if (V.Type == "Text") then String = String..V.Text..Space end
		
		-- Check Break.
		if (V.Break) then
			print(String)
			
			-- String.
			String = ""
		end
	end
	
	-- Check String.
	if (String != "") then print(String) end
end

-- Extract Types.
function Chat.ExtractTypes(Message)
	local Length = 0
	
	-- Check Title.
	if (Message.Title) then Length = Length + string.len(Message.Title.Text) end
	if (Message.Name) then Length = Length + string.len(Message.Name.Text..":") end
	
	-- Set Font.
	surface.SetFont("Chat_MainText")
	
	-- For Loop.
	for K, V in pairs(Message.Text) do
		local Extracted = false
		
		-- Characters.
		local Characters = string.len(V) + 1
		
		-- Check Length.
		if (Length + Characters >= 75) then
			local Break = math.Clamp(Characters - ((Length + Characters) - 75), 0, Characters)
			
			-- Dash.
			local Dash = "-"
			local One = string.sub(V, 1, Break)
			local Two = string.sub(V, Break + 1)
			
			-- Check Find.
			if (string.find(string.sub(One, -1), "%p")) then Dash = "" end
			if (string.find(string.sub(Two, 1, 1), "%p")) then
				Dash, One, Two = "", One..string.sub(Two, 1, 1), string.sub(Two, 2)
			end
			
			-- Check One.
			if (One == "" or Two == "") then Dash = "" end
			
			-- Check Insert.
			table.insert(Message.Blocks, {Type = "Text", Text = One..Dash, Break = true})
			
			-- Check Two.
			if (Two != "") then table.insert(Message.Blocks, {Type = "Text", Text = Two}) end
			
			-- Lines.
			Message.Lines = Message.Lines + 1
			
			-- Length.
			Length = string.len(Two)
			Extracted = true
		end
		
		-- Check Extracted.
		if (!Extracted) then
			Length = Length + Characters
			
			-- Insert.
			table.insert(Message.Blocks, {Type = "Text", Text = V})
		end
	end
	
	-- For Loop.
	for K, V in pairs(Message.Blocks) do
		if (V.Break) then
			if (!Message.Blocks[K + 1]) then
				Message.Blocks[K].Break = false
				
				-- Lines.
				Message.Lines = Message.Lines - 1
			end
		end
	end
end

-- Think.
function Chat.Think()
	local Time = CurTime()
	
	-- For Loop.
	for K, V in pairs(Chat.Messages) do
		if (Time >= V.TimeFade) then
			local FadeTime = V.TimeFinish - V.TimeFade
			local TimeLeft = V.TimeFinish - Time
			local Alpha = math.Clamp((255 / FadeTime) * TimeLeft, 0, 255)
			
			-- Check Alpha.
			if (Alpha == 0) then
				table.remove(Chat.Messages, K)
			else
				V.Alpha = Alpha
			end
		end
	end
end

-- Add.
hook.Add("Think", "Chat.Think", Chat.Think)

-- HUD Paint.
function Chat.HUDPaint()
	local X, Y = Chat.GetPosition()
	
	-- Set Font.
	surface.SetFont("Chat_MainText")
	
	-- Space.
	local Space = surface.GetTextSize(" ")
	local Box = {Width = 0, Height = 0}
	
	-- Table.
	local Table = Chat.Messages
	local IsVisible = Chat.Derma.Panel:IsVisible()
	
	-- Check Is Visible.
	if (IsVisible) then
		Table = {}
		
		-- For Loop.
		for I = 0, 15 do
			table.insert(Table, Chat.History.Messages[Chat.History.Position - I])
		end
	else
		if (#Chat.History.Messages > 100) then
			local Amount = #Chat.History.Messages - 100
			
			-- For Loop.
			for I = 1, Amount do table.remove(Chat.History.Messages, 1) end
		end
	end
	
	-- For Loop.
	for K, V in pairs(Table) do
		if (Table[K - 1]) then Y = Y - Table[K - 1].Spacing end
		
		-- Is Visible.
		local IsVisible = Chat.Derma.Panel:IsVisible()
		
		-- Check Is Visible.
		if (!IsVisible and K == 1) then
			Y = Y - ((Chat.GetSpacing() + V.Spacing) * (V.Lines - 1)) + 14
		else
			if (K == 1) then Y = Y + 2 end
			
			-- Y.
			Y = Y - ((Chat.GetSpacing() + V.Spacing) * V.Lines)
		end
		
		-- Message X.
		local MessageX = X
		local MessageY = Y
		
		-- Check Title.
		if (V.Title) then
			local Width = surface.GetTextSize(V.Title.Text)
			
			-- Title Color.
			local TitleColor = Color(V.Title.Color.r, V.Title.Color.g, V.Title.Color.b, V.Alpha)
			
			-- Draw.
			draw.SimpleText(V.Title.Text, "Chat_MainText", MessageX + 1, MessageY + 1, Color(0, 0, 0, V.Alpha), 0, 0)
			draw.SimpleText(V.Title.Text, "Chat_MainText", MessageX, MessageY, TitleColor, 0, 0)
			
			-- Message X.
			MessageX = MessageX + Width + Space
		end
		
		-- Check Name.
		if (V.Name) then
			local Width = surface.GetTextSize(V.Name.Text)
			
			-- Name Color.
			local NameColor = Color(V.Name.Color.r, V.Name.Color.g, V.Name.Color.b, V.Alpha)
			
			-- Draw.
			draw.SimpleText(V.Name.Text, "Chat_MainText", MessageX + 1, MessageY + 1, Color(0, 0, 0, V.Alpha), 0, 0)
			draw.SimpleText(V.Name.Text, "Chat_MainText", MessageX, MessageY, NameColor, 0, 0)
			
			-- Message X.
			MessageX = MessageX + Width
			
			-- Width.
			local Width = surface.GetTextSize(":")
			
			-- Text.
			draw.SimpleText(":", "Chat_MainText", MessageX + 1, MessageY + 1, Color(0, 0, 0, V.Alpha), 0, 0)
			draw.SimpleText(":", "Chat_MainText", MessageX, MessageY, Color(255, 255, 255, V.Alpha), 0, 0)
			
			-- Message X.
			MessageX = MessageX + Width + Space
		end
		
		-- Text Color.
		local TextColor = Color(V.Color.r, V.Color.g, V.Color.b, V.Alpha)
		local Tag = nil
		
		-- For Loop.
		for K2, V2 in pairs(V.Blocks) do
			if (V2.Type == "Text") then
				local Width = surface.GetTextSize(V2.Text)
				
				-- Draw.
				draw.SimpleText(V2.Text, "Chat_MainText", MessageX + 1, MessageY + 1, Color(0, 0, 0, V.Alpha), 0, 0)
				draw.SimpleText(V2.Text, "Chat_MainText", MessageX, MessageY, TextColor, 0, 0)
				
				-- Message X.
				MessageX = MessageX + Width + Space
			end
			
			-- Check Message X.
			if (MessageX - 8 > Box.Width) then Box.Width = MessageX - 8 end
			if (Chat.GetY() - Y > Box.Height) then Box.Height = Chat.GetY() - Y end
			
			-- Check Break.
			if (V2.Break) then
				MessageY = MessageY + Chat.GetSpacing() + V.Spacing
				MessageX = X
			end
		end
	end
	
	-- Set Pos.
	Chat.Derma.Scroll:SetPos(X, Y)
	Chat.Derma.Scroll:SetSize(Box.Width, Box.Height)
end

-- Add.
hook.Add("HUDPaint", "Chat.HUDPaint", Chat.HUDPaint)

-- Start Chat.
function Chat.StartChat(Team) 
	return true
end

-- Add.
hook.Add("StartChat", "Chat.StartChat", Chat.StartChat)

-- Chat Text.
function Chat.ChatText(Index, Name, Text, Filter)
	local Type = Filter
	local Filtered = false
	
	-- Check Filter.
	if (Filter == "arrested" or Filter == "yell" or Filter == "whisper" or Filter == "looc"
	or Filter == "request") then
		Filter = "ic"
	end
	
	-- Check ConVar Exists.
	if (ConVarExists("chat_"..Filter) and GetConVarNumber("chat_"..Filter) == 0) then
		Filtered = true
	end
	
	-- Player.
	local Player = player.GetByID(Index)
	
	-- Check Player.
	if (ValidEntity(Player)) then
		local Team = Player:Team()
		local TeamColor = team.GetColor(Team)
		local Nick = Player:Nick()
		
		-- Check Filter.
		if (Type == "chat") then
			Chat.MessageAdd(nil, {Name, TeamColor}, {Text}, Filtered)
		elseif (Type == "ic") then
			Chat.MessageAdd(nil, nil, {Nick..": "..Text, Color(255, 255, 255, 255)}, Filtered)
		elseif (Type == "advert") then
			Chat.MessageAdd({"[Advert]"}, nil, {Nick..": "..Text, Color(200, 150, 225, 255)}, Filtered)
		elseif (Type == "yell") then
			Chat.MessageAdd({"[Yell]", Color(198, 0, 0, 255)}, nil, {Nick..": "..Text, Color(255, 255, 255, 255)}, Filtered)
		elseif (Type == "whisper") then
			Chat.MessageAdd({"[Whisper]", Color(198, 0, 0, 255)}, nil, {Nick..": "..Text, Color(255, 255, 255, 255)}, Filtered)
		elseif (Type == "looc") then
			Chat.MessageAdd({"[Local OOC]", Color(198, 0, 0, 255)}, nil, {Name .. " - " .. Nick .. ": "..Text, Color(255, 255, 255, 255)}, Filtered)
		elseif (Type == "radio") then
			Chat.MessageAdd({"[Radio]", Color(198, 0, 0, 255)}, nil, {Nick..": "..Text, Color(255, 255, 255, 255)}, Filtered)
		elseif (Type == "arrested") then
			Chat.MessageAdd({"[Arrested]"}, nil, {Nick..": "..Text, Color(255, 255, 150, 255)}, Filtered)
		elseif (Type == "request") then
			Chat.MessageAdd({"[Request]"}, nil, {Nick..": "..Text, Color(125, 200, 255, 255)}, Filtered)
		elseif (Type == "broadcast") then
			Chat.MessageAdd({"[Broadcast]", Color(198, 0, 0, 255)}, nil, {Nick..": "..Text, Color(255, 75, 75, 255)}, Filtered)
		elseif (Type == "pm") then
			Chat.MessageAdd({"[PM]"}, nil, {Nick..": "..Text, Color(255, 150, 125, 255)}, Filtered)
		elseif (Type == "ooc") then
			Chat.MessageAdd({"[OOC]:", Color(255, 255, 255, 255)}, {Name .. " - " .. Nick, TeamColor}, {Text}, Filtered)
		elseif (Type == "event") then
			Chat.MessageAdd({"[EVENT]**"}, nil, {Text, Color(255, 0, 0, 255)}, Filtered)
		elseif (Type == "it") then
			Chat.MessageAdd({"**"}, nil, {Text .. " **", Color(255, 255, 255, 255)}, Filtered)
		end
	else
		if (Name == "Console" and Type == "chat") then
			Chat.MessageAdd({"[OOC]"}, {"Console", Color(150, 150, 150, 255)}, {Text}, Filtered)
		elseif (Filter == "joinleave") then
			Text = Text.."."
			
			-- Check Find.
			if (string.find(Text, "%(") and string.find(Text, "%)")) then
				Text = string.gsub(Text, "Kicked by Console :", "Kicked by Console:", 1)
				Text = string.gsub(Text, "%.%)", ")")
				
				-- Message Add.
				Chat.MessageAdd(nil, nil, {Text, Color(255, 75, 75, 255)}, Filtered)
			else
				Chat.MessageAdd(nil, nil, {Text, Color(175, 255, 125, 255)}, Filtered)
			end
		else
			Chat.MessageAdd(nil, nil, {Text, Color(255, 255, 150, 255)}, Filtered)
		end
	end
	
	-- Return True.
	return true
end

-- Add.
hook.Add("ChatText", "Chat.ChatText", Chat.ChatText)

-- Create Derma All.
Chat.CreateDermaAll()