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

#ifndef MiX_DOCUMENT_H_
#define MiX_DOCUMENT_H_

#include "classes.h"
#include "misc.h"
#include "XMLString.h"
#include "extern/noncopyable.hpp"

namespace MiX{

  template <class charT,class char_traits,class xml_traits>
  class Document : boost::noncopyable,
		   public NodeContainer<charT,char_traits,xml_traits>{
  public:
    MiX_Template_Typedef(charT,char_traits,xml_traits);
    typedef Document<charT,char_traits,xml_traits> this_type;
    typedef typename nodelist_type::iterator nodelist_iter; 
    typedef NodeContainer<charT,char_traits,xml_traits> nodecontainer_type;
  private:
    const static typename nodelist_type::iterator dmy_it;
  protected:
    /**
     * コンストラクタ
     *
     * Documentのコンストラクタは直接呼べません。
     * Document<...>::createで生成してください
     */
    Document() { };
  public:
    ///デストラクタ
    virtual ~Document()throw() { };
    ///このノードのタイプを得ます
    virtual NodeType getType() const{ return Node_Document; };
    /**
     * 静的にクラスからNodeTypeを得ます
     *
     * 常にNode_Documentを返します
     */
    static NodeType type(){ return Node_Document; } ;
    ///唯一の子Elementを返します
    element_type& getRoot()const;
    /**
     * このDocumentの文字列表現を得ます
     *
     * 完全なXML文書を作る場合はこれを呼びます<br>
     * bIndentが真の時インデントを追加します。
     */
    virtual string_type toString(bool is_indent=false,int indent_off=0)const;
    /**
     * 子Attributeにアクセスします
     *
     * szNameで与えられた名前のAttributeへの参照を返します<br>
     * 見つからなかった場合はDomException<...>を投げます
     */
    attribute_type& operator[](const string_type& name){
      return getAttribute(name);
    }
    /**
     * このDocumentを複製します
     */
    node_type& clone(nodecontainer_type& dmy,const nodelist_iter& it=dmy_it)const { return clone(); }

    /**
     * このDocumentを複製します
     */
    node_type& clone() const;
    /**
     * Documentを生成します
     *
     * Document生成と同時に唯一の子Elementも生成します
     * \param rootname 同時に生成される子Elementの名前
     */
    static this_type& create(const string_type& rootname);
    
    friend class DOM_Parser<charT,char_traits,xml_traits>;
  };
}

#ifndef MiX_DOCUMENT_CPP_
#include "Document.cpp"
#endif

#endif
