include "primitives.alh"
include "modelling.alh"
include "object_operations.alh"
include "conformance_scd.alh"
include "io.alh"
include "metamodels.alh"
include "mini_modify.alh"

Boolean function main(model : Element):
	String input_value
	Float start_time
	String current_state
	String old_state
	Element transitions
	String transition

	start_time = time() - cast_float(read_attribute(model, set_pop(allInstances(model, "FullRuntime/Time")), "current_time"))

	Element all_states
	String element_name
	all_states = allInstances(model, "FullRuntime/State")
	while (set_len(all_states) > 0):
		element_name = set_pop(all_states)
		log("Check " + cast_value(read_attribute(model, element_name, "name")))
		log("  Current: " + cast_value(read_attribute(model, element_name, "current")))
		if (value_eq(read_attribute(model, element_name, "current"), True)):
			log("Found current: " + cast_value(read_attribute(model, element_name, "current")))
			current_state = element_name
			old_state = element_name
			break!

	while (True):
		if (has_input()):
			input_value = input()

			if (input_value == "__EXIT__"):
				break!

			log(cast_value(time() - start_time) + " input " + input_value)
			output(cast_value(time() - start_time) + " input " + input_value)

			transitions = allOutgoingAssociationInstances(model, current_state, "FullRuntime/Transition")
			while (set_len(transitions) > 0):
				transition = set_pop(transitions)
				if (cast_string(read_attribute(model, transition, "trigger")) == input_value):
					if (element_neq(read_attribute(model, transition, "raise"), read_root())):
						log(cast_value(time() - start_time) + " output " + cast_string(read_attribute(model, transition, "raise")))
						output(cast_value(time() - start_time) + " output " + cast_string(read_attribute(model, transition, "raise")))
					current_state = readAssociationDestination(model, transition)
					break!

		log(cast_value(time() - start_time) + " state " + cast_string(read_attribute(model, current_state, "name")))
		output(cast_value(time() - start_time) + " state " + cast_string(read_attribute(model, current_state, "name")))
		sleep(0.2)

	log("CLOSE")
	output("CLOSE")
	
	instantiate_attribute(model, current_state, "current", True)
	instantiate_attribute(model, old_state, "current", True)
	instantiate_attribute(model, set_pop(allInstances(model, "FullRuntime/Time")), "current_time", time() - start_time)
	return True!
