<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="Tethys"
    elementFormDefault="qualified" 
    attributeFormDefault="unqualified"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:Tethys="Tethys">
 
    <complexType name="ItemType">
        <attribute name="Id" type="token"/>
    </complexType>

    <element name="Item" type="Tethys:ItemType" abstract="true"/>

    <simpleType name="FilenameType" >
        <restriction base="string">
            <pattern value='[\p{L}\p{N}\._/]+\.[\p{L}][mM][lL]'/>
        </restriction>
    </simpleType>
    
    <complexType name="InsertType">
        <complexContent>
            <extension base="Tethys:ItemType">
                <attribute name="Filename" type="Tethys:FilenameType" use="required"/>
            </extension>
        </complexContent>
    </complexType>

    <element name="Insert" type="Tethys:InsertType" substitutionGroup="Tethys:Item"/>

    <complexType name="CallType">
        <complexContent>
            <extension base="Tethys:ItemType">
                <attribute name="refId" type="token"/>
                <attribute name="RefId" type="token"/>
                <attribute name="PriorityHere" type="boolean"/>
            </extension>
        </complexContent>
    </complexType>

    <element name="Call" type="Tethys:CallType" substitutionGroup="Tethys:Item"/>

    <complexType name="SeqenceItemType">
        <complexContent>
            <extension base="Tethys:ItemType">
                <sequence>
                    <element name="Timeout" type="Tethys:TimeoutType" minOccurs="0" />
                    <element name="Preemptive" type="Tethys:BoolClauseType" minOccurs="0" />
                    <element name="Until" type="Tethys:BoolClauseType" minOccurs="0" />
                    <element name="When" type="Tethys:BoolClauseType" minOccurs="0" />
                    <element name="While" type="Tethys:BoolClauseType" minOccurs="0" />
                </sequence>
                <attribute name="Repeat" type="unsignedInt"/>
            </extension>
        </complexContent>
    </complexType>

    <complexType name="StackType">
        <complexContent>
            <extension base="Tethys:SeqenceItemType">
                <choice minOccurs="0" maxOccurs="unbounded">
                    <element ref="Tethys:Item" />
                    <element name="Shorelog" type="Tethys:ShorelogType" />
                    <element name="Syslog" type="Tethys:SyslogType" />
                    <element name="Touch" type="Tethys:TouchType" />
                </choice>
                <attribute name="RunIn" type="Tethys:RunInType"/>
            </extension>
        </complexContent>
    </complexType>

    <element name="Stack" type="Tethys:StackType" substitutionGroup="Tethys:Item"/>

    <complexType name="MissionType">
        <sequence>
            <element name="DefineArg" type="Tethys:DefineArgType" minOccurs="0" maxOccurs="unbounded"/>
            <element name="Timeout" type="Tethys:TimeoutType" minOccurs="0"/>
            <choice minOccurs="0" maxOccurs="unbounded"> 
                <element ref="Tethys:Item" />
                <element name="Shorelog" type="Tethys:ShorelogType" />
                <element name="Syslog" type="Tethys:SyslogType" />
                <element name="Touch" type="Tethys:TouchType" />
            </choice>
        </sequence>
        <attribute name="Id" type="token"/>
    </complexType>

    <complexType name="DefineArgType">
        <choice>
            <element ref="Tethys:UniversalUri"/>
            <element ref="Tethys:Uri"/>
            <element ref="Tethys:String"/>
            <sequence>
                <element ref="Tethys:Unit"/>
                <element ref="Tethys:Value"/>
            </sequence>
        </choice>
        <attribute name="Name" type="token" use="required"/>
    </complexType>
    
    <complexType name="ShorelogType">
        <choice>
            <element name="Arg" type="Tethys:ArgType"/>
            <!-- 
            <sequence>
                <choice>
                    <element ref="Tethys:UniversalUri"/>
                    <element ref="Tethys:Uri"/>
                </choice>
                <element ref="Tethys:Unit"/>
            </sequence> 
            -->
        </choice>
    </complexType>
    
    <element name="Mission" type="Tethys:MissionType"/>

    <simpleType name='ExactDuration'>
        <restriction base="string">
          <pattern value='P(\p{Nd}+D)?(\p{Nd}+H)?(\p{Nd}+M)?(\p{Nd}+(.\p{Nd}+)?S)?'/>
        </restriction>
    </simpleType>

    <complexType name="TimeoutType">
        <complexContent>
            <extension base="Tethys:StackType">
                <attribute name="Duration" type="Tethys:ExactDuration"/>
            </extension>
        </complexContent>
    </complexType>    

     <simpleType name="RunInType">
        <restriction base="string">
            <enumeration value="Sequence"></enumeration>
            <enumeration value="Parallel"></enumeration>
            <enumeration value="Progression"></enumeration>
        </restriction>
    </simpleType>

    <complexType name="ParallelType">
        <complexContent>
            <extension base="Tethys:ItemType">
                <sequence>
                    <element name="Timeout" type="Tethys:TimeoutType" minOccurs="0" />
                    <element name="While" type="Tethys:BoolClauseType" minOccurs="0"/>
                    <sequence minOccurs="0" maxOccurs="unbounded">
                        <choice>
                            <element name="Set" type="Tethys:SetType"/>
                            <element name="SetString" type="Tethys:SetStringType" />
                            <element name="SetUri" type="Tethys:SetType"/>
                            <element name="OutputArg" type="Tethys:OutputArgType"/>
                        </choice>
                    </sequence>
                </sequence>
                <attribute name="RunIn" type="Tethys:RunInType" use="required" fixed="Parallel"/>
            </extension>
        </complexContent>
    </complexType>

    <complexType name="SequenceType">
        <complexContent>
            <extension base="Tethys:SeqenceItemType">
                <sequence minOccurs="0" maxOccurs="unbounded">
                    <choice>
                        <element name="Set" type="Tethys:SetType"/>
                        <element name="SetString" type="Tethys:SetStringType" />
                        <element name="SetUri" type="Tethys:SetType"/>
                        <element name="OutputArg" type="Tethys:OutputArgType"/>
                    </choice>
                </sequence>
                <attribute name="RunIn" type="Tethys:RunInType" use="required" />
            </extension>
        </complexContent>
    </complexType>

    <complexType name="BoolClauseType">
        <group ref="Tethys:BoolClauseArgGroup"></group>
    </complexType>
    
    <complexType name="TrueFalseType">
        <complexContent>
            <restriction base="anyType"></restriction>
        </complexContent>
    </complexType>

    <complexType name="ElapsedType">
        <choice minOccurs="0">
            <element ref="Tethys:UniversalUri"/>
            <element ref="Tethys:Uri"/>
            <element name="Arg" type="Tethys:ArgType"/>
        </choice>
    </complexType>
    
    <complexType name="CalledType">
        <complexContent>
            <restriction base="anyType"></restriction>
        </complexContent>
    </complexType>

    <complexType name="UriType">
        <complexContent>
            <restriction base="anyType"></restriction>
        </complexContent>
    </complexType>

    <element name="Uri" type="Tethys:UriType" abstract="true"/>

    <complexType name="UniversalUriType">
        <complexContent>
            <restriction base="Tethys:UriType"></restriction>
        </complexContent>
    </complexType>
    
    <element name="UniversalUri" type="Tethys:UniversalUriType" abstract="true"/>

    <complexType name="UnitType">
        <complexContent>
            <restriction base="anyType"></restriction>
        </complexContent>
    </complexType>
   
    <element name="Unit" type="Tethys:UnitType" abstract="true"/>

    <complexType name="OperatorType">
        <complexContent>
            <restriction base="anyType"></restriction>
        </complexContent>
    </complexType>

    <group name="BoolClauseArgGroup">
        <sequence>
            <choice>
                <element name="True" type="Tethys:TrueFalseType"/>
                <element name="False" type="Tethys:TrueFalseType"/>
                <element name="Not" type="Tethys:BoolClauseType"/>
                <element name="Elapsed" type="Tethys:ElapsedType"/>
                <element name="Called" type="Tethys:CalledType"/>
                <element name="Arg" type="Tethys:ArgType"/>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
                <choice minOccurs="2" maxOccurs="2">
                    <element ref="Tethys:Unit" minOccurs="1"/>
                    <element ref="Tethys:Value" minOccurs="1"/>
                </choice>
            </choice>
            <sequence minOccurs="0" maxOccurs="1">
                <choice>
                    <element name="Eq" type="Tethys:OperatorType"/>
                    <element name="Ne" type="Tethys:OperatorType"/>
                    <element name="Lt" type="Tethys:OperatorType"/>
                    <element name="Le" type="Tethys:OperatorType"/>
                    <element name="Gt" type="Tethys:OperatorType"/>
                    <element name="Ge" type="Tethys:OperatorType"/>
                </choice>
                <choice>
                    <element name="True" type="Tethys:TrueFalseType"/>
                    <element name="False" type="Tethys:TrueFalseType"/>
                    <element name="Not" type="Tethys:BoolClauseType"/>
                    <element name="Elapsed" type="Tethys:ElapsedType"/>
                    <element name="Called" type="Tethys:CalledType"/>
                    <element name="Arg" type="Tethys:ArgType"/>
                    <element ref="Tethys:UniversalUri"/>
                    <element ref="Tethys:Uri"/>
                    <choice minOccurs="2" maxOccurs="2">
                        <element ref="Tethys:Unit" minOccurs="1"/>
                        <element ref="Tethys:Value" minOccurs="1"/>
                    </choice>
                </choice>
            </sequence>
            <sequence minOccurs="0" maxOccurs="unbounded">
                <choice>
                    <element name="Or" type="Tethys:BoolClauseType"/>
                    <element name="And" type="Tethys:BoolClauseType"/>
                </choice>
            </sequence>
        </sequence>
    </group>
   
   <complexType name="ArgType">
       <attribute name="Name" type="token" use="required"/>
   </complexType>
   
    <complexType name="OutputArgType">
        <sequence>
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
            </choice>
        </sequence>
        <attribute name="Name" type="token" use="required"/>
    </complexType>

    <complexType name="SetType">
        <sequence>
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
            </choice>
            <choice>
                <element name="Arg" type="Tethys:ArgType"/>
                <sequence>
                    <element ref="Tethys:Unit"/>
                    <element ref="Tethys:Value"/>
                </sequence>
                <element ref="Tethys:String"/>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
            </choice>
        </sequence>
    </complexType>

    <complexType name="SetStringType" mixed="true">
        <sequence>
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
                <element name="Arg" type="Tethys:ArgType"/>
            </choice>
        </sequence>
    </complexType>

    <simpleType name="SyslogSeverityType">
        <restriction base="string">
            <enumeration value="None"></enumeration>
            <enumeration value="Debug"></enumeration>
            <enumeration value="Info"></enumeration>
            <enumeration value="Error"></enumeration>
            <enumeration value="Critical"></enumeration>
        </restriction>
    </simpleType>

    <complexType name="SyslogType" mixed="true">
        <sequence minOccurs="0" maxOccurs="unbounded">
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
                <element name="Arg" type="Tethys:ArgType"/>
            </choice>
            <element ref="Tethys:Unit"/>
        </sequence>
        <attribute name="Id" type="token"/>
        <attribute name="Severity" type="Tethys:SyslogSeverityType" default="Info"/>
    </complexType>

    <complexType name="TouchType">
        <sequence>
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
            </choice>
        </sequence>
        <attribute name="Id" type="token"/>
    </complexType>

    <simpleType name="ConstantType">
        <union memberTypes="boolean double"/></simpleType>

    <simpleType name="ConstantTypeList">
       <list itemType="Tethys:ConstantType"/>
    </simpleType>
    
    <simpleType name="ConstantTypeListOf2">
       <restriction base="Tethys:ConstantTypeList">
           <length value="2"/>
       </restriction>
    </simpleType>

    <simpleType name="ConstantTypeListOf3">
       <restriction base="Tethys:ConstantTypeList">
           <length value="3"/>
       </restriction>
    </simpleType>

    <simpleType name="ConstantTypeListOf6">
       <restriction base="Tethys:ConstantTypeList">
           <length value="6"/>
       </restriction>
    </simpleType>
    
    <simpleType name="ConstantTypeUnion">
        <union memberTypes="Tethys:ConstantType Tethys:ConstantTypeListOf2 Tethys:ConstantTypeListOf3 Tethys:ConstantTypeListOf6"/>
    </simpleType>

    <element name="Value" type="Tethys:ConstantTypeUnion"/>

    <element name="String" type="string"/>

    <complexType name="InputType">
        <sequence>
            <choice>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Uri"/>
            </choice>
            <element ref="Tethys:Unit"/>
            <element name="DefaultValue" type="Tethys:ConstantTypeUnion"/>
        </sequence>        
        <attribute name="Name" type="Name" use="required"/>  
    </complexType>

    <complexType name="OutputType">
        <choice>
            <sequence>
                <element ref="Tethys:UniversalUri"/>
                <element ref="Tethys:Unit"/>
                <element name="Accuracy" type="Tethys:ConstantType"/>
            </sequence>
            <sequence>
                <element ref="Tethys:Uri"/>
                <element ref="Tethys:Unit"/>
            </sequence>
        </choice>            
    </complexType>

    <complexType name="NewOutputType">
        <sequence>
            <element ref="Tethys:Uri"/>
            <element ref="Tethys:Unit"/>
            <element name="DefaultValue" type="Tethys:ConstantTypeUnion"/>
        </sequence>
    </complexType>

    <simpleType name="ScriptLanguageType">
        <restriction base="string">
            <enumeration value="Lua"></enumeration>
        </restriction>
    </simpleType>

    <complexType name="ScriptType">
        <simpleContent>
            <extension base="string">
                <attribute name="Language" type="Tethys:ScriptLanguageType" use="required"/>
            </extension>
        </simpleContent>
    </complexType>        

    <complexType name="ExecTestType">
        <attribute name="InputValue" type="Tethys:ConstantTypeList"/>
        <attribute name="OutputValue" type="Tethys:ConstantTypeList"/>
    </complexType>

    <complexType name="ExecType">
        <sequence>
            <element name="Input" type="Tethys:InputType" minOccurs="0" maxOccurs="unbounded"/>
            <sequence minOccurs="0" maxOccurs="1">
                <choice minOccurs="0" maxOccurs="unbounded">
                    <element name="Output" type="Tethys:OutputType"/>
                    <element name="NewOutput" type="Tethys:NewOutputType"/>
                </choice>
                <element name="Test" type="Tethys:ExecTestType" minOccurs="1" maxOccurs="unbounded"/>
            </sequence>
            <element name="Script" type="Tethys:ScriptType"/>
        </sequence>
    </complexType>

    <complexType name="BoolExecTestType">
        <attribute name="InputValue" type="Tethys:ConstantTypeList"/>
        <attribute name="OutputValue" type="boolean" use="required"/>
    </complexType>            
    
    <element name="Test" type="Tethys:BoolExecTestType"/>
    
    <complexType name="BoolExecType">
        <sequence>
            <element name="Input" type="Tethys:InputType" minOccurs="0" maxOccurs="unbounded"/>
            <element name="Test" type="Tethys:BoolExecTestType" minOccurs="2" maxOccurs="unbounded"/>
            <element name="Script" type="Tethys:ScriptType"/>
        </sequence>
    </complexType>

    <complexType name="CustomCommandType">
        <complexContent>
            <extension base="Tethys:SequenceType">
                <sequence>
                    <element name="Initialize" type="Tethys:ExecType" minOccurs="0"/>
                    <element name="Run" type="Tethys:ExecType"/>
                    <element name="IsSatisfied" type="Tethys:BoolExecType" minOccurs="0"/>
                    <element name="Uninitialize" type="Tethys:ExecType" minOccurs="0"/>
                </sequence>
                <attribute name="Name" type="Name" use="required"/>
            </extension>
        </complexContent>
    </complexType>
    
    <element name="CustomCommand" type="Tethys:CustomCommandType" substitutionGroup="Tethys:Item"/>
    
    <complexType name="CustomUriType">
        <complexContent>
            <extension base="Tethys:UriType">
                <attribute name="Uri" type="anyURI" use="required"/>
            </extension>
        </complexContent>
    </complexType>
    
    <element name="CustomUri" substitutionGroup="Tethys:Uri" type="Tethys:CustomUriType"/>

</schema>