<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://sarasvati.googlecode.com/ProcessDefinition"
 targetNamespace="http://sarasvati.googlecode.com/ProcessDefinition"
 elementFormDefault="qualified">

    <xs:element name="process-definition">
      <xs:complexType>

        <xs:annotation>
          <xs:documentation>
            A process definition consists of a unique name and a set of nodes.
            The nodes are connected via arcs.
          </xs:documentation>
        </xs:annotation>

        <xs:sequence>
          <xs:element name="custom" minOccurs="0" maxOccurs="1">
            <xs:complexType>
              <xs:sequence>
                <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>

          <xs:element name="node" type="Node" minOccurs="1" maxOccurs="unbounded" >
            <xs:annotation>
              <xs:documentation>
                Every process definition must have at least one
                node. If a process definition contains no nodes
                with the isStart attribute set to true, it can
                not be run on it's own. This is still valid
                however, since it could be referenced from
                another process definition.
              </xs:documentation>
            </xs:annotation>
          </xs:element>

          <xs:element name="external" type="External" minOccurs="0" maxOccurs="unbounded" >
            <xs:annotation>
              <xs:documentation>
                Every process definition may contain contain zero or more
                references to external process definitions.
              </xs:documentation>
            </xs:annotation>
          </xs:element>

        </xs:sequence>

        <xs:attribute name="name" type="xs:string" use="required">
          <xs:annotation>
            <xs:documentation>
              Every process definition must have a unique name.
            </xs:documentation>
          </xs:annotation>
        </xs:attribute>

      </xs:complexType>

    </xs:element>


    <xs:complexType name="Node">

      <xs:sequence>
        <xs:element name="join" type="Join" minOccurs="0" maxOccurs="1" />
        <xs:element name="guard" type="Guard" minOccurs="0" maxOccurs="1" />
        <xs:element name="arc" type="Arc" minOccurs="0" maxOccurs="unbounded" />

        <xs:element name="custom" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>

      <xs:attribute name="name" type="xs:string" use="required">
        <xs:annotation>
          <xs:documentation>
            Node names must be unique within a given process definition.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="joinType"
                    type="JoinType"
                    use="optional"
                    default="or"/>

      <xs:attribute name="joinParam" type="xs:string" use="optional">
        <xs:annotation>
          <xs:documentation>

          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="type"
                    type="xs:string"
                    use="optional"/>

      <xs:attribute name="isStart"
                    type="xs:boolean"
                    use="optional"
                    default="false">
        <xs:annotation>
          <xs:documentation>
            If isStart is set to true, this node will have a token
            placed in it. Guard functions will still be called for
            start nodes.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="x"
                    type="xs:int"
                    use="optional"/>

      <xs:attribute name="y"
                    type="xs:int"
                    use="optional"/>

    </xs:complexType>

    <xs:complexType name="External">
      <xs:sequence>
        <xs:element name="arc" type="ExternalArc" minOccurs="0" maxOccurs="unbounded" />

        <xs:element name="custom" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>


      <xs:attribute name="name" type="xs:string" use="required">
        <xs:annotation>
          <xs:documentation>
            Since it may be desirable to include the same external process definition
            more than once, each external must define a name which must be unique in
            the process definition.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="processDefinition" type="xs:string" use="required">
        <xs:annotation>
          <xs:documentation>
            Must refer to a valid process definition name.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="x"
                    type="xs:int"
                    use="optional"/>

      <xs:attribute name="y"
                    type="xs:int"
                    use="optional"/>


    </xs:complexType>

    <xs:simpleType name="Guard">
        <xs:annotation>
          <xs:documentation>
            Contains a GuardLang statement
          </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
        <xs:whiteSpace value="collapse"></xs:whiteSpace>
      </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="Join">
        <xs:annotation>
          <xs:documentation>
            Join strategies may require additional information, which can be provided in the join parameter.
            This may include things like a token set name or a JoinLang program
          </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
        <xs:whiteSpace value="collapse"></xs:whiteSpace>
      </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="Arc">
      <xs:attribute name="external" type="xs:string" use="optional" default=""/>
      <xs:attribute name="to" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="optional" default=""/>
    </xs:complexType>

    <xs:complexType name="ExternalArc">

      <xs:attribute name="from" type="xs:string" use="required" >
        <xs:annotation>
          <xs:documentation>
            Name of the node in the this external process
            definition that this arc will start from
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="external" type="xs:string" use="optional" default="">
        <xs:annotation>
          <xs:documentation>
            Specifies the instance name of the external process definition that is
            being linked to. The latest version of the external process definition
            will be used. If this is not specified, it is assumed that we are linking
            to a node in the surrounding process definition.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="to" type="xs:string" use="required" >
        <xs:annotation>
          <xs:documentation>
            Name of the node in the specified external process
            definition that this arc will connect to
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

      <xs:attribute name="name" type="xs:string" use="optional" default="" >
        <xs:annotation>
          <xs:documentation>
            The arc name. Does not need to be unique. Arcs with the same name
            are considered to be part of a set.
          </xs:documentation>
        </xs:annotation>
      </xs:attribute>

    </xs:complexType>

    <xs:simpleType name="JoinType">
      <xs:restriction base="xs:string">
        <xs:enumeration value="or"/>
        <xs:enumeration value="and"/>
        <xs:enumeration value="labelAnd"/>
        <xs:enumeration value="tokenSet"/>
        <xs:enumeration value="tokenSetOr"/>
        <xs:enumeration value="class"/>
        <xs:enumeration value="first"/>
        <xs:enumeration value="joinlang"/>
      </xs:restriction>
    </xs:simpleType>

</xs:schema>