/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.1  1999/11/09 01:08:59  twl
 * Initial revision
 *
 * Revision 1.4  1999/11/08 20:44:19  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef DOM_Node_HEADER_GUARD_
#define DOM_Node_HEADER_GUARD_

#include <util/XML4CDefs.hpp>
#include <dom/DOMString.hpp>

class DOM_NodeList;
class DOM_NamedNodeMap;
class DOM_Document;
class NodeImpl;

class DOM_NullPtr;  // A dummy class, with no implementation, that is
                    //  used as in overloaded functions as a way to
                    //  pass 0 or null.

/**
 * The <code>Node</code> interface is the primary datatype for the entire
 * Document Object Model.
 *
 * It represents a single node in the document tree.
 * While all objects implementing the <code>Node</code> interface expose
 * methods for dealing with children, not all objects implementing the
 * <code>Node</code> interface may have children. For example,
 * <code>Text</code> nodes may not have children, and adding children to such
 * nodes results in a <code>DOMException</code> being raised.
 * <p>The attributes <code>nodeName</code>, <code>nodeValue</code>  and
 * <code>attributes</code> are  included as a mechanism to get at node
 * information without  casting down to the specific derived interface. In
 * cases where  there is no obvious mapping of these attributes for a specific
 *  <code>nodeType</code> (e.g., <code>nodeValue</code> for an Element  or
 * <code>attributes</code>  for a Comment), this returns <code>null</code>.
 * Note that the  specialized interfaces may contain additional and more
 * convenient mechanisms to get and set the relevant information.
 */
class  CDOM_EXPORT DOM_Node {

    public:
    /** @name Constructors and assignment operators */
    //@{
    /**
      * Default constructor for DOM_Node.  The resulting object does not
      * refer to an actual  node; it will compare == to 0, and is similar
      * to a null object reference variable in Java.  It may subsequently be
      * assigned to refer to an actual node.  "Acutal Nodes" will always
      * be of some derived type, such as Element or Attr.
      *
      */
    DOM_Node();

    /**
      * Copy constructor.
      *
      * @param other The object to be copied.
      */
    DOM_Node(const DOM_Node &other);

    /**
      * Assignment operator.
      *
      * @param other The source to be assigned.
      */
    DOM_Node & operator = (const DOM_Node &other);

     /**
      * Assignment operator.  This overloaded variant is provided for
      *   the sole purpose of setting a DOM_Node reference variable to
      *   zero.  Nulling out a reference variable in this way will decrement
      *   the reference count on the underlying Node object that the variable
      *   formerly referenced.  This effect is normally obtained when reference
      *   variable goes out of scope, but zeroing them can be useful for
      *   global instances, or for local instances that will remain in scope
      *   for an extended time,  when the storage belonging to the underlying
      *   node needs to be reclaimed.
      *
      * @param val.  Only a value of 0, or null, is allowed.
      */
    DOM_Node & operator = (const DOM_NullPtr *val);

   //@}
    /** @name Destructor. */
    //@{
	 /**
	  * Destructor for DOM_Node.  The object being destroyed is the reference
      * object, not the underlying node itself.
	  *
	  */
    ~DOM_Node();

    //@}
    /** @name Equality and Inequality operators. */
    //@{
    /**
     * The equality operator.  This compares to references to nodes, and
     * returns true if they both refer to the same underlying node.  It
     * is exactly analogous to Java's operator ==  on object reference
     * variables.  This operator can not be used to compare the values
     * of two different nodes in the document tree.
     *
     * @param other The object reference with which <code>this</code> object is compared
     * @returns True if both <code>DOM_Node</code>s refer to the same
     *  actual node, or are both null; return false otherwise.
     */
    bool operator == (const DOM_Node & other)const;

    /**
      *  Compare with a pointer.  Intended only to allow a convenient
      *    comparison with null.
      *
      */
    bool operator == (const DOM_NullPtr *other) const;

    /**
     * The inequality operator.  See operator ==.
     *
     */
    bool operator != (const DOM_Node & other) const;

     /**
      *  Compare with a pointer.  Intended only to allow a convenient
      *    comparison with null.
      *
      */
   bool operator != (const DOM_NullPtr * other) const;


    enum NodeType {
        ELEMENT_NODE         = 1,
        ATTRIBUTE_NODE       = 2,
        TEXT_NODE            = 3,
        CDATA_SECTION_NODE   = 4,
        ENTITY_REFERENCE_NODE = 5,
        ENTITY_NODE          = 6,
        PROCESSING_INSTRUCTION_NODE = 7,
        COMMENT_NODE         = 8,
        DOCUMENT_NODE        = 9,
        DOCUMENT_TYPE_NODE   = 10,
        DOCUMENT_FRAGMENT_NODE = 11,
        NOTATION_NODE        = 12
    };

    //@}
    /** @name Get functions. */
    //@{

    /**
     * The name of this node, depending on its type; see the table above.
     */
    DOMString       getNodeName() const;

    /**
     * Gets the value of this node, depending on its type.
     *
     * @exception DOMException
     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
     * @exception DOMException
     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
     *   fit in a <code>DOMString</code> variable on the implementation
     *   platform.
     */
    DOMString       getNodeValue() const;

    /**
     * An enum value representing the type of the underlying object.
     */
    short           getNodeType() const;

    /**
     * Gets the parent of this node.
     *
     * All nodes, except <code>Document</code>,
     * <code>DocumentFragment</code>, and <code>Attr</code> may have a parent.
     * However, if a node has just been created and not yet added to the tree,
     * or if it has been removed from the tree, a <code>null</code> DOM_Node
     * is returned.
     */
    DOM_Node        getParentNode() const;

    /**
     * Gets a <code>NodeList</code> that contains all children of this node.
     *
     * If there
     * are no children, this is a <code>NodeList</code> containing no nodes.
     * The content of the returned <code>NodeList</code> is "live" in the sense
     * that, for instance, changes to the children of the node object that
     * it was created from are immediately reflected in the nodes returned by
     * the <code>NodeList</code> accessors; it is not a static snapshot of the
     * content of the node. This is true for every <code>NodeList</code>,
     * including the ones returned by the <code>getElementsByTagName</code>
     * method.
     */
    DOM_NodeList    getChildNodes() const;
    /**
     * Gets the first child of this node.
     *
     * If there is no such node, this returns <code>null</code>.
     */
    DOM_Node        getFirstChild() const;

    /**
     * Gets the last child of this node.
     *
     * If there is no such node, this returns <code>null</code>.
     */
    DOM_Node        getLastChild() const;

    /**
     * Gets the node immediately preceding this node.
     *
     * If there is no such node, this returns <code>null</code>.
     */
    DOM_Node        getPreviousSibling() const;

    /**
     * Gets the node immediately following this node.
     *
     * If there is no such node, this returns <code>null</code>.
     */
    DOM_Node        getNextSibling() const;

    /**
     * Gets a <code>NamedNodeMap</code> containing the attributes of this node (if it
     * is an <code>Element</code>) or <code>null</code> otherwise.
     */
    DOM_NamedNodeMap  getAttributes() const;

    /**
     * Gets the <code>Document</code> object associated with this node.
     *
     * This is also
     * the <code>Document</code> object used to create new nodes. When this
     * node is a <code>Document</code> or a <code>DocumentType</code>,
     * which is not used with any <code>Document</code> yet, this is
     * <code>null</code>.
     */
    DOM_Document      getOwnerDocument() const;

    /**
      * Return the user data pointer.
      *
      * User data allows application programs
      * to attach extra data to DOM nodes, and can be set using the
      * function <code>DOM_Node::setUserData(p)</code>.
      * @return The user data pointer.
      */
    void              *getUserData() const;

    //@}
    /** @name Cloning function. */
    //@{

    /**
     * Returns a duplicate of this node.
     *
     * This function serves as a generic copy constructor for nodes.
     *
     * The duplicate node has no parent (
     * <code>parentNode</code> returns <code>null</code>.).
     * <br>Cloning an <code>Element</code> copies all attributes and their
     * values, including those generated by the  XML processor to represent
     * defaulted attributes, but this method does not copy any text it contains
     * unless it is a deep clone, since the text is contained in a child
     * <code>Text</code> node. Cloning any other type of node simply returns a
     * copy of this node.
     * @param deep If <code>true</code>, recursively clone the subtree under the
     *   specified node; if <code>false</code>, clone only the node itself (and
     *   its attributes, if it is an <code>Element</code>).
     * @return The duplicate node.
     */
    DOM_Node         cloneNode(bool deep) const;

    //@}
    /** @name Functions to modify the DOM Node. */
    //@{

    /**
     * Inserts the node <code>newChild</code> before the existing child node
     * <code>refChild</code>.
     *
     * If <code>refChild</code> is <code>null</code>,
     * insert <code>newChild</code> at the end of the list of children.
     * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
     * all of its children are inserted, in the same order, before
     * <code>refChild</code>. If the <code>newChild</code> is already in the
     * tree, it is first removed.  Note that a <code>DOM_Node</code> that
     * has never been assigned to refer to an actual node is == null.
     * @param newChild The node to insert.
     * @param refChild The reference node, i.e., the node before which the new
     *   node must be inserted.
     * @return The node being inserted.
     * @exception DOMException
     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
     *   allow children of the type of the <code>newChild</code> node, or if
     *   the node to insert is one of this node's ancestors.
     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
     *   from a different document than the one that created this node.
     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
     *   <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of
     *   this node.
     */
    DOM_Node               insertBefore(const DOM_Node &newChild,
                                        const DOM_Node &refChild);


    /**
     * Replaces the child node <code>oldChild</code> with <code>newChild</code>
     * in the list of children, and returns the <code>oldChild</code> node.
     *
     * If the <code>newChild</code> is already in the tree, it is first removed.
     * @param newChild The new node to put in the child list.
     * @param oldChild The node being replaced in the list.
     * @return The node replaced.
     * @exception DOMException
     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
     *   allow children of the type of the <code>newChild</code> node, or it
     *   the node to put in is one of this node's ancestors.
     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
     *   from a different document than the one that created this node.
     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
     *   this node.
     */
    DOM_Node       replaceChild(const DOM_Node &newChild,
                                const DOM_Node &oldChild);
    /**
     * Removes the child node indicated by <code>oldChild</code> from the list
     * of children, and returns it.
     *
     * @param oldChild The node being removed.
     * @return The node removed.
     * @exception DOMException
     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
     *   this node.
     */
    DOM_Node        removeChild(const DOM_Node &oldChild);

    /**
     * Adds the node <code>newChild</code> to the end of the list of children of
     * this node.
     *
     * If the <code>newChild</code> is already in the tree, it is
     * first removed.
     * @param newChild The node to add.If it is a  <code>DocumentFragment</code>
     *   object, the entire contents of the document fragment are moved into
     *   the child list of this node
     * @return The node added.
     * @exception DOMException
     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
     *   allow children of the type of the <code>newChild</code> node, or if
     *   the node to append is one of this node's ancestors.
     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
     *   from a different document than the one that created this node.
     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
     */
    DOM_Node        appendChild(const DOM_Node &newChild);

    //@}
    /** @name Query functions. */
    //@{

    /**
     *  This is a convenience method to allow easy determination of whether a
     * node has any children.
     *
     * @return  <code>true</code> if the node has any children,
     *   <code>false</code> if the node has no children.
     */
    bool             hasChildNodes() const;


    /**
     * Test whether this node is null.
     *
     * This C++ class, <code>DOM_Node<code>
     * functions much like an object reference to an underlying Node, and
     * this function tests for that reference being null.  Several DOM
     * APIs, <code>Node.getNextSibling()</code> for example, can return null, and
     * this function is used to test for that condition.
     *
     * <p>Operator == provides another way to perform this null test on a
     * DOM_Node.
     */
    bool                    isNull() const;

    //@}
    /** @name Set functions. */
    //@{


    /**
    * Sets the value of the node.
    *
    * Any node which can have a nodeValue (@see getNodeValue) will
    * also accept requests to set it to a string. The exact response to
    * this varies from node to node -- Attribute, for example, stores
    * its values in its children and has to replace them with a new Text
    * holding the replacement value.
    *
    * For most types of Node, value is null and attempting to set it
    * will throw DOMException(NO_MODIFICATION_ALLOWED_ERR). This will
    * also be thrown if the node is read-only.
    */
    void              setNodeValue(const DOMString &nodeValue);

    /**
      * Set the user data for a node.
      *
      * User data allows application programs
      * to attach extra data to DOM nodes, and can be retrieved using the
      * function <code>DOM_Node::getUserData(p)</code>.
      * <p>
      * Deletion of the user data remains the responsibility of the
      * application program; it will not be automatically deleted when
      * the nodes themselves are reclaimed.
      *
      * <p> Because DOM_Node is not designed to be subclassed, userdata
      * provides an alternative means for extending the the information
      * kept with nodes by an application program.
      *
      * @param p The pointer to be kept with the node.
      */
    void              setUserData(void *p);

    //@}
    /** @name Functions introduced in DOM Level 2. */
    //@{

    /**
     * Tests whether the DOM implementation implements a specific
     * feature and that feature is supported by this node.
     * @param feature The string of the feature to test. This is the same
     * name as what can be passed to the method <code>hasFeature</code> on
     * <code>DOMImplementation</code>.
     * @param version This is the version number of the feature to test. In
     * Level 2, version 1, this is the string "2.0". If the version is not
     * specified, supporting any version of the feature will cause the
     * method to return <code>true</code>.
     * @return Returns <code>true</code> if the specified feature is supported
     * on this node, <code>false</code> otherwise.
     */
    bool              supports(const DOMString &feature,
	                       const DOMString &version) const;

    /**
     * Get the <em>namespace URI</em> of
     * this node, or <code>null</code> if it is unspecified. When this node is
     * of any type other than <code>ELEMENT_NODE</code> and
     * <code>ATTRIBUTE_NODE</code>, this is always <code>null</code> and
     * setting it has no effect.
     * <p>
     * This is not a computed value that is the result of a namespace lookup
     * based on an examination of the namespace declarations in scope. It is
     * merely the namespace URI given at creation time.
     * <p>
     * For nodes created with a DOM Level 1 method, such as
     * <code>createElement</code> from the <code>DOM_Document</code> interface,
     * this is <code>null</code>.
     */
    DOMString         getNamespaceURI() const;

    /**
     * Get the <em>namespace prefix</em>
     * of this node, or <code>null</code> if it is unspecified. When this node
     * is of any type other than <code>ELEMENT_NODE</code> and
     * <code>ATTRIBUTE_NODE</code> this is always <code>null</code> and
     * setting it has no effect.
     * <p>
     * For nodes created with a DOM Level 1 method, such as
     * <code>createElement</code> from the <code>DOM_Document</code> interface,
     * this is <code>null</code>.
     */
    DOMString         getPrefix() const;

    /**
     * Returns the local part of the <em>qualified name</em> of this node.
     * <p>
     * For nodes created with a DOM Level 1 method, such as
     * <code>createElement</code> from the <code>DOM_Document</code> interface,
     * and for nodes of any type other than <code>ELEMENT_NODE</code> and
     * <code>ATTRIBUTE_NODE</code> this is the same as the
     * <code>nodeName</code> attribute.
     */
    DOMString         getLocalName() const;

    /**
     * Get the <em>namespace prefix</em> of this node.
     * <p>
     * Note that setting this attribute changes the <code>nodeName</code>
     * attribute, which holds the <em>qualified name</em>,
     * as well as the <code>tagName</code> and
     * <code>name</code> attributes of the <code>Element</code> and
     * <code>Attr</code> interfaces, when applicable.
     *
     * @param prefix The prefix of this node.
     * @exception DOMException
     *   INVALID_CHARACTER_ERR: Raised if the specified prefix contains
     *                          an invalid character.
     * <br>
     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
     */
    void              setPrefix(const DOMString &prefix);

    //@}

protected:
    NodeImpl   *fImpl;

    DOM_Node(NodeImpl *);

    friend class DOM_Document;
    friend class DocumentImpl;
    friend class TreeWalkerImpl;
    friend class NodeIteratorImpl;
    friend class DOM_NamedNodeMap;
    friend class DOM_NodeList;
};


#endif

