extends Node2D
class_name PlayerSprite

# Signals
signal DrawingBowAnimationFinished
signal FiringArrowAnimationFinished
signal AnimationFinished(animation_name: String)

# Exports
@export var state_machine: PlayerStateMachine
@export var direction_component: FacingDirectionComponent

# OnReady Variables
@onready var full: AnimatedSprite2D = $Full

# Private Variables
var _all_parts: Array[AnimatedSprite2D]
var _current_animation := "idle-down"
var _is_flipped := false

# Public Methods
func UpdateSprite() -> void:
	var current_state := state_machine.current_state
	var current_direction := direction_component.GetCurrentDirection()
	var animation := _build_animation_name(current_state, current_direction)
	var should_flip := _should_flip_horizontal()
	
	if animation == _current_animation and should_flip == _is_flipped:
		return
	
	_current_animation = animation
	_is_flipped = should_flip
	
	for part in _all_parts:
		part.animation = animation
		part.play()
		part.flip_h = should_flip


func OnAnimationFinished() -> void:
	if _current_animation.begins_with("drawing-bow-"):
		DrawingBowAnimationFinished.emit()
	elif _current_animation.begins_with("firing-arrow-"):
		FiringArrowAnimationFinished.emit()
	AnimationFinished.emit(_current_animation)


func PlaySpecifiedAnimation(animation_name: String) -> void:
	_current_animation = animation_name
	for part in _all_parts:
		part.animation = animation_name
		part.play()


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	_all_parts = [
		full
	]
	
	UpdateSprite()


func _build_animation_name(state: BaseState, direction: Enums.Directions) -> String:
	# e.g. "idle-down", "walking-up"
	var state_str := state.GetAnimationBaseName().replace("_", "-")
	var direction_str := _direction_to_animation_state(direction)
	return "%s-%s" % [state_str, direction_str]


func _direction_to_animation_state(direction: Enums.Directions) -> String:
	if direction == Enums.Directions.LEFT or direction == Enums.Directions.RIGHT:
		return "side"
	return Enums.Directions.keys()[direction].to_lower()


func _should_flip_horizontal() -> bool:
	return direction_component.GetCurrentDirection() == Enums.Directions.LEFT
