class_name VNTextbox extends PanelContainer

const VN_REVEAL_TIME = 0.01

var label:AdvancedRichText;
var parsedOutText = ""
var revealTimer:float = 0;

var lineStarts:Array[int] = [];
var newlineIndexes:Array[int] = [];
var currentViewScrolled = true;
var isSpeedupDown = false;

var hasLetGoOfInteract:bool = true;

var isClosed:bool = false:
  get():
    return !self.visible;
  set(value):
    self.visible = !value;

signal textboxClosing

func _ready() -> void:
  label = $MarginContainer/Label
  isClosed = true

func _process(delta: float) -> void:
  if isClosed:
    return;

  if label.getFinalText() == "":
    isClosed = true;
    return;
  
  if Input.is_action_just_released("interact") && !hasLetGoOfInteract:
    hasLetGoOfInteract = true;
    return

  # Have we finished displaying the current page?
  if label.visible_characters >= label.getCharactersDisplayedCount():
    # Not finished displaying current page
    if (label.maxLines + label.startLine) < label.getTotalLineCount():
      if Input.is_action_just_pressed("interact") && hasLetGoOfInteract:
        label.startLine += label.maxLines;
        label.visible_characters = 0;
        currentViewScrolled = false;
        return

      currentViewScrolled = true;
    else:
      # On last page
      if Input.is_action_just_released("interact") && hasLetGoOfInteract:
        textboxClosing.emit();
        isClosed = true;
      currentViewScrolled = true
    return;

  # This prevents the game trying to advance if the player is still holding
  # down interact.
  if Input.is_action_just_pressed("interact") && hasLetGoOfInteract:
    isSpeedupDown = true;
  elif Input.is_action_just_released("interact") && hasLetGoOfInteract:
    isSpeedupDown = false;
  elif !Input.is_action_pressed("interact") && hasLetGoOfInteract:
    isSpeedupDown = false;

  revealTimer += delta;
  if isSpeedupDown:
    revealTimer += delta;

  if revealTimer > VN_REVEAL_TIME:
    revealTimer = 0;
    label.visible_characters += 1;

func setText(text:String) -> void:
  # Prepare textbox for scrolling

  # Resets scroll
  revealTimer = 0;
  currentViewScrolled = false;
  label.startLine = 0;

  # I had a frame wait here before.
  label.text = text;
  label.visible_characters = 0;

  # Resets speedup and advancing
  hasLetGoOfInteract = !Input.is_action_pressed("interact");
  isSpeedupDown = false
  isClosed = false;

func setTextAndWait(text:String) -> void:
  self.setText(text);
  await self.textboxClosing
  await get_tree().process_frame
