/* 
 * AT-SPI - Assistive Technology Service Provider Interface 
 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
 *
 * Copyright 2001 Sun Microsystems, Inc.
 *
 * 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; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

module Accessibility {

  /**
   * Specifies the boundary conditions determining a run of text as returned from
   * getTextAtOffset, getTextAfterOffset, and getTextBeforeOffset.
   */
  enum TEXT_BOUNDARY_TYPE {
    TEXT_BOUNDARY_CHAR,/**< Text is bounded by this character only. 
			* Start and end offsets differ by one, by definition, for this value. 
			*/
    TEXT_BOUNDARY_WORD_START,/**< Boundary condition is start of a word; i.e. range is from start of
			      * one word to the start of another word. 
			      */
    TEXT_BOUNDARY_WORD_END,/**< Boundary condition is the end of a word; i.e. range is from 
			    * the end of one word to the end of another. 
			    * @note some locales may not distinguish between words and
			    * characters or glyphs, in particular those locales which use
			    * wholly or partially ideographic character sets.  In these cases,
			    * characters may be returned in lieu of multi-character substrings.
			    */
    TEXT_BOUNDARY_SENTENCE_START,/**< Boundary condition is start of a sentence, as determined 
				*  by the application. 
				*  @note Some locales or character sets may not include explicit sentence
				*  delimiters, so this boundary type can not always be honored.
				*  Some locales will return lines of text instead of grammatical sentences.
				  */
    TEXT_BOUNDARY_SENTENCE_END,/**< Boundary condition is end of a sentence, as determined by the application, 
				*  including the sentence-delimiting character, for instance '.'
				*  @note Some locales or character sets may not include explicit sentence
				*  delimiters, so this boundary type can not always be honored.
				*  Some locales will return lines of text instead of grammatical sentences.
				*/
    TEXT_BOUNDARY_LINE_START,/**< Boundary condition is the start of a line; i.e. range is 
			      * from start of one line to the start of another.  This generally 
			      * means that an end-of-line character will appear at the end of the range. 
			      */
    TEXT_BOUNDARY_LINE_END /**< Boundary condition is the end of a line; i.e. range is
			    * from start of one line to the start of another.  This generally 
			    * means that an end-of-line character will be the first character of the range. 
			    */
  };

  /**
   * TEXT_CLIP_TYPE:
   * CLIP_MIN means text clipped by min coordinate is omitted,
   * CLIP_MAX clips text interescted by the max coord, and CLIP_BOTH
   * will retain only text falling fully within the min/max bounds.
   *
   **/
  enum TEXT_CLIP_TYPE {
    TEXT_CLIP_NONE,
    TEXT_CLIP_MIN,/**< characters/glyphs clipped by the minimum coordinate are omitted */
    TEXT_CLIP_MAX,/**< characters/glyphs which intersect the maximum coordinate are omitted */
    TEXT_CLIP_BOTH /**< only glyphs falling entirely within the region bounded by min and max are retained. */
  };

    /** 
     * The text interface should be implemented by objects which place textual information onscreen as character
     * strings or glyphs.  The text interface allows access to textual content, including display attributes and
     * semantic hints associated with runs of text, and access to bounding box information for glyphs and substrings.
     * It also allows portions of textual content to be selected, if the object's StateSet includes
     * STATE_SELECTABLE_TEXT. 
     *
     * In some cases a Text object may have, as its content, an empty string.  In particular this can
     * occur in the case of Hypertext objects which do not display explicitly textual information onscreen,
     * as Hypertext is derived from the Text interface.  @see Hypertext.
     *
     * Typographic and semantic attributes of onscreen textual content, for instance typeface, weight, 
     * language, and such qualities as 'emphasis' or 'blockquote', are represented as text attributes.
     * Contiguous sequences of characters over which these attributes are unchanged are referred to as
     * "attribute runs", and are available via Text::getAttributeRun.  Where possible, implementing clients
     * will report textual attributes which are the same over the entire text object, for instance those
     * inherited from a default or document-scope style, via getDefaultAttributes instead of reporting them
     * explicitly for each character.  Therefore, for any span of text, the attributes in effect are the union
     * of the set returned by Text::getDefaultAttributes, and the set returned at a particular character
     * offset via Text::getAttributeRun.
     *
     * @note Events that may be emitted by instances of Text include:
     * \li \c "object:text-attributes-changed" The attributes of a range of text, or the range over 
     *         which attributes apply, has changed.
     * \li \c "object:text-changed" The text content of this object has changed.
     * \li \c "object:text-bounds-changed" The character bounds of a text object have changed, 
     *         for instance in response to a reformatting or reflow operation.
     * \li \c "object:text-caret-moved" The character offset of the text caret (visible or notional) within
     *         this object has changed.  Events of this type may also be generated when an onscreen
     *         text caret appears or disappears.
     * \li \c "object:text-selection-changed" The range or number of text selections within this text object
     *         has changed.
     *
     * @note In some cases, objects which are not onscreen may implement Text, but if such objects
     * implement Component, their potential visibility should be examined (via comparison with STATE_VISIBLE 
     * and STATE_SHOWING) before exposing them to the user.  Objects which implement Text but not Component 
     * may be encountered in special-purpose interfaces or as special ¨accessibility¨ extensions to visual 
     * interfaces to allow non-graphical access to application features.  These instances should be considered 
     * the exception, rather than the rule.
     */
  interface Text : Bonobo::Unknown {

    /** A structure used to define a continguous range of text, including its 
     * (unattributed) textual content. 
     **/
    struct Range {
      long startOffset;
      long endOffset; 
      string content;
      any  data;
    };
    
    typedef sequence<Range> RangeList;

    /** The total current number of characters in the Text object, 
     * including whitespace and non-spacing characters.  
     **/
    readonly attribute long characterCount;

    /** The current offset of the text caret in the Text object.  
     * This caret may be virtual, e.g. non-visual and notional-only, but if an
     * onscreen representation of the caret position is visible, it will correspond to this offset.
     * The caret offset is given as a character offset, as opposed to a byte offset into 
     * a text buffer or a column offset. 
     **/
    readonly attribute long caretOffset;

      /**
       * Obtain all or part of the onscreen textual content of a Text object.  If endOffset is specified as 
       * "-1", then this method will return the entire onscreen textual contents of the Text object.
       * @note 'onscreen' in this context means "potentially onscreen", this method does not perform any sort 
       * of coordinate visibility clipping or window-stack-ordering clipping.  The text thus reported 
       * corresponds to the text which would be presented onscreen if the object implementing the Text interface
       * were entirely unobscured. 
       * @returns the textual content of the current Text object beginning startOffset (inclusive) 
       * up to but not including the character at endOffset.
       **/
    string getText (in long startOffset, in long endOffset);

      /** Programmatically move the text caret (visible or virtual, as above) to a given position. 
       * @param offset a long int indicating the desired character offset.  Not all implementations of
       * Text will honor setCaretOffset requests, so the return value below should be checked by the client.
       * @returns \c TRUE if the request was carried out, or \c FALSE if the caret could not be moved to 
       * the requested position.
       **/
    boolean setCaretOffset (in long offset);

      /**
       * Obtain a subset of the text content of an object which entirely precedes \c offset,
       * delimited by character, word, line, or sentence boundaries as specified by \c type.  The
       * starting and ending offsets of the resulting substring are returned in \c startOffset
       * and \c endOffset.  By definition, if such a substring exists, \c endOffset is less than or
       * equal to \c offset.
       * @param offset the offset from which the substring search begins.
       * @param type the text-boundary delimiter which determines whether the returned text constitures
       *        a character, word, line, or sentence (and possibly attendant whitespace), 
       *        and whether the start or ending of such a substring forms the boundary condition.
       * @param startOffset back-filled with the starting offset of the resulting substring, if one exists.
       * @param endOffset back-filled with the offset of the character immediately following the resulting
       *                  substring, if one exists.
       * @see TEXT_BOUNDARY_TYPE
       * @returns a string which is a substring of the text content of the object, delimited by the
       * specified boundary condition.
       */
    string getTextBeforeOffset (in long offset, in TEXT_BOUNDARY_TYPE type,
				out long startOffset, out long endOffset);
      /**
       * Obtain a subset of the text content of an object which includes the specified \c offset, 
       * delimited by character, word, line, or sentence boundaries as specified by \c type.  The
       * starting and ending offsets of the resulting substring are returned in \c startOffset
       * and \c endOffset.  
       * @param offset the offset from which the substring search begins, and which must 
       *        lie within the returned substring.
       * @param type the text-boundary delimiter which determines whether the returned text constitures
       *        a character, word, line, or sentence (and possibly attendant whitespace), 
       *        and whether the start or ending of such a substring forms the boundary condition.
       * @param startOffset back-filled with the starting offset of the resulting substring, if one exists.
       * @param endOffset back-filled with the offset of the character immediately following the resulting
       *                  substring, if one exists.
       * @see TEXT_BOUNDARY_TYPE
       * @returns a string which is a substring of the text content of the object, delimited by the
       * specified boundary condition.
       */
    string getTextAtOffset (in long offset, in TEXT_BOUNDARY_TYPE type,
			    				out long startOffset, out long endOffset);
      /**
       * Obtain a subset of the text content of an object which entirely follows \c offset,
       * delimited by character, word, line, or sentence boundaries as specified by \c type.  The
       * starting and ending offsets of the resulting substring are returned in \c startOffset
       * and \c endOffset.  By definition, if such a substring exists, \c startOffset must be greater than
       * \c offset.
       * @param offset the offset from which the substring search begins, and which must 
       *        lie before the returned substring.
       * @param type the text-boundary delimiter which determines whether the returned text constitures
       *        a character, word, line, or sentence (and possibly attendant whitespace), 
       *        and whether the start or ending of such a substring forms the boundary condition.
       * @param startOffset back-filled with the starting offset of the resulting substring, if one exists.
       * @param endOffset back-filled with the offset of the character immediately following the resulting
       *                  substring, if one exists.
       * @see TEXT_BOUNDARY_TYPE
       * @returns a string which is a substring of the text content of the object, delimited by the
       * specified boundary condition.
       */
    string getTextAfterOffset (in long offset, in TEXT_BOUNDARY_TYPE type,
			       				out long startOffset, out long endOffset);
      /**
       * @returns an unsigned long integer whose value corresponds to the UCS-4 representation of the
       * character at the specified text offset, or 0 if offset is out of range.
       */
    unsigned long getCharacterAtOffset (in long offset);  /* long instead of wchar, 
							   * to allow unicode chars > 16 bits 
							   */
    /** 
     * Get the string value of a named attribute at a given offset, if defined.
     * @param offset the offset of the character for which the attribute run is to be obtained.
     * @param attributeName the name of the attribute for which the value is to be returned, if defined.
     * @param startOffset back-filled with the offset of the first character in the attribute run
     * containing the character at \c offset.
     * @param endOffset back-filled with the offset of the first character past the end of the
     * attribute run containing the character at \c offset.
     * @param defined back-filled with \c True if the attributeName has a defined value at \c offset,
     * \c False otherwise.
     * @returns the value of attribute (name-value pair) corresponding to "name", if defined. 
     **/
    string getAttributeValue (in long offset, in string attributeName,
			      out long startOffset,
			      out long endOffset,
			      out boolean defined);
    /** 
     * getAttributes is deprecated in favor of getAttributeRun.
     * @returns the attributes at offset, as a semicolon-delimited set of colon-delimited name-value pairs. 
     * @see getAttributeRun
     **/
    string getAttributes (in long offset,
			  out long startOffset, out long endOffset);
      /** 
       * Deprecated in favor of getDefaultAttributeSet.
       * @returns the attributes which apply to the entire text content, but which were not explicitly
       * specified by the content creator.
       * @see getDefaultAttributeSet
       **/
    string getDefaultAttributes ();
      /**
       * Obtain a the bounding box, as x, y, width, and height, of the character or glyph at a particular 
       * character offset in this object's text content.  The coordinate system in which the results are
       * reported is specified by coordType.  If an onscreen glyph corresponds to multiple character offsets,
       * for instance if the glyph is a ligature, the bounding box reported will include the entire glyph and
       * therefore may apply to more than one character offset.
       * @param offset the character offset of the character or glyph being queried.
       * @param x the minimum horizontal coordinate of the bounding box of the glyph representing 
       *          the character at \c offset.
       * @param y the minimum vertical coordinate of the bounding box of the glyph representing 
       *          the character at \c offset.
       * @param width the horizontal extent of the bounding box of the glyph representing 
       *          the character at \c offset.
       * @param height the vertical extent of the bounding box of the glyph representing 
       *          the character at \c offset.
       * @param coordType If 0, the results will be reported in screen coordinates, i.e. in pixels
       *                  relative to the upper-left corner of the screen, with the x axis pointing right
       *                  and the y axis pointing down.
       *                  If 1, the results will be reported relative to the containing toplevel window,
       *                  with the x axis pointing right and the y axis pointing down.
       **/
    void getCharacterExtents (in long offset, out long x, out long y, out long width, out long height, in short coordType);
      /** 
       * Get the offset of the character at a given onscreen coordinate.  The coordinate system used to interpret
       * x and y is determined by parameter coordType.
       * @param x
       * @param y
       * @param coordType if 0, the input coordinates are interpreted relative to the entire screen, if 1,
       *                  they are relative to the toplevel window containing this Text object.
       * @returns the text offset (as an offset into the character array) of the glyph whose onscreen bounds contain the point x,y, or -1 if the point is outside the bounds of any glyph.
       **/
    long getOffsetAtPoint (in long x, in long y, in short coordType);
      /**
       * Obtain the number of separate, contiguous selections in the current Text object.
       * Text objects which do not implement selection of discontiguous text regions will always
       * return '0' or '1'.  Note that "contiguous" is defined by continuity of the offsets, i.e.
       * a text 'selection' is defined by a start/end offset pair.  In the case of bidirectional text,
       * this means that a continguous selection may appear visually discontiguous, and vice-versa.
       *
       * @returns the number of contiguous selections in the current Text object.
       **/
    long getNSelections ();
      /**
       * The result of calling getSelection with an out-of-range selectionNum (i.e. for a selection 
       * which does not exist) is not strictly defined, but should set endOffset equal to startOffset.
       **/
    void getSelection (in long selectionNum, out long startOffset, out long endOffset);
      /**
       * The result of calling addSelection on objects which already have one selection present, and which
       * do not include STATE_MULTISELECTABLE, is undefined, other than the return value.
       * @returns \c True of the selection was successfully added, \c False otherwise. Selection may
       * fail if the object does not support selection of text (see STATE_SELECTABLE_TEXT), if the
       * object does not support multiple selections and a selection is already defined, or for other reasons
       * (for instance if the user does not have permission to copy the text into the relevant selection 
       * buffer).
       **/
    boolean addSelection (in long startOffset, in long endOffset);
      /**
       * Deselect the text contained in the specified selectionNum, if such a selection
       * exists, otherwise do nothing.  Removal of a non-existant selectionNum has no effect.
       * @returns \c True if the selection was successfully removed, \c False otherwise.
       **/
    boolean removeSelection (in long selectionNum);
      /**
       * Modify an existing selection's start or ending offset. 
       *
       * Calling setSelection for a selectionNum that is not already defined has no effect.
       * The result of calling setSelection with a selectionNum greater than 0 for objects that
       * do not include STATE_MULTISELECTABLE is undefined.
       * @param selectionNum indicates which of a set of non-contiguous selections to modify.
       * @param startOffset the new starting offset for the selection
       * @param endOffset the new ending offset for the selection
       * @returns \c True if the selection corresponding to selectionNum is successfully modified, 
       *             \c False otherwise.
       **/
    boolean setSelection (in long selectionNum, in long startOffset, in long endOffset);
      /**
       * Obtain the bounding box which entirely contains a given text range.
       * Negative values may be returned for the bounding box parameters in the event
       * that all or part of the text range is offscreen or not mapped to the screen.
       * @param startOffset the offset of the first character in the specified range.
       * @param endOffset the offset of the character immediately after the last 
       *        character in the specified range.
       * @param x an integer parameter which is back-filled with the minimum
       *        horizontal coordinate of the resulting bounding box.
       * @param y an integer parameter which is back-filled with the minimum
       *        vertical coordinate of the resulting bounding box.
       * @param width an integer parameter which is back-filled with the
       *        horizontal extent of the bounding box.
       * @param height an integer parameter which is back-filled with the
       *        vertical extent of the bounding box.
       * @param coordType If 0, the above coordinates are reported in pixels relative to
       *        corner of the screen; if 1, the coordinates are reported relative to the
       *        corner of the containing toplevel window.
       **/
    void    getRangeExtents (in long startOffset, in long endOffset, 
			     out long x, out long y, 
			     out long width, out long height, in short coordType);

      /**
       * Return the text content within a bounding box, 
       * as a list of Range structures.
       * Depending on the TEXT_CLIP_TYPE parameters, glyphs which are clipped by the
       * bounding box (i.e. which lie partially inside and partially outside it)
       * may or may not be included in the ranges returned.  
       * @note This method may be of particular interest to screen review algorithms.
       * @see TEXT_CLIP_TYPE.
       * @param x the minimum x ( i.e. leftmost)  coordinate of the bounding box.
       * @param y the minimum y coordinate of the bounding box.
       * @param width the horizontal size of the bounding box.  The rightmost bound of the bounding box
       *        is (x + width);
       * @param height the vertical size of the bounding box.  The maximum y value of the bounding box
       *        is (y + height);
       * @param coordType If 0, the above coordinates are interpreted as pixels relative to
       *        corner of the screen; if 1, the coordinates are interpreted as pixels relative to the
       *        corner of the containing toplevel window.
       * @param xClipType determines whether text which intersects the bounding box in the x direction
       *        is included.
       * @param yClipType determines whether text which intersects the bounding box in the y direction
       *        is included.
       **/
    RangeList getBoundedRanges (in long x, in long y, 
				in long width, in long height, 
				in short coordType, 
				in TEXT_CLIP_TYPE xClipType, 
				in TEXT_CLIP_TYPE yClipType);

       AttributeSet getAttributeRun (in long offset,
				     out long startOffset, 
				     out long endOffset,
				     in boolean includeDefaults);
       
       AttributeSet getDefaultAttributeSet ();

    /** \cond
     * unImplemented:
     *
     * placeholders for future expansion.
     */
    void unImplemented ();
    void unImplemented2 ();
    void unImplemented3 ();
    void unImplemented4 ();
    /** \endcond **/
  };
};
