/* InputMethodRequests.java -- handles text insertion via input methods
   Copyright (C) 2002 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.awt.im;

import java.awt.Rectangle;
import java.awt.font.TextHitInfo;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;

/**
 * This interface handles requests made by input methods on text editing
 * components. A component must specify a handler for input methods that
 * implements this interface, and which supports one of two user interfaces:
 * <ul><li><em>on-the-spot</em>: composed text is shown in place</li>
 * <li><em>below-the-spot</em>: composed text is in a separate window,
 * usually below the main text window, until it is committed into place at
 * the insertion point, overwriting any selected text</li></ul>
 *
 * @author Eric Blake <ebb9@email.byu.edu>
 * @see Component#getInputMethodRequests()
 * @see InputMethodListener
 * @since 1.2
 * @status updated to 1.4
 */
public interface InputMethodRequests
{
  /**
   * Gets the location of a given offset of the text. This can be used to
   * position a composition window near the location of where the composed
   * text will be inserted.
   *
   * <p>If the component has composed text (from the most recent
   * InputMethodEvent), then offset 0 indicates the location of the first
   * character of this composed text. Otherwise, the offset is ignored, and
   * the location should be the beginning of the final line of selected
   * text (in horizontal left-to-right text, like English, this would be the
   * lower left corner of the selction; in vertical top-to-bottom text, like
   * Chinese, this would be the top right corner of the selection).
   *
   * <p>The location returned is a 0-thickness caret (either horizontal or
   * vertical, depending on text flow), mapped to absolute screen coordinates.
   *
   * @param offset offset within composed text, or null
   * @return the screen location of the caret at the offset
   */
  Rectangle getTextLocation(TextHitInfo offset);

  /**
   * Get the text offset for the given screen coordinate. The offset is
   * relative to the composed text, and the return is null if it is outside
   * the range of composed text. For example, this can be used to find
   * where a mouse click should pop up a text composition window.
   *
   * @param x the x screen coordinate
   * @param y the y screen coordinate
   * @return a text hit info describing the composed text offset
   */
  TextHitInfo getLocationOffset(int x, int y);

  /**
   * Gets the offset where the committed text exists in the text editing
   * component. This can be used to examine the text surrounding the insert
   * position.
   *
   * @return the offset of the insert position
   */
  int getInsertPositionOffset();

  /**
   * Gets an interator which provides access to the text and its attributes,
   * except for the uncommitted text. The input method may provide a list of
   * attributes it is interested in; and the iterator need not provide
   * information on the remaining attributes. If the attribute list is null,
   * the iterator must list all attributes.
   *
   * @param beginIndex the index of the first character in the iteration
   * @param endIndex the index of the last character in the iteration
   * @param attributes a list of attributes interested in, or null
   * @return an iterator over the region of text with its attributes
   */
  AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex,
                                               Attribute[] attributes);

  /**
   * Gets the length of committed text.
   *
   * @return the number of committed characters
   */
  int getCommittedTextLength();

  /**
   * Gets the latest committed text, and removes it from the component's text
   * body. This allows an input method to provide an "Undo" command. In
   * general, this should only be supported immediately after a commit, and
   * not when other actions intervene; if not supported, simply return null.
   * The input method may provide a list of attributes it is interested in;
   * and the iterator need not provide information on the remaining attributes.
   * If the attribute list is null, the iterator must list all attributes.
   *
   * @param attributes a list of attributes interested in, or null
   * @return the latest committed text, or null
   */
  AttributedCharacterIterator cancelLatestCommittedText
    (Attribute[] attributes);

  /**
   * Gets the currently selected text. One use of this is to implement a
   * "Reconvert" feature in an input method, which modifies the selection
   * based on the text in the composition window. The input method may
   * provide a list of attributes it is interested in; and the iterator need
   * not provide information on the remaining attributes. If the attribute
   * list is null, the iterator must list all attributes.
   *
   * @param attributes a list of attributes interested in, or null
   * @return the current selection
   */
  AttributedCharacterIterator getSelectedText(Attribute[] attributes);
} // interface InputMethodRequests
