<?xml version="1.0"?>
<xs:schema targetNamespace="urn:Alias:GreenBox" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:aw="urn:Alias:GreenBox" elementFormDefault="qualified">
	<xs:element name="translator">
		<xs:complexType>
			<xs:sequence>
				<xs:choice>
					<xs:element ref="aw:application"/>
					<xs:element ref="aw:plugin"/>
					<xs:element ref="aw:xsl"/>
				</xs:choice>
				<xs:element ref="aw:authorization" minOccurs="1" />
				<xs:element ref="aw:label" minOccurs="0"/>
				<xs:element ref="aw:copyright" minOccurs="0"/>
				<xs:element ref="aw:documentation" minOccurs="0"/>
				<xs:element ref="aw:input" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element ref="aw:output" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element ref="aw:options" minOccurs="0"/>
			</xs:sequence>
			<xs:attribute name="id" type="xs:string" use="required"/>
			<xs:attribute name="class" type="xs:string" use="required"/>
			<!-- A translator has a required 'id' option which can
			be used to distinguish translators. -->
		</xs:complexType>
		<!-- The root element is a translator. It contains additional
		elements which describe the translator sufficiently for an
		application to build a UI to the translator. -->
	</xs:element>
	<!-- The application is a simple string representing the translator
	executable name. It is assumed this is the same on all platforms.
	i.e. on Windows using "appname" works just as well as "appname.exe".
	An application element would be used as:
		<application>appname</application>
	-->
	<xs:element name="application" type="xs:string" nillable="false"/>
	<!-- The copyright is a series of text lines for any copyright information
	associated with the translator. This will generally be used by third party
	translators. -->
	<xs:element name="copyright" type="xs:string" nillable="false"/>
	<!-- The plugin is a simple string representing the translator
	plugin name. It is assumed this is the same on all platforms.
	A plugin element would be used as:
		<plugin>pluginName</plugin>
	-->
	<xs:element name="plugin" type="xs:string" nillable="false"/>
	<!-- The xsl is a simple string representing the transformation
	name. It is assumed this is the same on all platforms.
	An XSL element would be used as:
		<xsl>xslFileName</xsl>
	-->
	<xs:element name="xsl" type="xs:string" nillable="false"/>
	<!-- The authorized element lists the applications authorized to
	run a translation. Unauthorized modification of this element will
	cause the given translator to fail in all applications. -->
	<xs:element name="authorization" type="aw:authorizationList" nillable="false" />
	<xs:complexType name="authorizationList" mixed="false">
		<xs:sequence minOccurs="1" maxOccurs="1">
			<xs:element name="applications" type="aw:appList" minOccurs="1"
				maxOccurs="1"/>
			<!-- platforms is optional, but since most translators are
			unavailable on Linux, it's necessary to specify all other
			platforms. -->
			<xs:element name="platforms" type="aw:platformList" minOccurs="0"
				maxOccurs="1"/>
		</xs:sequence>
	</xs:complexType>
	<xs:simpleType name="appList">
		<xs:list itemType="aw:appName"/>
	</xs:simpleType>
	<xs:simpleType name="appName">
		<xs:restriction base="xs:string">
			<xs:enumeration value="ais"/>
			<xs:enumeration value="all"/>
			<xs:enumeration value="maui"/>
			<xs:enumeration value="maya"/>
			<xs:enumeration value="studio"/>
		</xs:restriction>
	</xs:simpleType>
	<xs:simpleType name="platformList">
		<xs:list itemType="aw:platformName"/>
	</xs:simpleType>
	<xs:simpleType name="platformName">
		<xs:restriction base="xs:string">
			<xs:enumeration value="i386"/>
			<xs:enumeration value="mips"/>
			<xs:enumeration value="ppc"/>
			<xs:enumeration value="x86"/>
		</xs:restriction>
	</xs:simpleType>
	<!-- Label is a short text desciption of the element. It is localizable.
	It may also be extracted from the documentation. A label would be used as:
		<label>
			Optional Default text
			<text lang="en_US">US english text</text>
			<text lang="en_JIS">Japanese JIS text</text>
		<label>
		An XPATH search to find all labels would simply be "//label".
		An XPATH search for all US english labels would be
		"//label/@en_US".
	-->
	<xs:element name="label" type="aw:labelType"/>
	<xs:complexType name="labelType" mixed="true">
		<xs:sequence minOccurs="0" maxOccurs="unbounded">
			<xs:element ref="aw:text"/>
			<!-- We want a list of encoded text. -->
		</xs:sequence>
		<!-- Allow a string to have descriptions in multiple languages.
		The element text is the default text for the label. -->
	</xs:complexType>
	<xs:element name="text">
		<xs:complexType mixed="true">
			<xs:attribute name="lang" type="aw:langType" use="required"/>
		</xs:complexType>
		<!-- text is an element that encodes localized text. The lang is
		specified as an attribute to make querying easier. An application looks
		for a text element and then checks the lang on it. XPATH would also
		allow queries of specific languages. -->
	</xs:element>
	<xs:simpleType name="langType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="en_US"/>
			<xs:enumeration value="jp_JIS"/>
		</xs:restriction>
		<!-- langType is a restriction that ensures we only write text
		in recognized languages. By simply adding new lines here we add new
		langs without requiring a change to any application. -->
	</xs:simpleType>
	<xs:element name="documentation">
		<xs:complexType>
			<xs:choice>
				<xs:element name="file" type="xs:string"/>
			</xs:choice>
		</xs:complexType>
		<!-- Any documentation for the translator is included in the documentation
		element. For now there is only one child node which is "file". In the future
		we may choose to embed documentation in which case there will be a sibling
		element to "file". -->
	</xs:element>
	<xs:element name="input">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="aw:ioOptionType">
					<xs:sequence>
						<xs:element name="criteria" type="aw:criteriaType"/>
					</xs:sequence>
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
		<!-- input is a special case of an option. The type of the argument is
		restricted to being a filename, as well it has a filetype element. -->
	</xs:element>
	<xs:complexType name="criteriaType" mixed="false">
		<xs:choice>
			<xs:element ref="aw:tests"/>
			<xs:element ref="aw:header"/>
			<xs:element ref="aw:suffix"/>
		</xs:choice>
		<!-- The criteria contains one of a "tests" element,
		a "header" element, or a "suffix" element. -->
	</xs:complexType>
	<xs:element name="tests">
		<xs:complexType mixed="false">
			<xs:choice maxOccurs="unbounded">
				<xs:element ref="aw:tests"/>
				<xs:element ref="aw:header"/>
				<xs:element ref="aw:suffix"/>
			</xs:choice>
			<xs:attribute name="conditional" type="aw:conditionalType" default="AND"/>
		</xs:complexType>
		<!-- Criteria tests can be a single header or suffix test, they can be several
		of each combined by a conditional operator, or there can be nested tests. -->
	</xs:element>
	<xs:simpleType name="conditionalType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="AND"/>
			<xs:enumeration value="OR"/>
			<xs:enumeration value="NOR"/>
			<xs:enumeration value="NAND"/>
			<xs:enumeration value="and"/>
			<xs:enumeration value="or"/>
			<xs:enumeration value="nor"/>
			<xs:enumeration value="nand"/>
			<xs:enumeration value="||"/>
			<xs:enumeration value="&amp;&amp;"/>
		</xs:restriction>
		<!-- A conditionalType allows tests to be combined in the expected fashion. -->
	</xs:simpleType>
	<xs:element name="header">
		<xs:complexType mixed="false">
			<xs:attribute name="value" type="xs:string" use="required"/>
			<xs:attribute name="operator" type="aw:operatorType" use="required"/>
			<xs:attribute name="offset" type="xs:unsignedInt" default="0"/>
		</xs:complexType>
		<!-- header is used to test the header of a file. The "value" specifies
		what to compare the header against. The "operator" sepcifies how to
		compare the value to the header. The "offset" is optional (defaulting
		to 0) and indicates where in the file to start the comparison.
		i.e. <header value="StudioPacketFile" operator="==" offset="1" />
		checks if the string "StudioPacketFile" occurs in the file starting at
		the second byte. -->
	</xs:element>
	<xs:element name="suffix">
		<xs:complexType mixed="false">
			<xs:attribute name="value" type="xs:string" use="required"/>
			<xs:attribute name="operator" type="aw:operatorType" use="required"/>
		</xs:complexType>
		<!-- suffix is used to compare a file suffix. The "value" is the suffix
		to compare the file against. The "operator" is the kind of comparison to
		do. i.e. <suffix value=".wire" operator="!="> is used to check that the
		file suffix is not ".wire". -->
	</xs:element>
	<xs:simpleType name="operatorType">
		<xs:restriction base="xs:string">
			<xs:whiteSpace value="collapse"/>
			<xs:enumeration value="=="/>
			<xs:enumeration value="!="/>
			<xs:enumeration value="&lt;"/>
			<xs:enumeration value="&lt;="/>
			<xs:enumeration value="&gt;"/>
			<xs:enumeration value="&gt;="/>
		</xs:restriction>
	</xs:simpleType>
	<xs:element name="output">
		<xs:complexType mixed="false">
			<xs:complexContent mixed="false">
				<xs:extension base="aw:ioOptionType">
					<xs:sequence>
						<xs:element ref="aw:logfile" minOccurs="0"/>
					</xs:sequence>
				</xs:extension>
			</xs:complexContent>
			<!-- output's type is an ioOptionType with the addition of an output logfile. -->
		</xs:complexType>
		<!-- output is a special case of an option. The type of the argument is
		restricted to being a filename, as well it has a filetype element. -->
	</xs:element>
	<xs:element name="logfile">
		<xs:complexType mixed="false">
			<xs:attribute name="base" type="aw:logfileBaseType" use="required"/>
			<xs:attribute name="removeSuffix" type="xs:boolean" use="required"/>
			<xs:attribute name="suffix" type="xs:string" use="required"/>
		</xs:complexType>
		<!-- The logfile element describes how to determine the name of the logfile. -->
		<!-- base is used to specify whether logfile name is based on the input or output
		filename. removeSuffix indicates whether the suffix should frist be removed from the
		base filename. suffix is the suffix that is appended to the logfile name. -->
	</xs:element>
	<xs:simpleType name="logfileBaseType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="inputFileName"/>
			<xs:enumeration value="outputFileName"/>
		</xs:restriction>
		<!-- Base the logfile name on the inputFileName or the outputFileName. -->
	</xs:simpleType>
	<xs:complexType name="ioOptionType">
		<xs:sequence>
			<xs:element ref="aw:label" minOccurs="0"/>
			<xs:element name="argument" type="aw:ioArgumentType"/>
			<xs:element ref="aw:filetype"/>
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required"/>
		<!-- An ioOptionType has a label (defined above) an
		argument, and a filetype description. Attributes allow it to
		be labelled with an ID. -->
	</xs:complexType>
	<xs:complexType name="ioArgumentType">
		<xs:complexContent>
			<xs:restriction base="aw:argumentType">
				<xs:sequence>
					<xs:element ref="aw:filename"/>
				</xs:sequence>
			</xs:restriction>
		</xs:complexContent>
		<!-- An ioArgumentType is an argumentType restricted to just filenames. -->
	</xs:complexType>
	<xs:element name="filetype">
		<xs:complexType mixed="false">
			<xs:attribute name="name" type="xs:string" use="required"/>
			<xs:attribute name="version" use="required">
				<xs:simpleType>
					<xs:list itemType="xs:string"/>
					<!-- The version could be a whitespace separated list of versions. -->
				</xs:simpleType>
			</xs:attribute>
			<xs:attribute name="suffix" use="optional">
				<!-- The suffix is required by the server to determine the name of the result
				however some translators do not add a suffix, so the suffix must be optional. -->
				<xs:simpleType>
					<xs:list itemType="xs:string"/>
					<!-- The suffix could be a whitespace separated list of suffixes. -->
				</xs:simpleType>
			</xs:attribute>
		</xs:complexType>
		<!-- A filetype element describes the type of the input or output.
		It identifies the name of the type, the version of the type, and
		the expected suffix. i.e.
		<filetype name="SPF" version="10.0" suffix=".wire" />
		-->
	</xs:element>
	<!-- "options" is used to list the set of options used by a translator. -->
	<xs:element name="options" type="aw:optionsType"/>
	<xs:complexType name="optionsGroupType">
		<xs:sequence>
			<xs:element ref="aw:requires" minOccurs="0"/>
			<xs:element ref="aw:label"/>
			<xs:choice maxOccurs="unbounded">
				<xs:element ref="aw:option" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element ref="aw:control" minOccurs="0" maxOccurs="unbounded"/>
				<xs:element name="optionsGroup" type="aw:optionsGroupType" minOccurs="0" maxOccurs="unbounded"/>
			</xs:choice>
		</xs:sequence>
		<xs:attribute name="id" type="xs:string" use="required"/>
		<!-- optionsType describes a group of options. Such a group can be a set
		of individual options or grouped options (for UI purposes). -->
	</xs:complexType>
	<xs:complexType name="optionsType">
		<xs:complexContent>
			<xs:restriction base="aw:optionsGroupType">
				<xs:sequence>
					<xs:element ref="aw:label"/>
					<xs:choice maxOccurs="unbounded">
						<xs:element ref="aw:option" minOccurs="0" maxOccurs="unbounded"/>
						<xs:element ref="aw:control" minOccurs="0" maxOccurs="unbounded"/>
						<xs:element name="optionsGroup" type="aw:optionsGroupType" minOccurs="0" maxOccurs="unbounded"/>
					</xs:choice>
				</xs:sequence>
			</xs:restriction>
		</xs:complexContent>
		<!-- An optionsGroup can have a "requires" element that indicates what
		conditions must be true for the option group to be visible. -->
	</xs:complexType>
	<xs:element name="option">
		<xs:complexType mixed="false">
			<xs:sequence>
				<xs:element ref="aw:requires" minOccurs="0"/>
				<xs:element ref="aw:label"/>
				<xs:element name="argument" type="aw:argumentType"/>
			</xs:sequence>
			<xs:attribute name="id" type="xs:string" use="required"/>
		</xs:complexType>
		<!-- An option describes a single option to a translator. This description
		includes an optional "requires" element which provides tests for enabling
		or disabling an option based on other options or option groups. It includes
		a label which describes the option (from Documentation?) and it includes
		a description of the command line argument used for building the UI. -->
	</xs:element>
	<xs:element name="control">
		<xs:complexType mixed="false">
			<xs:sequence>
				<xs:element ref="aw:requires" minOccurs="0"/>
				<xs:element ref="aw:label"/>
				<xs:choice>
					<xs:element name="boolean">
							<xs:complexType mixed="false">
								<xs:attribute name="default" type="xs:boolean" use="required"/>
							</xs:complexType>
					</xs:element>
					<xs:element ref="aw:enumeration"/>
				</xs:choice>
			</xs:sequence>
			<xs:attribute name="id" type="xs:string" use="required"/>
		</xs:complexType>
		<!-- An option describes a single option to a translator. This description
		includes an optional "requires" element which provides tests for enabling
		or disabling an option based on other options or option groups. It includes
		a label which describes the option (from Documentation?) and it includes
		a description of the command line argument used for building the UI. -->
	</xs:element>
	<xs:element name="requires">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="aw:requires" minOccurs="0"/>
				<xs:element ref="aw:test" maxOccurs="unbounded"/>
			</xs:sequence>
			<xs:attribute name="conditional" type="aw:conditionalType" default="AND"/>
		</xs:complexType>
		<!-- requires is a set of tests and optionally other requires that
		are used to test the setting of other options to determine if an
		option or set of options should be displayed. -->
	</xs:element>
	<xs:element name="test">
		<xs:complexType mixed="false">
			<xs:attribute name="optionID" type="xs:string" use="required"/>
			<xs:attribute name="operator" type="aw:operatorType" use="required"/>
			<xs:attribute name="value" type="xs:string" use="required"/>
		</xs:complexType>
		<!-- A test references another option through its ID and allows the value on
		the option to be compared to a specific value. -->
	</xs:element>
	<xs:complexType name="argumentType" mixed="false">
		<xs:choice>
			<xs:element ref="aw:boolean"/>
			<xs:element ref="aw:double"/>
			<xs:element ref="aw:enumeration"/>
			<xs:element ref="aw:filename"/>
			<xs:element ref="aw:integer"/>
			<xs:element ref="aw:string"/>
		</xs:choice>
		<xs:attribute name="flag" type="xs:string"/>
		<!-- An argumentType is a flag followed by a type. The flag
		may be omitted. It could be used as:
			<argument flag="-i">
				<filename />
			</argument>
			The type specifies the type required by the argument.
		-->
	</xs:complexType>
	<xs:element name="boolean">
		<xs:complexType mixed="false">
			<xs:attribute name="true" type="xs:string" use="required"/>
			<xs:attribute name="false" type="xs:string" use="required"/>
			<xs:attribute name="default" type="xs:boolean" use="required"/>
		</xs:complexType>
		<!-- Use <boolean true='true value' false='false value' -->
		<!-- default='defaultvalue'/> -->
		<!-- i.e. <boolean true='1' false='0' default='false'/> -->
		<!-- or <boolean true='-t' false='-f' default='true' /> -->
		<!-- or <boolean true='' false='-x' default='false' -->
		<!-- The value associated with 'true' or 'false' will be -->
		<!-- passed to the command line after the flag if specified -->
		<!-- or on its own if no flag is specified. -->
	</xs:element>
	<xs:element name="double">
		<xs:complexType mixed="false">
			<xs:attribute name="min" type="xs:double" use="required"/>
			<xs:attribute name="max" type="xs:double" use="required"/>
			<xs:attribute name="default" type="xs:double" use="required"/>
		</xs:complexType>
		<!-- Use <double min='minValue' max='maxValue' default='default' /> -->
		<!-- i.e. <double min='0.0' max='10.0' default='1.0' /> -->
		<!-- The value will be placed on the command line after a command -->
		<!-- line flag if specified. -->
	</xs:element>
	<xs:element name="enumeration" nillable="false">
		<xs:complexType mixed="false">
			<xs:sequence>
				<xs:element name="label" nillable="false" maxOccurs="unbounded">
					<xs:complexType>
						<xs:complexContent>
							<xs:extension base="aw:labelType">
								<xs:attribute name="value" type="xs:string" use="required"/>
							</xs:extension>
						</xs:complexContent>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="default" type="xs:string" use="required"/>
		</xs:complexType>
		<!-- An enumeration is a set of labels which describe the set of possible
		values for an argument. The normal labelType is extended with a value
		attribute which is what the label is "evaluated" to when selected. The
		enumeration requires a default value to be set.
		i.e.
			<argument>
				<enumeration default="-a">
					<label value="-a">Choice A</label>
					<label value="-b">Choice B</label>
					<label value="-c">Choice C</label>
				</enumeration>
			</argument>
		Note that the argument has no default flag in this case. Another example
		would be:
			<argument flag="-v">
				<enumeration default="a">
					<label value="a">Choice A</label>
					<label value="b">Choice B</label>
					<label value="c">Choice C</label>
				</enumeration>
			</argument>
		In this case the argument does have a flag. The enumeration value is then
		plaecd after the flag when the command line is built up. -->
	</xs:element>
	<xs:element name="filename">
		<xs:complexType mixed="false">
			<!-- No contents here. -->
		</xs:complexType>
		<!-- Use <filename />. A filename is an empty element indicating that the
		argument is a filename. -->
	</xs:element>
	<xs:element name="integer">
		<xs:complexType mixed="false">
			<xs:attribute name="min" type="xs:integer" use="required"/>
			<xs:attribute name="max" type="xs:integer" use="required"/>
			<xs:attribute name="default" type="xs:integer" use="required"/>
		</xs:complexType>
		<!-- Use is the same as for 'double' above. -->
	</xs:element>
	<xs:element name="string">
		<xs:complexType mixed="false">
			<xs:attribute name="minLength" type="xs:integer" use="optional" default="1"/>
			<xs:attribute name="maxLength" type="xs:integer" use="required"/>
			<xs:attribute name="default" type="xs:string" use="optional"/>
		</xs:complexType>
		<!-- Use <string minLength='...' maxLength='...' default='...' /> -->
		<!-- i.e. <string maxLength='10' default='logfile' /> -->
		<!-- minLength has a default of 1. -->
	</xs:element>
</xs:schema>
