#@tool
#@icon(icon_path: String)
class_name Musician
extends AnimatedSprite2D
## Documentation comments

#signal
#enum
#const

#@export_group("Input Textures")
#@export var solid_texture: Texture2D
#@export var outline_texture: Texture2D

@export var song_tempo: int = 120

@export_enum("whole:4", "half:2", "quarter:1") var boost_note_type: int
@export_enum("sample", "viol", "cello", "bass", "execute") var input_action: String

var beat_count: int = 0
var decay_length: float
var decay_rate: float
var is_playing_music: bool = false
var is_boosted: bool
var is_over_boosted: bool = false
var seconds_per_beat: float
var useconds_per_beat: int

@onready var audio: AudioStreamPlayer2D = %Audio
@onready var light: PointLight2D = %Light
@onready var occluder: LightOccluder2D = %Occluder
@onready var input_prompt: Sprite2D = %InputPrompt
@onready var volume_bar: ProgressBar = %VolumeBar
@onready var beat_timer: Timer = %BeatTimer
@onready var boost_timer: Timer = %BoostTimer
@onready var beat_particles: CPUParticles2D = $BeatParticles

## OVERRIDES

func _ready() -> void:
	light.visible = false
	_connect_signals()
	#input_prompt.texture = outline_texture
	seconds_per_beat = 60.0/float(song_tempo)
	beat_timer.wait_time = seconds_per_beat
	decay_length = boost_note_type * seconds_per_beat
	print("this musician's boosts will last %s seconds" % decay_length)
	boost_timer.wait_time = decay_length
	decay_rate = 80.0 / decay_length
	print("so the volume will drop by %s db per second" % decay_rate)

func _process(delta: float) -> void:
	if is_over_boosted:
		distort_pitch()
	if is_playing_music and not is_boosted:
		drop_volume(decay_rate * delta)
	volume_bar.value = audio.volume_db

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("play_pause"):
		play_pause()
	if event.is_action_pressed(input_action):
		boost_volume()

## CORE
func boost_volume() -> void:
	if is_boosted:
		is_over_boosted = true
	audio.volume_db = 0.0
	is_boosted = true
	boost_timer.start()

func distort_pitch() -> void:
	audio.pitch_scale += randf_range(-0.001, 0.0001)

func drop_volume(d_r: float) -> void:
	audio.volume_db -= d_r

func play_pause() -> void:
	if not is_playing_music:
		_play()
	else:
		_pause()

## PRIVATE/HELPER

func _connect_signals() -> void:
	boost_timer.connect("timeout", on_boost_timer_timeout)
	audio.connect("finished", play_pause)
	beat_timer.connect("timeout", on_beat_timer_timeout)

func _play() -> void:
	play("default")
	audio.play()
	beat_timer.start()
	if not is_boosted:
		is_boosted = true
		boost_timer.start()
	light.visible = true
	is_playing_music = true

func _pause() -> void:
	play("idle")
	audio.stop()
	beat_timer.stop()
	light.visible = false
	is_playing_music = false

## RECEIVERS

func on_beat_timer_timeout() -> void:
	beat_count += 1
	if beat_count % 4 == 0:
		beat_particles.color = Color.RED
		beat_particles.amount = 24
		beat_particles.lifetime = 0.2
	else:
		beat_particles.color = Color.WHITE
		beat_particles.amount = 8
		beat_particles.lifetime = 0.15
	beat_particles.restart()

func on_boost_timer_timeout() -> void:
	print("boost over")
	boost_timer.stop()
	is_boosted = false
	is_over_boosted = false
	audio.pitch_scale = 1.0

## SETTERS/GETTERS
