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

#include <akaxiso/content_model.h>

namespace xml {
  typedef std::string lang;
}

namespace xs {
  typedef std::string ID;
  typedef std::string anyURI;
  typedef std::string token;
  typedef std::string NCName;
  typedef aka::qname QName;
  typedef long nonNegativeInteger;
  typedef long positiveInteger;

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



  struct maxOccursLeaf : aka::simpletype<long, maxOccursLeaf> {
    static void read_text(void *elm, std::istringstream &istm, 
			  const aka::global_attributes &gattrs);
    static void write_text(const void *elm, std::ostream &ostm,
			   const aka::global_attributes &gattrs);
    static bool equals(const void *lhs, const void *rhs) {
      return *static_cast<const long*>(lhs) == *static_cast<const long*>(rhs);
    }
  };

  // Base types in schemastructure.
  struct openAttrs {
    aka::wc_attributes attrs_;// ##other
  };

  struct appinfo {
    aka::any_array info_;
    anyURI source_;
  };

  struct documentation {
    aka::any_array anys_;
    anyURI source_;
    std::string lang_; // xml:lang
  };


  struct annotation : openAttrs {
    choice contents_; // appinfo, documentation.
    ID id_; //attribute
  };

  struct annotated : openAttrs {
    aka::deep_ptr<annotation> annotation_; // 0 or 1.
    ID id_;
  };


  /**
   * facet
   */
  struct facet : annotated {
    // annotation_;
    // id_;
    bool fixed_;
    std::string value_; // Ur-type
  };

  struct noFixedFacet : annotated {
    // annotation_;
    // id_;
    std::string value_; // Ur-type
  };

  struct numFacet : public annotated {
    // annotation_;
    // id_;
    bool fixed_;
    nonNegativeInteger value_;  //Type is given in derived classes.
  };

  struct totalDigits : public annotated {  
    // annotation_;
    // id_;
    bool fixed_;
    positiveInteger value_;  //Type is given in derived classes.
  };

  struct whiteSpace : public annotated {  
    // annotation_;
    // id_;
    bool fixed_;
    std::string value_; // !!! preserve, replace, collapse.
  };

  // derivationControl;
  // derivation control substitution, extension, restriction, list, union.

  typedef std::string simpleDerivationSet;
  // "list", "union", "restriction" is acceptable. !!!!!

  typedef std::list<aka::item> simpleDerivation;
  typedef token simpleDerivationSet;

  struct simpleType : annotated {
    simpleDerivation simpleDerivation_;
    simpleDerivationSet final_;
    NCName name_;
  protected:
    simpleType(){}
  };

  struct topLevelSimpleType : simpleType {  };
  struct localSimpleType : simpleType {  };
  typedef std::list<aka::item> facets;

  struct simpleRestrictionModel {
    aka::deep_ptr<localSimpleType> simpleType_;
    facets facets_;
  };

  struct list : public annotated {
    aka::deep_ptr<localSimpleType> simpleType_;
    QName itemType_;
  };

  typedef std::list<localSimpleType> localSimpleTypes;
  typedef std::string memberTypes; // !!!!! Should be list of QName.

  struct _union : public annotated {
    localSimpleTypes simpleTypes_;
    memberTypes memberTypes_;
  };

  struct restriction : public annotated {
    simpleRestrictionModel simpleRestrictionModel_;
    QName base_;
  };

}

#endif
