<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://schemas.cybozu.co.jp/base/2008"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://schemas.cybozu.co.jp/base/2008"
            elementFormDefault="qualified"
            >

  <!-- Base -->
  <xsd:element name="base">
    <xsd:complexType>
      <xsd:all>
        <xsd:element ref="users" minOccurs="0" />
        <xsd:element ref="organizations" minOccurs="0" />
        <xsd:element ref="static_groups" minOccurs="0" />
        <xsd:element ref="dynamic_groups" minOccurs="0" />
        <xsd:element ref="posts" minOccurs="0" />
        <xsd:element ref="post_relations" minOccurs="0" />
        <xsd:element ref="acl" minOccurs="0" />
      </xsd:all>
    </xsd:complexType>
  </xsd:element>

  <!-- Users -->
  <xsd:element name="users">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="user" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <!-- User -->
  <xsd:element name="user" type="UserType">
    <xsd:key name="user_key">
      <xsd:selector xpath="user" />
      <xsd:field xpath="@key" />
    </xsd:key>
  </xsd:element>

  <xsd:complexType name="UserType">
    <xsd:sequence>
      <xsd:element name="photo" minOccurs="0" maxOccurs="1">
        <xsd:complexType>
          <xsd:attribute name="file_id" type="IDType" use="required" />
          <xsd:attribute name="version" type="VersionType" use="required" />
          <xsd:attribute name="name" type="NonBlankStringType" use="required" />
          <xsd:attribute name="size" type="xsd:unsignedLong" use="optional" />
          <xsd:attribute name="mime_type" type="xsd:string" use="optional" />
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="organization" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:attribute name="id" type="IDType" use="required" />
          <xsd:anyAttribute processContents="lax" />
        </xsd:complexType>
      </xsd:element>
      <xsd:element ref="acl" minOccurs="0" maxOccurs="1" />
      <xsd:any processContents ="skip" minOccurs="0" maxOccurs="unbounded" namespace="##local" />
    </xsd:sequence>
    <xsd:attribute name="key" type="IDType" use="required" />
    <xsd:attribute name="version" type="VersionType" use="required" />
    <xsd:attribute name="order" type="xsd:unsignedLong" use="optional" />
    <xsd:attribute name="name" type="xsd:string" use="optional" />
    <xsd:attribute name="status" type="xsd:byte" use="optional" />
    <xsd:attribute name="reading" type="xsd:string" use="optional" />
    <xsd:attribute name="url" type="xsd:string" use="optional" />
    <xsd:attribute name="email" type="xsd:string" use="optional" />
    <xsd:attribute name="phone" type="xsd:string" use="optional" />
    <xsd:attribute name="birth_date" type="xsd:date" default="1970-01-01" use="optional" />
    <xsd:attribute name="join_date" type="xsd:date" default="1970-01-01" use="optional" />
    <xsd:attribute name="employee_number" type="xsd:string" use="optional" />
    <xsd:attribute name="extension_number" type="xsd:string" use="optional" />
    <xsd:attribute name="employment_pattern" type="xsd:string" use="optional" />
    <xsd:attribute name="title" type="xsd:string" use="optional" />
    <xsd:attribute name="office" type="xsd:string" use="optional" />
    <xsd:attribute name="description" type="xsd:string" use="optional" />
    <xsd:attribute name="primary_organization" type="IDType" use="optional" />
    <xsd:anyAttribute processContents="lax" />
  </xsd:complexType>

  <!-- Posts -->
  <xsd:element name="posts">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="post" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="post" type="ListType" />

  <!-- Post Relation -->
  <xsd:element name="post_relations">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="post_relation" minOccurs="0" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element ref="organization" minOccurs="1" maxOccurs="1" />
              <xsd:element ref="post" minOccurs="1" maxOccurs="1" />
              <xsd:element ref="user" minOccurs="1" maxOccurs="1" />
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <!-- List Type -->
  <xsd:complexType name="ListType">
    <xsd:attribute name="key" type="IDType" use="required" />
    <xsd:attribute name="name" type="xsd:string" use="required" />
    <xsd:attribute name="order" type="xsd:unsignedLong" use="optional" />
    <xsd:attribute name="description" type="xsd:string" />
  </xsd:complexType>
  
  <!-- Organizations -->
  <xsd:element name="organizations">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="organization" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <!-- Organization -->
  <xsd:element name="organization" type="OrganizationType">
    <xsd:key name="organization_key">
      <xsd:selector xpath="organization" />
      <xsd:field xpath="@key" />
    </xsd:key>
  </xsd:element>

  <!-- Organization Type -->
  <xsd:complexType name="OrganizationType">
    <xsd:complexContent>
      <xsd:extension base="GroupType">
        <xsd:sequence>
          <xsd:element ref="organization" minOccurs ="0" maxOccurs="unbounded" />
          <xsd:element name="members" type="MembersType" minOccurs="0" maxOccurs="1" />
          <xsd:element ref="acl" minOccurs="0" maxOccurs="1" />
          <xsd:any processContents ="skip" minOccurs="0" maxOccurs="unbounded" namespace="##local" />
        </xsd:sequence>
        <xsd:attribute name="parent_organization" type="IDType" use="optional" />
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <!-- Static Groups  -->
  <xsd:element name="static_groups">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="static_group" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="static_group">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="GroupType">
          <xsd:sequence>
            <xsd:element name="members" type="MembersType" minOccurs="1" maxOccurs="1" />
            <xsd:element ref="acl" minOccurs="0" maxOccurs="1" />
            <xsd:any processContents ="skip" minOccurs="0" maxOccurs="unbounded" namespace="##local" />
          </xsd:sequence>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
    <xsd:key name="static_group_key">
      <xsd:selector xpath="static_group" />
      <xsd:field xpath="@key" />
    </xsd:key>
  </xsd:element>

  <!-- Dynamic Group -->
  <xsd:element name="dynamic_groups">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="dynamic_group" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <xsd:element name="dynamic_group">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="GroupType">
          <xsd:sequence>
            <xsd:element ref="acl" minOccurs="0" maxOccurs="1" />
            <xsd:any processContents ="skip" minOccurs="0" maxOccurs="unbounded" namespace="##local" />
          </xsd:sequence>
          <xsd:attribute name="condition" type="xsd:string" />
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
    <xsd:key name="dynamic_group_key">
      <xsd:selector xpath="dynamic_group" />
      <xsd:field xpath="@key" />
    </xsd:key>
  </xsd:element>

  <!-- Group type -->
  <xsd:complexType name="GroupType">
    <xsd:attribute name="key" type="IDType" use="required" />
    <xsd:attribute name="name" type="xsd:string" use="required" />
    <xsd:attribute name="version" type="VersionType" use="required" />
    <xsd:attribute name="description" type="xsd:string" use="optional" />
    <xsd:attribute name="order" type="xsd:unsignedLong" use="optional" />
  </xsd:complexType>

  <!-- Members Type -->
  <xsd:complexType name="MembersType">
    <xsd:sequence>
      <xsd:element name="user" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:attribute name="id" type="IDType" use="required" />
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- File Type -->
  <xsd:complexType name="FileType">
    <xsd:sequence>
      <xsd:element name="content" type="xsd:base64Binary" minOccurs="1" maxOccurs="1" />
    </xsd:sequence>
    <xsd:attribute name="id" type="IDType" use="required" />
    <xsd:attribute name="version" type="VersionType" use="required" />
    <xsd:attribute name="name" type="xsd:string" use="required" />
    <xsd:attribute name="size" type="xsd:unsignedLong" use="optional" />
    <xsd:attribute name="mime_type" type="xsd:string" use="optional" />
  </xsd:complexType>

  <!-- ACL -->
  <xsd:element name="acl">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="ace" type="AceType" minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <!-- ACE -->
  <xsd:complexType name="AceType">
    <xsd:choice>
      <xsd:element ref="user" />
      <xsd:element ref="static_group" />
      <xsd:element ref="dynamic_group" />
      <xsd:element ref="organization" />
    </xsd:choice>
    <xsd:attribute name="action" type="xsd:string" use="required" />
    <xsd:attribute name="rights" type="RightsType" use="required" />
    <xsd:attribute name="quick" type="xsd:boolean" default="false" use="optional" />
    <xsd:attribute name="order" type="xsd:unsignedLong" use="optional" />
  </xsd:complexType>

  <xsd:simpleType name="RightsType">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="allow" />
      <xsd:enumeration value="deny" />
    </xsd:restriction>
  </xsd:simpleType>

  <!-- Basic Types -->

  <xsd:simpleType name="NonBlankStringType">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1" /> 
    </xsd:restriction>
  </xsd:simpleType>

  <!-- Text -->
  <xsd:complexType name="TextType">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
        Each "Text" type element can contain two types of text data, 
        one is plain text, and the other is html markup text.
        Since a plain text element is useful for text search application,
        a "Text" type element must have one child element which is plain text
        when it contains a html markupe body element.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="plain" type="xsd:string" minOccurs="1" maxOccurs="1" />
      <xsd:element name="markup" minOccurs="0" maxOccurs="1">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:any processContents ="skip" minOccurs="0" maxOccurs="unbounded" namespace="##any" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="ChangeLogType">
    <xsd:attribute name="user_id" type="IDType" use="optional" />
    <xsd:attribute name="name" type="NonBlankStringType" use="required" />
    <xsd:attribute name="date" type="xsd:dateTime" use="required" />
  </xsd:complexType>

  <xsd:simpleType name="IPPhoneURIType">
    <xsd:restriction base="xsd:anyURI">
      <xsd:pattern value="callto:.*" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="IDType">
    <xsd:restriction base="NonBlankStringType" />
  </xsd:simpleType>

  <xsd:simpleType name="VersionType">
    <xsd:restriction base="NonBlankStringType" />
  </xsd:simpleType>

    <!-- Region Type-->
  <xsd:complexType name="RegionType">
    <xsd:sequence>
        <xsd:element name="city" minOccurs="0" maxOccurs="unbounded">
            <xsd:complexType>
                <xsd:attribute name="name" type="xsd:string"/>
                <xsd:attribute name="timezone" type="xsd:string"/>
            </xsd:complexType>
        </xsd:element>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string"/>
  </xsd:complexType>

</xsd:schema>
