/* -*- 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 docdef *def = system_document_factory().get_docdef(name);
      if (def == 0)
        throw internal_error();
      create_formatter(ostm);
      serialize_internal(static_cast<const void*>(&root), name, *def->op_);
      formatter_.reset();
    }

  private:
    void create_formatter(std::ostream& ostm);
    virtual void serialize_internal(const void *root, const qname &name,
                                    const element_op &op) = 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__ */
