@tool
class_name TextTerminal extends Node3D
## An in-game terminal that can display diegetic text

const CHAR_LIMIT := 34
const LINE_LIMIT := 11

@export var char_speed := 0.01
@export var cursor_sym := "_"
@export var cursor_blink_speed := 0.4
@export_multiline var text: String:
	set = _set_text

var _text_buffer: String

var _text_out: String:
	set(value):
		_text_out = value
		_update_label()

var _cursor_on := false:
	set(value):
		_cursor_on = value
		_update_label()

@onready var label_3d: Label3D = %Label3D
@onready var output_interval: Timer = %OutputInterval
@onready var cursor_blinker: Timer = %CursorBlinker


func _ready() -> void:
	cursor_blinker.start(cursor_blink_speed)

	if text:
		_set_text(text)


func _update_label() -> void:
	label_3d.text = _text_out
	if _cursor_on:
		label_3d.text += cursor_sym


func _set_text(value: String) -> void:
	text = value
	_text_out = ""
	_text_buffer = text
	if _text_buffer:
		output_interval.start(char_speed)


func _blink_cursor() -> void:
	_cursor_on = not _cursor_on
	cursor_blinker.start(cursor_blink_speed)


func _show_next_char() -> void:
	var head := _text_buffer[0]
	_text_out += head
	_text_buffer = _text_buffer.substr(1)
	if _text_buffer:
		output_interval.start(char_speed)
