local m={}m.__index=m function m.SayMessage(L,m,n,w)if L.ChatService:InternalDoProcessCommands(L.Name,m,n)then return end if not n then return end local t=L.Channels[n:lower()]if not t then error("\083\112\101\097\107\101\114 \105\115 \110\111\116 \105\110 \099\104\097\110\110\101\108 \""..(n.."\""))end local d=t:InternalPostMessage(L,m,w)if d then local m,w=pcall(function()L.eSaidMessage:Fire(d,n)end)if not m and w then print("\069\114\114\111\114 \115\097\121\105\110\103 \109\101\115\115\097\103\101\058 "..w)end end return d end function m.JoinChannel(n,m)if n.Channels[m:lower()]then warn("\083\112\101\097\107\101\114 \105\115 \097\108\114\101\097\100\121 \105\110 \099\104\097\110\110\101\108 \""..(m.."\""))return end local w=n.ChatService:GetChannel(m)if not w then error("\067\104\097\110\110\101\108 \""..(m.."\" \100\111\101\115 \110\111\116 \101\120\105\115\116\033"))end n.Channels[m:lower()]=w w:InternalAddSpeaker(n)local L,t=pcall(function()n.eChannelJoined:Fire(w.Name,w.WelcomeMessage)end)if not L and t then print("\069\114\114\111\114 \106\111\105\110\105\110\103 \099\104\097\110\110\101\108\058 "..t)end end function m.LeaveChannel(n,m)if not n.Channels[m:lower()]then warn("\083\112\101\097\107\101\114 \105\115 \110\111\116 \105\110 \099\104\097\110\110\101\108 \""..(m.."\""))return end local w=n.Channels[m:lower()]n.Channels[m:lower()]=nil w:InternalRemoveSpeaker(n)local L,t=pcall(function()n.eChannelLeft:Fire(w.Name)end)if not L and t then print("\069\114\114\111\114 \108\101\097\118\105\110\103 \099\104\097\110\110\101\108\058 "..t)end end function m.IsInChannel(n,m)return n.Channels[m:lower()]~=nil end function m.GetChannelList(m)local n={}for m,w in pairs(m.Channels)do table.insert(n,w.Name)end return n end function m.SendMessage(t,m,n,w,L)local d=t.Channels[n:lower()]if d then d:SendMessageToSpeaker(m,t.Name,w,L)else warn(string.format("\083\112\101\097\107\101\114 \'\037\115\' \105\115 \110\111\116 \105\110 \099\104\097\110\110\101\108 \'\037\115\' \097\110\100 \099\097\110\110\111\116 \114\101\099\101\105\118\101 \097 \109\101\115\115\097\103\101 \105\110 \105\116\046",t.Name,n))end end function m.SendSystemMessage(L,m,n,w)local t=L.Channels[n:lower()]if t then t:SendSystemMessageToSpeaker(m,L.Name,w)else warn(string.format("\083\112\101\097\107\101\114 \'\037\115\' \105\115 \110\111\116 \105\110 \099\104\097\110\110\101\108 \'\037\115\' \097\110\100 \099\097\110\110\111\116 \114\101\099\101\105\118\101 \097 \115\121\115\116\101\109 \109\101\115\115\097\103\101 \105\110 \105\116\046",L.Name,n))end end function m.GetPlayer(m)return m.PlayerObj end function m.SetExtraData(w,m,n)w.ExtraData[m]=n w.eExtraDataUpdated:Fire(m,n)end function m.GetExtraData(n,m)return n.ExtraData[m]end function m.SetMainChannel(n,m)local w,L=pcall(function()n.eMainChannelSet:Fire(m)end)if not w and L then print("\069\114\114\111\114 \115\101\116\116\105\110\103 \109\097\105\110 \099\104\097\110\110\101\108\058 "..L)end end

local methods = {}
methods.__index = methods

function methods:SayMessage(message, channelName, extraData)
	if (self.ChatService:InternalDoProcessCommands(self.Name, message, channelName)) then return end
	if (not channelName) then return end

	local channel = self.Channels[channelName:lower()]
	if (not channel) then
		error("Speaker is not in channel \"" .. channelName .. "\"")
	end

	local messageObj = channel:InternalPostMessage(self, message, extraData)
	if (messageObj) then
		local success, err = pcall(function() self.eSaidMessage:Fire(messageObj, channelName) end)
		if not success and err then
			print("Error saying message: " ..err)
		end
	end

	return messageObj
end

function methods:JoinChannel(channelName)
	if (self.Channels[channelName:lower()]) then
		warn("Speaker is already in channel \"" .. channelName .. "\"")
		return
	end

	local channel = self.ChatService:GetChannel(channelName)
	if (not channel) then
		error("Channel \"" .. channelName .. "\" does not exist!")
	end

	self.Channels[channelName:lower()] = channel
	channel:InternalAddSpeaker(self)
	local success, err = pcall(function()
		self.eChannelJoined:Fire(channel.Name, channel.WelcomeMessage)
	end)
	if not success and err then
		print("Error joining channel: " ..err)
	end
end

function methods:LeaveChannel(channelName)
	if (not self.Channels[channelName:lower()]) then
		warn("Speaker is not in channel \"" .. channelName .. "\"")
		return
	end

	local channel = self.Channels[channelName:lower()]

	self.Channels[channelName:lower()] = nil
	channel:InternalRemoveSpeaker(self)
	local success, err = pcall(function()
		self.eChannelLeft:Fire(channel.Name)
	end)
	if not success and err then
		print("Error leaving channel: " ..err)
	end
end

function methods:IsInChannel(channelName)
	return (self.Channels[channelName:lower()] ~= nil)
end

function methods:GetChannelList()
	local list = {}
	for i, channel in pairs(self.Channels) do
		table.insert(list, channel.Name)
	end
	return list
end

function methods:SendMessage(message, channelName, fromSpeaker, extraData)
	local channel = self.Channels[channelName:lower()]
	if (channel) then
		channel:SendMessageToSpeaker(message, self.Name, fromSpeaker, extraData)

	else
		warn(string.format("Speaker '%s' is not in channel '%s' and cannot receive a message in it.", self.Name, channelName))

	end
end

function methods:SendSystemMessage(message, channelName, extraData)
	local channel = self.Channels[channelName:lower()]
	if (channel) then
		channel:SendSystemMessageToSpeaker(message, self.Name, extraData)

	else
		warn(string.format("Speaker '%s' is not in channel '%s' and cannot receive a system message in it.", self.Name, channelName))

	end
end

function methods:GetPlayer()
	return self.PlayerObj
end

function methods:SetExtraData(key, value)
	self.ExtraData[key] = value
	self.eExtraDataUpdated:Fire(key, value)
end

function methods:GetExtraData(key)
	return self.ExtraData[key]
end

function methods:SetMainChannel(channelName)
	local success, err = pcall(function() self.eMainChannelSet:Fire(channelName) end)
	if not success and err then
		print("Error setting main channel: " ..err)
	end
end
