// -*- mode: c++ -*-

#ifndef MIX_DOMPARSER_H_
#define MIX_DOMPARSER_H_

#include "classes.h"
#include "DefaultXMLTraits.h"
#include "SAX_Parser.h"

namespace MiX{

  template <class charT,class char_traits,class xml_traits>
  class DOM_Parser : public SAX_EventHandler<charT,char_traits,xml_traits>{
  public:
    MiX_Template_Typedef(charT,char_traits,xml_traits);
    typedef DOM_Parser<charT,char_traits,xml_traits> this_type;
    typedef NodeContainer<charT,char_traits,xml_traits> nodecontainer_type;
  private:
    ///実際にパージングをするSAX_Parser
    SAX_Parser<charT,char_traits,xml_traits> parser_;
    ///現在構築中のノード
    NodeContainer<charT,char_traits,xml_traits>* current_;
    /// 属性を解析し名前空間宣言を登録する。
    void parseAttribute(const attrmap_type& attr);
  protected:
    ///SAX_Parserのためのハンドラ(内部利用のみ)
    virtual void onXMLDeclaration(attrmap_type attr);
    ///SAX_Parserのためのハンドラ(内部利用のみ)
    virtual void onStart(string_type name,attrmap_type attr);
    ///SAX_Parserのためのハンドラ(内部利用のみ)
    virtual void onEnd(string_type name);
    ///SAX_Parserのためのハンドラ(内部利用のみ)
    virtual void onText(string_type text);
    ///SAX_Parserのためのハンドラ(内部利用のみ)
    virtual void onComment(string_type text);
  public:
    ///デストラクタ
    virtual ~DOM_Parser(){ };

    ///与えられた文字列をもとにDOMツリーを構築します
    document_type& parse(const charT* text);
    ///与えられたストリームをもとにDOMツリーを構築します
    document_type& parse(std::basic_istream<charT, char_traits>& is);

    /**
     * 文字列の前後にある空白(インデント)を無視するかどうか設定します
     *
     * setIgnoreSpace(true)をした場合、インデント等によって整形された
     * XMLドキュメントを簡単に処理することができます
     */
    void setIgnoreSpace(bool flag){ parser_.setIgnoreSpace(flag); };
  };
}

#ifndef MiX_DOMPARSER_CPP_
#include "DOM_Parser.cpp"
#endif

#endif
