/*
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

module core {

    interface [CustomMarkFunction, GenerateConstructor, GenerateNativeConverter, GenerateToJS, ObjCCustomInternalImpl] Node {        
        // NodeType
        const unsigned short      ELEMENT_NODE                   = 1;
        const unsigned short      ATTRIBUTE_NODE                 = 2;
        const unsigned short      TEXT_NODE                      = 3;
        const unsigned short      CDATA_SECTION_NODE             = 4;
        const unsigned short      ENTITY_REFERENCE_NODE          = 5;
        const unsigned short      ENTITY_NODE                    = 6;
        const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
        const unsigned short      COMMENT_NODE                   = 8;
        const unsigned short      DOCUMENT_NODE                  = 9;
        const unsigned short      DOCUMENT_TYPE_NODE             = 10;
        const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
        const unsigned short      NOTATION_NODE                  = 12;

        readonly attribute [ConvertNullStringTo=Null] DOMString        nodeName;

                 // FIXME: the spec says this can also raise on retrieval.
                 attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString        nodeValue
                     setter raises(DOMException);

        readonly attribute unsigned short   nodeType;
        readonly attribute Node             parentNode;
        readonly attribute NodeList         childNodes;
        readonly attribute Node             firstChild;
        readonly attribute Node             lastChild;
        readonly attribute Node             previousSibling;
        readonly attribute Node             nextSibling;
        readonly attribute NamedNodeMap     attributes;
        readonly attribute Document         ownerDocument;

        [OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild, 
                                                 in Node refChild)
            raises(DOMException);
        [OldStyleObjC, Custom] Node replaceChild(in Node newChild, 
                                                 in [Return] Node oldChild)
            raises(DOMException);
        [Custom] Node               removeChild(in [Return] Node oldChild)
            raises(DOMException);
        [Custom] Node               appendChild(in [Return] Node newChild)
            raises(DOMException);

        boolean            hasChildNodes();
        Node               cloneNode(in boolean deep);
        void               normalize();

        // Introduced in DOM Level 2:

        [OldStyleObjC] boolean isSupported(in DOMString feature, 
                                           in [ConvertNullToNullString] DOMString version);

        readonly attribute [ConvertNullStringTo=Null] DOMString        namespaceURI;
                 attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString        prefix
                     setter raises(DOMException);
        readonly attribute [ConvertNullStringTo=Null] DOMString        localName;

        boolean            hasAttributes();

        // Introduced in DOM Level 3:

        readonly attribute [ConvertNullStringTo=Null] DOMString       baseURI;

                 // FIXME: the spec says this can also raise on retrieval.
                 attribute [ConvertNullStringTo=Null, ConvertNullToNullString] DOMString       textContent
                     setter raises(DOMException);

        boolean            isSameNode(in Node other);
        boolean            isEqualNode(in Node other);
        [ConvertNullStringTo=Null] DOMString          lookupPrefix(in [ConvertNullToNullString] DOMString namespaceURI);
        boolean            isDefaultNamespace(in [ConvertNullToNullString] DOMString namespaceURI);
        [ConvertNullStringTo=Null] DOMString          lookupNamespaceURI(in [ConvertNullToNullString] DOMString prefix);

#if 0
        // DocumentPosition
        const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
        const unsigned short      DOCUMENT_POSITION_PRECEDING    = 0x02;
        const unsigned short      DOCUMENT_POSITION_FOLLOWING    = 0x04;
        const unsigned short      DOCUMENT_POSITION_CONTAINS     = 0x08;
        const unsigned short      DOCUMENT_POSITION_CONTAINED_BY = 0x10;
        const unsigned short      DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;

        unsigned short     compareDocumentPosition(in Node other)
            raises(DOMException);

        DOMObject          getFeature(in DOMString feature, 
                                      in DOMString version);
        DOMUserData        setUserData(in DOMString key, 
                                       in DOMUserData data, 
                                       in UserDataHandler handler);
        DOMUserData        getUserData(in DOMString key);
#endif /* 0 */

        // IE extentions
        readonly attribute Node             parentElement;

#if defined(LANGUAGE_OBJECTIVE_C)
        // Objective-C extensions
        readonly attribute boolean          isContentEditable;
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
    };

}
