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

#include <akaxiso/tricklib/tricklib.h>

#ifdef USE_XERCESC
#include <memory.h> /* {BCB6} */
#include <xercesc/util/TransService.hpp>
#include <akaxiso/classes/scoped_ptr.h>
#endif

namespace aka2 {

  class formatter {
  public:
    formatter(std::ostream &ostm) 
      : ostm_(&ostm) {}
    virtual ~formatter() {}

    virtual void prepare(const std::string &encoding) = 0;

    void write(const std::string &value);
    void write_attribute_entity(const std::string &entity);
    void write_text_entity(const std::string &entity);


    static bool use_xerces_transcoder_;

  private:
    virtual ustring lcp_to_ucs2(const std::string &source) = 0;
    virtual void write(const ustring &entity) = 0;
    void write_entity(const std::string &entity, const int escape_index);

  protected:
    std::ostream *ostm_;
  };

  class babel_formatter : public formatter {
  public:
    babel_formatter(std::ostream &ostm) 
      : formatter(ostm), bom_(0) {}
    virtual ~babel_formatter() {}

    virtual void prepare(const std::string &encoding);
  private:
    virtual ustring lcp_to_ucs2(const std::string &source);
    virtual void write(const ustring &entity);

    babel::bbl_translater<std::string, ustring> in_translator_;
    babel::bbl_translater<ustring, std::string> out_translator_;

    struct bom {
      char chars_[16];
      size_t length_;
    };
    const bom *bom_;
  };

#ifdef USE_XERCESC
  class xerces_formatter : public formatter {
  public:
    xerces_formatter(std::ostream &ostm) 
      : formatter(ostm), in_transcoder_(0), out_transcoder_(0) {};
    virtual ~xerces_formatter() {}

    virtual void prepare(const std::string &encoding);

  private:
    virtual ustring lcp_to_ucs2(const std::string &source);
    virtual void write(const ustring &entity);
    void set_bom(const std::string &encoding);

    scoped_ptr<xercesc::XMLLCPTranscoder> in_transcoder_;
    scoped_ptr<xercesc::XMLTranscoder> out_transcoder_;
   };
#endif

} // namespace aka2

#endif /* AKAXISO_FORMATTER_H__ */
