/*
 * 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:09:03  twl
 * Initial revision
 *
 * Revision 1.2  1999/11/08 20:44:21  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef DOM_ProcessingInstruction_HEADER_GUARD_
#define DOM_ProcessingInstruction_HEADER_GUARD_

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

class ProcessingInstructionImpl;

/**
 * The <code>ProcessingInstruction</code> interface represents a  "processing 
 * instruction", used in XML as a way to keep processor-specific information 
 * in the text of the document.
 */
class  CDOM_EXPORT DOM_ProcessingInstruction: public DOM_Node {
public:
    /** @name Constructors and assignment operator */
    //@{
    /**
      * Default constructor for DOM_ProcessingInstruction.  The resulting object
      *  does not refer to an actual PI 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 PI node.
      * <p>
      * New Processing Instruction nodes are created by DOM_Document::createProcessingInstruction().
      *
      *
      */
    DOM_ProcessingInstruction();

    /**
      * Copy constructor.  Creates a new <code>DOM_ProcessingInstruction</code> that refers to the
      * same underlying node as the original.  See also DOM_Node::clone(),
      * which will copy the actual PI node, rather than just creating a new
      * reference to the original node.
      *
      * @param other The object to be copied.
      */
    DOM_ProcessingInstruction(const DOM_ProcessingInstruction &other);

    /**
      * Assignment operator.
      *
      * @param other The object to be copied.
      */
    DOM_ProcessingInstruction & operator = (const DOM_ProcessingInstruction &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_ProcessingInstruction & operator = (const DOM_NullPtr *val);

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

    //@}
    /** @name Get functions. */
    //@{
    /**
     * The target of this processing instruction. 
     *
     * XML defines this as being the 
     * first token following the markup that begins the processing instruction.
     */
    DOMString        getTarget() const;

    /**
     * The content of this processing instruction. 
     *
     * This is from the first non 
     * white space character after the target to the character immediately 
     * preceding the <code>?&gt;</code>.
     * @exception DOMException
     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
     */
    DOMString        getData() const;

    //@}
    /** @name Set functions. */
    //@{
    /**
    * Sets the content of this processing instruction. 
    *
    * This is from the first non 
    * white space character after the target to the character immediately 
    * preceding the <code>?&gt;</code>.
    * @param data The string containing the processing instruction
    */
    void             setData(const DOMString &data);
    //@}

private:
    DOM_ProcessingInstruction(ProcessingInstructionImpl *impl);

    friend class DOM_Document;

};

#endif

