extends KinematicBody2D

const WALK_SPEED = 50.0
const RUN_SPEED = 130.0
const JUMP_FORCE = 250.0
const GRAVITY = 600.0
const JUMP_MAX_AIRBORNE_TIME = 0.2
const RUN_ENERGY_INTAKE = 1
const JUMP_ENERGY_INTAKE = 10

onready var gun = get_node("main/gun")
onready var head = get_node("main/body/head")
onready var anim_node = get_node("anim")
onready var ray = get_node("main/gun/ray")
onready var gun_partice = get_node("main/gun/Particles2D")
onready var particle = get_node("hurt_particle")
onready var offset = Vector2(0, 0)

var anim = "idle"
var velocity = Vector2()
var floor_velocity  = Vector2()
var siding_left = false
var look_left = false
var bullet_shell = preload("res://scenes/items/bullet_shell.scn")
var bullet = preload("res://scenes/items/bullet.scn")
var is_grounded = false
var b_pos_changer = false
var is_second_jump_able = false
var second_jump = false
var rate_of_fire = 0.1
var on_air_time = 100
var time_factor = 1
var dead = false

var key_left = ""
var key_right = ""
var key_jump = ""
var key_run = ""
var key_relkad = ""
var key_use = ""

func _draw():
	if get_node("main/gun/ray").is_colliding():
		var gpos = get_global_pos()
		var point = get_node("main/gun/ray").get_collision_point() - gpos
		draw_line(get_node("main/gun/laser").get_global_pos() - gpos, point, Color(0.8, 0.1, 0.1), 2)

func _process(delta):
	offset = -get_viewport().get_canvas_transform().o * get_node("camera").get_zoom() 
	var mpos = get_viewport().get_mouse_pos() * get_node("camera").get_zoom() + offset
	gun.look_at(mpos)
	head.look_at(mpos)

	var pos = get_pos()
	if mpos>pos:
		look_left = false
	else:
		look_left = true
		
	var time_dilation = Input.is_action_pressed("action")
	var shoot = Input.is_action_pressed("shoot")
	
	if time_dilation and !global.time_dilated and global.stats[2]  > 3:
		time_factor = 10
		get_node("bullet_timer").stop()
		get_node("bullet_timer").set_wait_time(0.01)
		get_node("main/gun/Particles2D").set_time_scale(time_factor)
		anim_node.set_speed(time_factor)
		global.time_dilation(0.05)
		Globals.get("UI").show_screen_effect("radial_blur", true)
	elif (!time_dilation and global.time_dilated) or global.stats[2]<=0:
		time_factor = 1
		get_node("bullet_timer").set_wait_time(0.1)
		get_node("main/gun/Particles2D").set_time_scale(time_factor)
		anim_node.set_speed(1)
		global.time_dilation(1)
		Globals.get("UI").show_screen_effect("radial_blur", false)
	update()
	
	if shoot and global.stats[3] >0 and get_node("bullet_timer").get_time_left() == 0:
		gun_partice.set_emitting(true)
		audio.play_sound("shoot")
		get_node("bullet_timer").start()
		var bs = bullet_shell.instance()
		var b = bullet.instance()
		var bs_pos = get_node("main/gun/extractor").get_global_pos()
		var b_pos
		if  b_pos_changer:
			b_pos = get_node("main/gun/bullet_shoot_1").get_global_pos()
		else:
			b_pos = get_node("main/gun/bullet_shoot_2").get_global_pos()
		b_pos_changer = !b_pos_changer
		var rot = get_node("main/gun/").get_rot()+PI/2
		bs.set_pos(bs_pos)
		b.set_pos(b_pos)
		if look_left:
			b.set_rot(-rot)
			bs.set_linear_velocity(Vector2(-40,rand_range(70,100)).rotated(-rot))
			bs.set_angular_velocity(rand_range(-1,1))
		elif !look_left:
			bs.set_rot(rot)
			b.set_rot(rot-PI)
			bs.set_linear_velocity(Vector2(40,rand_range(70,100)).rotated(rot))
			bs.set_angular_velocity(rand_range(-1,1))
		get_parent().add_child(bs)
		get_parent().add_child(b)
		PS2D.body_add_collision_exception(bs.get_rid(),get_rid())
		ray.add_exception_rid(bs.get_rid())
		global.stats[3] -= 1
	elif !shoot and get_node("bullet_timer").get_time_left() == 0:
		gun_partice.set_emitting(false)
	
func _fixed_process(delta):
#	get_world_2d()
#	var space = get_world_2d().get_space()
#	var space_state = Physics2DServer.space_get_direct_state(space)
	
	var new_anim = anim
	var new_siding_left = siding_left

	var move_left = Input.is_action_pressed(key_left)
	var move_right = Input.is_action_pressed(key_right)
	var jump = Input.is_action_pressed(key_jump)
	var run = Input.is_action_pressed(key_run) and global.stats[1] > 0

	
	velocity.y += delta * GRAVITY
	velocity.x = clamp(velocity.x, -RUN_SPEED, RUN_SPEED)
	
	if move_left:
		if is_grounded:
			if !run or global.stats[1] <= 0:
				velocity.x = -WALK_SPEED * time_factor
				new_anim = "walk"
			else:
				velocity.x = -RUN_SPEED * time_factor
				new_anim = "run"
				global.stats[1] -= RUN_ENERGY_INTAKE
			new_siding_left = true
		elif abs(velocity.x) < 1:
			velocity.x = -WALK_SPEED
	elif move_right:
		if is_grounded:
			if !run or global.stats[1] <= 0:
				velocity.x = WALK_SPEED * time_factor
				new_anim = "walk"
			else:
				velocity.x = RUN_SPEED * time_factor
				new_anim = "run"
				global.stats[1] -= RUN_ENERGY_INTAKE
			new_siding_left = false
		elif abs(velocity.x) < 1:
			velocity.x = WALK_SPEED
	else:
		if is_grounded:
			velocity.x = 0
			new_anim = "idle"
			global.stats[1] = clamp(global.stats[1]  + 3, 0, 1000)
#			
#	if velocity.x == 0:
#		get_tree().set_pause(true)
#	else:
#		get_tree().set_pause(false)
	
	if jump: 
		if is_grounded and global.stats[1]  > 0:
			is_second_jump_able = false
			velocity.y = -JUMP_FORCE 
			is_grounded = false
			audio.play_sound("jump")
			global.stats[1]  -= JUMP_ENERGY_INTAKE
		elif !is_grounded and !second_jump and is_second_jump_able:
			second_jump = true
			velocity.y = -JUMP_FORCE
			audio.play_sound("jump")
			global.stats[1]  -= JUMP_ENERGY_INTAKE
	elif !is_grounded and !is_second_jump_able and velocity.y>-150:
		is_second_jump_able = true
			
#	print(velocity.y)

	if !is_grounded:
		if velocity.y<0:
			new_anim = "jumping"
		else:
			new_anim = "falling"

	var motion = velocity * delta
	if motion != Vector2(0,0):
		motion = move( motion )
		
	if is_colliding():
		var normal = get_collision_normal()
		if normal.y < 0:
			if normal.y != -1:
				motion.y = 0
			else:
				is_grounded = true
				second_jump = false
			floor_velocity = get_collider_velocity()
		motion = normal.slide( motion ) 
		if motion != Vector2(0,0):
			move(motion)
		velocity = normal.slide( velocity )
	
	if (floor_velocity!=Vector2()):
		move(floor_velocity * delta)
		
	#	change siding
	if (new_siding_left!=siding_left):
		if (new_siding_left):			
			get_node("legs").set_scale( Vector2(-1,1) )
		else:
			get_node("legs").set_scale( Vector2(1,1) )
		siding_left=new_siding_left
		
	if look_left:
		get_node("main").set_scale( Vector2(-1,1) )
	else:
		get_node("main").set_scale( Vector2(1,1) )	

	if (new_anim !=anim):
		anim=new_anim
		anim_node.play(anim)

func apply_damage(var touch_pos, var touch_rot, var damage, var delay):
	particle.set_emitting(true)
	global.stats[0] -= damage
	if !dead and global.stats[0] <= 0:
		die()
		dead = true
	
func die():
	set_fixed_process(false)
	set_process(true)
	global.time_dilation(1)
	audio.play_sound("explosion_10")
	get_node("anim").play("die")
	global.show_effect(get_pos(), 2, 1)
	global.show_effect(get_pos(), 1, 1)
	get_node("game_over_timer").start()
	yield(get_node("game_over_timer"),"timeout")
	global.game_over_event()

func bind_keys():
	var keys_names = global.input_map
	key_left = keys_names[0]
	key_right = keys_names[1]
	key_jump = keys_names[2]
	key_run = keys_names[3]
	key_relkad = keys_names[4]
	key_use = keys_names[5]

func _ready():
	bind_keys()	
	anim_node.play(anim)
	set_fixed_process(true)
	set_process(true)	
	
func _init():
	Globals.set("PLAYER", self)




