include "primitives.alh"
include "modelling.alh"
include "object_operations.alh"
include "conformance_scd.alh"

Boolean function main(model : Element):
    Element rules
    String rule
	String file
	String content

    rules = allInstances(model, "Rules/Rule")
    while (set_len(rules) > 0):
        rule = set_pop(rules)
        content = print_rule(model, rule)

		file = instantiate_node(model, "Files/File", "")
		instantiate_attribute(model, file, "name", rule + ".dot")
		instantiate_attribute(model, file, "content", content)

    return True!

String function print_rule(model : Element, rule : String):
    String text
    String type
    text = ""

    // Preamble
    text = text + "digraph {\n"
    text = text + "\tnode [shape=\"point\"]\n"

    // First go through the list of all entries in the rule
    Element nodes
    Element edges
    nodes = set_create()
    edges = set_create()

    Element all
    String el
    all = allAssociationDestinations(model, rule, "Rules/contains")
    while (set_len(all) > 0):
        el = set_pop(all)
        if (is_nominal_instance(model, el, "Rules/Edge")):
            // Is an edge
            set_add(edges, el)
        else:
            // Only a node
            set_add(nodes, el)

    // Print out all the nodes in the rule
    String node
    while (set_len(nodes) > 0):
        node = set_pop(nodes)
        text = text + "\t" + string_replace(node, "/", "_") + "["

        // Try to add value
        if (element_neq(read_attribute(model, node, "value"), read_root())):
            // Has a value, so add a label and make it oval
            text = text + "shape=\"oval\", label=\"" + cast_string(read_attribute(model, node, "value")) + "\", "

        // Add style
        type = read_type(model, node)
        if (type == "Rules/Match"):
            text = text + "color=\"black\""
        elif (type == "Rules/Root"):
            text = text + "color=\"black\""
        elif (type == "Rules/Create"):
            text = text + "color=\"green\""
        elif (type == "Rules/Delete"):
            text = text + "color=\"blue\""
        elif (type == "Rules/NAC"):
            text = text + "color=\"red\""

        text = text + "]\n"

    // Print out all the edges in the rule
    String edge
    String style
	String source
	String destination
    while (set_len(edges) > 0):
        edge = set_pop(edges)

        type = read_type(model, edge)
        if (type == "Rules/MatchEdge"):
            style = "color=\"black\""
        elif (type == "Rules/CreateEdge"):
            style = "color=\"green\", penwidth=4"
        elif (type == "Rules/DeleteEdge"):
            style = "color=\"blue\", style=\"dashed\""
        elif (type == "Rules/NACEdge"):
            style = "color=\"red\", style=\"dotted\""

        // Try to add value
		source = string_replace(readAssociationSource(model, edge), "/", "_")
		destination = string_replace(readAssociationDestination(model, edge), "/", "_")

        if (element_neq(read_attribute(model, edge, "value"), read_root())):
            // Has a value, so add a label
            text = text + "\t" + source + " -> " + destination + "["
            text = text + style + ", label=\"" + cast_string(read_attribute(model, edge, "value")) + "\"]\n"
        elif (set_len(allOutgoingAssociationInstances(model, edge, "")) > 0):
            // Has no value, and we have outgoing edges ourself, so we should have an edge handle
            text = text + "\t" + string_replace(edge, "/", "_") + "[width=0]\n"
            text = text + "\t" + source + " -> " + string_replace(edge, "/", "_") + "[" + style + ", arrowhead=\"none\"]"
            text = text + "\t" + string_replace(edge, "/", "_") + " -> " + destination + "[" + style + "]\n"
        else:
            // Has no value, meaning that we are referring to an intermediate edge...
            text = text + "\t" + source + " -> " + destination + "[" + style + "]\n"

    // Close everything
    text = text + "}"

    return text!
