extends Node


signal connection_succeeded()
signal connection_failed()
signal player_list_changed()
signal game_error()
signal game_started()
signal game_ended()


const PORT = 10567

const MAX_PEERS = 2


var peer: ENetMultiplayerPeer = null

var player = {
	idx = 0,
	name = "",
	character = "Tux",
}
var winning_player = player

# Dictionary { id = { idx: 1, name: "" } }
var players = {}
var players_ready = []


func _ready():
	multiplayer.connect("peer_connected", Callable(self, '_player_connected'))
	multiplayer.connect("peer_disconnected", Callable(self, "_player_disconnected"))
	multiplayer.connect("connected_to_server", Callable(self, "_connection_succeeded"))
	multiplayer.connect("connection_failed", Callable(self, "_connection_failed"))
	multiplayer.connect("server_disconnected", Callable(self, "_server_disconnected"))
	Global.connect("game_started", Callable(self, "_on_Global_game_started"))
	Global.connect("game_ended", Callable(self, "_on_Global_game_ended"))
	Global.connect("game_won", Callable(self, "_on_Global_game_won"))


@rpc("any_peer") func register_player(player_name):
	var id = get_tree().get_remote_sender_id()
	self.players[id] = {
		name = player_name,
		ip = self.peer.get_peer_address(id),
	}
	emit_signal("player_list_changed")


@rpc("any_peer") func unregister_player(id):
	self.players.erase(id)
	emit_signal("player_list_changed")


func host_game(player_name):
	self.player.name = player_name
	self.peer = ENetMultiplayerPeer.new()
	self.peer.create_server(self.PORT, self.MAX_PEERS)
	multiplayer.multiplayer_peer = self.peer


func join_game(ip, player_name):
	self.player.name = player_name
	self.peer = ENetMultiplayerPeer.new()
	self.peer.create_client(ip, self.PORT)
	multiplayer.multiplayer_peer = self.peer


func leave_game():
	rpc("_leave_game")
	multiplayer.multiplayer_peer = null


@rpc("any_peer") func _leave_game():
	var id = get_tree().get_remote_sender_id()
	self.peer.disconnect_peer(id)


func get_player_count():
	return self.players.size() + 1


func _on_Global_game_started():
	# preconfigure game and set idx to each player
	var idx = 1
	for id in self.players:
		self.players[id].idx = idx
		rpc_id(id, "_preconfigure_game", idx)
		idx += 1
	
	# start game for everyone
	rpc("_start_game")


@rpc("any_peer") func _preconfigure_game(idx):
	self.player.idx = idx
	

@rpc("any_peer", "call_local") func _start_game():
	emit_signal("game_started")


func _on_Global_game_ended():
	# tell all peers to end the game
	rpc("_end_game")


func _on_Global_game_won(winning_player):
	rpc("_end_game", winning_player)


@rpc("any_peer", "call_local") func _end_game(winning_player):
	self.winning_player = winning_player
	emit_signal("game_ended")


func _player_connected(_id):
	rpc("register_player", self.player.name)


func _player_disconnected(id):
	# if game is in progress:
		# self.end_game() ?
	# else
		#rpc("unregister_player", id)
	rpc("unregister_player", id)


func _connection_succeeded():
	emit_signal("connection_succeeded")


func _connection_failed():
	get_tree().set_multiplayer_peer(null) # remove peer
	emit_signal("connection_failed")


func _server_disconnected():
	emit_signal("game_error", "Server disconnected!")
	#self.end_game("")