A Godot v4 game about working in an office
extends Control
class_name DialogBox


var dialog: Array
var dialog_index := 0
var finished_line := false
var is_active := false
var letters_per_second = 16

var typing_tween: Tween

@onready var window: NinePatchRect = $Window
@onready var content: RichTextLabel = $Window/Content

signal line_finished(index)
signal dialog_finished
signal dialog_hidden

func _ready() -> void:
	window.size.y = 0
	window.position.x = 2000
	content.text = ""

func initialize(dialog_lines: Array):
	print("Initializing dialog box with lines: %s" % dialog_lines)
	content.text = ""
	window.size.y = 0
	window.position.x = 2000
	dialog = dialog_lines.duplicate()
	dialog_index = 0
	finished_line = false
	$Window/Next/NextIndicator.visible = false
	
	var move_tween = get_tree().create_tween()
	move_tween.tween_property(window, "position", Vector2(0, 0), 0.5).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
	var scale_tween = get_tree().create_tween()
	scale_tween.tween_property(window, "size", Vector2(window.size.x, 75), 0.5).set_trans(Tween.TRANS_CUBIC).set_delay(0.25)
	await scale_tween.finished
	
	is_active = true
	
	next_line()


func next_line():
	if dialog_index < dialog.size():
		finished_line = false
		content.text = dialog[dialog_index]
		content.visible_characters = 0
		typing_tween = get_tree().create_tween()
		var duration = dialog[dialog_index].length() / letters_per_second
		typing_tween.tween_property(content, "visible_characters", dialog[dialog_index].length(), duration).set_trans(Tween.TRANS_LINEAR)
		await typing_tween.finished
		line_finished.emit(dialog_index)
		finished_line = true
	else:
		# Box go bye bye
		is_active = false
		dialog_finished.emit()
		var scale_tween = get_tree().create_tween()
		scale_tween.tween_property(window, "size", Vector2(window.size.x, 14), 0.5).set_trans(Tween.TRANS_CUBIC)
		var move_tween = get_tree().create_tween()
		move_tween.tween_property(window, "position", Vector2(2000, 0), 0.5).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN).set_delay(0.25)
		await move_tween.finished
		dialog_hidden.emit()
	dialog_index += 1
		
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if !is_active:
		return
	$Window/Next/NextIndicator.visible = finished_line
	if Input.is_action_just_pressed('select'):
		if finished_line:
			next_line()
		else:
			print("Immediately finishing line... (%s)" % content.text)
			typing_tween.finished.emit()
			typing_tween.kill()
			content.visible_characters = content.text.length()