extends Node2D

export (float) var visor_ratio = 1.0

signal get_firing
signal is_full
signal gain_new_bullet
signal interrupt_wave
signal move_visor

enum State {
	READY,
	FIRING,
	WAITING,
	INTERRUPTING,
	DEAD
}

export var BULLET_SPEED = 500.0

const visor_min_heigth = 10
const visor_start_shift = Vector2(0, -visor_min_heigth)

var _ballScene = preload("res://scenes/Ball.tscn")

var nbAmmo = 0
var nbStorage = 1

onready var target = $TargetLine
onready var visor = $TargetLine/TargetVisor
onready var source = $Source
onready var shootDelay = $ShootDelay
onready var grid = $Grid

onready var current_state = State.WAITING


func _ready():
	get_ready()


func _input(event):
	if event is InputEventMouseButton and event.is_pressed() :
		trigger(event.position)
	elif event is InputEventMouseMotion and current_state == State.READY:
		aim_at(event.position)


func aim_at(cursor:Vector2):
	var visor_pos = (cursor - source.position) * visor_ratio
	if abs(visor_pos.y) > visor_min_heigth:
		visor.position = visor_pos
		emit_signal("move_visor")


func trigger(aim:Vector2):
	if (current_state == State.READY):
		current_state = State.FIRING
		emit_signal("get_firing")
	elif (current_state == State.WAITING):
		current_state = State.INTERRUPTING
		emit_signal("interrupt_wave")


func shoot():
		var bullet = _ballScene.instance()
		bullet.position = source.position
		bullet.linear_velocity = (target.get_visor_pos() - source.position).normalized()
		bullet.linear_velocity *= BULLET_SPEED
		add_child(bullet)
		bullet.connect("tree_exited", self, "_on_Ball_tree_exited")
		bullet.connect("kace_contact", grid, "_on_Ball_kace_contact")
		self.connect("interrupt_wave", bullet, "_on_Launcher_interrupt_wave")


func gain_new_bullet():
	load_bullet(1)
	emit_signal("gain_new_bullet")


func load_bullet(n:int):
	nbStorage += n


func end_of_round():
	if (current_state != State.DEAD):
		get_ready()


func get_ready():
	current_state = State.READY
	target.set_visor_pos(source.position + visor_start_shift)
	nbAmmo = nbStorage
	nbStorage = 0


func die():
	current_state = State.DEAD


func _on_ShootDelay_timeout():
	shoot()
	nbAmmo -= 1
	if (nbAmmo == 0):
		current_state = State.WAITING
	else:
		emit_signal("get_firing")


func _on_Launcher_get_firing():
	shootDelay.start()


func _on_Ball_tree_exited():
	load_bullet(1)
	if (get_tree().get_nodes_in_group("ball").size() == 0):
		emit_signal("is_full")


func _on_Grid_has_moved():
	end_of_round()


func _on_Grid_kace_broken():
	gain_new_bullet()


func _on_DeadLine_game_lost():
	die()