<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<!-- the flexsim-tree element is the root node of the xml document. --> 
	<xs:element name="flexsim-tree">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="node" maxOccurs="unbounded"/>
			</xs:sequence>
			<!-- the flexsim-tree element must have a treetype attribute 
				with a value of either project, view, model, tree, userlibrary, or distributed -->
			<xs:attribute name="treetype" use="required">
				<xs:simpleType>
					<xs:restriction base="xs:string">
						<xs:enumeration value="project"/>
						<xs:enumeration value="view"/>
						<xs:enumeration value="model"/>
						<xs:enumeration value="tree"/>
						<xs:enumeration value="userlibrary"/>
						<xs:enumeration value="distributed"/>
					</xs:restriction>
				</xs:simpleType>
			</xs:attribute>
			<!-- the flexsim-tree element also must have a version attribute that defines the flexsim xml
				format version -->
			<xs:attribute name="version" type="xs:integer" use="required"/>
		</xs:complexType>
	</xs:element>

	<!-- the node element ... -->
	<xs:element name="node">
		<xs:complexType>
			<xs:sequence>
				<!-- the node's name must come first -->
				<xs:element name="name" type="xs:string" />
				<!-- next, the node can optionally have a data element, if the node contains data -->
				<xs:element name="data" minOccurs="0">
					<xs:complexType mixed="true">
						<!-- the content of the data element will be read dependent on the value of the node's
						dt attribute-->
						<xs:choice minOccurs="0">
							<!-- if the node has object data, then the data element will have one or more node elements 
							inside of it-->
							<xs:element ref="node" maxOccurs="unbounded"/>
							<!-- if the node has coupling data, then the data element will have a coupling element inside
							of it, with an integer value (or "null") that represents the node that the object is pointing to -->
							<xs:element name="coupling" type="xs:string"/>
							<!-- if the node has number data, then the data element will contain a 16-wide hexadecimal number
							that is a direct hexadecimal representation of the 64-bit double precision floating point number 
							contained-->
							
							<!-- if the node has string (or byteblock) data, then there are two possibilities:
								1. if the string is a standard, null-terminated string (this is usually the case), then 
									the text of the string will be represented verbatim in the content of the data element
								2. if the data is binary (byteblock) data that can't be represented as a null-terminated 
									string, such as kinematics data, then the data element will have a 
									storagetype="hexadecimal" attribute, and the content of the data element will be a 
									hexadecimal representation of the block of bytes
							-->
						</xs:choice>
						<xs:attribute name="storagetype" fixed="hexadecimal" />
					</xs:complexType>
				</xs:element>
				<!-- the node can optionally have any number of node elements inside of it -->
				<xs:element ref="node" minOccurs="0" maxOccurs="unbounded"/>
				<!-- if the node has the distributed attributes with a file-map-method of "split-points" 
					then it may have one or more "split-point" elements that define the different 
					files that split up the node -->
				<xs:element name="split-point" minOccurs="0" maxOccurs="unbounded">
					<xs:complexType>
						<xs:attribute name="file" type="xs:string" />
						<xs:attribute name="coupling-offset" type="xs:integer"/>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<!-- the node element usually will have an "f" attribute, defining flags.
			This is a 64-bit value. Some flags of note:
				0x01 - the node's content is expanded in the tree
				0x04 - the node is toggled as c++
				0x10 - the object is flagged to hide its output/input/center ports
				0x20 - the object is flagged to hide its name in the 3d view
				0x0000000100 - object data is expanded
				0x0000000200 - the node is selected (red)
				0x0000000400 - the node is toggled flexscript
				0x0000004000 - the node's code state is "locked"
				0x0000010000 - the node is protected, i.e. you get an error when you click on it and hit delete, or try to move the object
				0x0000020000 - the object's shape is hidden
				0x0000100000 - the object's content is hidden
				0x0001000000 - the node is toggled dll
				0x0004000000 - the node is toggled global c++
				0x0080000000 - node is set to manage a hash table of names
				0x0200000000 - node has active listeners on it
				0x0800000000 - coupling partners will be preserved when copied
			-->
			<xs:attribute name="f">
				<xs:simpleType>
					<xs:restriction base="xs:string">
						<xs:pattern value="[A-Fa-f0-9]+"/>
					</xs:restriction>
				</xs:simpleType>
			</xs:attribute>
			<!-- the node element can optionally have a "dt" attribute, defining datatype, with a value 1-4 
				this is the same value as when you call getdatatype(thenode)
			-->
			<xs:attribute name="dt">
				<xs:simpleType>
					<xs:restriction base="xs:integer">
						<xs:minInclusive value="1"/>
						<xs:maxInclusive value="4"/>
					</xs:restriction>
				</xs:simpleType>
			</xs:attribute>
			<!-- the node element can optionally have a "cpptype" attribute, defining the rank of the library 
				object of which this object is an instance -->
			<xs:attribute name="cpptype" type="xs:integer"/>
			<!-- the node element may have "distributed" attributes that define how it and its 
				sub-nodes are split across files-->
			<xs:attributeGroup ref="distributedAtts"/>
		</xs:complexType>
	</xs:element>

	<!-- Here's a definition of the distributed attributes group, which defines 
	how a model/tree is split across multiple files-->
	<xs:attributeGroup name="distributedAtts">
		<xs:attribute name="file-map-method">
			<xs:simpleType>
				<xs:restriction base="xs:string">
					<xs:enumeration value="single-node"/>
					<xs:enumeration value="split-points"/>
				</xs:restriction>
			</xs:simpleType>
		</xs:attribute>
		<xs:attribute name="file" type="xs:string"/>
		<xs:attribute name="coupling-offset" type="xs:integer"/>
	</xs:attributeGroup>
</xs:schema>