extends Node

const MAX_PEERS = 4
const LOBBY_READY_WAIT_TIME = 3

var Game = preload("res://scenes/game/Game.tscn")
var Player = preload("res://scenes/player/Player.tscn")
var HumanPlayer = preload("res://scenes/player/HumanPlayer.tscn")
var BotPlayer = preload("res://scenes/player/BotPlayer.tscn")

var game:Game
var players = {}

var game_name = ""
var bots:bool = false
var game_running:bool = false

signal players_changed(players)
signal game_ready(ready)
signal game_started()
signal game_ended()


remote func set_player(id, new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false):
	players[id] = {"name" : new_name, "color" : new_color, "ready" : new_ready, "prepared" : false}
	emit_signal("players_changed", players)
	
	if get_tree().is_network_server():
		var all_ready = true
		for p_id in players: 
			rpc_id(id, "set_player", p_id, players[p_id].name, players[p_id].color, players[p_id].ready) 
			rpc_id(p_id, "set_player", id, new_name, new_color, new_ready)
			all_ready = all_ready && players[p_id].ready
		rpc("game_ready", all_ready)


func update_player(new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false):
	if get_tree().is_network_server():
		set_player(get_tree().get_network_unique_id(), new_name, new_color, new_ready)
	else:
		rpc("set_player",get_tree().get_network_unique_id(), new_name, new_color, new_ready)


remotesync func remove_player(id):
	players.erase(id)
	
	if game != null:
		var game_players = game.get_node("players")
		if game_players.has_node(str(id)):
			game_players.remove_child(game_players.get_node(str(id)))
	
	emit_signal("players_changed", players)


remotesync func game_ready(all_ready:bool):
	if get_tree().is_network_server():
		if all_ready:
			game_running = true
		else:
			game_running = false
	emit_signal("game_ready", all_ready)


remotesync func prepare_game():
	get_tree().set_pause(true)
	
	game = Game.instance()
	get_tree().get_root().add_child(game)

	get_tree().get_root().get_node("main_menu").hide()
	
	for p_id in players:
		var controls
		var player = players[p_id]
		
		var player_scene = Player.instance()
		player_scene.set_network_master(p_id)
		player_scene.set_name(str(p_id))
		game.get_node("players").add_child(player_scene)
		player_scene.set_player_name(player.name)
		player_scene.set_player_color(player.color)
		
		if p_id == get_tree().get_network_unique_id():
			controls = HumanPlayer.instance()
			controls.set_name("HumanControl_" + str(p_id))
			game.add_child(controls)
			controls.set_player(player_scene.get_path())
			controls.set_network_master(p_id)
		
		player_scene.set_start(player_scene.get_index())
	
	if bots:
		for index in range(MAX_PEERS-players.size()):
			var bot_index = players.size() + index
			var player_scene = Player.instance()
			player_scene.set_name("bot_player" + str(bot_index))
			game.get_node("players").add_child(player_scene)
			player_scene.set_player_name("Bot " + str(bot_index))
			player_scene.set_player_color(Color(randf(),randf(),randf()))
			player_scene.add_to_group("bots")
			if get_tree().is_network_server():
				var bot = BotPlayer.instance()
				bot.set_name("bot" + str(bot_index))
				game.add_child(bot)
				bot.set_player(player_scene.get_path())
				bot.set_network_master(get_tree().get_network_unique_id())
			player_scene.set_start(bot_index)
	if players.has(get_tree().get_network_unique_id()):
		rpc_id(1, "player_prepared", get_tree().get_network_unique_id())

	if get_tree().is_network_server():
		if players.has(get_tree().get_network_unique_id()):
			player_prepared(get_tree().get_network_unique_id())
	else:
		rpc_id(1, "player_prepared", get_tree().get_network_unique_id())


remotesync func player_prepared(id):
	if get_tree().is_network_server():
		players[id].prepared = true
		var all_prepared = true
		for p_id in players: 
			all_prepared = all_prepared && players[p_id].prepared
		if all_prepared:
			rpc("post_start_game")


remotesync func post_start_game():
	get_tree().set_pause(false)
	emit_signal("game_started")


remotesync func set_bots(has_bots:bool):
	bots = has_bots


func quit_game():
	if game != null: 
		game.queue_free()
		game = null

	players.clear()
	if get_tree().get_root().has_node("multiplayer_menu"):
		get_tree().get_root().get_node("multiplayer_menu").show()
		get_tree().get_root().get_node("main_menu").hide()
	elif get_tree().get_root().has_node("main_menu"):
		get_tree().get_root().get_node("main_menu").show()
	game_running = false
	bots = false
	game_name = ""
	
	emit_signal("game_ended")
