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

#include <akaxiso/classes/types.h>
#include <akaxiso/classes/traits.h>
#include <akaxiso/serializer.h>

namespace aka2 {
  
  class xml_serializer : public serializer {
  public:
    xml_serializer(const std::string &encoding = DEFAULT_CHARSET) : 
      serializer(2), encoding_(encoding), gattrs_(system_global_attributes()) {};
  private:
    virtual void serialize_internal(const void *root, const qname &name,
				    const element_op &op,
				    std::ostream &ostm);

    void write_element(const qname &tagname, 
		       const void *e, const element_op &op, std::ostream &ostm,
		       bool is_root);
    void write_element_entity(const void *e, const element_op &op, std::ostream &ostm);
    void write_content(const void *e, const element_op &op, std::ostream &ostm);

    void write_sequence(const qname &tagname, 
			const void *e, const sequence_op &sop, std::ostream &ostm,
			bool is_root);
    void write_sequence_entity(const void *e, const sequence_op &sop, std::ostream &ostm);

    void write_choice(const qname &tagname, 
		      const void *e, const choice_op &sop, std::ostream &ostm,
		      bool is_root);
    void write_choice_entity(const void *e, const choice_op &sop, std::ostream &ostm);

    void write_all(const qname &tagname, 
		      const void *e, const all_op &sop, std::ostream &ostm,
		      bool is_root);
    void write_all_entity(const void *e, const all_op &sop, std::ostream &ostm);

    void write_simplecontent(const qname &tagname, 
			     const void *e, const simplecontent_op &sop, std::ostream &ostm,
			     bool is_root);

    void write_array(const qname& tagname, 
		     const void *e, const array_op &sop, std::ostream &ostm);
    void write_group_array(const void *e, const array_op &sop, std::ostream &ostm);


    void write_simpletype(const qname &tagname,
			  const void *e, const simpletype_op &sop, std::ostream &ostm,
			  bool is_root);

    void write_nill_element(const qname &tagname, 
			    const void *e, const element_op &op, std::ostream &ostm,
			    bool is_root);
    void write_beginning_tag(const qname& tagname, 
			     const void *e, const element_op &op, std::ostream &ostm,
			     bool is_root);
    void write_ending_tag(const qname &tagname, std::ostream &ostm);

    void write_attributes(const void *e, const attribute_types *attrs, std::ostream &ostm);
    void write_namespace_attributes(std::ostream &ostm);

    static void escape_attribute_value(const std::string &value, std::ostream &ostm);
    static void escape_text_value(const std::string &value, std::ostream &ostm);

    std::string encoding_;
    const global_attributes &gattrs_;
  };




}


#endif




