extends "../BaseEnemy.gd"

enum States { IDLE, ROAM, RETURN, SPOT, FOLLOW, STAGGER, ATTACK, ATTACK_COOLDOWN, DIE, DEAD}

export(float) var MAX_ROAM_SPEED = 100.0
export(float) var ROAM_RADIUS = 100.0

var roam_target_position = Vector2()
var roam_slow_radius = 0.0


func _ready():
	_change_state(States.IDLE)


func _physics_process(_delta):
	var current_state = state

	match current_state:
		
		States.IDLE:
			var distance_to_target = position.distance_to(target_position)
			if distance_to_target < SPOT_RANGE:
				if not has_target:
					return
				_change_state(States.FOLLOW)
			_animate()
		
		States.ROAM:
			velocity = arrive_to(velocity, roam_target_position, roam_slow_radius, MAX_ROAM_SPEED)
			move_and_slide(velocity)
			_animate(velocity)
			if position.distance_to(roam_target_position) < ARRIVE_DISTANCE:
				_change_state(States.IDLE)
			if position.distance_to(target_position) < SPOT_RANGE:
				if not has_target:
					return
				_change_state(States.FOLLOW)
		
		States.FOLLOW:
			velocity = follow(velocity, target_position, MAX_FOLLOW_SPEED)
			move_and_slide(velocity)
			
			if position.distance_to(target_position) > FOLLOW_RANGE:
				_change_state(States.RETURN)
			if position.distance_to(target_position) < ATTACK_RANGE:
				_change_state(States.ATTACK)
			_animate(velocity)
		States.RETURN:
			velocity = arrive_to(velocity, spawn_position, SLOW_RADIUS, MAX_ROAM_SPEED)
			move_and_slide(velocity)
			_animate(velocity)
			if position.distance_to(spawn_position) < ARRIVE_DISTANCE:
				_change_state(States.IDLE)
			if position.distance_to(target_position) < SPOT_RANGE:
				if not has_target:
					return
				_change_state(States.FOLLOW)


func _change_state(new_state):
	match state:
		States.IDLE:
			$Timer.stop()
		States.RETURN:
			$RayCast2D.visible = false
		States.FOLLOW:
			$RayCast2D.visible = false
	
	
		
	match new_state:
		States.IDLE:
			randomize()
			var random_time = randf() * 2.0 + 1.0
			$Timer.wait_time = random_time
			$Timer.start()
		States.ROAM:
			randomize()
			var random_angle = randf() * PI * 2
			randomize()
			var random_radius = randf() * ROAM_RADIUS * 0.5 + 0.5 * ROAM_RADIUS
			#print ("roam radius: %s" % random_radius)
			roam_target_position = spawn_position + Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius)
			roam_slow_radius = spawn_position.distance_to(roam_target_position) / 2
			#print ("roam distance: %s" % position.distance_to(roam_target_position))
		States.RETURN:
			$RayCast2D.visible = true
		States.FOLLOW:
			$RayCast2D.visible = true
	state = new_state


func _on_Timer_timeout():
	if state == States.DIE or state == States.DEAD:
		return
	_change_state(States.ROAM)


func _on_target_died():
	if state == States.DIE or state == States.DEAD:
		return
	target_position = Vector2()
	has_target = false
	
	_change_state(States.DIE)
	_animate()
	$CollisionShape2D.set_deferred("disabled", true)
	#$Health.take_damage(1)


func _animate(direction = Vector2()):
	match state:
		States.IDLE:
			#animationTree.set("parameters/Idle/blend_position", direction)
			animationState.travel("Idle")
		States.RETURN, States.FOLLOW, States.ROAM:
			animationTree.set("parameters/Walk/blend_position", direction)
			animationTree.set("parameters/Idle/blend_position", direction)
			animationTree.set("parameters/Death/blend_position", direction)
			animationState.travel("Walk")
		States.ATTACK:
			animationTree.set("parameters/Attack/blend_position", direction)
			animationState.travel("Attack")
		States.DIE:
			animationState.travel("Death")
			_change_state(States.DEAD)


func attack_animation_finished():
	if state == States.DIE or state == States.DEAD:
		return
	_change_state(States.IDLE)
