<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://www.stepmania.com"
 xmlns="http://www.stepmania.com"
 elementFormDefault="qualified">

<xs:element name="Lua">
	<xs:complexType>
		<xs:all>
			<xs:element name="Singletons" type="Singletons" />
			<xs:element name="Classes" type="Classes" />
			<xs:element name="Namespaces" type="Namespaces" />
			<xs:element name="GlobalFunctions" type="GlobalFunctions" />
			<xs:element name="Enums" type="Enums" />
			<xs:element name="Constants" type="Constants" />
			<xs:element name="Date" type="xs:date" />
			<xs:element name="Version" type="xs:string" />
		</xs:all>
	</xs:complexType>
</xs:element>


<xs:element name="Documentation">
	<xs:complexType>
		<xs:all>
			<xs:element name="Classes" type="Classes" />
			<xs:element name="Namespaces" type="Namespaces" />
			<xs:element name="GlobalFunctions" type="GlobalFunctions" />
			<xs:element name="Enums" type="Enums" />
		</xs:all>
	</xs:complexType>
</xs:element>

<xs:simpleType name="Identifier">
	<xs:restriction base="xs:string">
	<!-- Not totally valid since the following are not valid
	     identifiers in Lua.
		and	break	do	else		elseif
		end	false	for	function	if
		in	local	nil	not		or
		repeat	return	then	true		until
		while
	-->
		<xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*" />
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="IdentifierOrTable">
	<xs:restriction base="xs:string">
		<xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*|\{[a-zA-Z_][a-zA-Z0-9_]*\}" />
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="IdentifierOrNonemptyString">
	<xs:restriction base="xs:string">
	<!-- XXX: Doesn't support double quoted strings. -->
		<xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*|'[^']+'" />
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="IdentifierStringOrNumber">
	<xs:restriction base="xs:string">
		<xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*|'[^']+'|[0-9]+" />
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="ArgumentList">
	<xs:restriction base="xs:string">
		<xs:whiteSpace value="collapse" />
		<!-- ((IdentifierOrTable Identifier(, IdentifierOrTable Identifier)*(, ...)?)|...)? -->
		<xs:pattern value="((([a-zA-Z_][a-zA-Z0-9_]*|\{[a-zA-Z_][a-zA-Z0-9_]*\}) [a-zA-Z_][a-zA-Z0-9_]*( ?, ?([a-zA-Z_][a-zA-Z0-9_]*|\{[a-zA-Z_][a-zA-Z0-9_]*\}) [a-zA-Z_][a-zA-Z0-9_]*)*)( ?, ?\.\.\.)?|\.\.\.)?" />
	</xs:restriction>
</xs:simpleType>

<xs:complexType name="Singletons">
	<xs:sequence>
		<xs:element name="Singleton" minOccurs="0" maxOccurs="unbounded">
			<xs:complexType>
				<xs:attribute name="name" type="Identifier" use="required" />
				<xs:attribute name="class" type="Identifier" use="required" />
			</xs:complexType>
		</xs:element>
	</xs:sequence>
</xs:complexType>

<xs:group name="DocumentationGroup">
	<xs:sequence>
		<xs:choice>
			<xs:element name="Link" type="Link" />
			<!-- HTML elements we want to let through. -->
			<xs:element name="code" />
			<xs:element name="pre" />
			<xs:element name="br" />
			<xs:element name="del" />
		</xs:choice>
	</xs:sequence>
</xs:group>

<xs:complexType name="Description" mixed="true">
	<xs:group ref="DocumentationGroup" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>

<xs:complexType name="Classes">
	<xs:sequence>
		<xs:element name="Class" minOccurs="0" maxOccurs="unbounded">
			<xs:complexType>
				<xs:sequence>
					<xs:element name="Description" type="Description"
					 minOccurs="0" maxOccurs="1" />
					<xs:element name="Function" type="Function"
					 minOccurs="0" maxOccurs="unbounded" />
				</xs:sequence>
				<xs:attribute name="name" type="Identifier" use="required" />
				<xs:attribute name="base" type="Identifier" use="optional" />
			</xs:complexType>
		</xs:element>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="Namespaces">
	<xs:sequence>
		<xs:element name="Namespace" minOccurs="0" maxOccurs="unbounded">
			<xs:complexType>
				<xs:sequence>
					<xs:element name="Description" type="Description"
					 minOccurs="0" maxOccurs="1" />
					<xs:element name="Function" type="Function"
					 minOccurs="0" maxOccurs="unbounded" />
			 	</xs:sequence>
				<xs:attribute name="name" type="Identifier" use="required" />
			</xs:complexType>
		</xs:element>
	</xs:sequence>
</xs:complexType>


<xs:complexType name="GlobalFunctions">
	<xs:sequence>
		<xs:element name="Function" type="Function"
		 minOccurs="0" maxOccurs="unbounded" />
	</xs:sequence>
</xs:complexType>

<xs:complexType name="Function" mixed="true">
	<xs:group ref="DocumentationGroup" minOccurs="0" maxOccurs="unbounded" />
	<xs:attribute name="name" type="Identifier" use="required" />
	<xs:attribute name="theme" type="Identifier" use="optional" />
	<xs:attribute name="return" type="IdentifierOrTable" use="optional" />
	<xs:attribute name="arguments" type="ArgumentList" use="optional" />
	<xs:attribute name="since" type="xs:string" use="optional" />
</xs:complexType>

<xs:complexType name="Link" mixed="true">
	<xs:group ref="DocumentationGroup" minOccurs="0" maxOccurs="unbounded"/>
	<xs:attribute name="function" type="Identifier" use="optional" />
	<xs:attribute name="class" type="Identifier" use="optional" />
</xs:complexType>

<xs:complexType name="Enums">
	<xs:sequence>
		<xs:element name="Enum" minOccurs="0" maxOccurs="unbounded">
			<xs:complexType>
				<xs:sequence>
					<xs:element name="Description" type="Description"
					 minOccurs="0" maxOccurs="1" />
					<xs:element name="EnumValue" type="Constant"
					 minOccurs="0" maxOccurs="unbounded" />
				</xs:sequence>
				<xs:attribute name="name" type="Identifier" use="required" />
			</xs:complexType>
		</xs:element>
	</xs:sequence>
</xs:complexType>


<xs:complexType name="Constants">
	<xs:sequence>
		<xs:element name="Constant" type="Constant"
		 minOccurs="0" maxOccurs="unbounded" />
	</xs:sequence>
</xs:complexType>


<xs:complexType name="Constant">
	<xs:attribute name="name" type="IdentifierOrNonemptyString" use="required" />
	<xs:attribute name="value" type="IdentifierStringOrNumber" use="required" />
</xs:complexType>
</xs:schema>
<!-- vim: set tw=0: -->
