class_name Chicken
extends KinematicBody2D


enum State {IDLE, WALKING, ANGRY, RUNNING}

export var walk_linear_speed = 100
export var run_boost = 4
export var push_impulse = 150

var velocity = Vector2.ZERO

var _current_state = State.IDLE


func attack(from: Vector2, angle: float):
	position = from

	velocity = Vector2(walk_linear_speed, 0).rotated(angle)
	$AnimatedSprite.play("walk")
	_update_sprite_direction()

	_current_state = State.WALKING


func _physics_process(delta: float):
	var collision = _move(delta)
	_collide_and_react(collision)


func _on_VisibilityNotifier2D_screen_exited():
	_die()


func _on_Spawner_reset():
	_die()


func _on_AngryTimer_timeout():
	assert(_current_state == State.ANGRY)
	_start_running()


func _die():
	queue_free()


func _move(delta: float) -> KinematicCollision2D:
	if _current_state == State.WALKING or _current_state == State.RUNNING:
		return move_and_collide(velocity * delta, false)
	else:
		return move_and_collide(Vector2.ZERO, false)


func _collide_and_react(collision: KinematicCollision2D) -> void:
	if collision == null:
		return

	var collider = collision.get_collider()
	if collider is Node2D:
		var node_collider = collider as Node
		if _current_state == State.WALKING:
			if node_collider.is_in_group("chicken") and _facing_collider(collision.get_normal()):
				_turn_away()
			elif node_collider.is_in_group("wheel"):
				_get_angry()

	if collider is RigidBody2D:
		_push_away(collider as RigidBody2D, -collision.normal)


func _turn_away() -> void:
	velocity.x = -velocity.x
	_update_sprite_direction()


func _push_away(body: RigidBody2D, dir: Vector2) -> void:
	body.apply_central_impulse(dir * push_impulse)


func _get_angry() -> void:
	$AngryTimer.start()
	$AnimatedSprite.play("get_hit")
	_current_state = State.ANGRY


func _start_running() -> void:
	velocity *= run_boost
	$AnimatedSprite.play("run")
	_current_state = State.RUNNING


func _facing_collider(normal: Vector2) -> bool:
	return normal.x * velocity.normalized().x < -0.5


func _update_sprite_direction() -> void:
	$AnimatedSprite.flip_h = velocity.x < 0.0
