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

#include "schema.h"
#include "classcontents.h"
#include "type_registory.h"
#include <vector>


namespace osixaka {

  class generator {
  private:
    typedef std::vector<xs::GlobalElement> GlobalElementList;
    typedef std::vector<xs::Element> ElementList;
    typedef std::vector<xs::ComplexType> ComplexTypeList; 
    typedef std::vector<xs::Attribute> AttributeList;
    
    contents_array contents_;
    document_contents documents_;

    void generate();

    /** Top-level element */
    void declare_global_elements(const GlobalElementList &gel);
    void generate_global_elements(const GlobalElementList &gel);

    /** Top-level complexType */
    void declare_global_complexTypes(const ComplexTypeList &cel);
    void generate_global_complexTypes(const ComplexTypeList &cel);

    /** complexType in element declarations */
    void generate_complexType(const xs::ComplexType &ct, const aka::qname &name);

    /** Particles */
    void generate_sequence(const xs::Sequence &seq, const aka::qname &name, 
			   const AttributeList &attrs);
    void generate_choice(const xs::Choice &cho, const aka::qname &name, 
			 const AttributeList &attrs);
    void generate_simpleType_leaf(const aka::qname &name);

    const aka::qname generate_array(const aka::qname &itemtype);

    /* attribute */
    void generate_attributes(const AttributeList &attrs, attribute_contents *cls);

    static std::string get_filesig(const std::string &filename);
    static void write_header(std::ostream &ostm, const std::string &filename);
    static void write_footer(std::ostream &ostm, const std::string &filename);

    const contents *find_contents(const aka::qname &type) const;

  public:
    int generate_classes(xs::Schema &root);

    void write_element_header(const std::string &filename, std::ostream &ostm);
    void write_xiso_header(const std::string &element_fn, 
			   const std::string &xiso_fn, 
			   std::ostream &ostm);
    void write_xiso_implementation(const std::string &xiso_header, 
				   const std::string &xiso_impl,
				   std::ostream &ostm);
  };
  
}

#endif
