include "modelling.alh"
include "primitives.alh"
include "object_operations.alh"
include "model_management.alh"

String function JSON_print(model : Element):
	String result
	Element keys_m
	String v_m
	String type
	String attr_key
	Element attr_keys
	Boolean first
	Element attr_value

	result = "["
	keys_m = dict_keys(model["model"])
	first = True

	while (set_len(keys_m) > 0):
		v_m = set_pop(keys_m)
		type = read_type(model["metamodel"], read_type(model, v_m))

		if (bool_or(type == "Class", type == "Association")):
			if (bool_not(first)):
				result = result + ","
			else:
				first = False

			result = result + "{"
			result = result + "\"id\": \"" + v_m + "\""
			result = result + "," + "\"type\": \"" + read_type(model, v_m) + "\""
			if (type == "Association"):
				result = result + ", \"__source\": \"" + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m])) + "\""
				result = result + ", \"__target\": \"" + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m])) + "\""

			// Has attributes
			attr_keys = dict_keys(getAttributeList(model, v_m))
			while (0 < set_len(attr_keys)):
				attr_key = set_pop(attr_keys)
				attr_value = read_attribute(model, v_m, attr_key)
				if (element_eq(attr_value, read_root())):
					result = result + ", \"" + attr_key + "\": null"
				else:
					if (is_physical_boolean(attr_value)):
						if (attr_value):
							result = result + ", \"" + attr_key + "\": true"
						else:
							result = result + ", \"" + attr_key + "\": false"
					else:
						result = result + ", \"" + attr_key + "\": " + cast_value(attr_value)

			result = result + "}"
	result = result + "]"
	return result!

Element function list_reverse(lst : Element):
	Element result
	result = list_create()

	Integer i
	i = list_len(lst) - 1
	while (i >= 0):
		list_append(result, list_read(lst, i))
		i = i - 1

	return result!

Element function list_splice(lst : Element, start : Integer, end : Integer):
	Element result
	result = list_create()

	Integer i
	i = start
	while (i < end):
		list_append(result, list_read(lst, i))
		i = i + 1

	return result!

Void function list_extend(lst : Element, ext : Element):
	Integer i
	i = 0

	while (i < list_len(ext)):
		list_append(lst, list_read(ext, i))
		i = i + 1

	return!

String function get_taskname():
	return reverseKeyLookup(read_root(), read_taskroot())!

Element function string_split_nr(str : String, split : String, count : Integer):
	Element splitted
	String new

	splitted = string_split(str, split)
	count = count + 1

	while (list_len(splitted) > count):
		new = split + cast_string(list_pop_final(splitted))
		new = cast_string(list_pop_final(splitted)) + new
		list_append(splitted, new)

	return splitted!

Element function alphabet():
	Element chars
	chars = list_create()
	list_append(chars, "a")
	list_append(chars, "b")
	list_append(chars, "c")
	list_append(chars, "d")
	list_append(chars, "e")
	list_append(chars, "f")
	list_append(chars, "g")
	list_append(chars, "h")
	list_append(chars, "i")
	list_append(chars, "j")
	list_append(chars, "k")
	list_append(chars, "l")
	list_append(chars, "m")
	list_append(chars, "n")
	list_append(chars, "o")
	list_append(chars, "p")
	list_append(chars, "q")
	list_append(chars, "s")
	list_append(chars, "t")
	list_append(chars, "u")
	list_append(chars, "v")
	list_append(chars, "w")
	list_append(chars, "x")
	list_append(chars, "y")
	list_append(chars, "z")
	return chars!
