﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ImageManifestSchema" 
           elementFormDefault="qualified" 
           targetNamespace="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014"
           xmlns="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="ST_Guid">
    <!-- Any attribute with this type can have a guid with or without braces as valid entries. -->
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <!-- Guid w/ Braces Pattern: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -->
          <xs:pattern value="\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\}"/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <!-- Guid w/o Braces Pattern: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -->
          <xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>

  <xs:simpleType name="ST_GuidValue">
    <!-- Any attribute with this type can have a guid or symbol as valid entries. -->
    <xs:union memberTypes="ST_Guid ST_SymbolReference" />
  </xs:simpleType>

  <xs:simpleType name="ST_IdValue">
    <!-- Any attribute with this type can have an int or symbol as valid entries. -->
    <xs:union memberTypes="ST_NonNegativeInt ST_SymbolReference" />
  </xs:simpleType>

  <xs:simpleType name="ST_MinLengthString">
    <xs:restriction base="xs:string">
      <xs:minLength value="1" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_NativeType">
    <xs:union>
      <!-- This part of the enumeration allows VS Intellisense to suggest values for elements using this type -->
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="PNG" />
          <xs:enumeration value="XAML" />
        </xs:restriction>
      </xs:simpleType>
      <!-- This part of the enumeration allows elements using this type to enter case-insensitive enumeration values -->
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:pattern value="[Pp][Nn][Gg]" />
          <xs:pattern value="[Xx][Aa][Mm][Ll]" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
    
  <xs:simpleType name="ST_NonNegativeInt">
    <xs:restriction base="xs:int">
      <xs:minInclusive value="0" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_PositiveInt">
    <xs:restriction base="xs:int">
      <xs:minExclusive value="0" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_SourceBackgroundType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Light" />
      <xs:enumeration value="Dark" />
      <xs:enumeration value="HighContrast" />
      <xs:enumeration value="HighContrastLight" />
      <xs:enumeration value="HighContrastDark" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_SymbolName">
    <xs:restriction base="xs:string">
      <!-- Symbol Name Pattern: SymbolName follows the same rules as C-based identifiers -->
      <!-- The first char is letter or underscore, and the rest of the identifier can contain letters, numbers, and underscores-->
      <xs:pattern value="[a-zA-Z_]{1}[0-9a-zA-Z_]*"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_SymbolReference">
    <xs:restriction base="xs:string">
      <!-- Symbol Reference Pattern: $(<SymbolName>) where <SymbolName> follows the same rules as C-based identifiers -->
      <!-- The first char is letter or underscore, and the rest of the identifier can contain letters, numbers, and underscores-->
      <xs:pattern value="\$\([a-zA-Z_]{1}[0-9a-zA-Z_]*\)"/>
    </xs:restriction>
  </xs:simpleType>
  
  <xs:element name="ImageManifest">
    <xs:complexType>
      <xs:all>
        <xs:element minOccurs="0" name="Symbols">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:annotation>
                <xs:documentation>Defines a symbol that can be used in place of hard-coded values.</xs:documentation>
              </xs:annotation>
              <xs:element name="Import">
                <xs:annotation>
                  <xs:documentation>[Optional] Imports the symbols from another manifest.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:attribute name="Manifest" use="required" type="ST_MinLengthString" />
                </xs:complexType>
              </xs:element>
              <xs:element name="Guid">
                <xs:annotation>
                  <xs:documentation>[Optional] The symbol is a placeholder for a guid.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:attribute name="Name" use="required" type="ST_SymbolName" />
                  <xs:attribute name="Value" use="required" type="ST_Guid" />
                </xs:complexType>
              </xs:element>
              <xs:element name="ID">
                <xs:annotation>
                  <xs:documentation>[Optional] The symbol is a placeholder for an ID.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:attribute name="Name" use="required" type="ST_SymbolName" />
                  <xs:attribute name="Value" use="required" type="ST_NonNegativeInt" />
                </xs:complexType>
              </xs:element>
              <xs:element name="String">
                <xs:annotation>
                  <xs:documentation>[Optional] The symbol is a placeholder for an arbitrary string.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:attribute name="Name" use="required" type="ST_SymbolName" />
                  <xs:attribute name="Value" use="required" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:choice>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" name="Images">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="Image">
                <xs:annotation>
                  <xs:documentation>Defines an image that can be referenced by a moniker.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Source">
                      <xs:annotation>
                        <xs:documentation>[Required] [Minimum: 1] Defines a single image source asset.</xs:documentation>
                      </xs:annotation>
                      <xs:complexType>
                        <xs:sequence>
                          <xs:choice minOccurs="0">
                            <xs:element name="Size">
                              <xs:annotation>
                                <xs:documentation>[Optional] The source will be used only for the the given value. (If specified, this must be the first child of the source)</xs:documentation>
                              </xs:annotation>
                              <xs:complexType>
                                <xs:attribute name="Value" use="required" type="ST_PositiveInt" />
                              </xs:complexType>
                            </xs:element>
                            <xs:element name="SizeRange">
                              <xs:annotation>
                                <xs:documentation>[Optional] The source will be used between the min/max size inclusively. (If specified, this must be the first child of the source)</xs:documentation>
                              </xs:annotation>
                              <xs:complexType>
                                <xs:attribute name="MinSize" use="required" type="ST_PositiveInt" />
                                <xs:attribute name="MaxSize" use="required" type="ST_PositiveInt" />
                              </xs:complexType>
                            </xs:element>
                            <xs:element name="Dimensions">
                              <xs:annotation>
                                <xs:documentation>[Optional] The source will be used only for the given width and height. (If specified, this must be the first child of the source)</xs:documentation>
                              </xs:annotation>
                              <xs:complexType>
                                <xs:attribute name="Width" use="required" type="ST_PositiveInt" />
                                <xs:attribute name="Height" use="required" type="ST_PositiveInt" />
                              </xs:complexType>
                            </xs:element>
                            <xs:element name="DimensionRange">
                              <xs:annotation>
                                <xs:documentation>[Optional] The source will be used between the min/max width/height inclusively. (If specified, this must be the first child of the source)</xs:documentation>
                              </xs:annotation>
                              <xs:complexType>
                                <xs:attribute name="MinWidth" use="required" type="ST_PositiveInt" />
                                <xs:attribute name="MinHeight" use="required" type="ST_PositiveInt" />
                                <xs:attribute name="MaxWidth" use="required" type="ST_PositiveInt" />
                                <xs:attribute name="MaxHeight" use="required" type="ST_PositiveInt" />
                              </xs:complexType>
                            </xs:element>
                          </xs:choice>
                          <xs:element minOccurs="0" name="NativeResource">
                            <xs:annotation>
                              <xs:documentation>[Optional] The source is defined in a native assembly with the given resource ID and type. (If a size[range] or dimension[range] is specified for the source, this, if specified, must appear after other child.)</xs:documentation>
                            </xs:annotation>
                            <xs:complexType>
                              <xs:attribute name="ID" use="required" type="ST_IdValue" />
                              <xs:attribute name="Type" use="required" type="ST_NativeType" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="Uri" use="required" type="ST_MinLengthString" />
                        <xs:attribute name="Background" use="optional" type="ST_SourceBackgroundType" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="Guid" use="required" type="ST_GuidValue" />
                  <xs:attribute name="ID" use="required" type="ST_IdValue" />
                  <xs:attribute name="AllowColorInversion" use="optional" type="xs:boolean" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" name="ImageLists">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="ImageList">
                <xs:annotation>
                  <xs:documentation>Defines a collection of images that can be returned in a single image strip.</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="ContainedImage">
                      <xs:annotation>
                        <xs:documentation>[Required] [Minimum: 1] An image in the image strip. The order in the image list determines the order in the generated image strip.</xs:documentation>
                      </xs:annotation>
                      <xs:complexType>
                        <xs:attribute name="Guid" use="required" type="ST_GuidValue" />
                        <xs:attribute name="ID" use="required" type="ST_IdValue" />
                        <xs:attribute name="External" use="optional" type="xs:boolean" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="Guid" use="required" type="ST_GuidValue" />
                  <xs:attribute name="ID" use="required" type="ST_IdValue" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:all>
      <xs:attribute name="PackageGuid" use="optional" type="ST_GuidValue" />
    </xs:complexType>
  </xs:element>
  
</xs:schema>
