gPlayers = {}

-- commands
SetCommand("say",function(text)
	if text then
		for player in pairs(gPlayers) do
			SendNetworkEvent(player,"chat:ServerMessage",text)
		end
	else
		PrintError("expected message")
	end
end,true)
SetCommand("say_as",function(who,...)
	local text
	if not who then
		PrintError("expected player name")
		return
	end
	for _,v in ipairs(arg) do
		if text then
			text = text.." "..v
		else
			text = v
		end
	end
	if not text then
		PrintError("expected message")
		return
	end
	for player,data in pairs(gPlayers) do
		local name = GetPlayerName(player)
		if string.lower(name) == string.lower(who) then
			for player in pairs(gPlayers) do
				SendNetworkEvent(player,"chat:PlayerMessage",name,text,unpack(data.color))
			end
			return
		end
	end
	for player in pairs(gPlayers) do
		SendNetworkEvent(player,"chat:PlayerMessage",who,text,255,213,3)
	end
end)

-- exports
function exports.Say(text)
	text = tostring(text)
	for player in pairs(gPlayers) do
		SendNetworkEvent(player,"chat:ServerMessage",text)
	end
end
function exports.SayAs(player,text)
	local data = gPlayers[player]
	if data then
		local name = GetPlayerName(player)
		text = tostring(text)
		for player in pairs(gPlayers) do
			SendNetworkEvent(player,"chat:PlayerMessage",name,text,unpack(data.color))
		end
	end
end

-- events
RegisterLocalEventHandler("PlayerConnected",function(player)
	if IsPlayerValid(player,false) then
		local name = GetPlayerName(player)
		for player in pairs(gPlayers) do
			SendNetworkEvent(player,"chat:PlayerJoined",name)
		end
		F_InitPlayer(player)
	end
end)
RegisterLocalEventHandler("PlayerDropped",function(player)
	-- it's possible to drop without fully connecting, so we'll make sure they did connect to send this message
	if gPlayers[player] then
		local name = GetPlayerName(player)
		gPlayers[player] = nil
		for player in pairs(gPlayers) do
			SendNetworkEvent(player,"chat:PlayerLeft",name)
		end
	end
end)
RegisterNetworkEventHandler("chat:SendMessage",function(player,message)
	-- check the message is okay because we shouldn't fully trust messages from players
	local data = gPlayers[player]
	if data and type(message) == "string" and string.find(message,"%S") and string.len(message) <= GetConfigNumber(GetScriptConfig(),"max_message_length",100) and RunLocalEvent("chat:SendMessage",player,message) then
		local id = GetPlayerId(player)
		local name = GetPlayerName(player)
		for player,x in pairs(gPlayers) do
			if x.moderator then
				SendNetworkEvent(player,"chat:PlayerMessage","["..id.."] "..name,message,unpack(data.color))
			else
				SendNetworkEvent(player,"chat:PlayerMessage",name,message,unpack(data.color))
			end
		end
		if GetConfigBoolean(GetScriptConfig(),"log_chat",false) then
			PrintOutput(name..": "..message)
		end
	end
end)

-- utility
function F_InitPlayer(player)
	gPlayers[player] = {
		color = {F_GetPlayerColor(player)},
		moderator = F_IsPlayerModerator(player),
	}
end
function F_GetPlayerColor(player)
	if dsl.role_colors then
		return dsl.role_colors.GetColor(player)
	end
	return 230,230,230
end
function F_IsPlayerModerator(player)
	for role in AllConfigStrings(GetScriptConfig(),"see_id_role") do
		if DoesPlayerHaveRole(player,role) then
			return true
		end
	end
	return false
end

-- init (for restarting scripts)
for player in AllPlayers() do
	F_InitPlayer(player)
end
