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

#include <akaxiso/content_model.h>
#include "schema.h"


namespace xiso {

  template<>
  struct leaf<aka::qname> : public aka::simpletype<aka::qname> {
    static void read_text(void *elm, std::istringstream &istm, 
			  const aka::global_attributes &gattrs) {
      aka::qname &name = *static_cast<aka::qname*>(elm);
      std::string rawname;
      istm >> rawname;
      name.set(rawname, gattrs);
    }
  };
}



struct ComplexTypeLeaf;

struct ComplexTypesLeaf : public aka::sequential_array<xs::ComplexTypes, 
			  ComplexTypeLeaf> {
};



struct maxOccursLeaf : public 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);
  }
};



struct ElementLeaf :  public aka::sequence<xs::Element, ElementLeaf> {
  void model() {
    //      static_typeinfo().set_typename("xs:element");
    member("xs:complexType", 
	   &xs::Element::complexTypes_, ComplexTypesLeaf(),
	   0, 1);
    attribute("name", &xs::Element::name_);
    attribute("type", &xs::Element::type_);
    attribute("ref", &xs::Element::ref_);
    attribute("minOccurs", &xs::Element::minOccurs_).set_default("1");
    attribute("maxOccurs", &xs::Element::maxOccurs_, maxOccursLeaf()).set_default("1");
  }
};




  
struct GlobalElementLeaf : public aka::sequence<xs::GlobalElement, GlobalElementLeaf> {
  void model() {
    //static_typeinfo().set_typename("xs:global_element");
    member("xs:complexType", &xs::GlobalElement::complexTypes_,
	   ComplexTypesLeaf(),
	   0, 1);
    attribute("name", &xs::GlobalElement::name_);
    attribute("type", &xs::GlobalElement::type_);
  }
};

struct ElementsLeaf : public aka::sequential_array<xs::Elements, ElementLeaf> {
};

struct AttributeLeaf : public aka::simplecontent<xs::Attribute, AttributeLeaf> {
  void model() {
    //static_typeinfo().set_typename("xs:attribute");
    attribute("name", &xs::Attribute::name_);
    attribute("type", &xs::Attribute::type_);
  }
};


struct SequenceLeaf : public aka::sequence<xs::Sequence, SequenceLeaf> {
  void model() {
    //static_typeinfo().set_typename("xs:sequence");
    member("xs:element", &xs::Sequence::elements_, ElementsLeaf(),
	   0, aka::unbounded);
//     attribute("minOccurs", &xs::Sequence::minOccurs_).set_default("1");
//     attribute("maxOccurs", &xs::Sequence::maxOccurs_, maxOccursLeaf()).set_default("1");
  }
};

struct ChoiceLeaf : public aka::sequence<xs::Choice, ChoiceLeaf> {
  void model() {
    //    static_typeinfo().set_typename("xs:choice");
    member("xs:element", &xs::Choice::elements_, ElementsLeaf(), 0, aka::unbounded);
    attribute("minOccurs", &xs::Choice::minOccurs_).set_default("1");
    attribute("maxOccurs", &xs::Choice::maxOccurs_, maxOccursLeaf()).set_default("1");
  }
};


struct ParticlesLeaf : public aka::sequential_choice<xs::Particles, ParticlesLeaf> {
  void model() {
    //    static_typeinfo().set_typename("xs:complexType");
    item("xs:element", ElementLeaf());
    item("xs:sequence", SequenceLeaf());
    item("xs:choice", ChoiceLeaf());
    item("xs:attribute", AttributeLeaf());
  }
};


struct ComplexTypeLeaf : public aka::sequence<xs::ComplexType, ComplexTypeLeaf> {
  void model() {
    //    static_typeinfo().set_typename("xs:complexType");
    member("&particles", 
	   &xs::ComplexType::particles_, ParticlesLeaf(),
	   0, aka::unbounded);
    attribute("name", &xs::ComplexType::name_);
  }
};


struct TopLevelNodesLeaf : public aka::sequential_choice<xs::TopLevelNodes, TopLevelNodesLeaf> {
  void model() {
    //    static_typeinfo().set_typename("xs:schema");
    item("xs:complexType", ComplexTypeLeaf());// OCCURENCE(0, aka::unbounded)
    item("xs:element", GlobalElementLeaf());// OCCURENCE(0, aka::unbounded)
    // item("xs:simpleType", SimpleTypeLeaf());
    //       ITEM(simpleType)
    //       ITEM(group)
    // ITEM(attributeGroup)
    // redefinable end.
    //      ITEM(attribute)
    //      ITEM(notation)
    //     ITEMTYPE(group, Group);
    //     ITEMTYPE(simpleType, SimpleType);
  }
};

struct SchemaLeaf : public aka::sequence<xs::Schema, SchemaLeaf> {
  void model() {
    member("&topLevelNodes",
	   &xs::Schema::nodes_, TopLevelNodesLeaf(),
	   0, aka::unbounded);
    attribute("targetNamespace", &xs::Schema::targetNamespace_);
  }
};

#endif

