extends KinematicBody2D

# Constains for movement
const MOVE_SPEED = 3.0
const RUN_MULTIPLIER = 2
const GRAVITY = 10
const JUMP_POWER = -180
const FLOOR = Vector2(0, -1)

export var BASE_CAMERA_ZOOM: float = 0.7
export var VIEW_SMOOTH_FACTOR: float = 0.5

enum MoveDirection { UP, DOWN, LEFT, RIGHT, NONE }

# Networking
slave var slave_position = Vector2()
slave var slave_movement = MoveDirection.NONE
slave var slave_transparency = 0
slave var slave_gone = false

var velocity = Vector2()
var isRunning = false
var look_direction = Vector2(1, 0)
var minimap = false
var zoom_interpolation = 0

# True if step sound is playing
var sound_playing = false
# Contains id of the underlying tile
# 0: Office Concrete
# 1: Office Concrete 2
var current_ground = 0

# Get camara
onready var camera_focus = $"/root/Node2D/Game/Focus" as Position2D
onready var camera = $"/root/Node2D/Game/Focus/Camera" as Camera2D
onready var gui = $"/root/Node2D/GUI" as CanvasLayer
onready var client = $"/root/Node2D/Game/Connection" as Node2D

func _process(delta):
	pass

func _physics_process(delta):
	# Check if game is visable
	if(get_node("../../Game").is_visible() == false):
		return
	
	for player in Networking.players:
		if player != int(name):
			var p = (get_node("/root/Node2D/Game/" + String(player)) as KinematicBody2D)
			if p != self:
				var distance = p.position.distance_to(position)
				var transparency = (distance - ($View/CollisionShape2D as CollisionShape2D).shape.radius + 10) * VIEW_SMOOTH_FACTOR
				
				# Clip values
				if transparency > 1:
					transparency = 1
				if transparency < 0:
					transparency = 0
				rset_id(player, "slave_transparency", transparency)
	
	modulate.a = 1-slave_transparency
	
	"""
	MAP OVERVIEW
	"""
	# Put focus on player if not in minimap
	var start = Vector2(BASE_CAMERA_ZOOM, BASE_CAMERA_ZOOM)
	var end = Vector2(1.5, 1.5)
	
	if $Kill.get_overlapping_bodies().size() > 1:
		($"/root/Node2D/GUI/Game/Kill" as Button).disabled = false
	else:
		($"/root/Node2D/GUI/Game/Kill" as Button).disabled = true
	
	# Camera movement
	if !minimap:
		if is_network_master():
			camera_focus.position = position
			
		if zoom_interpolation <= 1.1:
			zoom_interpolation -= 0.05
			camera.set_zoom(start.cubic_interpolate(end, start/2, end/2, zoom_interpolation))
			
			# Stop zooming in
			if zoom_interpolation <= 0:
				camera.smoothing_speed = 6
				zoom_interpolation = 0
	else:
		# Update camera zoom
		if zoom_interpolation <= 1:
			zoom_interpolation += 0.05
			camera.set_zoom(start.cubic_interpolate(end, start/2, end/2, zoom_interpolation))
	
	# View map
	if Input.is_action_just_pressed("minimap"):
		if !minimap:
			minimap = true
			camera.smoothing_speed = 2
			camera_focus.position = get_node("/root/Node2D").position
		else:
			minimap = false
	
	"""
	MOVEMENT
	"""
	var direction = MoveDirection.NONE
	
	var RIGHT = Input.is_action_pressed("ui_right")
	var LEFT = Input.is_action_pressed("ui_left")
	var JUMP = Input.is_action_pressed("ui_up")
	var SNEAK = Input.is_action_pressed("ui_down")
	var RUN = Input.is_action_pressed("ui_shift")
	
	if get_tree().network_peer != null and is_network_master():
		if LEFT:
			direction = MoveDirection.LEFT
		elif RIGHT:
			direction = MoveDirection.RIGHT
		elif JUMP:
			direction = MoveDirection.UP
		elif SNEAK:
			direction = MoveDirection.DOWN
		
		"""
		for player in Networking.players:
			if player != int(name):
				var p = Networking.get_player_node(int(player))
				if $Receive.overlaps_body(p):
					# Send everyone in receive area the current position
					rset_unreliable_id(int(player), 'slave_position', position)
					rset_id(int(player), 'slave_movement', direction)
				else:
					# Hide from everyone else
					rset_id(int(player), 'slave_movement', MoveDirection.NONE)"""
		if Networking.move:
			rset_unreliable('slave_position', position)
			rset('slave_movement', direction)
			
			_move(direction)
	else:
		_move(slave_movement)
		position = slave_position

	if get_tree().network_peer != null and get_tree().is_network_server():
		Networking.update_position(int(name), position)

func _move(direction):
	if direction != MoveDirection.NONE:
		play_step()
	else:
		$ConcreteSteps.stop()
	
	match direction:
		MoveDirection.NONE:
			return
		MoveDirection.UP:
			move_and_collide(Vector2(0, -MOVE_SPEED))
			$AnimatedSprite.play("jump")
		MoveDirection.DOWN:
			move_and_collide(Vector2(0, MOVE_SPEED))
			velocity.x = 0
			$AnimatedSprite.play("idle")
		MoveDirection.LEFT:
			move_and_collide(Vector2(-MOVE_SPEED, 0))
			$AnimatedSprite.play("run")
			$AnimatedSprite.set_flip_h(true);
			look_direction = Vector2(-1, 0)
		MoveDirection.RIGHT:
			move_and_collide(Vector2(MOVE_SPEED, 0))
			look_direction = Vector2(1, 0)
			$AnimatedSprite.play("run")
			$AnimatedSprite.set_flip_h(false);
	
	if(isRunning):
		velocity.x = MOVE_SPEED*RUN_MULTIPLIER
	else:
		velocity.x = MOVE_SPEED

func play_step():
	if !$ConcreteSteps.playing:
		$ConcreteSteps.play()
		sound_playing = true
