class_name ShotHUD extends Control
## HUD for main gameplay loop

## Scale factor for the life bar rumble intensity on taking damage
const LIFE_BAR_DAMAGE_RUMBLE_SCALE := 0.2
## Time it takes to dampen the life bar rumble on taking damage, in seconds
const LIFE_BAR_DAMAGE_RUMBLE_TIME := 0.2

var _life_signal: Signal

@onready var power_bar: TextureProgressBar = %PowerBar
@onready var curve_bar: ProgressBar = %CurveBar
@onready var life_bar: TextureProgressBar = %LifeBar

@onready var club_selector: ClubSelector = %ClubSelector

@onready var hud_state_machine: AnimationTree = %HUDStateMachine

@onready var _curve_animation: AnimationPlayer = %CurveAnimation
@onready var _power_animation: AnimationPlayer = %PowerAnimation

@onready var _nice_animation: AnimationPlayer = %NiceAnimation
@onready var _wasted_animation: AnimationPlayer = %WastedAnimation

@onready var _player_name: Label = %PlayerName

@onready var _life_bar_rumbler: Rumbler = %LifeBarRumbler

@onready var _state: AnimationNodeStateMachinePlayback = hud_state_machine["parameters/playback"]


## Set any HUD state specific to the player.
func set_state_for_player(player: WorldPlayer) -> void:
	print_debug("Setting HUD for player ", player.name)
	club_selector.set_state_for_player(player)
	_player_name.text = player.name
	# TODO animate on life loss?
	life_bar.value = player.life
	life_bar.tint_progress = player.color

	# TODO this is soooooo wack...
	# TODO we should just revert to having distinct ShotHUDs for each player
	if _life_signal and _life_signal.is_connected(set_life_value):
		_life_signal.disconnect(set_life_value)
	_life_signal = player.on_life_changed
	_life_signal.connect(set_life_value)

	# TODO special equipment
	# TODO abilities


func show_hud() -> void:
	_state.travel("visible")


func hide_hud() -> void:
	_state.travel("hidden")


func start_power_bar() -> void:
	_power_animation.play("fill")


func stop_power_bar() -> void:
	_power_animation.pause()


func reset_power_bar() -> void:
	_power_animation.stop()


func start_curve_bar() -> void:
	_curve_animation.play("fill")


func stop_curve_bar() -> void:
	_curve_animation.pause()


func reset_curve_bar() -> void:
	_curve_animation.stop()


func play_nice_animation() -> void:
	_nice_animation.play("display")


func play_wasted_animation() -> void:
	_wasted_animation.play("display")


## Set the value of the life bar, potentially playing some kind of effect in response.
##
## To set the life bar without triggering an effect, set it directly with `life_bar.value`
func set_life_value(new_value: float) -> void:
	var difference := new_value - life_bar.value
	if difference < 0:
		# Taking damage
		_life_bar_rumbler.intensity = LIFE_BAR_DAMAGE_RUMBLE_SCALE * abs(difference)
		var tween := get_tree().create_tween()
		(
			tween
			. tween_property(_life_bar_rumbler, "intensity", 0, LIFE_BAR_DAMAGE_RUMBLE_TIME)
			. set_trans(Tween.TRANS_CUBIC)
		)
	elif difference > 0:
		# Restoring health
		# TODO: something for this?
		pass
	life_bar.value = new_value
