extends Node

var net = NetworkedMultiplayerENet.new()
var api = MultiplayerAPI.new()
var port = 0
var ip = ''
# Called when the node enters the scene tree for the first time.
func _ready():
	print('connecting to port: ' + str(port))
	print('at ip: '+ip)
	net.create_client(ip,port)
	
	self.set_custom_multiplayer(api)
	custom_multiplayer.set_root_node(self)
	custom_multiplayer.set_network_peer(net)
	
	net.connect("connection_failed", self, "_On_Connection_Failed")
	net.connect("connection_succeeded", self, "_On_Connection_Succeeded")
	pass # Replace with function body.

func _process(_delta):
	custom_multiplayer.poll()

remote func ping():
	print('messaged received from server')

remote func tokerequest():
	print('tokenreply_')
	var tk = get_parent().get_node('Loginetcode').token_buffer
	print('tk is ' + tk)
	var username = get_parent().get_node('Loginetcode').username_server
	rpc_id(1,'tokenreply', tk, username)

remote func on_token_confirmed():
#	if loadlevel_buffer == 'lobby':
	$spawnmsg/CenterContainer.visible = true

remote func on_player_state_data(arg):
	print(arg)
	$spawnmsg/CenterContainer/VBoxContainer/spawnmsg2.text = str(arg)
#	$spawnmsg/CenterContainer.visible = false

remote func on_queue_spawn():
	$spawnmsg/CenterContainer/VBoxContainer/spawnmsg2.text = 'awaiting checkpoint...'

func spawn_request():
	rpc_id(1,'spawn_request')

remote func on_spawn_request_reply():
	emit_signal('client_request')
	yield(get_tree(),"physics_frame")
	yield(get_tree(),"physics_frame")
	yield(get_tree(),"physics_frame")
	for x in get_tree().get_nodes_in_group('playersprite'): x.die = false
	$spawnmsg/CenterContainer.visible = false
	

func _On_Connection_Failed():
	print("Failed to connect to game server")

var playerphsyics = preload('res://playersprite.tscn')
var playerhud = preload('res://hud.tscn')

export var dummy = false

func _On_Connection_Succeeded():
	rpc_id(1,'connected_peer')

remote func _On_Peer_Connected():
	$Input.enabled = true
	print("Succesfully connected to game server")
	if not has_node("players"): return
	request_clients()
	yield(self, 'client_request')
	for x in current_clients:
		gen_objs(playerphsyics,x,$players)
		gen_objs(playerhud,x, $Hud/HBoxContainer)
		if x == api.get_network_unique_id():
			if $players.has_node(str(x)):
				if not $players.get_node(str(x)).has_node('Camera2D'):
					var cam2d = Camera2D.new()
					cam2d.current = true
					cam2d.offset.y = -90
					$players.get_node(str(x)).add_child(cam2d)
	
	if dummy:
		rpc_id(1,'makedummmy')

func gen_objs(arg,x, node):
	if not node.has_node(str(x)):
		var instance = arg.instance()
		instance.name = str(x)
		node.add_child(instance)

remote func _On_Player_Disconnect(arg):
	print(str(arg) + ' had left the server')
	var arr = [$players, $Hud/HBoxContainer]
	for x in arr:
		if x.has_node(str(arg)):
			x.get_node(str(arg)).queue_free()

signal client_request
var current_clients = []

func request_clients():
	rpc_id(1,'send_clients')

remote func client_data(arg):
	current_clients = arg

# extra stuff

var ping = 0

func latency_test():
	rpc_id(1,'latency',OS.get_system_time_msecs())

remote func returnping(arg):
	ping = (OS.get_system_time_msecs() - arg)

func send_input(arg, arg2):
	rpc_id(1,'input_handler',arg, arg2)

remote func player_position(arg):
	if not has_node("players"): return
	for id in arg.keys():
		if $players.has_node(str(id)):
			var node = $players.get_node(str(id))
			if node.global_position.x != arg[id].x:
				node.flip_h = node.global_position.x > arg[id].x
				node.get_node('Label').scale.x = -1 if node.global_position.x > arg[id].x else 1
			node.global_position = arg[id]

remote func player_animation(arg):
	if not has_node("players"): return
	for id in arg.keys():
		if $players.has_node(str(id)):
			$players.get_node(str(id)).animation  = arg[id]

remote func aimanim(id):
	if $players.has_node(str(id)):
			$players.get_node(str(id)).shooting()


func reconstruct_int16(bytetest):
	return ((bytetest[0] * 255) + bytetest[1])-32768

var argbuffer
var posbuffer

remote func projectiles_sync(arg):
	if not has_node('projectiles'): return
	for i in $projectiles.get_children():
		i.hide()
	
	argbuffer = posbuffer
	posbuffer = []
	var sprite = []
	for i in range(0,arg.size(),6):
		var aux =  Vector2( reconstruct_int16([ arg[i] , arg[i+1]]), reconstruct_int16([ arg[i+2] , arg[i+3]]) )
		posbuffer.append(aux)
		sprite.append(arg[i+4])
	
	for i in posbuffer.size():
		$projectiles.get_child(i).show()
		$projectiles.get_child(i).global_position = posbuffer[i]
	
	for i in sprite.size():
		$projectiles.get_child(i).texture = get_node('../Textures').dict[sprite[i]]

remote func enemy_dmg_anim(arg):
	$enemies.get_child(arg).flash = true
	$enemies.get_child(arg).counter = 0

remote func enemies_position_2(arg):
	if not has_node('enemies'): return
	for i in $enemies.get_children():
		i.hide()
	
	argbuffer = posbuffer
	posbuffer = []
	var sprite = []
	var side = []
	for i in range(0,arg.size(),6):
		var aux =  Vector2( reconstruct_int16([ arg[i] , arg[i+1]]), reconstruct_int16([ arg[i+2] , arg[i+3]]) )
		posbuffer.append(aux)
		sprite.append(arg[i+4])
		side.append(arg[i+5])
	
	for i in posbuffer.size():
		var node = $enemies.get_child(i)
		node.show()
		node.scale.x = 1 if side[i] else -1
		node.global_position = posbuffer[i]
	
	for i in sprite.size():
		$enemies.get_child(i).texture = get_node('../Textures').dict[sprite[i]]

remote func attack_anim(arg, id):
	if not has_node("players"): return
	if not $players.has_node(str(id)): return
	$players.get_node(str(id)).get_node('weapon/AnimationPlayer').play(arg)

remote func atr_update(arg):
	if has_node('Hud/HBoxContainer/'+arg.keys()[0]):
		get_node('Hud/HBoxContainer/'+arg.keys()[0])._update(arg.values()[0])

remote func player_death_update(id):
	print('die1')
	if not has_node("players"): return
	print('die2')
	$players.get_node(str(id))._die()

remote func level_up(arg, id):
	if not has_node("players"): return
	$players.get_node(str(id)).level_up_anim()

var loadlevel_buffer = 'lobby'

remote func loadlevel(arg):
	arg += 'client'
	loadlevel_buffer = arg
	get_parent().get_node('Levelselect').loadlevel(arg, false)

#powerpick
remote func powerpick(arg , id):
	if has_node('PowerMenu'):
		$PowerMenu/CenterContainer.show()
		print(arg)
		$PowerMenu.showmenu(arg, id)

func players_choice_is(choice, idbuffer):
#	print(choice)
	rpc_id(1,'optionpick',idbuffer, choice)

remote func _On_chat_Message(arg, id):
	$Chat/RichTextLabel.text += arg + "\n"
	$players.get_node(str(id)).message(arg)

func chat_messages(arg):
	print(arg)
	$Chat/LineEdit.text= ''
	rpc_id(1,'chat_messages', arg)

var usernamelist = {}

remote func _on_usernames(arg):
	for i in arg.keys():
		usernamelist[i] = arg[i]

var spriter = preload('res://enemie/enemyspriter.tscn')
var sprite_list = {}

remote func add_sprite(anim, pos, id, auto):
	if not sprite_list.keys().has(id):
		var instancer = spriter.instance()
		add_child(instancer)
		instancer.id = id
		sprite_list[id] = instancer
	if is_instance_valid(sprite_list[id]):
		sprite_list[id].global_position = pos
		if sprite_list[id].get_animation() != anim: 
			sprite_list[id].set_animation(anim)
			sprite_list[id]._set_playing(true) 

remote func nuke_sprite(id):
	if is_instance_valid(sprite_list[id]):
		if sprite_list.keys().has(id):
			sprite_list[id].queue_free()

remote func flash_spriter(id):
	
	if is_instance_valid(sprite_list[id]):
		if sprite_list.keys().has(id):
			
			sprite_list[id].modulate = Color(5,2,1)
			yield(get_tree().create_timer(0.05),"timeout")
			sprite_list[id].modulate = Color(1,1,1)
