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

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

namespace aka2 {

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

  class ns_stack {
  public:
    typedef std::vector<nsdecl> prefixes;
  public:
    ns_stack() : depth_(0){}
    void inc_depth();
    const prefixes& get_current_prefixes() const;
    void dec_depth();
    bool process_namespace_attribute(const yggdrasil::ygg_node &attr, const nsdecl *&decl);
  private:
    typedef std::stack<prefixes> prefixes_stack;
    size_t depth_;
    prefixes_stack prefixes_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);
    }
    void set_gattrs(global_attributes &gattrs) {
      handler_.set_gattrs(gattrs);
    }

    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:
    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_;
    document_handler handler_;
  };

}

#endif

