/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISelection.idl"

interface nsRange;
interface nsIDOMNode;
interface nsISelectionListener;
interface nsIContent;
interface nsINode;

%{C++
class nsIFrame;
struct nsPoint;
struct ScrollAxis;
template<class T> class nsTArray;
#include "nsDirection.h"
#include "nsIPresShell.h" // TODO: Remove this include
#include "mozilla/EventForwards.h"
%}

[ptr] native nsIFrame(nsIFrame);
[ptr] native RangeArray(nsTArray<nsRange*>);
[ref] native constTextRangeStyleRef(const mozilla::TextRangeStyle);
[ref] native nsPointRef(nsPoint);
native nsDirection(nsDirection);
native ScrollAxis(nsIPresShell::ScrollAxis);

[scriptable, builtinclass, uuid(0c9f4f74-ee7e-4fe9-be6b-0ba856368178)]
interface nsISelectionPrivate : nsISelection
 {
    const short ENDOFPRECEDINGLINE=0;
    const short STARTOFNEXTLINE=1;

    attribute boolean interlinePosition;
    [noscript] attribute nsIContent ancestorLimiter;

    /* startBatchChanges
       match this up with endbatchChanges. will stop ui updates while multiple selection methods are called
    */
    [noscript] void startBatchChanges();

    /* endBatchChanges
       match this up with startBatchChanges
    */
    [noscript] void endBatchChanges();

    DOMString  toStringWithFormat(in string formatType, in unsigned long flags, in int32_t wrapColumn);
    void  addSelectionListener(in nsISelectionListener newListener);
    void  removeSelectionListener(in nsISelectionListener listenerToRemove);

    /* Table selection stuff
       We should probably move this and table-related 
       items in nsFrameSelection  to a
       new nsITableSelection interface
    */
    const long TABLESELECTION_NONE     = 0;
    const long TABLESELECTION_CELL     = 1;
    const long TABLESELECTION_ROW      = 2;
    const long TABLESELECTION_COLUMN   = 3;
    const long TABLESELECTION_TABLE    = 4;
    const long TABLESELECTION_ALLCELLS = 5;

    /** Test if supplied range points to a single table element:
      *    Result is one of above constants. "None" means
      *    a table element isn't selected.
      */
    [noscript] long getTableSelectionType(in nsIDOMRange range);

    /* canCacheFrameOffset
     * Frame Offset cache can be used just during calling nsEditor::EndPlaceHolderTransaction.
     * EndPlaceHolderTransaction will give rise to reflow/refreshing view/scroll, and call times
     * of nsTextFrame::GetPointFromOffset whose return value is to be cached.
     * see bugs 35296 and 199412
     */
    [noscript] attribute boolean canCacheFrameOffset;

    /* GetCachedOffsetForFrame
     * Returns cached value for nsTextFrame::GetPointFromOffset.
     */
    [noscript] void getCachedFrameOffset(in nsIFrame aFrame, in int32_t inOffset, in nsPointRef aPoint);

    /**
     * Set the painting style for the range. The range must be a range in
     * the selection. The textRangeStyle will be used by text frame
     * when it is painting the selection.
     */
    [noscript] void setTextRangeStyle(in nsIDOMRange range,
                      in constTextRangeStyleRef textRangeStyle);

    /**
     * Get the direction of the selection.
     */
    [noscript, notxpcom] nsDirection getSelectionDirection();
    [noscript, notxpcom] void setSelectionDirection(in nsDirection aDirection);
    
    /**
     * Returns the type of the selection (see nsISelectionController for
     * available constants).
     */
    readonly attribute short type;

    /**
     * Return array of ranges intersecting with the given DOM interval.
     */
    void GetRangesForInterval(
        in nsIDOMNode beginNode, in int32_t beginOffset,
        in nsIDOMNode endNode, in int32_t endOffset,
        in boolean allowAdjacent,
        out uint32_t resultCount,
        [retval, array, size_is(resultCount)] out nsIDOMRange results);

    [noscript] void GetRangesForIntervalArray(
        in nsINode beginNode, in int32_t beginOffset,
        in nsINode endNode, in int32_t endOffset,
        in boolean allowAdjacent,
        in RangeArray results);

    /**
     * Scrolls a region of the selection, so that it is visible in
     * the scrolled view.
     *
     * @param aRegion - the region inside the selection to scroll into view
     *                  (see selection region constants defined in
     *                   nsISelectionController).
     * @param aIsSynchronous - when true, scrolls the selection into view
     *                         before returning. If false, posts a request which
     *                         is processed at some point after the method returns.
     * @param aVPercent - how to align the frame vertically.
     * @param aHPercent - how to align the frame horizontally.
     */
    void scrollIntoView(in short aRegion, in boolean aIsSynchronous,
                        in int16_t aVPercent,
                        in int16_t aHPercent);

    /**
     * Scrolls a region of the selection, so that it is visible in
     * the scrolled view.
     *
     * @param aRegion - the region inside the selection to scroll into view
     *                  (see selection region constants defined in
     *                   nsISelectionController).
     * @param aIsSynchronous - when true, scrolls the selection into view
     *                         before returning. If false, posts a request which
     *                         is processed at some point after the method returns.
     * @param aVertical - how to align the frame vertically and when.
     *                    See nsIPresShell.h:ScrollAxis for details.
     * @param aHorizontal - how to align the frame horizontally and when.
     *                    See nsIPresShell.h:ScrollAxis for details.
     */
    [noscript] void scrollIntoViewInternal(in short aRegion,
                                           in boolean aIsSynchronous,
                                           in ScrollAxis aVertical,
                                           in ScrollAxis aHorizontal);

    /**
     * Modifies the cursor Bidi level after a change in keyboard direction
     * @param langRTL is PR_TRUE if the new language is right-to-left or
     *                PR_FALSE if the new language is left-to-right.
     */
    [noscript] void selectionLanguageChange(in boolean langRTL);
};

