//
//
// Copyright 2002 Rob Tougher <robt@robtougher.com>
//
// This file is part of xmlrpc.
//
// xmlrpc is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// xmlrpc is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with xmlrpc; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//


// Definition of the xml::node class.

#ifndef _xml_node_class
#define _xml_node_class

#include <string>
#include <vector>
#include "expat.h"

#include "xml_exceptions.hpp"
#include "persistable.hpp"

namespace xml
{

  class node : public persistable
  {
  public:

    node ( const std::string name = "", const std::string text = "" ) :
      m_root(0),
      m_current_node(0),
      m_cleanup ( true ),
      m_name ( name ),
      m_text ( text )
    {}

    virtual ~node()
    { cleanup(); }

    virtual std::string get_xml() const;
    virtual void load_xml ( const std::string );

    void add_child ( node * );
    node* add_child ( const std::string name = "", const std::string text = "" );
    node* get_child ( const int ) const;
    int get_child_count() const { return m_children.size(); }

    std::string get_text() const { return m_text; }
    void set_text ( const std::string s ) { m_text = s; }
    void append_text ( const std::string s ) { m_text += s; }

    std::string get_name() const { return m_name; }
    void set_name ( const std::string s ) { m_name = s; }


  private:

    void cleanup();
    std::string encode ( const std::string s ) const;
    std::string m_text;
    std::string m_name;
    std::vector<node*> m_children;

    //
    // Don't allow these
    //
    node ( const node& );
    void operator= ( const node& );


    // -------------------------------------------------
    //
    // The following is temporary stuff needed for
    // the parsing operation.
    //
    // -------------------------------------------------


  public:

    std::vector<node*>& node_stack() { return m_node_stack; }
    node* current_node() { return m_current_node; }
    void set_current_node ( node* p ) { m_current_node = p; }
    void set_root ( node * p ) { if ( m_root ) { delete m_root; } m_root = p; }
    node * root () { return m_root; }

  private:

    node * m_root;
    std::vector<node*> m_node_stack;
    node* m_current_node;
    bool m_cleanup;

  };
}

#endif
