/*
 * Copyright (C) 2006 Apple Computer, Inc.
 * 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 ranges {

    // Introduced in DOM Level 2:
    interface Range {

        readonly attribute Node startContainer
            getter raises(DOMException);
        readonly attribute long startOffset
            getter raises(DOMException);
        readonly attribute Node endContainer
            getter raises(DOMException);
        readonly attribute long endOffset
            getter raises(DOMException);
        readonly attribute boolean collapsed
            getter raises(DOMException);
        readonly attribute Node commonAncestorContainer
            getter raises(DOMException);

        [OldStyleObjC] void setStart(in Node refNode, 
                                     in long offset)
            raises(RangeException, DOMException);
        [OldStyleObjC] void setEnd(in Node refNode, 
                                   in long offset)
            raises(RangeException, DOMException);
        void setStartBefore(in Node refNode)
            raises(RangeException, DOMException);
        void setStartAfter(in Node refNode)
            raises(RangeException, DOMException);
        void setEndBefore(in Node refNode)
            raises(RangeException, DOMException);
        void setEndAfter(in Node refNode)
            raises(RangeException, DOMException);
        void collapse(in boolean toStart)
            raises(DOMException);
        void selectNode(in Node refNode)
            raises(RangeException, DOMException);
        void selectNodeContents(in Node refNode)
            raises(RangeException, DOMException);

        // CompareHow
        const unsigned short START_TO_START = 0;
        const unsigned short START_TO_END   = 1;
        const unsigned short END_TO_END     = 2;
        const unsigned short END_TO_START   = 3;

        [OldStyleObjC] short compareBoundaryPoints(in CompareHow how,
                                                   in Range sourceRange)
            raises(DOMException);

        void deleteContents()
            raises(DOMException);
        DocumentFragment extractContents()
            raises(DOMException);
        DocumentFragment cloneContents()
            raises(DOMException);
        void insertNode(in Node newNode)
            raises(DOMException, RangeException);
        void surroundContents(in Node newParent)
            raises(DOMException, RangeException);
        Range cloneRange()
            raises(DOMException);
        DOMString toString()
            raises(DOMException);

        void detach()
            raises(DOMException);

#if defined(LANGUAGE_JAVASCRIPT) || LANGUAGE_JAVASCRIPT
        // CSSOM View Module API extensions

        ClientRectList getClientRects();
        ClientRect getBoundingClientRect();
#endif

        // extensions

        DocumentFragment createContextualFragment(in DOMString html)
            raises(DOMException);

        // WebKit extensions

        boolean intersectsNode(in Node refNode)
            raises(RangeException, DOMException);

        short compareNode(in Node refNode)
            raises(RangeException, DOMException);

        // CompareResults
        const unsigned short NODE_BEFORE           = 0;
        const unsigned short NODE_AFTER            = 1;
        const unsigned short NODE_BEFORE_AND_AFTER = 2;
        const unsigned short NODE_INSIDE           = 3;

        short comparePoint(in Node refNode, 
                           in long offset)
            raises(RangeException, DOMException);

        boolean isPointInRange(in Node refNode, 
                               in long offset)
            raises(RangeException, DOMException);

        void expand(in DOMString unit)
            raises(RangeException, DOMException);

#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
        readonly attribute DOMString text;
#endif
    };

}
