class_name FootstepComponent
extends Node

signal footstep_occured

@export var step_measure: float = 1.25
@export var character: CharacterBody3D
@export_node_path("AudioStreamPlayer", "AudioStreamPlayer2D", "AudioStreamPlayer3D")
var audio_player: NodePath: set = set_audio_player

var _distance_traveled: float = 0.0
var _was_in_air: bool = false
var _audio_player: Node


func _ready() -> void:
	set_audio_player(audio_player)


func _physics_process(delta: float) -> void:
	if not is_instance_valid(character) or audio_player.is_empty():
		return

	var on_floor: bool = character.is_on_floor()

	if on_floor:
		if _was_in_air:
			# We landed. Play a footstep.
			play_footstep()
			_distance_traveled = 0.0

		var velocity: Vector3 = character.velocity * Utils.VEC3_HOR

		if velocity.is_zero_approx():
			_distance_traveled = 0.0
		else:
			_distance_traveled += velocity.length() * delta

	if _distance_traveled >= step_measure:
		_distance_traveled = 0.0
		play_footstep()

	_was_in_air = not on_floor


func play_footstep() -> void:
	footstep_occured.emit()

	if is_instance_valid(_audio_player) and _audio_player.has_method(&"play"):
		_audio_player.play()


func set_audio_player(new_player_path: NodePath) -> void:
	audio_player = new_player_path

	var player: Node = get_node_or_null(new_player_path)
	_audio_player = player if Utils.is_node_audioplayer(player) else null
