<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2008-2016 Haulmont.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
  -->

<xs:schema targetNamespace="http://schemas.haulmont.com/cuba/window.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://schemas.haulmont.com/cuba/window.xsd"
           xmlns:views="http://schemas.haulmont.com/cuba/view.xsd"
           xmlns:layout="http://schemas.haulmont.com/cuba/screen/layout.xsd"
           elementFormDefault="qualified">

    <xs:import namespace="http://schemas.haulmont.com/cuba/view.xsd"
               schemaLocation="http://schemas.haulmont.com/cuba/view.xsd"/>

    <xs:include schemaLocation="http://schemas.haulmont.com/cuba/screen/layout.xsd"/>

    <xs:attributeGroup name="isDatasource">
        <xs:attribute name="id" type="xs:string" use="required"/>
        <xs:attribute name="class" type="xs:string"/>
        <xs:attribute name="view" type="xs:string"/>
        <xs:attribute name="allowCommit" type="xs:boolean"/>
        <xs:attribute name="datasourceClass" type="xs:string"/>
    </xs:attributeGroup>

    <xs:attributeGroup name="isCollectionDatasource">
        <xs:attributeGroup ref="isDatasource"/>
        <xs:attribute name="maxResults" type="xs:int"/>
    </xs:attributeGroup>

    <xs:attributeGroup name="isNestedDatasource">
        <xs:attribute name="id" type="xs:string" use="required"/>
        <xs:attribute name="property" type="xs:string" use="required"/>
        <xs:attribute name="datasourceClass" type="xs:string"/>
        <xs:attribute name="allowCommit" type="xs:boolean"/>
    </xs:attributeGroup>

    <!-- Utils -->

    <xs:complexType name="companionType">
        <xs:attribute name="class" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="filterType">
        <xs:choice>
            <xs:element name="c" type="filterClauseType" minOccurs="0"/>
            <xs:element name="and" type="filterLogicalType" minOccurs="0"/>
            <xs:element name="or" type="filterLogicalType" minOccurs="0"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="filterClauseType" mixed="true">
        <xs:attribute name="join" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="filterLogicalType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="c" type="filterClauseType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="and" type="filterLogicalType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="or" type="filterLogicalType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
    </xs:complexType>

    <xs:simpleType name="refreshMode">
        <xs:restriction base="xs:string">
            <xs:enumeration value="ALWAYS"/>
            <xs:enumeration value="NEVER"/>
        </xs:restriction>
    </xs:simpleType>

    <!-- Datasources -->

    <!-- CollectionDatasource -->
    <xs:complexType name="collectionDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:group ref="nestedDatasources" minOccurs="0"/>
        </xs:sequence>

        <xs:attributeGroup ref="isCollectionDatasource"/>

        <xs:attribute name="query" type="xs:string"/>
        <xs:attribute name="refreshMode" type="refreshMode"/>
        <xs:attribute name="softDeletion" type="xs:boolean"/>
        <xs:attribute name="cacheable" type="xs:boolean"/>
        <xs:attribute name="loadDynamicAttributes" type="xs:boolean"/>
    </xs:complexType>

    <!-- HierarchicalDatasource -->
    <xs:complexType name="hierarchicalDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:group ref="nestedDatasources" minOccurs="0"/>
        </xs:sequence>

        <xs:attributeGroup ref="isCollectionDatasource"/>

        <xs:attribute name="query" type="xs:string"/>
        <xs:attribute name="hierarchyProperty" type="xs:string"/>
        <xs:attribute name="refreshMode" type="refreshMode"/>
        <xs:attribute name="softDeletion" type="xs:boolean"/>
        <xs:attribute name="cacheable" type="xs:boolean"/>
        <xs:attribute name="loadDynamicAttributes" type="xs:boolean"/>
    </xs:complexType>

    <!-- GroupDatasource -->
    <xs:complexType name="groupDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"
                        />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:group ref="nestedDatasources" minOccurs="0"/>
        </xs:sequence>

        <xs:attributeGroup ref="isCollectionDatasource"/>

        <xs:attribute name="query" type="xs:string"/>
        <xs:attribute name="refreshMode" type="refreshMode"/>
        <xs:attribute name="softDeletion" type="xs:boolean"/>
        <xs:attribute name="cacheable" type="xs:boolean"/>
        <xs:attribute name="loadDynamicAttributes" type="xs:boolean"/>
    </xs:complexType>

    <!-- RuntimePropsDatasource -->
    <xs:complexType name="runtimePropsDatasourceType">
        <xs:sequence>
            <xs:group ref="nestedDatasources"/>
        </xs:sequence>

        <xs:attribute name="id" type="xs:string" use="required"/>

        <xs:attribute name="mainDs" type="xs:string" use="required"/>
        <xs:attribute name="categorizedEntityClass" type="xs:string"/>
    </xs:complexType>

    <!-- ValueCollectionDatasource -->
    <xs:complexType name="valueCollectionDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="properties" type="valueDatasourcePropertiesType"/>
        </xs:sequence>

        <xs:attribute name="id" type="xs:string" use="required"/>
        <xs:attribute name="maxResults" type="xs:int"/>
        <xs:attribute name="store" type="xs:string"/>
        <xs:attribute name="datasourceClass" type="xs:string"/>
    </xs:complexType>

    <!-- ValueGroupDatasource -->
    <xs:complexType name="valueGroupDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="properties" type="valueDatasourcePropertiesType"/>
        </xs:sequence>

        <xs:attribute name="id" type="xs:string" use="required"/>
        <xs:attribute name="maxResults" type="xs:int"/>
        <xs:attribute name="store" type="xs:string"/>
        <xs:attribute name="datasourceClass" type="xs:string"/>
    </xs:complexType>

    <!-- ValueHierarchicalDatasource -->
    <xs:complexType name="valueHierarchicalDatasourceType">
        <xs:sequence>
            <xs:element name="query" minOccurs="0">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="filter" type="filterType" minOccurs="0"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="properties" type="valueDatasourcePropertiesType"/>
        </xs:sequence>

        <xs:attribute name="id" type="xs:string" use="required"/>
        <xs:attribute name="maxResults" type="xs:int"/>
        <xs:attribute name="store" type="xs:string"/>
        <xs:attribute name="hierarchyProperty" type="xs:string"/>
        <xs:attribute name="datasourceClass" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="valueDatasourcePropertiesType">
        <xs:sequence>
            <xs:element name="property" maxOccurs="unbounded">
                <xs:complexType mixed="true">
                    <xs:attribute name="name" type="xs:string" use="required"/>
                    <xs:attribute name="datatype" type="layout:datatypeEnum"/>
                    <xs:attribute name="class" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="properties" minOccurs="0" type="valueDatasourcePropertiesType"/>
        </xs:sequence>

        <xs:attribute name="idProperty" type="xs:string"/>
    </xs:complexType>

    <!-- PropertyDatasource -->
    <xs:group name="nestedDatasources">
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="datasource" minOccurs="0" maxOccurs="unbounded" type="nestedDs"/>
                <xs:element name="collectionDatasource" minOccurs="0" maxOccurs="unbounded" type="nestedDs"/>
                <xs:element name="groupDatasource" minOccurs="0" maxOccurs="unbounded" type="nestedDs"/>
                <xs:element name="hierarchicalDatasource" minOccurs="0" maxOccurs="unbounded"
                            type="nestedHierarchicalDs"/>
            </xs:choice>
        </xs:sequence>
    </xs:group>

    <!-- CollectionPropertyDatasource -->
    <xs:complexType name="nestedDs">
        <xs:sequence>
            <xs:group ref="nestedDatasources"/>
        </xs:sequence>
        <xs:attributeGroup ref="isNestedDatasource"/>
    </xs:complexType>

    <!-- HierarchicalPropertyDatasource -->
    <xs:complexType name="nestedHierarchicalDs">
        <xs:sequence>
            <xs:group ref="nestedDatasources"/>
        </xs:sequence>
        <xs:attributeGroup ref="isNestedDatasource"/>
        <xs:attribute name="hierarchyProperty" type="xs:string"/>
    </xs:complexType>

    <!-- Datasource -->
    <xs:complexType name="datasourceType">
        <xs:sequence>
            <xs:group ref="nestedDatasources"/>
        </xs:sequence>
        <xs:attributeGroup ref="isDatasource"/>
        <xs:attribute name="loadDynamicAttributes" type="xs:boolean"/>
    </xs:complexType>

    <!-- Window -->
    <xs:element name="window">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="companions" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="web" type="companionType" minOccurs="0"/>
                            <xs:element name="desktop" type="companionType" minOccurs="0"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="metadataContext" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="deployViews" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:attribute name="name" type="xs:string"/>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="view" type="views:viewType" minOccurs="0" maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="dsContext" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:choice minOccurs="0" maxOccurs="unbounded">
                                <xs:element name="datasource" type="datasourceType"/>
                                <xs:element name="groupDatasource" type="groupDatasourceType"/>
                                <xs:element name="collectionDatasource" type="collectionDatasourceType"/>
                                <xs:element name="hierarchicalDatasource" type="hierarchicalDatasourceType"/>
                                <xs:element name="runtimePropsDatasource" type="runtimePropsDatasourceType"/>
                                <xs:element name="valueCollectionDatasource" type="valueCollectionDatasourceType"/>
                                <xs:element name="valueGroupDatasource" type="valueGroupDatasourceType"/>
                                <xs:element name="valueHierarchicalDatasource" type="valueHierarchicalDatasourceType"/>
                            </xs:choice>
                        </xs:sequence>
                        <xs:attribute name="class" type="xs:string"/>
                    </xs:complexType>
                </xs:element>
                <xs:element name="timers" minOccurs="0" type="layout:timer"/>
                <xs:element name="actions" minOccurs="0" type="frameActions"/>
                <xs:element name="assign" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="name" use="required"/>
                        <xs:attribute name="value" use="required"/>
                    </xs:complexType>
                </xs:element>

                <xs:element name="dialogMode" minOccurs="0" type="layout:dialogMode"/>

                <xs:element name="layout">
                    <xs:complexType>
                        <xs:complexContent>
                            <xs:extension base="layout:rootLayout">
                                <xs:attribute name="minHeight" type="layout:componentSize"/>
                                <xs:attribute name="minWidth" type="layout:componentSize"/>

                                <xs:attribute name="maxHeight" type="layout:componentSize"/>
                                <xs:attribute name="maxWidth" type="layout:componentSize"/>
                            </xs:extension>
                        </xs:complexContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>

            <xs:attribute name="extends" type="xs:string"/>
            <xs:attribute name="class" type="xs:string"/>
            <xs:attribute name="icon" type="xs:string"/>
            <xs:attribute name="messagesPack" type="xs:string"/>
            <xs:attribute name="lookupComponent" type="xs:string"/>

            <xs:attribute name="datasource" type="xs:string"/>
            <xs:attribute name="dataSupplier" type="xs:string"/>
            <xs:attribute name="caption" type="layout:resourceString"/>
            <xs:attribute name="description" type="layout:resourceString"/>
            <xs:attribute name="focusComponent" type="xs:string"/>
            <xs:attribute name="crossFieldValidate" type="xs:boolean"/>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="frameActions">
        <xs:sequence>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="action" type="layout:frameAction"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
</xs:schema>