## SpellDeck — 运行时执行游标
## 权威来源：implementation_plan.md §2.2
extends RefCounted
class_name SpellDeck

var _nodes:  Array    = []  # Array[SpellNode]
var _cursor: int      = 0
var _consumed: PackedByteArray = PackedByteArray()  # 消费掩码（共鸣 consume_inputs，P6-N29）；1=跳过

func setup(nodes: Array, consumed_indices: Array = []) -> void:
	_nodes  = nodes
	_cursor = 0
	_consumed = PackedByteArray()
	_consumed.resize(_nodes.size())  # 全 0
	for idx in consumed_indices:
		if idx >= 0 and idx < _consumed.size():
			_consumed[idx] = int(1)

func has_next() -> bool:
	var c: int = _cursor
	while c < _nodes.size() and c < _consumed.size() and _consumed[c] != 0:
		c += 1
	return c < _nodes.size()

func pop() -> SpellNode:
	while _cursor < _nodes.size() and _cursor < _consumed.size() and _consumed[_cursor] != 0:
		_cursor += 1  # 跳过被共鸣消费的槽位
	if _cursor >= _nodes.size():
		return null
	var node: SpellNode = _nodes[_cursor]
	_cursor += 1
	return node

func peek() -> SpellNode:
	if _cursor >= _nodes.size():
		return null
	return _nodes[_cursor]

func reset_cursor() -> void:
	_cursor = 0

## 跳过直到遇到 SCOPE_CLOSE（深度计数器处理嵌套）
func skip_until_scope_end() -> void:
	var depth := 1
	while _cursor < _nodes.size():
		var n: SpellNode = _nodes[_cursor]
		_cursor += 1
		if n.type == SpellNode.SpellType.SCOPE_CLOSE:
			depth -= 1
			if depth <= 0:
				return
		elif n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
			depth += 1

## 将游标到下一个 SCOPE_CLOSE 之间的节点列表取出（用于打包 SubPayload）
func consume_until_scope_end() -> Array:
	var result: Array = []
	var depth := 1
	while _cursor < _nodes.size():
		var n: SpellNode = _nodes[_cursor]
		_cursor += 1
		if n.type == SpellNode.SpellType.SCOPE_CLOSE:
			depth -= 1
			if depth <= 0:
				break
			result.append(n)
		else:
			if n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
				depth += 1
			result.append(n)
	return result

func get_remaining_count() -> int:
	return _nodes.size() - _cursor
