<?xml version="1.0" encoding="UTF-8"?>
<grammar 
  xmlns="http://relaxng.org/ns/structure/1.0"
  xmlns:ev="http://www.w3.org/2001/xml-events"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
  ns="http://jelix.org/ns/forms/1.1">

  <start>
    <element name="form">
      <optional><attribute name="allowAnyOrigin">
        <choice><value>true</value><value>false</value></choice>
        </attribute></optional>
      <ref name="form.controls" />
    </element>
  </start>

  <!--  ==================  Controls  ==========================  -->

   <define name="form.controls">
      <oneOrMore>
        <choice>
            <ref name="primary_controls" />
            <ref name="group" />
            <ref name="submit" />
            <ref name="choice" />
            <ref name="captcha" />
            <ref name="image" />
            <!--
            <ref name="range" />
            -->
        </choice>
      </oneOrMore>
      <optional>
        <ref name="reset" />
      </optional>
  </define>

  <define name="primary_controls">
    <ref name="input" />
    <ref name="textarea" />
    <ref name="htmleditor" />
    <ref name="wikieditor" />
    <ref name="secret" />
    <ref name="output" />
    <ref name="upload" />
    <ref name="upload2" />
    <ref name="checkbox" />
    <ref name="checkboxes" />
    <ref name="listbox" />
    <ref name="radiobuttons"/>
    <ref name="menulist" />
    <ref name="hidden" />
    <ref name="date" />
    <ref name="datetime" />
    <ref name="button"/>
  </define>


  <define name="input">
     <element name="input">
         <ref name="control.common" />
         <choice>
            <group>
                <attribute name="type"><value>string</value></attribute>
                <ref name="attr.length" />
                
                <optional><attribute name="pattern" /></optional>
            </group>
            <group>
                <attribute name="type"><value>integer</value></attribute>
                <ref name="attr.range" />
            </group>
            <group>
                <attribute name="type"><value>decimal</value></attribute>
                <ref name="attr.range" />
            </group>
            <group>
                <attribute name="type"><value>html</value></attribute>
                <ref name="attr.length" />
            </group>
            <attribute name="type">
                <choice>
                    <value>boolean</value>
                    <value>decimal</value>
                    <value>integer</value>
                    <value>hexadecimal</value>
                    <value>datetime</value>
                    <value>date</value>
                    <value>time</value>
                    <value>localedatetime</value>
                    <value>localedate</value>
                    <value>localetime</value>
                    <value>url</value>
                    <value>email</value>
                    <value>ipv4</value>
                    <value>ipv6</value>
                    <value>html</value>
                    <value>xhtml</value>
                </choice>
            </attribute>
        </choice>
        <ref name="attr.size" />
       <ref name="UI.attr.readonly" />
       <ref name="UI.attr.required" />
       <ref name="UI.attr.defaultvalue" />
       <ref name="emptyvaluelabel" />
     </element>
  </define>

  <define name="textarea">
     <element name="textarea">
       <ref name="textarea.common" />
       <optional><attribute name="type">
            <choice>
              <value>html</value>
              <value>xhtml</value>
            </choice>
       </attribute></optional>
     </element>
  </define>

  <define name="htmleditor">
     <element name="htmleditor">
       <ref name="textarea.common" />
       <optional><attribute name="xhtml">
          <choice><value>true</value><value>false</value></choice>
       </attribute></optional>
       <optional><attribute name="config" /></optional>
       <optional><attribute name="skin" /></optional>
     </element>
  </define>

  <define name="wikieditor">
     <element name="wikieditor">
       <ref name="textarea.common" />
       <optional><attribute name="config" /></optional>
     </element>
  </define>

  <define name="textarea.common">
      <ref name="control.common" />
      <ref name="UI.attr.readonly" />
      <ref name="UI.attr.required" />
      <ref name="UI.attr.defaultvalue" />
      <ref name="attr.length" />
      <ref name="emptyvaluelabel" />
      <optional><attribute name="rows"><data type="integer" /></attribute></optional>
      <optional><attribute name="cols"><data type="integer" /></attribute></optional>
  </define>
  
  <define name="secret">
     <element name="secret">
       <ref name="control.common" />
       <ref name="UI.attr.readonly" />
       <ref name="UI.attr.required" />
       <ref name="attr.length" />
       <ref name="attr.size" />
       <optional><attribute name="pattern" /></optional>
       <optional>
          <element name="confirm">
            <choice>
                <text />
                <group>
                    <empty/>
                    <attribute name="locale" />
                </group>
            </choice>
          </element>
       </optional>
       <ref name="emptyvaluelabel" />
     </element>
  </define>


  <define name="upload">
     <element name="upload">
       <ref name="control.common" />
       <ref name="UI.attr.readonly" />
       <ref name="UI.attr.required" />
       <optional><attribute name="mimetype" /></optional>
       <optional><attribute name="maxsize"><data type="integer" /></attribute></optional>
       <!--<element name="storage">
           <attribute name="type"><choice><value>file</value><value>blob</value></choice></attribute>
           <attribute name="value" /> 
       </element>
       -->
       <ref name="emptyvaluelabel" />
     </element>
  </define>

    <define name="upload2">
        <element name="upload2">
            <ref name="control.common" />
            <ref name="UI.attr.readonly" />
            <ref name="UI.attr.required" />
            <optional><attribute name="mimetype" /></optional>
            <optional><attribute name="maxsize"><data type="integer" /></attribute></optional>
            <ref name="emptyvaluelabel" />
        </element>
    </define>

    <define name="image">
        <element name="image">
            <ref name="control.common" />
            <ref name="UI.attr.readonly" />
            <ref name="UI.attr.required" />
            <optional><attribute name="mimetype" /></optional>
            <optional><attribute name="maxsize"><data type="integer" /></attribute></optional>
            <optional><attribute name="maxWidth"><data type="integer" /></attribute></optional>
            <optional><attribute name="maxHeight"><data type="integer" /></attribute></optional>
            <ref name="emptyvaluelabel" />
        </element>
    </define>

    <define name="checkbox">
     <element name="checkbox">
       <ref name="control.common" />
       <ref name="UI.attr.readonly" />
       <ref name="UI.attr.required" />
       <ref name="UI.attr.defaultvalue" />
       <optional>
          <choice>
            <attribute name="valueoncheck" />
            <element name="oncheckvalue">
                 <choice>
                     <attribute name="locale" />
                     <attribute name="label" />
                 </choice>
            </element>
          </choice>
        </optional>
       <optional>
          <choice>
            <attribute name="valueonuncheck" />
            <element name="onuncheckvalue">
                 <choice>
                     <attribute name="locale" />
                     <attribute name="label" />
                 </choice>
            </element>
          </choice>
        </optional>
     </element>
  </define>

  <define name="listbox">
     <element name="listbox">
       <ref name="control.common" />
       <ref name="control.list.common" />
       <ref name="attr.size" />
       <ref name="emptyvaluelabel" />
       <optional>
            <attribute name="multiple">
                <choice><value>true</value><value>false</value></choice>
            </attribute>
       </optional>
       <optional><element name="emptyitem"><ref name="message.content" /></element></optional>
     </element>
  </define>

  <define name="menulist">
     <element name="menulist">
       <interleave>
            <ref name="control.common" />
            <ref name="control.list.common" />
            <optional><element name="emptyitem"><ref name="message.content" /></element></optional>
            <ref name="emptyvaluelabel" />
        </interleave>
     </element>
  </define>

  <define name="checkboxes">
     <element name="checkboxes">
       <ref name="control.common" />
       <ref name="control.list.common" />
       <ref name="emptyvaluelabel" />
     </element>
  </define>

  <define name="radiobuttons">
     <element name="radiobuttons">
       <ref name="control.common" />
       <ref name="control.list.common" />
       <ref name="emptyvaluelabel" />
     </element>
  </define>
  <define name="output">
     <element name="output">
       <ref name="control.common" />
       <ref name="UI.attr.defaultvalue" />
       <ref name="emptyvaluelabel" />
     </element>
  </define>

  <define name="submit">
     <element name="submit">
       <ref name="control.common" />
       <ref name="datasources" />
     </element>
  </define>

  <define name="reset">
     <element name="reset">
       <ref name="control.common" />
     </element>
  </define>

  <define name="hidden">
     <element name="hidden">
       <attribute name="ref" />
       <ref name="UI.attr.defaultvalue" />
     </element>
  </define>

  <define name="captcha">
     <element name="captcha">
       <ref name="control.common" />
     </element>
  </define>

  <define name="group">
     <element name="group">
        <attribute name="ref" />
        <ref name="label" />
        <ref name="UI.attr.readonly" />
        <oneOrMore>
            <choice>
                <ref name="primary_controls" />
            </choice>
        </oneOrMore>
     </element>
  </define>

  <define name="choice">
     <element name="choice">
        <ref name="control.common" />
        <ref name="UI.attr.readonly" />
        <ref name="UI.attr.required" />
        <optional><attribute name="selectedvalue" /></optional>
        <oneOrMore>
            <element name="item">
                <attribute name="value" />
                <optional>
                    <attribute name="selected">
                        <choice><value>true</value><value>false</value></choice>
                    </attribute>
                </optional>
                <ref name="label" />
                <zeroOrMore>
                    <ref name="primary_controls" />
                </zeroOrMore>
            </element>
        </oneOrMore>
     </element>
  </define>

  <define name="date">
    <element name="date">
      <ref name="control.common" />
      <ref name="UI.attr.readonly" />
      <ref name="UI.attr.required" />
      <ref name="UI.attr.defaultvalue" />
      <optional><attribute name="mindate"/></optional>
      <optional><attribute name="maxdate"/></optional>
      <optional><attribute name="datepicker"/></optional>
      <ref name="emptyvaluelabel" />
    </element>
  </define>

  <define name="datetime">
    <element name="datetime">
      <ref name="control.common" />
      <ref name="UI.attr.readonly" />
      <ref name="UI.attr.required" />
      <ref name="UI.attr.defaultvalue" />
      <ref name="emptyvaluelabel" />
      <optional><attribute name="mindate"/></optional>
      <optional><attribute name="maxdate"/></optional>
      <optional><attribute name="datepicker"/></optional>
      <optional><attribute name="seconds"><choice><value>true</value><value>false</value></choice></attribute></optional>
    </element>
  </define>

  <define name="button">
      <attribute name="ref" />
      <ref name="label" />
      <ref name="UI.attr.defaultvalue" />
  </define>

  <define name="control.common">
     <attribute name="ref" />
     <interleave>
        <ref name="label" />
        <optional>
            <ref name="help" />
        </optional>
        <optional>
            <ref name="hint" />
        </optional>
        <optional>
            <ref name="alert" />
        </optional>
     </interleave>
  </define>

  <define name="UI.attr.readonly">
      <optional><attribute name="readonly"><choice><value>true</value><value>false</value></choice></attribute></optional>
  </define>
  <define name="UI.attr.required">
      <optional><attribute name="required"><choice><value>true</value><value>false</value></choice></attribute></optional>
  </define>
  <define name="UI.attr.defaultvalue">
      <optional><attribute name="defaultvalue" /></optional>
  </define>

  <define name="attr.length">
      <optional><attribute name="minlength"><data type="integer" /></attribute></optional>
      <optional><attribute name="maxlength"><data type="integer" /></attribute></optional>
  </define>
  <define name="attr.range">
      <optional><attribute name="minvalue"><data type="integer" /></attribute></optional>
      <optional><attribute name="maxvalue"><data type="integer" /></attribute></optional>
  </define>

  <define name="attr.size">
      <optional><attribute name="size"><data type="integer" /></attribute></optional>
  </define>

  <define name="emptyvaluelabel">
    <optional>
        <element name="emptyvaluelabel">
          <choice>
              <text />
              <empty />
              <group>
                  <attribute name="locale" />
                  <empty/>
              </group>
          </choice>
        </element>
    </optional>
  </define>


  <define name="control.list.common">
     <ref name="UI.attr.readonly" />
     <ref name="UI.attr.required" />
    <ref name="datasources" />
    <optional>
        <choice>
            <attribute name="selectedvalue" />
            <element name="selectedvalues">
                <oneOrMore>
                    <element name="value"><text/></element>
                </oneOrMore>
            </element>
        </choice>
    </optional>
  </define>

  <define name="datasources">
     <optional><choice>
        <ref name="datasource" />
        <ref name="datasources.items" />
        <ref name="datasources.dao" />
        <ref name="datasources.class" />
    </choice></optional>
  </define>

  <define name="datasources.items">
     <oneOrMore>
        <choice>
          <ref name="datasources.item" />
          <element name="itemgroup">
              <choice>
                  <attribute name="label" />
                  <attribute name="locale"/>
              </choice>
              <ref name="datasources.item" />
          </element>
        </choice>
    </oneOrMore>
  </define>
  
  <define name="datasources.item">
    <element name="item">
        <choice>
            <text />
            <empty />
            <group>
                <attribute name="locale" />
                <empty/>
            </group>
        </choice>
        <optional><attribute name="selected"><choice><value>true</value><value>false</value></choice></attribute></optional>
        <attribute name="value" />
    </element>
  </define>

  <define name="datasources.dao">
      <attribute name="dao" />
      <attribute name="daomethod" />
      <attribute name="daolabelproperty" />
      <optional><attribute name="daovalueproperty" /></optional>
  </define>

  <define name="datasources.class">
      <attribute name="dsclass" />
  </define>

  <define name="datasource">
    <element name="datasource">
        <choice>
            <group>
                <attribute name="dao" />
                <attribute name="method" />
                <attribute name="labelproperty" />
                <optional><attribute name="profile" /></optional>
                <optional><attribute name="labelseparator" /></optional>
                <optional><attribute name="valueproperty" /></optional>
                <optional><attribute name="groupby" /></optional>
                <optional>
                    <choice>
                        <attribute name="criteria" />
                        <attribute name="criteriafrom" />
                    </choice>
                </optional>
            </group>
            <group>
              <attribute name="class" />
              <optional><attribute name="groupby" /></optional>
            </group>
        </choice>
    </element>
  </define>

  <define name="message.content">
      <choice>
          <text />
          <attribute name="locale" />
      </choice>
  </define>

  <define name="label">
     <element name="label">
        <ref name="message.content" />
     </element>
  </define>

  <define name="help">
     <element name="help">
        <ref name="message.content" />
     </element>
  </define>

  <define name="hint">
     <element name="hint">
        <ref name="message.content" />
     </element>
  </define>

  <define name="alert">
     <element name="alert">
        <optional>
           <attribute name="type">
                <choice>
                    <value>required</value>
                    <value>invalid</value>
                </choice>
            </attribute>
        </optional>
        <ref name="message.content" />
     </element>
  </define>

   <!--
   <define name="any">
      <element>
         <anyName/>
         <zeroOrMore>
            <choice>
               <attribute>
                  <anyName/>
               </attribute>
               <text/>
               <ref name="any"/>
            </choice>
         </zeroOrMore>
      </element>
   </define>
-->
  <!--
      <define name="range">
          <element name="range">
              <ref name="control.common" />
              <ref name="UI.Common.Attrs" />
              <optional><attribute name="start"/></optional>
              <optional><attribute name="end"/></optional>
              <optional><attribute name="step"/></optional>
              <optional><attribute name="incremental"><data type="boolean" /></attribute></optional>
          </element>
      </define>

  -->
  

</grammar>