# TypewriterLogic.gd
# 一个辅助类，用于为 Label 节点提供打字机效果逻辑。
# 它本身不是一个 Node。

class_name TypewriterLogic # 使用 class_name 使其可以在其他脚本中按类型提示引用

# --- 信号 ---
signal finished # 当打字动画自然完成时，或在start_typing中因文本为空/速度无效而立即完成时发出

# --- 属性 ---
var target_label: Label     # 要应用效果的目标 Label 节点
var typing_speed: float = 20.0 # 每秒显示的字符数
var current_tween: Tween = null # 当前活动的 Tween 动画
var _is_typing: bool = false   # 内部状态：是否正在打字

# --- 构造函数 ---
# 初始化时必须传入目标 Label 节点
func _init(p_target_label: Label, p_typing_speed: float = 20.0):
	if not is_instance_valid(p_target_label):
		printerr("TypewriterLogic: Invalid target Label provided during initialization.")
		# 可以选择在这里 queue_free() 自身或抛出错误，但作为辅助类，打印错误通常足够
		return 
	
	target_label = p_target_label
	typing_speed = p_typing_speed
	print("TypewriterLogic initialized for Label: ", target_label.name if is_instance_valid(target_label) else "INVALID_LABEL")


# --- 公共方法 ---

# 开始显示指定的文本
func start_typing(full_text: String):
	if not is_instance_valid(target_label):
		printerr("TypewriterLogic: Target Label is not valid.")
		return

	# 1. 停止可能正在进行的旧动画
	stop_typing() # 调用 stop_typing 来清理旧的 tween

	# 2. 设置完整文本，但可见字符为0
	target_label.text = full_text
	target_label.visible_characters = 0
	
	# 3. 如果文本为空或速度<=0，则直接显示完成，不创建动画
	if full_text.length() == 0 or typing_speed <= 0:
		if is_instance_valid(target_label):
			target_label.visible_characters = full_text.length() # 直接显示全部
		_is_typing = false
		finished.emit() # 即使没有动画，也视为完成
		print("TypewriterLogic: Text is empty or speed is non-positive. Displaying all and emitting finished.")
		return

	# 4. 设置标记，表示正在打字
	_is_typing = true

	# 5. 创建新的Tween动画 (使用 Label 节点作为 Tween 的宿主)
	#    注意：Tween 需要一个 Node 来运行，我们使用 target_label 本身
	#    确保 target_label 仍然有效才创建 Tween
	if not is_instance_valid(target_label): # 再次检查，以防在 stop_typing 后 target_label 失效
		printerr("TypewriterLogic: Target Label became invalid before Tween creation.")
		_is_typing = false
		return
		
	current_tween = target_label.create_tween() 
	
	# 6. 绑定动画完成信号到内部处理函数
	#    使用 bind() 来确保 _on_typing_finished 被这个实例调用
	#    Callable(self, "_on_typing_finished") 是更现代的写法
	current_tween.finished.connect(Callable(self, "_on_typing_finished")) 

	# 7. 计算动画时长
	var duration = float(full_text.length()) / typing_speed

	# 8. 设置动画属性：让 visible_characters 从 0 变到 full_text.length()
	current_tween.tween_property(target_label, "visible_characters", full_text.length(), duration)

	# 9. 设置动画过渡类型为线性（匀速）
	current_tween.set_trans(Tween.TRANS_LINEAR)
	
	print("TypewriterLogic: Started typing on Label '", target_label.name, "' with text: ", full_text)


# 跳过当前的打字动画，立即显示全部文本
func skip_typing():
	if not _is_typing: # 如果没有在打字，则什么也不做
		return
		
	if not is_instance_valid(target_label):
		printerr("TypewriterLogic: Target Label is not valid for skip_typing.")
		_is_typing = false # 确保状态更新
		if current_tween != null and current_tween.is_valid(): # 尝试清理 tween
			current_tween.kill()
		current_tween = null
		return

	if current_tween != null and current_tween.is_valid():
		current_tween.kill() # 停止动画
		current_tween = null
	
	target_label.visible_characters = target_label.text.length() # 显示全部字符
	_is_typing = false # 更新状态
	# 注意：跳过时通常不发出 finished 信号，因为这不是自然完成
	# 如果需要在跳过时也认为“完成”，调用方应在调用 skip_typing() 后手动处理，
	# 或在此处添加 finished.emit() 并明确其行为。
	print("TypewriterLogic: Skipped typing on Label '", target_label.name, "'")


# 停止当前的打字动画 (例如，对话框提前关闭)
func stop_typing():
	# 即使 Label 无效，也要尝试清理 _is_typing 和 current_tween
	if current_tween != null and current_tween.is_valid():
		current_tween.kill() # 停止动画
	current_tween = null
	_is_typing = false # 确保状态被重置
	
	if is_instance_valid(target_label):
		print("TypewriterLogic: Stopped typing on Label '", target_label.name, "'")
	else:
		print("TypewriterLogic: Stopped typing (target Label was invalid).")


# 返回当前是否正在进行打字动画
func is_typing() -> bool:
	return _is_typing


# --- 内部回调函数 ---

# 当 Tween 动画自然完成时调用
func _on_typing_finished():
	_is_typing = false
	current_tween = null # 清理 Tween 引用
	if is_instance_valid(target_label):
		print("TypewriterLogic: Typing finished naturally on Label '", target_label.name, "'")
	else:
		print("TypewriterLogic: Typing finished naturally (target Label was invalid).")
	finished.emit() # 发出完成信号
