/*
  Copyright (C) 2000-2004

  Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane

  This file is part of xmds.
 
  This program 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.

  This program 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 this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/*
  $Id: dom3.h,v 1.11 2004/04/28 00:29:49 paultcochrane Exp $
*/

/*! @file dom3.h
  @brief Provides the abstracted Document Object Model (DOM) level 3 
  interface as specified in the W3C Working Draft as of 05 June 2001.
  
  Most of the documentation of this file is taken directly from the 
  W3C Working Draft of 05 June 2001.
*/

/* This header file provides the abstracted DOM level 3
   interface as specified in the W3C Working Draft as of 05 June 2001.
   (http://www.w3.org/TR/2001/WD-DOM-level-3-core-20010605)
   My (GC) implementation of this is in the files "kissdom.h" and "kissdom.cc".*/

using namespace std;

typedef XMLString DOMString; //!< Defines a DOMString

const DOMString EMPTY_STRING = "";  //!< The empty string
const DOMString XML_PREFIX = "xml"; //!< The xml prefix string
const DOMString XML_NAMESPACEURI = "http://www.w3.org/XML/1998/namespace"; //!< The xml namespace URI
const DOMString XMLNS_PREFIX = "xmlns";  //!< The xmlns prefix, and quite possibly the xml namespace prefix
const DOMString XMLNS_NAMESPACEURI = "http://www.w3.org/2000/xmlns";  //!< The xmlns namespace uri, or the uri of the xml namespace

typedef long DOMTimeStamp;   //!< Defines the DOM time stamp
typedef long DOMKey;         //!< Defines the DOM key

// ******************************************************************************
// ******************************************************************************
//      DOMException
// ******************************************************************************
// ******************************************************************************

//! Structure containing the DOM defined exceptions
struct DOMException {

  //! Enumerator containing the DOM defined exception numbers
  /*! 
    The exception code is an integer indicating the type of error generated
  */
  enum {
    INDEX_SIZE_ERR                  =  1,  //!< If index or size is negative, or greater than the allowed value
    DOMSTRING_SIZE_ERR              =  2,  //!< If the specified range of text does not fit into a DOMString
    HIERARCHY_REQUEST_ERR           =  3,  //!< If any node is inserted somewhere it doesn't belong
    //! If a node is used in a different document than the one that created it (that doesn't support it)
    WRONG_DOCUMENT_ERR              =  4,  
    INVALID_CHARACTER_ERR           =  5,  //!< If an invalid or illegal character is specified, such as in a name
    NO_DATA_ALLOWED_ERR             =  6,  //!< If data is specified for a node which does not support data
    NO_MODIFICATION_ALLOWED_ERR     =  7,  //!< If an attempt is made to modify an object where modifications are not allowed
    NOT_FOUND_ERR                   =  8,  //!< If an attempt is made to reference a node in a context where is does not exist
    NOT_SUPPORTED_ERR               =  9,  //!< If the implementation doesn't support the requested type of object or operation
    INUSE_ATTRIBUTE_ERR             = 10,  //!< If an attempt is made to add an attribute that is already in use elsewhere

    // Introduced in DOM Level 2:
    INVALID_STATE_ERR               = 11,  //!< If an attempt is made to use an object that is not, or is not longer, usable
    SYNTAX_ERR                      = 12,  //!< If an invalid or illegal string is specified
    INVALID_MODIFICATION_ERR        = 13,  //!< If an attempt is made to modify the type of the underlying object
    //! If an attempt is made to create or change an object in a way which is incorrect with regard to namespaces
    NAMESPACE_ERR                   = 14,  
    INVALID_ACCESS_ERR              = 15   //!< If a parameter or an operation is not supported by the underlying object
  };

  //! The exception code for a DOMException
  unsigned long code;

  //! Constructor of DOMException object
  DOMException();

  //! Constructor of DOMException object where error is specified
  /*!
    @param err Error code of exception
  */
  DOMException(
               unsigned long err);

  //! Destructor
  ~DOMException();

  //! Gets an error
  /*!
    Returns the string specifying the type of error that occurred
  */
  const char* getError() const;
};

// ******************************************************************************
// ******************************************************************************
// ******************************************************************************
//      The Core Interfaces
// ******************************************************************************
// ******************************************************************************
// ******************************************************************************

// Document class
class Document;
// DocumentType class
class DocumentType;

// ******************************************************************************
// ******************************************************************************
//      DOMImplementation
// ******************************************************************************
// ******************************************************************************

//! DOMImplementation class
/*!
  The @c DOMImplementation interface provides a number of methods for performing operations
  that are independent of any particular instance of the document object model.
*/
class DOMImplementation {

public :

  //! Tests if the DOM implementation implements a specific feautre
  /*!
    @param feature The name of the feature to test (case-insensitive).  The name must be an XML name
    @param version This is the version number of the feature to test.  In DOM 
    Level 2, the string can be either "2.0" or "1.0"
  */
  virtual bool hasFeature(
                          DOMString& feature,
                          DOMString& version) const = 0;

  // Introduced in DOM Level 2:

  //! Creates an empty DocumentType node
  /*!
    Creates an empty @c DocumentType node.  Entity declarations and notations are not made available
    Entity reference expansions and default atribute additions do not occur.
    @param qualifiedName The qualified name of the document type to be created
    @param publicId The external subset public identifier
    @param systemId The external subset system identifier
  */
  virtual DocumentType* createDocumentType(
                                           const DOMString& qualifiedName,
                                           const DOMString& publicId,
                                           const DOMString& systemId) = 0;

  //! Creates a DOM document object of the specified type with its document element
  /*!
    @param namespaceURI The namespace URI of the document to create
    @param qualifiedName The qualified name of the document element to be created
    @param doctype The type of document to be created or @c null.  When doctype 
    is not @c null, its @c Node.ownerDocument attribute is set to the document being created
  */
  virtual Document* createDocument(
                                   const DOMString& namespaceURI,
                                   const DOMString& qualifiedName,
                                   DocumentType* doctype) = 0;

  // Introduced in DOM Level 3:

  //! Makes available a @c DOMImplementation's specialised interface.
  /*!
    @param feature The name of the feature requested (case-insensitive)
  */
  virtual DOMImplementation* getAs(
                                   DOMString& feature) = 0;
};

// Node class
class Node;

// ******************************************************************************
// ******************************************************************************
//      NodeList
// ******************************************************************************
// ******************************************************************************

//! NodeList class
/*!
  The @c NodeList interface provides the abstraction of an ordered collection of 
  nodes, without defining or constraining how this collection is implemented.
  The items in the @c NodeList are accessible via an integral index, starting from 0.
*/
class NodeList {

public :
  //! Gets an item from the node list at index
  /*!
    Returns the @c index th item in the collection.  If @c index is greater than
    or eaual to the number of nodes in the list, this returns @c null.
    @param index Index into the collection
  */
  virtual Node* item(
                     unsigned long      index) const = 0;

  //! Returns the length of the node list
  /*
    Returns the number of nodes in the list.  The range of valid child node indices 
    is 0 to @c length-1 inclusive.
  */
  virtual unsigned long length() const = 0;
};

// ******************************************************************************
// ******************************************************************************
//      NamedNodeMap
// ******************************************************************************
// ******************************************************************************

//! NamedNodeMap class
/*!
  Objects implementing the @c NamedNodeMap interface are used to represent collections
  of nodes that can be accessed by name.  Note that @c NamedNodeMap does not inherit from
  @c NodeList; @c NamedNodeMaps are not maintained in any particular order.  Objects
  contained in an object implementing @c NamedNodeMap may also be accessed by an ordinal
  index, but this is simply to allow convenient enumeration of the contents of a 
  @c NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
*/
class NamedNodeMap {

public :

  //! Gets a named item
  /*!
    Retrieves a node specified by name
    @param name The @c nodeName of a node to retrieve
  */
  virtual Node* getNamedItem(
                             const DOMString& name) const = 0;

  //! Sets a named item
  /*!
    Adds a node using its @c nodeName attribute.  If a node with that name is already
    present in this map, it is replaced by the new one.

    As the @c nodeName attribute is used to derive the name which the node must be stored
    under, multiple nodes of certain types (those that have a "special" string value) 
    cannot be stored as the names would clash.  This is seen as preferable to allowing
    nodes to be aliased.
    @param arg A node to store in this map.  The node will later be accessible using the value
    of its @c nodeName attribute.
  */
  virtual Node* setNamedItem(
                             Node& arg) = 0;

  //! Removes a named item
  /*!
    Removes a node specified by a name.  When this map contains the attributes attached
    to an element, if the removed attribute is known to have a default value, an attribute
    immediately appears containing the default value as well as the corresponding namespace
    URI, local name, and prefix when applicable.
    @param name The @c nodeName of the node to remove.
  */
  virtual Node* removeNamedItem(
                                const DOMString& name) = 0;

  //! Gets the length of the object
  /*!
    Returns the number of nodes in this map.  The range of valid child node indices
    is @c 0 to @c length-1 inclusive.
  */
  virtual unsigned long length() const = 0;

  //! Returns the node item at index
  /*!
    Returns the @c index th item in the map.  If @c index is greater than or equal to
    the number of nodes in this map, this returns @c null.
    @param index Index into this map.
  */
  virtual Node* item(
                     const unsigned long index) const = 0;

  // Introduced in DOM Level 2:

  //! Gets the named item namespace
  /*!
    Retrieves a node spcified by local name and namespace URI.  Documents which do not support the 
    "XML" feature will permit only the DOM Level 1 calls for creating/setting elements and attributes.
    Hence, if you specify a non-null namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The namespace URI of the node to retrieve
    @param localname The local name of the node to retrieve
  */
  virtual Node* getNamedItemNS(
                               const DOMString& namespaceURI,
                               const DOMString& localname) const = 0;

  //! Sets the named item namespace
  /*!
    Adds a node using its @c namespaceURI and @c localname.  If a node with that namespace URI
    and that local name is already present in this map, it is replaced by the new one.
    @param arg A node to store in this map.  The node will later be accessible using the value
    of its @c namespaceURI and @c localname attributes.
  */
  virtual Node* setNamedItemNS(
                               Node& arg) = 0;

  //! Removes the named item namespace
  /*!
    Removes a node specified by local name and namespace URI.  A removed attribute may be
    known to have a default value when this map contains the attributes attached to an element,
    as returned by the attributes atribute of the @c Node interface.  If so, an attribute 
    immediately appears containing the default value as well as the corresponding namespace URI,
    local name, and prefix when applicable.

    Documents which do not support the "XML" feature will permit only the DOM level 1 calls for
    creating/setting elements and attributes.  Hence, if you specify an non-null namespace URI,
    these DOMs will never find a matching node.
    @param namespaceURI The namespace URI of the node to remove
    @param localname The local name of the node to remove
  */
  virtual Node* removeNamedItemNS(
                                  const DOMString& namespaceURI,
                                  const DOMString& localname) = 0;      
};

// ******************************************************************************
// ******************************************************************************
//      Node
// ******************************************************************************
// ******************************************************************************

//! Node class
/*!
  This @c Node 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 @c Node interface expose methods for dealing with children, not all objects
  implementing the @c Node interface may have children.  For example, @c Text 
  nodes may not have children, and adding children to such nodes results in a 
  @c DOMException being raised.

  The attributes @c nodeName, @c nodeValue and @c attributes 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
  @c nodeType (e.g. @c nodeValue for an @c Element or @c attributes for a @c Comment),
  this returns @c null.  Note that the specialised interfaces may contain additional and
  more convenient mechanisms to get and set the relevant information.
*/
class Node {

public :

  //! Destructor
  virtual ~Node() {};
        
  //! Enumerator containing the document node numbers
  /*!
    These are the @c nodeTypes; an integer indicating which type of node this is.

    The values of @c nodeName, @c nodeValue, and @c attributes vary according to 
    the node type as follows:
    <table>
    <tr>
    <th>Interface</th> <th>nodeName</th> <th>nodeValue</th> <th>attributes</th>
    </tr>
    <tr>
    <td>Attr</td> <td>name of attribute</td> <td>value of attribute</td> <td>null</td>
    </tr>
    <tr>
    <td>CDATASection</td> <td>"#cdata-section"</td> <td>content of the CDATA section</td> <td>null</td>
    </tr>
    <tr>
    <td>Comment</td> <td>"#comment"</td> <td>content of the comment</td> <td>null</td>
    </tr>
    <tr>
    <td>Document</td> <td>"#document"</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>DocumentFragment</td> <td>"#document-fragment"</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>DocumentType</td> <td>document type name</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>Element</td> <td>tag name</td> <td>null</td> <td>NamedNodeMap</td>
    </tr>
    <tr>
    <td>Entity</td> <td>entity name</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>EntityReference</td> <td>name of entity referenced</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>Notation</td> <td>notation name</td> <td>null</td> <td>null</td>
    </tr>
    <tr>
    <td>ProcessingInstruction</td> <td>target</td> <td>entire content excluding the target</td> <td>null</td>
    </tr>
    <tr>
    <td>Text</td> <td>"#text"</td> <td>content of the text node</td> <td>null</td>
    </tr>
    </table>
  */
  enum {
    ELEMENT_NODE                =  1, //!< The node is an @c Element
    ATTRIBUTE_NODE              =  2, //!< The node is an @c Attr
    TEXT_NODE                   =  3, //!< The node is a @c Text node
    CDATA_SECTION_NODE          =  4, //!< The node is a @c CDATASection
    ENTITY_REFERENCE_NODE       =  5, //!< The node is an @c EntityReference
    ENTITY_NODE                 =  6, //!< The node is an @c Entity
    PROCESSING_INSTRUCTION_NODE =  7, //!< The node is a @c ProcessingInstruction
    COMMENT_NODE                =  8, //!< The node is a @c Comment
    DOCUMENT_NODE               =  9, //!< The node is a @c Document
    DOCUMENT_TYPE_NODE          = 10, //!< The node is a @c DocumentType
    DOCUMENT_FRAGMENT_NODE      = 11, //!< The node is a @c DocumentFragment
    NOTATION_NODE               = 12  //!< The node is a @c Notation
  };

  //! Returns the node name as a DOMString
  /*!
    Returns the name of this node, depending on its type.
  */
  virtual const DOMString* nodeName() const = 0;

  //! Returns the node value as a DOMString
  /*!
    Returns the value of this node, depending on its type.  When it is defined to be
    @c null, setting it has no effect.
  */
  virtual const DOMString* nodeValue() const = 0;

  //! Sets the node value
  /*!
    Sets the node value to the value specified.
    @param newNodeValue The new node value
  */
  virtual void setNodeValue(
                            const DOMString& newNodeValue) = 0;

  //! Returns the node type
  /*!
    Returns a code representing the type of the underlying object.
  */
  virtual unsigned long nodeType() const = 0;

  //! Returns the parent node
  /*!
    Returns the parent of this node.  All nodes, except @c Attr, @c Document, @c DocumentFragment
    @c Entity and @c Notation 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, this is @c null.
  */
  virtual Node* parentNode() const = 0;

  //! Sets the parent node
  /*!
    Sets the parent node of the current node to the @c Node specified.
    @param newParentNode The new parent node of the current node
  */
  virtual void setParentNode(
                             Node* newParentNode) = 0;

  //! Returns the child nodes as a node list
  /*!
    Returns a @c NodeList that contains all children of this node.  If there are no children, this is
    a @c NodeList containing no nodes.
  */
  virtual const NodeList* childNodes() const = 0;

  //! Returns the first child node
  /*!
    Returns the first child of this node.  If there is no such node, this returns @c null.
  */
  virtual Node* firstChild() const = 0;

  //! Returns the last child node
  /*!
    Returns the last child of this node.  If there is no such node, this returns @c null.
  */
  virtual Node* lastChild() const = 0;

  //! Returns the previous sibling node
  /*!
    Returns the node immediately preceding this node.  If there is no such node, this returns @c null.
  */
  virtual Node* previousSibling() const = 0;

  //! Returns the next sibling node
  /*!
    Returns the node immediately following this node.  If there is no such node, this returns @c null.
  */
  virtual Node* nextSibling() const = 0;

  //! Returns the attributes of the node
  /*!
    Returns a @c NamedNodeMap containing the attributes of this node (if it is an @c Element or @c null otherwise).
  */
  virtual const NamedNodeMap* attributes() const = 0;

  //! Returns the owner document
  /*!
    Returns the @c Document object associated with this node.  This is also the @c Document object used to 
    create new nodes.  When this node is a @c Document or a @c DocumentType which is not used with any 
    @c Document yet, this is @c null.
  */
  virtual const Document* ownerDocument() const = 0;

  //! Sets the owner document
  /*!
    Sets the owner document to the @c Document object specified.
    @param newOwnerDocument The new @c Document object to own the node
  */
  virtual void setOwnerDocument(
                                const Document *const newOwnerDocument) = 0;

  //! Inserts child node before reference child node
  /*!
    Inserts the node @c newChild before the existing child node @c refChild.  If @c refChild is @c null,
    insert @c newChild at the end of the list of children.
    
    If @c newChild is a @c DocumentFragement object, all of its children are inserted, in the same order,
    before @c refChild.  If the @c newChild is already in the tree, it is first removed.

    @param newChild The node to insert
    @param refChild The reference node, i.e., the node before which th new node must be inserted
  */
  virtual Node* insertBefore(
                             Node* newChild,
                             Node* refChild) = 0;

  //! Replaces a child node
  /*!
    Replaces the child node @c oldChild with @c newChild in the list of children, and returns the 
    @c oldChild node.

    If @c newChild is a @c DocumentFragment object, @c oldChild is replaced by all of the 
    @c DocumentFragment children, which are inserted in the same order.  If the @c newChild 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
  */
  virtual Node* replaceChild(
                             Node* newChild,
                             Node* oldChild) = 0;

  //! Removes a child node
  /*!
    Removes the child node indicated by @c oldChild from the list of children, and returns it.
    @param oldChild The node being removed
  */
  virtual Node* removeChild(
                            Node* oldChild) = 0;

  //! Appends a child node
  /*!
    Adds the node @c newChild to the end of the list of children of this node.  If the @c newChild
    is already in the tree, it is first removed.
    @param newChild The node to add.  If it is a @c DocumentFragment object, the entire contents of the 
    document fragment are moved into the child list of this node
  */
  virtual Node* appendChild(
                            Node* newChild) = 0;

  //! Determines if object has child nodes
  /*!
    Returns whether this node has any children.
  */
  virtual bool hasChildNodes() const = 0;

  //! Clones a node
  /*!
    Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes.  The 
    duplicate has ho parent; (@c parentNode is @c null).

    Cloning an @c Element 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 @c Text node.
    Cloning an @c Attribute directly, as opposed to be cloned as part of an @c Element cloning
    operation, returns a specified attribute (@c specified is @c true).  Cloning any other type
    of node simply returns a copy of this node.
    @param deep If @c true, recursively clone the subtree under the specified node; if @c false, 
    clone only the node itself (and its attributes, if it is an @c Element).
  */
  virtual Node* cloneNode(
                          const bool& deep) const = 0;

  //! Puts all Text nodes into a ``normal'' form
  /*!
    Puts all @c Text nodes in the full depth of the sub-tree underneath this @c Node, including attriubte
    nodes, into a "normal" form where only structure (e.g., elements, comments, processing instructions,
    CDATA sections and entity references) separates @c Text nodes, i.e., there are neither adjacent @c Text
    nodes nor empty @c Text nodes.  This can be used to ensure that the DOM view of a document is the same
    as if it were saved and reloaded, and is useful when operations (such as XPointer lookups) that
    depend on a particular document tree structure are to be used.
  */
  virtual void normalize() = 0; // Modified in DOM Level 2:

  // Introduced in DOM Level 2:

  //! Determines if feature is supported
  /*!
    Tests whether the DOM implementation implements a specific feature and that fearture is supported by this
    node.
    @param feature The name of the feature to test.  This is the same name which can be passed to the 
    method @c hasFeature on @c DOMImplementation
    @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, supoorting any version of the feature will cause
    the method to return @c true
  */
  virtual bool isSupported(
                           DOMString& feature,
                           DOMString& version) const = 0;

  //! Returns the namespace URI as a DOMString
  /*!
    Returns the namespace URI of this node, or @c null if it is unspecified.  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.

    For nodes of any type other than @c ELEMENT_NODE and @c ATTRIBUTE_NODE and nodes created with a DOM
    Level 1 method, such as @c createElement from the @c Document interface, this is always @c null.
  */
  virtual const DOMString* namespaceURI() const = 0;

  //! Returns the prefix as a DOMString
  /*!
    Returns the namespace prefix of this node, of @c null if it is unspecified.

    Note that setting this attribute, when permitted, changes the @c nodeName attribute, which holds
    the qualified name, as well as the @c tagName and @c name attributes of the @c Element and @c Attr 
    interfaces when applicable.

    Note also that changing the prefix of an attribute that is known to have a default value, does not
    make a new attribute with the default value and the original prefix appear, since the @c namespaceURI
    and @c localName do not change.

    For nodes of any type other than @c ELEMENT_NODE and @c ATTRIBUTE_NODE and nodes created with a DOM
    Level 1 method, such as @c createElement from the @c Document interface, this is always @c null.    
  */
  virtual const DOMString* prefix() const = 0;

  //! Sets the prefix
  /*!
    Sets the namespace prefix to the specified @c DOMString.
    @param newPrefix The prefix to set
  */
  virtual void setPrefix(
                         const DOMString& newPrefix) = 0;

  //! Returns the local name as a DOMString
  /*!
    Returns the local part of the qualified name of this node.  

    For nodes of any type other than @c ELEMENT_NODE and @c ATTRIBUTE_NODE and nodes created with a DOM
    Level 1 method, such as @c createElement from the @c Document interface, this is always @c null.
  */
  virtual const DOMString* localName() const = 0;

  // Introduced in DOM Level 3:

  //! Determines if object has attributes
  /*!
    Returns whether this node (if it is an element) has any attributes.
  */
  virtual bool hasAttributes() const = 0;

  //! Returns the base URI as a DOMString
  /*!
    Returns the absolute base URI of this node.  This value is computed according to XML Base.
  */
  virtual const DOMString* baseURI() const = 0;

  //! An enumeration of the different orders the node can be in
  /*!
    The @c DocumentOrder is a type to hold the document order of a node relative to another node.
  */
  enum DocumentOrder {
    DOCUMENT_ORDER_PRECEDING, //!< The node precedes the reference node in document order
    DOCUMENT_ORDER_FOLLOWING, //!< The node follows the reference node in document order
    DOCUMENT_ORDER_SAME,      //!< The two nodes have the same document order
    DOCUMENT_ORDER_UNORDERED  //!< The two nodes are unordered, they do not have any common ancestor
  };

  //! Compares the document order with another node
  /*!
    Compares a node with this node with regard to document order.
    @param other The node to compare against this node
  */
  virtual DocumentOrder compareDocumentOrder(
                                             const Node* other) const = 0;

  //! An enumeration of the different orders the node can be in
  /*!
    The @c TreePosition is a type to hold the relative tree position of a node with respect to another node.
  */
  enum TreePosition {
    TREE_POSITION_PRECEDING,  //!< The node precedes the reference node
    TREE_POSITION_FOLLOWING,  //!< The node follows the reference node
    TREE_POSITION_ANCESTOR,   //!< The node is an ancestor of the reference node
    TREE_POSITION_DESCENDANT, //!< The node is a descendant of the reference node
    TREE_POSITION_SAME,       //!< The two nodes have the same position
    TREE_POSITION_UNORDERED   //!< The two nodes are unordered, they do not have any common ancestor
  };

  //! Compares the tree position with another node
  /*!
    Compares a node with this node with regard to their position in the tree.
    @param other The node to compare against this node
  */
  virtual TreePosition compareTreePosition(
                                           const Node* other) const = 0;

  //! Returns the text content
  /*!
    Returns the text content of this node and its descendants.  When set, any possible children this node
    may have are removed and replaced by a single @c Text node containing the string this attribute is set to.
    On getting, no serialisation is performed, the returned string does not contain any markup.  Similarly,
    on setting, no parsing is performed either, the input string is taken as pure textual content.

    The string returned is made of the text content of this node depending on its type, as defined below
    <table>
    <tr>
    <th>Node type</th> <th>Content</th>
    </tr>
    <tr>
    <td>ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE</td>
    <td>concatenation of the @c textContent attribute value of every child node, excluding COMMENT_NODE and 
    PROCESSING_INSTRUCTION_NODE nodes</td>
    </tr>
    <tr>
    <td>ATTRIBUTE_NODE, TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
    <td>@c nodeValue</td>
    </tr>
    <tr>
    <td>DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
    <td>empty string</td>
    </tr>
    </table>
  */
  virtual const DOMString* textContent(
                                       const bool& deep) const = 0;

  //! Sets the text content
  /*!
    Sets the text content to the @c DOMString specified.
    @param newTextContent The text content to be set for the node
  */
  virtual void setTextContent(
                              const DOMString& newTextContent) = 0;

  //! Determines if the current node is the same as other node
  /*!
    Returns whether this node is the same node as the given one.
    @param other The node to test against
  */
  virtual bool isSameNode(
                          const Node* other) const = 0;

  //! Looks up the namespace prefix
  /*!
    Look up the prefix associated to the given namespace URI, starting from this node.
    @param namespaceURI The namespace URI to look for
  */
  virtual const DOMString* lookupNamespacePrefix(
                                                 const DOMString& namespaceURI) const = 0;

  //! Looks up the namespace URI
  /*!
    Look up the namespace URI associcated to the given prefix, starting from this node.
    @param prefix The prefix to look for
  */
  virtual const DOMString* lookupNamespaceURI(
                                              const DOMString& prefix) const = 0;

  //! Adds namespace declarations so that every namespace is properly declared
  /*!
    This method walks down the tree, starting from this node, and adds namespace declarations
    where needed so that every namespace being used is properly declared.  It also changes
    or assigns prefixes when needed.  This effectively makes this node subtree is "namespace wellformed".
  */
  virtual void normalizeNS() = 0;

  //! Returns the key
  /*!
    Ths returns a key identifying this node.  This key is unique within the document this node was
    creted from and is valid for the lifetime of that document.
  */
  virtual DOMKey key() const = 0;

  //! Determines if node equals argument node
  /*!
    Tests whether two nodes are equal.

    This method tests for equality of nodes, not sameness (i.e., whether the two nodes are exactly
    the same object) which can be tested with @c Node.isSameNode.  All objects that are the same will also
    be equal, though the reverse may not be true.
    
    @param arg The node to compare equality with
    @param deep If @c true, recursively compare the subtrees; if @c false, compare only the nodes themselves,
    (and its attributes, if it is an @c Element)
  */
  virtual bool equalsNode(
                          const Node* arg,
                          bool deep) const = 0;

  //! Makes available a Node's specialised interface. 
  /*!
    This method makes available a @c Node's specialised interface.
    @param feature The name of the feature requested (case-insensitive)
  */
  virtual Node* getAs(
                      DOMString& feature) = 0;

  //! Determines if node is read only
  /*!
    Returns @c true if the node is read only.  Not specified in the DOM Level 3.
  */
  virtual bool readOnly() const = 0;

  //! Sets node read only
  /*!
    Sets the node read only attribute.  Not specified in the DOM Level 3.
    @param newReadOnly Boolean specifying @c true for read only, @c false otherwise
    @param deep If @c true, then sets the attribute recursively for the subtrees, if @c false, then
    only sets the attribute for the current node
  */
  virtual void setReadOnly(
                           const bool& newReadOnly,
                           const bool& deep) = 0;
};

class Element;
class Attr;
class DocumentFragment;
class Text;
class Comment;
class CDATASection;
class ProcessingInstruction;
class EntityReference;

// ******************************************************************************
// ******************************************************************************
//      Document
// ******************************************************************************
// ******************************************************************************

//! Document class
/*!
  The Document interface represents the entire XML document.  Conceptually it is the
  root of the document tree, and provides the primary access to the document's data.
*/
class Document : public virtual Node {

public :
        
  //! Returns the @c DOMKey
  /*!
    A method which returns the @c DOMKey.  This is a utility method defined by 
    Greg Collecutt, and is not part of the W3C DOM specification.
  */
  virtual DOMKey getDOMKey() const = 0; // Mine!

  //! Returns the document type
  /*!
    Returns the Document Type Declaration (DTD) associated with this document.  Returns
    @c null if the document is without a document type.
  */
  virtual const DocumentType* doctype() const = 0;

  //! Returns the DOM implementation
  /*!
    Returns the @c DOMImplementation object that handles this document.  A DOM application
    may use objects from multiple implementations.
  */
  virtual const DOMImplementation* implementation() const = 0;

  //! Returns the document element
  /*!
    This is a convenience attribute that allows direct access to the child node that is 
    the root element of the document.
  */
  virtual Element* documentElement() const = 0;

  //! Creates an element of tagName
  /*!
    Creates an element of the type specified.  Note that the instance returned implements
    the @c Element interface, so attributes can be specified directly on the returned object.
    In addition, if there are known attributes with default values, @c Attr nodes representing
    them are automatically created and attached to the element.  To create an element with
    a qualified name and namespace URI, use the @c createElementNS method.
    @param tagName The name of the element to instantiate.  For XML this is case-sensitive.
  */
  virtual Element* createElement(
                                 const DOMString& tagName) = 0;

  //! Creates a document fragment
  /*!
    Creates an empty document fragment object
  */
  virtual DocumentFragment* createDocumentFragment() = 0;

  //! Creates a text node
  /*!
    Creates a @c Text node given the specified string
    @param data The data for the node.
  */
  virtual Text* createTextNode(
                               const DOMString& data) = 0;

  //! Creates a comment
  /*!
    Creates a @c Comment node given the specified string.
    @param data The data for the node.
  */
  virtual Comment* createComment(
                                 const DOMString& data) = 0;

  //! Creates a CDATA section
  /*!
    Creates a @c CDATASection node whose value is the specified string.
    @param data The data for the @c CDATASection
  */
  virtual CDATASection* createCDATASection(
                                           const DOMString& data) = 0;

  //! Creates a processing instruction
  /*!
    Creates a @c ProcessingInstruction node given the specified name and data strings.
    @param target The target part of the processing instruction
    @param data The data for the node
  */
  virtual ProcessingInstruction* createProcessingInstruction(
                                                             const DOMString& target,
                                                             const DOMString& data) = 0;

  //! Creates an attribute
  /*!
    Creates an @c Attr of the given name.  Note that the @c Attr instance can then
    be set on an @c Element using the @c setAttributeNode method.  To create an 
    attribute with a qualified name and namespace URI, use the @c createAttributeNS method.
    @param name The name of the attribute
  */
  virtual Attr* createAttribute(
                                const DOMString& name) = 0;

  //! Creates an entity reference
  /*!
    Creates an @c EntityReference object.  In addition, if the referenced entity is known,
    the child list of the @c EntityReference node is made the same as that of the
    corresponding @c Entity node.
    @param name The name of the entity to reference
  */
  virtual EntityReference* createEntityReference(
                                                 const DOMString& name) = 0;

  //! Gets the elements by tag name
  /*!
    Returns a @c NodeList of all the @c Elements with a given tag name in the
    order in which they are encountered in a preorder traversal of the @c Document tree.
    @param tagName The name of the tag to match on.  The special value "*" matches all tags.
  */
  virtual NodeList* getElementsByTagName(
                                         const DOMString& tagName) = 0;

  // Introduced in DOM Level 2:

  //! Imports a node
  /*!
    Imports a node from another document to this document.  The returned node has no parent; 
    (@c parentNode is @c null).  The source node is not altered or removed from the original
    document; this method creates a new copy of the source code.
    
    For all nodes, importing a node creates a node object owned by the importing document,
    with attribute values identical to the source node's @c nodeName and @c nodeType, plus 
    the attributes related to namespaces (@c prefix, @c localName, and @c namespaceURI).  As
    in the @c cloneNode operation on a @c Node, the source node is not altered.
    @see Node
  */
  virtual Node* importNode(
                           const Node* importNode,
                           const bool& deep) = 0;

  //! Creates an element's namespace
  /*!
    Creates an element of the given qualified name and namespace URI
    @param namespaceURI The namespace URI of the element to create
    @param qualifiedName The qualified name of the element type to instatiate
  */
  virtual Element* createElementNS(
                                   const DOMString& namespaceURI,
                                   const DOMString& qualifiedName) = 0;

  //! Creates an attribute's namespace
  /*!
    Creates an attribute of the given qualified name and namespace URI
    @param namespaceURI The namespace URI of the attribute to create
    @param qualifiedName The qualified name of the attribute to instatiate
  */
  virtual Attr* createAttributeNS(
                                  const DOMString& namespaceURI,
                                  const DOMString& qualifiedName) = 0;

  //! Gets the elements by tag name namespace
  /*!
    Returns a @c NodeList of all the @c Elements with a given local name
    and namespace URI in the order in which they are encountered in a preorder
    traversal of the @c Document tree
    @param namespaceURI The namespace URI of the elements to match on.  The
    special value "*" matches all namespaces
    @param localname of the elements to match on.  The special value "*" matches
    all local names
  */
  virtual NodeList* getElementsByTagNameNS(
                                           const DOMString& namespaceURI,
                                           const DOMString& localname) = 0;

  //! Gets element by id
  /*!
    Returns the @c Element whose @c ID is given by @c elementId.  If no such element
    exists, returns @c null.  Behaviour is not defined if more than one element has @c ID.
    @param elementId The unique @c id value for an element
  */
  virtual Element* getElementById(
                                  const DOMString& elementId) = 0;

  // Introduced in DOM Level 3:

  //! Returns the actual encoding
  /*!
    Returns a @c DOMString specifying the actual encoding of this document.  This is 
    @c null otherwise.
  */
  virtual const DOMString* actualEncoding() const = 0;

  //! Sets the actual encoding
  /*!
    Sets the actual encoding to the specified value.  This is not part of the W3C DOM
    Level 3..
    @param newActualEncoding The new actual encoding to set the actual encoding to.
  */
  virtual void setActualEncoding(
                                 const DOMString& newActualEncoding) = 0;

  //! Returns the encoding
  /*!
    Returns a @c DOMString specifying, as part of the XML declaration, the encoding of this
    document.  This is @c null when unspecified.
  */
  virtual const DOMString* encoding() const = 0;

  //! Sets the encoding
  /*!
    Sets the encoding of the document to the specified @c DOMString.  This is not
    defined in the W3C DOM level 3.
    @param newEncoding The new encoding to set for the document
  */
  virtual void setEncoding(
                           const DOMString& newEncoding) = 0;

  //! Determines if document is standalone
  /*!
    Returns a boolean specifying, as part of the XML declaration, whether this document is
    standalone.
  */
  virtual bool standalone() const = 0;

  //! Sets the document to be standalone
  /*!
    Sets the boolean specifying that the document is standalone.  This is not 
    defined in the W3C DOM level 3.
    @param newStandalone A boolean specifying if the document is standalone or not
  */
  virtual void setStandalone(
                             const bool& newStandalone) = 0;

  //! Determines if strict error checking is on
  /*!
    Returns a boolean specifying whether error checking is enforced or not.  When 
    set to @c false, the implementation is free to not test every possible error case
    normally defined on DOM operations, and not raise any @c DOMException.  In case of 
    error, the behaviour is undefined.  This is set to @c true by default.
  */
  virtual bool strictErrorChecking() const = 0;

  //! Sets strict error checking
  /*!
    Turns strict error checking on by setting the appropriate flag.
    @param newStrictErrorChecking Boolean value defining whether or not strict error checking is on
  */
  virtual void setStrictErrorChecking(
                                      const bool& newStrictErrorChecking) = 0;

  //! Returns version as DOMString
  /*!
    Returns a @c DOMString specifying, as part of the XML declaration, the version number
    of this document.  This is @c null when unspecified.
  */
  virtual const DOMString* version() const = 0;

  //! Sets the version
  /*!
    Sets the version number of the document to the @c DOMString specified.
    @param newVersion The new version number
  */
  virtual void setVersion(
                          const DOMString& newVersion) = 0;

  //! Adopts a node
  /*!
    Changes the @c ownerDocument of a node, its children, as well as the attached attribute
    nodes if there are any.  If the node has a parent it is first removed from its parent
    child list.  This effectively allows moving a subtree from one document to another.
    @param source The node to move into this document
  */
  virtual Node* adoptNode(
                          Node* source) = 0;

  //! Sets the base URI
  /*!
    Set the @c baseURI attribute from the @c Node interface.
    @param baseURI The new absolute URI for this document
  */
  virtual void setBaseURI(
                          const DOMString *const baseURI) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      Element
// ******************************************************************************
// ******************************************************************************

//! Element class
/*!
  The @c Element interface represents an element in an XML document.  Elements
  may have attributes associated with them; since the @c Element interface inherits
  from @c Node, the generic @c Node interface attribute @c attributes may be used to 
  retrieve the set of all attributes by name or an attribute value by name.  In XML,
  where an attribute value may contain entity references, an @c Attr object should be
  retrieved to examine the possibly failry complex sub-tree representing the attribute
  value.
*/
class Element : public virtual Node {

public :

  //! Returns the tag name as a DOMString
  /*!
    Returns the name of the element, for example
    \verbatim
    <elementExample> ... </elementExample>
    \endverbatim
    @c tagName is the value @c elementExample
  */
  virtual const DOMString* tagName() const = 0;

  //! Gets the attribute as a DOMString
  /*!
    Retrieves an attribute value by name.
    @param name The name of the attribute to retrieve
  */
  virtual const DOMString* getAttribute(
                                        const DOMString& name) const = 0;

  //! Sets an attribute
  /*!
    Adds a new attribute.  If an attribute with that name is already present in the 
    element, its value is changed to be that of the @c value parameter.  This value
    is a simple string; it is not parsed as it is being set.  In order to assign an
    attribute value that contains entity references, the user must create an @c Attr
    node plus any @c Text and @c EntityReference nodes, build the appropriate subtree,
    and use @c setAttributeNode to assign it as the value of an attribute.

    To set an attribute with a qualified name and namespace URI, use the @c setAttributeNS method.
    @param name The name of the attribute to create or alter
    @param value Value to set in string form
  */
  virtual void setAttribute(
                            const DOMString& name,
                            const DOMString& value) = 0;

  //! Removes an attribute
  /*!
    Removes an attribute by name.  If the removed attribute is known to have a default value,
    an attribute immediately appears containing the default value as well as the corresponding
    namespace URI, local name and prefix when applicable.

    To remove an attribute by local name and namespace URI, use the @c removeAttributeNS method.
    @param name The name of the attribute to remove
  */
  virtual void removeAttribute(
                               const DOMString& name) = 0;

  //! Gets an attribute node
  /*!
    Retrieves an attribute node by name.

    To retrieve an attribute node by qualified name and namespace URI, use the 
    @c getAttributeNodeNS method.
    @param name The name (@c nodeName) of the attribute to retrieve
  */
  virtual Attr* getAttributeNode(
                                 const DOMString& name) = 0;

  //! Sets an attribute node
  /*!
    Adds a new attribute node.  If an attribute with that name (@c nodeName) is already
    present in the element, it is replaced by the new one.

    To add a new attribute node with a qualified name and namespace URI, use the 
    @c setAttributeNodeNS method.
    @param newAttr The @c Attr node to add to the attribute list
  */
  virtual Attr* setAttributeNode(
                                 Attr& newAttr) = 0;

  //! Removes an attribute node
  /*!
    Removes the specified attribute node.  If the removed @c Attr has a default value it is
    immediately replaced.  The replacing attribute has the same namespaceURI and local name,
    as well as the original prefix, when applicable.
    @param oldAttr The @c Attr node to remove from the attribute list
  */
  virtual Attr* removeAttributeNode(
                                    Attr& oldAttr) = 0;

  //! Gets elements by tag name
  virtual const NodeList* getElementsByTagName(
                                               const DOMString& name,
                                               const bool& deep) const = 0;

  // Introduced in DOM Level 2:

  //! Gets the attribute's namespace
  /*!
    Retrieves an attribute value by local name and namespace URI.

    Documents which do not support the "XML" feature will permit only the DOM Level 1
    calls for creating/setting elements and attributes.  Hence, if you specify a non-null
    namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The namespace URI of the attribute to retrieve
    @param localname The local name of the attribute to retrieve
  */
  virtual const DOMString* getAttributeNS(
                                          const DOMString& namespaceURI,
                                          const DOMString& localname) const = 0;

  //! Sets the attribute's namespace
  /*!
    Adds a new attribute.  If an attribute with the same local name and namespace URI
    is already present on the element, its prefix is changed to the prefix part of the
    @c qualifiedName, and its value is changed to be the @c value parameter.  This value
    is a simple string; it is not parsed as it is being set.  In order to assign an
    attribute value that contains entity references, the user must create an @c Attr
    node plus any @c Text and @c EntityReference nodes, build the appropriate subtree, and
    use @c setAttributeNodeNS or @c setAttributeNode to assign it as the value of an attribute.
    @param namespaceURI The namespace URI of the attribute to create or alter
    @param qualifiedName The qualified name of the attribute to create or alter
    @param value The value to set in string form
  */
  virtual void setAttributeNS(
                              const DOMString& namespaceURI,
                              const DOMString& qualifiedName,
                              const DOMString& value) = 0;

  //! Removes the attribute's namespace
  /*!
    Removes an attribute by local name and namespace URI.  If the removed attribute has a default
    value it is immediately replaced.  The replacing attribute has the same namespace URI and 
    local name, as well as the original prefix.

    Documents which do not support the "XML" feature will permit only the DOM Level 1
    calls for creating/setting elements and attributes.  Hence, if you specify a non-null
    namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The namespace URI of the attribute to remove
    @param localname The local name of the attribute to remove
  */
  virtual void removeAttributeNS(
                                 const DOMString& namespaceURI,
                                 const DOMString& localname) = 0;

  //! Gets the attribute node's namespace
  /*!
    Retrieves an @c Attr node by local name and namespace URI.

    Documents which do not support the "XML" feature will permit only the DOM Level 1
    calls for creating/setting elements and attributes.  Hence, if you specify a non-null
    namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The namespace URI of the attribute to retrieve
    @param localname The local name of the attribute to retrieve
  */
  virtual Attr* getAttributeNodeNS(
                                   const DOMString& namespaceURI,
                                   const DOMString& localname) = 0;

  //! Sets the attribute node's namespace
  /*!
    Adds a new attribute.  If an atribute with that local name and that namespace URI is
    already present in the element, it is replaced by the new one.
    @param newAttr The @c Attr node to add to the attribute list
  */
  virtual Attr* setAttributeNodeNS(
                                   Attr& newAttr) = 0;

  //! Gets the elements by tag name namespace
  /*!
    Returns a @c NodeList of all the descendant @c Elements with a given local name and 
    namespace URI in the order in which they are encountered in a preorder traversal
    of this @c Element tree.

    Documents which do not support the "XML" feature will permit only the DOM Level 1 
    calls for creating/setting elements and attributes.  Hence if you specify a non-null
    namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The name space URI of the elements to match on.  The special value "*"
    matches all namespaces.
    @param localname The local name of the elements to match on.  The special value "*"
    matches all local names.
  */
  virtual NodeList* getElementsByTagNameNS(
                                           const DOMString& namespaceURI,
                                           const DOMString& localname) = 0;

  //! Determines if node has attribute name
  /*!
    Returns @c true when an attribute with a given name is specified on this element 
    or has a default value, @c false otherwise
    @param name The name of the attribute to look for
  */
  virtual bool hasAttribute(
                            const DOMString& name) const = 0;

  //! Determines if node has attribute namespace of localname
  /*!
    Returns @c true when an attribute with a given local name and namespace URI is specified
    on this element or has a default value, @c false otherwise.

    Documents which do not support the "XML" feature will permit only the DOM Level 1 
    calls for creating/setting elements and attributes.  Hence if you specify a non-null
    namespace URI, these DOMs will never find a matching node.
    @param namespaceURI The name space URI of the elements to match on.
    @param localname The local name of the elements to match on.
  */
  virtual bool hasAttributeNS(
                              const DOMString& namespaceURI,
                              const DOMString& localname) const = 0;    
};

// ******************************************************************************
// ******************************************************************************
//      Attr
// ******************************************************************************
// ******************************************************************************

//! Attribute class
/*!
  The @c Attr interface represents an attribute in an @c Element object.  Typically the
  allowable values for the attribute are defined in a document type definition.
  
  @c Attr objects inherit the @c Node interface, but since they are not actually child
  nodes of the element they describe, the DOM does not consider them part of the document
  tree.  Thus, the @c Node attributes @c parentNode, @c previousSibling, and @c nextSibling have
  a @c null valuue for @c Attr objects.  The DOM takes the view that attributes are properties of 
  elements rather than having a separate identity from the elements they are associated with;
  this should make is more efficient to implement such feautures as default attributes 
  associated with all elements of a given type.  Furthermore, @c Attr nodes may not be immediate
  children of a @c DocumentFragment.  However, they can be associated with @c Element nodes contained
  within a @c DocumentFragment.
*/
class Attr : public virtual Node {

public :

  //! Returns the attribute name as a DOMString
  /*!
    Returns the name of this attribute
  */
  virtual const DOMString* name() const = 0;

  //! Determines if the attribute was given explicitly in the original document
  /*!
    If this attribute was explicitly given a value in the original document, this is
    @c true; otherwise, it is @c false.
  */
  virtual bool specified() const = 0;

  //! Sets the specified boolean
  /*!
    Convenience function to set the @c specified boolean.  This is not explicitly defined
    in the W3C DOM Level 3.
    @param newSpecified Boolean value to set for the attribute
  */
  virtual void setSpecified(
                            const bool& newSpecified) = 0;

  //! Returns the attribute value
  /*!
    On retrieval, the value of the attribute is returned as a string.  Character and genera
    entity references are replaced with their values.
    @see @c getAttribute on the @c Element interface

    On setting, this creates a @c Text node with the unparsed contents of the string.  I.e.
    any characters that an XML processor would recognise as markup are instead treated as
    literal text.
    @see @c setAttribute on the @c Element interface
  */
  virtual const DOMString* value() const = 0;

  //! Sets the attribute value
  /*! 
    Convenience function to set the attribute value.  Not explicitly defined in the 
    W3C DOM Level 3, however, it is certainly implied that such a function should exist.
    @param newValue The new value of the attribute
  */
  virtual void setValue(
                        const DOMString& newValue) = 0;

  // Introduced in DOM Level 2:

  //! Returns the owner element of the attribute
  /*!
    Returns the @c Element node this attribute is attached to or @c null if this 
    attribute is not in use.
  */
  virtual const Element* ownerElement() const = 0; 

  //! Sets the owner element of the attribute
  /*!
    Convenience function to explicitly set the @c ownerElement of the attribute.
    Not defined in the W3C DOM Level 3
    @param newOwnerElement The new owner element of the attribute
  */
  virtual void setOwnerElement(
                               const Element* newOwnerElement) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      CharacterData
// ******************************************************************************
// ******************************************************************************

//! CharacterData class
/*!
  The @c CharacterData interface extends @c Node with a set of attributes and methods
  for accessing character data in the DOM.  For clarity this set is defined here 
  rather than on each object that uses these attributes and methods.  No DOM objects
  correspond directly to @c CharacterData, though @c Text and othersdo inherit the 
  interface from it.  All @c offsets in this interface start from 0.

  As explained in the @c DOMString interface, text strings in the DOM are represented
  in UTF-16, i.e. as a sequence of 16-bit units.  In the following, the term 16-bit 
  units is used whenever necessary to indicate that indexing on @c CharacterData is
  done in 16-bit units.

  Note: I believe that Greg Collecutt only implemented strings in UTF-8, so one
  must be damn careful when using this implementation of the DOM and that documented
  both here, and in the 05 June 2001 Working Draft.  PTC.
*/
class CharacterData : public virtual Node {

public :

  //! Returns the data as a DOMString
  /*!
    Returns the character data of the node that implements this interface.
  */
  virtual const DOMString* data() const = 0;

  //! Returns the length of the data
  /*!
    Returns the number of 16-bit units that are available through @c data and the 
    @c substringData method.  This may have the value zero, i.e., @c CharacterData
    nodes may be empty.
  */
  virtual unsigned long length() const = 0;

  //! Returns a substring of the character data of length count characters starting at offset
  /*!
    Extracts a range of data from the node.
    @param offset Start offset of substring to extract
    @param count The number of 16-bit units to extract
  */
  const virtual DOMString* substringData(
                                         unsigned long offset,
                                         unsigned long count) const = 0;

  //! Appends data
  /*!
    Append the string to the end of the character data of the node.  Upon success, @c data provides
    access to the concatenation of @c data and the @c DOMString specified.
    @param arg The @c DOMString to append
  */
  virtual void appendData(
                          const DOMString& arg) = 0;

  //! Inserts data at offset
  /*!
    Insert a string at the specified 16-bit unit offset.
    @param offset The character offset at which to insert
    @param arg The @c DOMString to insert
  */
  virtual void insertData(
                          unsigned long offset,
                          const DOMString& arg) = 0;

  //! Deletes count characters starting at offset
  /*!
    Remove a range of 16-bit units from the node.  Upon success, @c data and @c length 
    reflect the change.
    @param offset The offset from which to start removing
    @param count The number of 16-bit units to delete.  If the sum of @c offset and @c count
    exceeds @c length then all 16-bit units from @c offset to the end of the data are deleted
  */
  virtual void deleteData(
                          unsigned long offset,
                          unsigned long count) = 0;

  //! Replaces count characters starting at offset
  /*!
    Replace the characters starting at the specified 16-bit unit offset with the specified string.
    @param offset The offset from which to start replacing
    @param count The number of 16-bit units to replace.  If the sum of @c offset and @c count
    exceeds @c length, then all 16-bit units to the end of the data are replaced; (i.e. the effect
    is the same as a @c remove method call with the same range, followed by an @c append method
    invocation).
    @param arg The @c DOMString with which the range must be replaced
  */
  virtual void replaceData(
                           unsigned long offset,
                           unsigned long count,
                           const DOMString& arg) = 0;

  //! Sets the data
  /*!
    Convenience function to set data in a @c CharacterData object.  This is not
    specified in the W3C DOM Level 3.
    @param newData The new data that the @c CharacterData object should hold
  */
  virtual void setData(
                       const DOMString& newData) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      Text
// ******************************************************************************
// ******************************************************************************

//! Text class
/*!
  The @c Text interface inherits from @c CharacterData and represents the textual
  content (termed @em character @em data in XML) of an @c Element or @c Attr.  If there
  is no markup inside an element's content, the text is contained in a single object
  implementing the @c Text interface that is the only child of the element.  If there
  is markup, it is parsed into the information items (elements, comments, etc) and 
  @c Text nodes that form the list of children of the element.

  When a document is first made available via the DOM, there is only one @c Text node
  for each block of text.  Users may create adjacent @c Text nodes that represent
  the contents of a given element without any intervening markup, but should be aware
  that there is no way to represent the separations between these nodes in XML, so
  they will not (in general) persist between DOM editing sessions.  The @c normalize()
  method on @c Node merges any such adjacent @c Text objects into a single node for
  each block of text.
*/
class Text : public virtual CharacterData {

public :

  //! Splits text at offset
  /*!
    Breaks this node into two nodes at the specified @c offset, keeping both in the 
    tree as siblings.  After being split, this node will contain all the content up
    to the @c offset pint.  A new node of the same type, which contains all the content
    at and after the @c offset point, is returned.  If the original node had a parent
    node, the new node is inserted as the next sibling of the oriinal node.  When the
    @c offset is equal to the length of this node, the new node has no data.
    @param offset The 16-bit unit offset at which to split, starting from 0
  */
  virtual Text* splitText(
                          unsigned long offset) = 0;

  // Introduced in DOM Level 3:

  //! Determines if whitespace exists in element content
  /*!
    Returns whether this text node contains whitespace in element content,
    often abusively called "ignorable whitespace".
  */
  virtual bool isWhiteSpaceInElementContent() const = 0;

  //! Returns entire text (I think)
  /*!
    Returns all text of @c Text nodes logically-adjacent to this node.
  */
  virtual const DOMString* wholeText() const = 0;

  //! Replaces entire text
  /*!
    Replace all @c Text nodes logcally-adjacent to this node.
    @param content The content of the replacing @c Text node
  */
  virtual Text* replaceWholeText(
                                 const DOMString& content) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      DocumentFragment
// ******************************************************************************
// ******************************************************************************

//! DocumentFragment class
/*!
  A DocumentFragment is a "lightweight" or "minimal" Document object.  It is very common
  to want to be able to extract a portion of a document's tree or to create a new fragement
  of a document.  This object fulfils that purpose.
*/
class DocumentFragment : public virtual Node {
};

// ******************************************************************************
// ******************************************************************************
//      Comment
// ******************************************************************************
// ******************************************************************************

//! Comment class
/*!
  This interface inherits from @c CharacterData and represents the content of a comment, i.e., all the 
  characters between the starting "<!--" and ending "-->".
*/
class Comment : public virtual CharacterData {
};

// ******************************************************************************
// ******************************************************************************
// ******************************************************************************
//      The Extended Interfaces
// ******************************************************************************
// ******************************************************************************
// ******************************************************************************

// ******************************************************************************
// ******************************************************************************
//      Entity
// ******************************************************************************
// ******************************************************************************

//! Entity class
/*!
  This interface represents an entiy, either parsed or unparsed, in an XML document.  Not that this models
  the entity itself not the entity declaration.  @c Entity declaration modeling has been left for a later
  Level of the DOM specification.

  The @c nodeName attribute that is inherited from @c Node contains the name of the entity.

  An @c Entity node does not have a parent.
*/
class Entity : public virtual Node {

public :

  //! Returns the public id as DOMString
  /*!
    Returns the public identifier associated with the entity, if specified.  If the public identifier was
    not specified, this is @c null.
  */
  virtual const DOMString* publicId() const = 0;

  //! Returns the system id as DOMString
  /*!
    Returns the system identifier associated with the entity, if specified.  If the system identifier was
    not specified, this is @c null.
  */
  virtual const DOMString* systemId() const = 0;

  //! Returns the notation name as DOMString
  /*!
    For unparsed entities, this returns the name of the notation for the entity.  For parsed entities, this is @c null.
  */
  virtual const DOMString* notationName() const = 0;

  // Introduced in DOM Level 3:

  //! Returns the actual encoding as DOMString
  /*!
    Returns an attribute specifying the actual encoding of this entity, when it is an external parsed entity.  
    This is @c null otherwise.
  */
  virtual const DOMString* actualEncoding() const = 0;

  //! Sets the actual encoding
  /*!
    Sets the actual encoding of the entity to the string specified.
    @param newActualEncoding The new actual encoding of the entity
  */
  virtual void setActualEncoding(
                                 const DOMString& newActualEncoding) = 0;

  //! Returns the encoding as DOMString
  /*!
    Returns an attribute specifying, as part of the text declaration, the encoding of this entity, when
    it is an external parsed entity.  This is @c null otherwise.
  */
  virtual const DOMString* encoding() const = 0;

  //! Sets the encoding
  /*!
    Sets the encoding attribute of the entity to the specified string.
    @param newEncoding The new encoding attribute of the entity
  */
  virtual void setEncoding(
                           const DOMString& newEncoding) = 0;

  //! Returns the version as DOMString
  /*!
    Returns an attribute specifying, as part of the text declaration, the version number of his entity,
    when it is an external parsed entity.  This is @c null otherwise.
  */
  virtual const DOMString* version() const = 0;

  //! Sets the version
  /*!
    Sets the version attribute of the entity to the specified string.
    @param newVersion The new version of the entity
  */
  virtual void setVersion(
                          const DOMString& newVersion) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      DocumentType
// ******************************************************************************
// ******************************************************************************

//! DocumentType class
/*!
  Each @c Document has a @c doctype attribute whose value is either @c null or a @c DocumentType object.
*/
class DocumentType : public virtual Node {

public :

  //! Returns the name of the document type as a DOMString
  /*!
    Returns the name of DTD; i.e., the name immediately following the DOCTYPE keyword.
  */
  virtual const DOMString* name() const = 0;

  //! Returns the entities of the document type as a NamedNodeMap
  /*!
    Returns a @c NamedNodeMap containing the general entities, both external and internal, declared in the DTD.
    Parameter entities are not contained.  Duplicates are discarded.
  */
  virtual const NamedNodeMap* entities() const = 0;

  //! Returns the notations of the document type as a NamedNodeMap
  /*!
    Returns a @c NamedNodeMap containing the notations declared in the DTD.  Duplicates are discarded.  Every node in this map
    also implements the @c Notation interface.
  */
  virtual const NamedNodeMap* notations() const = 0;

  // Introduced in DOM Level 2:

  //! Returns the public id as a DOMString
  /*!
    Returns the public identifier of the external subset.
  */
  virtual const DOMString* publicId() const = 0;

  //! Returns the system id as a DOMString
  /*!
    Returns the system identifier of the external subset.
  */
  virtual const DOMString* systemId() const = 0;

  //! Returns the internal subset as a DOMString
  /*!
    Returns the internal subset as a string, or @c null if there is none.
  */
  virtual const DOMString* internalSubset() const = 0;
};

// ******************************************************************************
// ******************************************************************************
//      ProcessingInstruction
// ******************************************************************************
// ******************************************************************************

//! ProcessingInstruction class
/*!
  The @c ProcessingInstruction interface represents a "processing instruction", used in XML as a way to 
  keep prcoessor-specific information in the text of the document.
*/
class ProcessingInstruction : public virtual Node {

public :

  //! Returns the target as a DOMString
  /*!
    Returns the target of this processing instruction.  XML defines this as the first token following the
    markup that begins the processing instruction.
  */
  virtual const DOMString* target() const = 0;

  //! Returns the data as a DOMString
  /*!
    Returns the content of this processing instruction.  This is from the first non white space character
    after the target to the character immediately preceding the \?>.
  */
  virtual const DOMString* data() const = 0;

  //! Sets the data
  /*!
    Sets the data in a processing instruction to the specified string.
    @param newData The string to set the processing instruction to
  */
  virtual void setData(
                       const DOMString& newData) = 0;
};

// ******************************************************************************
// ******************************************************************************
//      Notation
// ******************************************************************************
// ******************************************************************************

//! Notation class
/*!
  This interface represents a notation declared in the DTD.  A notation either declares, by name, the format
  of an unparsed entity, or is used for formal declaration of processing instruction targets.  The @c nodeName
  attribute inherited from @c Node is set to the declared name of the notation.

  A @c Notation node does not have any parent.
*/
class Notation : public virtual Node {

public :

  //! Returns the public id as a DOMString
  /*!
    Returns the public identifier of this notation.  If the public identifier was not specified, this is @c null.
  */
  virtual const DOMString* publicId() const = 0;

  //! Returns the system id as a DOMString
  /*!
    Returns the system identifier of this notation.  If the system identifier was not specified, this is @c null.
  */
  virtual const DOMString* systemId() const = 0;
};

// ******************************************************************************
// ******************************************************************************
//      EntityReference
// ******************************************************************************
// ******************************************************************************

//! EntityReference class
/*!
  @c EntityReference objects may be inserted into the structure model when an entity reference is in the source document,
  or when the user wishes to insert an entity reference. 
*/
class EntityReference : public virtual Node {
};

// ******************************************************************************
// ******************************************************************************
//      CDATASection
// ******************************************************************************
// ******************************************************************************

//! CDATASection class
/*!
  CDATA sections are used to escape blocks of text containing characters that would otherwise be regarded as markup.
  The only delimiter that is recognised in a CDATA section is the "]]>" string that ends the CDATA section.  CDATA sections
  cannot be nested.

  The @c DOMString attribute of the @c Text node holds the text that is contained by the CDATA section.

  The @c CDATASection interface inherits from the @c CharacterData interface through the @c Text interface.
*/
class CDATASection : public virtual Text {
};

#define DOM3


syntax highlighted by Code2HTML, v. 0.9.1