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

#include <akaxiso/classes/document.h>
#include <akaxiso/parser/document_handler.h>
#include <akaxiso/tricklib/tricklib.h>
#include <stack>
#include <vector>

namespace aka2 {

  struct nsdecl {
    std::string prefix_;
    std::string uri_;
  };

  struct ns_decls {
    typedef std::vector<nsdecl> prefixes;
    ns_decls() :  default_ns_id_(empty_token){}
    prefixes prefixes_;
    id_type default_ns_id_;
  };

  class ns_stack {
  public:
    ns_stack() : depth_(0){}
    void inc_depth();
    const ns_decls& get_current_decls() const;
    void dec_depth();
    bool process_namespace_attribute(const yggdrasil::ygg_node &attr, const nsdecl ** decl);
  private:
    typedef std::stack<ns_decls> decls_stack;
    size_t depth_;
    decls_stack stack_;
  };

  class ygg_handler : public yggdrasil::sax_handler {
  public:
    ygg_handler();
    virtual ~ygg_handler(){}

    void set_source_name(const std::string &source_name) {
      handler_.set_source_name(source_name);
    }

    virtual void start_element(yggdrasil::ygg_node element);
    virtual void end_element(yggdrasil::ygg_node element);
    virtual void on_error(yggdrasil::ygg_error* parse_error);
/*
    virtual void start_document(ygg::ygg_node root){};
    virtual void catch_text(ygg::ygg_node text){};
    virtual void catch_comment(ygg::ygg_node comment){};
    virtual void end_document(ygg::ygg_node root);
*/

    document get_document();
  private:
    qname create_qname(const std::string &tagname);
    void start_prefix_mapping(const std::string &prefix, const std::string &uri);
    void end_prefix_mapping(const std::string &prefix);
    void process_attributes(const yggdrasil::ygg_node &elm, attribute_values &attrs);
    ns_stack ns_;
    prefix_map pfs_;
    document_handler handler_;
  };

}

#endif

