extends Node

var YarnScript = preload("yarn_script.gd")

export (Resource) var yarnScript

var say_func : FuncRef = null
var choices_func : FuncRef = null

func run_all():
	var next_node = yarnScript.nodes["Start"]
	while next_node != null:
		print("-> Jump to " + next_node["title"])
		var next_node_key = yield(run_body(next_node["body"]), "completed")
		if (yarnScript.nodes.has(next_node_key)):
			next_node = yarnScript.nodes[next_node_key]
		else:
			next_node = null

func run_body(body):
	for element in body:
		if element["type"] == "jump":
			return element["node"]
		elif element["type"] == "choice_blocks":
			var block = yield(decide_choice_block(element["blocks"]), "completed")
			print(block)
			return block["node"] # todo change later with "-> choices"
		elif element["type"] == "condition_blocks":
			var block = decide_condition_block(element["blocks"])
			var next_node_key = yield(run_body(block["body"]), "completed")
			if next_node_key != "":
				return next_node_key
		else:
			if say_func == null or !say_func.is_valid():
				print(element)
			else:
				yield(say_func.call_func(element), "completed")
	return ""

func decide_choice_block(blocks):
	if choices_func == null or !choices_func.is_valid():
		return blocks[0]
	else:
		return yield(choices_func.call_func(blocks), "completed")

func decide_condition_block(blocks):
	for block in blocks:
		var expr := Expression.new()
		var err := expr.parse(block["condition"])
		
		if err == OK and expr.execute():
			return block
	return null
