/* -*- c++ -*- */
#ifndef AKAXISO_SCHEMASTRUCTURE_H__
#define AKAXISO_SCHEMASTRUCTURE_H__

#define NS_XMLSCHEMA "http://www.w3.org/2001/XMLSchema"

#include <akaxiso/schema/schemadatatypes.h>
#include <list>
#include <sstream>

namespace xs {

  typedef std::list<aka::item> typeDefParticle;
  typedef std::string reduycedDerivationControl; // extension, restriction.
  typedef std::string blockSet; // extension, restriction, substitution.
  typedef long allNNI; // 0, 1, 2, 3, 4, ..... unbounded.


  typedef std::string derivationSet; // extension/restriction.


  struct occurs {
    nonNegativeInteger minOccurs_;
    allNNI maxOccurs_;
  };

  
  typedef std::list<aka::item> particle;
  typedef std::list<aka::item> nestedParticle;

  typedef std::string formChoice; // qualified / unqualified. !!!!!!

  typedef std::list<aka::item> particle;

  struct defRef {
    NCName name_;
    QName ref_;
  };

  typedef std::string useValue; // prohibited, optional, required. !!!!!!!!

  struct attribute : annotated, defRef {
    aka::deep_ptr<localSimpleType> simpleType_;
    QName type_;
    useValue use_;
    std::string default_;
    std::string fixed_;
    formChoice form_;
  };



  typedef aka::any anyAttribute;

  typedef std::list<aka::item> attributeChoice;


  struct attributeGroupRef : annotated {
    QName ref_;
  };

  struct attrDecls {
    attributeChoice choice_;
    attributeGroupRef attributeGroup_;
    aka::deep_ptr<anyAttribute> anyAttribute_;
  };


  struct attributeGroup : annotated, defRef {
    attrDecls attrDecls_;
  };


  typedef std::list<aka::item> restrictionContent;
  struct restrictionType : annotated {
    restrictionContent content_;
    attrDecls attrDecls_;
    QName base_;
  };


  struct simpleRestrictionType : annotated {
    aka::deep_ptr<simpleRestrictionModel> simpleRestrictionModel_;
    attrDecls attrDecls_;
    QName base_;
  };

  struct topLevelAttribute : attribute {  
    localSimpleType simpeType_;
    QName type_;
    std::string default_;
    std::string fixed_;
    NCName name_;
  };

  struct extensionType : public annotated {
    typeDefParticle typeDefParticle_;
    attrDecls attrDecls_;
    QName base_;
  };

  struct simpleExtensionType : public annotated {
    attrDecls attrDecls_;
    QName base_;
  };

  struct contentDef {
    typeDefParticle particle_;
    attrDecls attrDecls_;
  };

  typedef std::list<aka::item> complexTypeModel;

  struct complexType : public annotated {
    complexTypeModel model_;
    NCName name_;
    bool mixed_;
    bool abstract_;
    derivationSet final_;
    derivationSet block_;
  protected:
    complexType(){}
  };


  struct topLevelComplexType : public annotated {
    complexTypeModel model_;
    NCName name_;
    bool mixed_;
    bool abstract_;
    derivationSet final_;
    derivationSet block_;
  };


  struct localComplexType : annotated {
    complexTypeModel model_;
    bool mixed_;
  };

  struct complexRestrictionType : annotated {
    typeDefParticle typeDefParticle_;
    attrDecls attrDecls_;
    QName base_;
  };


  typedef std::list<aka::item> complexContentContents;
  struct complexContent : annotated {
    complexContentContents contents_;
    bool mixed_;
  };


  struct group : annotated, occurs, defRef {
    particle particle_;
  };

  typedef std::list<aka::item> realGroupParticle;
  struct realGroup : occurs, defRef {
    aka::deep_ptr<annotation> annotation_;
    realGroupParticle particle_; 
  };

  struct groupRef : occurs {
    aka::deep_ptr<annotation> annotation_;
    QName ref_;
  };


  struct selector : annotated {
    std::string xpath_; // xpath.
  };

  struct field : annotated {
    std::string xpath_; // xpath.
  };

  typedef std::list<field> fields;
  struct keybase : annotated {
    selector selector_;
    fields fields_;
    NCName name_;
  };

  struct keyref : keybase {
    NCName refer_;
  };


  typedef std::list<aka::item> typeChoice; // localSimpleType or localComplexType.
  typedef std::list<aka::item> identityConstraint; // <xs:unique>, <xs:key> or <xs:keyref>.
  

  struct element : annotated, occurs, defRef {
    typeChoice typeChoice_;
    identityConstraint identityConstraint_;
    QName type_;
    QName substitutionGroup_;
    std::string default_;
    std::string fixed_;
    bool nillable_;
    bool abstract_;
    derivationSet final_;
    blockSet block_;
    formChoice form_;
  protected:
    element(){}
  };


  struct topLevelElement : annotated {
    typeChoice typeChoice_;
    identityConstraint identityConstraint_;
    QName name_;
    QName type_;
    QName substitutionGroup_;
    std::string default_;
    std::string fixed_;
    bool nillable_;
    bool abstract_;
    derivationSet final_;
    blockSet block_;
  };


  struct localElement : annotated, occurs, defRef {
    typeChoice typeChoice_;
    identityConstraint identityConstraint_;
    QName type_;
    std::string default_;
    std::string fixed_;
    bool nillable_;
    blockSet block_;
    formChoice form_;
  };


  struct allModelElement : annotated, defRef, occurs {
    typeChoice typeChoice_;
    identityConstraint identityConstraint_;
    QName type_;
    std::string default_;
    std::string fixed_;
    bool nillable_;
    blockSet block_;
    formChoice form_;
  };


  typedef std::list<allModelElement> allModelElements;
  struct allModel {
    aka::deep_ptr<annotation> annotation_;
    allModelElements elements_;
  };


  struct explicitGroup : annotated, occurs {
    particle particle_;
  };


  struct simpleExplicitGroup : annotated {
    nestedParticle particle_;
  };

  struct all : explicitGroup {
    allModel allModel_;
  };

  
  struct namedGroup {
    aka::deep_ptr<annotation> annotation_;
    particle particle_;
    
    NCName name_;
  };

  typedef std::list<aka::item> redefinable;

  typedef std::string namespaceList; // anyURI or ##any, ##other
  typedef std::string processContents; // skip, lax, strict.

  struct wildcard : annotated {
    namespaceList namespaceList_;
    processContents processContents_;
  };


  struct any : wildcard, occurs {
    namespaceList namespaceList_;
    processContents processContents_;
  };

  typedef std::string restrictionEnum; // ##any, ##other.
  typedef std::list<aka::item>  simpleContentChoice;
  struct simpleContent : annotated {
    simpleContentChoice value_type_;
  };

  struct anyType {
    aka::any_array anys_;
  };

  typedef token public_type;  // token.

  struct notation : annotated {
    NCName name_;
    public_type public_;
    anyURI system_;
  };

  struct namedAttributeGroup : annotated {
    attrDecls attrDecls_;
    NCName name_;
  };

  struct _include : annotated {
    anyURI schemaLocation_;
  };


  typedef std::list<aka::item> redefineContents;
  struct redefine : openAttrs {
    redefineContents contents_;
  };

  struct import : annotated {
    anyURI namespace_;
    anyURI schemaLocation_;
  };


  typedef std::list<aka::item> directives;

  typedef std::list<aka::item> schemaTop;
  typedef std::list<annotation> annotations;

  struct annotatedSchemaTop {
    schemaTop schemaTop_;
    annotations annotations_;
  };

  typedef std::list<annotatedSchemaTop> annotatedSchemaTops;
  
  struct schema : openAttrs {
    directives directives_;
    annotatedSchemaTops annotatedSchemaTops_;
    anyURI anyURI_;
    token version_;
    derivationSet finalDefault_;
    blockSet blockDefault_;
    formChoice attributeFormDefault_;
    formChoice elementFormDefault_;
    ID id_;
    xml::lang lang_;
  };
} 

#endif
