/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Google Inc.  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.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS 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 APPLE 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.
 */

module window {

    // This is based off of Mozilla's Selection interface
    // https://developer.mozilla.org/En/DOM/Selection
    interface [
        JSGenerateIsReachable=ImplFrame,
        InterfaceName=Selection
    ] DOMSelection {
        readonly attribute Node anchorNode;
        readonly attribute long anchorOffset;
        readonly attribute Node focusNode;
        readonly attribute long focusOffset;

        readonly attribute boolean isCollapsed;
        readonly attribute long rangeCount;

        void collapse(in [Optional=DefaultIsUndefined] Node node, 
                      in [Optional=DefaultIsUndefined] long index)
            raises(DOMException);
        void collapseToEnd()
            raises(DOMException);
        void collapseToStart()
            raises(DOMException);

        void deleteFromDocument();
        boolean containsNode(in [Optional=DefaultIsUndefined] Node node, 
                             in [Optional=DefaultIsUndefined] boolean allowPartial);
        void selectAllChildren(in [Optional=DefaultIsUndefined] Node node)
            raises(DOMException);

        void extend(in [Optional=DefaultIsUndefined] Node node, 
                    in [Optional=DefaultIsUndefined] long offset)
            raises(DOMException);

        Range getRangeAt(in [Optional=DefaultIsUndefined] long index)
            raises(DOMException);
        void removeAllRanges();
        void addRange(in [Optional=DefaultIsUndefined] Range range);

#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
        [NotEnumerable] DOMString toString();
#endif

        // WebKit extensions
        readonly attribute Node baseNode;
        readonly attribute long baseOffset;
        readonly attribute Node extentNode;
        readonly attribute long extentOffset;

        // WebKit's "type" accessor returns "None", "Range" and "Caret"
        // IE's type accessor returns "none", "text" and "control"
        readonly attribute DOMString type;

        void modify(in [Optional=DefaultIsUndefined] DOMString alter, 
                    in [Optional=DefaultIsUndefined] DOMString direction, 
                    in [Optional=DefaultIsUndefined] DOMString granularity);
        void setBaseAndExtent(in [Optional=DefaultIsUndefined] Node baseNode, 
                              in [Optional=DefaultIsUndefined] long baseOffset, 
                              in [Optional=DefaultIsUndefined] Node extentNode, 
                              in [Optional=DefaultIsUndefined] long extentOffset)
            raises(DOMException);
        void setPosition(in [Optional=DefaultIsUndefined] Node node, 
                         in [Optional=DefaultIsUndefined] long offset)
            raises(DOMException);

        // IE extentions
        // http://msdn.microsoft.com/en-us/library/ms535869(VS.85).aspx
        void empty();
    };

}
