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

#include <akaxiso/classes/membertype.h>
#include <akaxiso/classes/document.h>
#include <akaxiso/formatter.h>
#include <akaxiso/classes/scoped_ptr.h>

namespace aka2 {

  class serializer  {
  public:
    serializer(int tab, const std::string &encoding);
    virtual ~serializer();

    void serialize(const document &doc, std::ostream &ostm);
    
    template <class R>
    void serialize(const R &root, const std::string &name, std::ostream &ostm) {
      const element_props &props = system_document_factory().get_props(name);
      do_serialize(&root, props, name, ostm);
    }

  private:
    void create_formatter(std::ostream& ostm);
    void do_serialize(const void *e, const element_props &props, const qname &name, std::ostream &ostm);
    virtual void serialize_internal(const void *e, const element_props &props, 
				    const qname &name) = 0;

  protected:
    int indent_;
    void inc_indent_level() { ++indent_; }
    void dec_indent_level() { --indent_; }
    void new_line();

    static bool is_sequence_empty(const void *e, const member_types &mtypes);
    static bool is_all_empty(const void *e, const member_map &mmap);
    static bool is_member_empty(const void *e, const member_type &mtype);

    std::string indent_str_;
    std::string encoding_;
    scoped_ptr<formatter> formatter_;
  };

} // namespace aka2

#endif  /* AKAXISO_SERIALIZER_H__ */
