/* TextComponent.java -- Widgets for entering text
   Copyright (C) 1999, 2002, 2003, 2006, 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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;

import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.peer.TextComponentPeer;
import java.io.Serializable;
import java.text.BreakIterator;
import java.util.EventListener;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.swing.text.AttributeSet;

/**
 * This class provides common functionality for widgets than
 * contain text.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public class TextComponent extends Component
  implements Serializable, Accessible
{

  private static final long serialVersionUID = -2214773872412987419L;

  /**
   * @serial Indicates whether or not this component is editable.
   * This is package-private to avoid an accessor method.
   */
  boolean editable;

  /**
   * @serial The starting position of the selected text region.
   * This is package-private to avoid an accessor method.
   */
  int selectionStart;

  /**
   * @serial The ending position of the selected text region.
   * This is package-private to avoid an accessor method.
   */
  int selectionEnd;

  /**
   * @serial The text in the component
   * This is package-private to avoid an accessor method.
   */
  String text;

  /**
   * A list of listeners that will receive events from this object.
   */
  protected transient TextListener textListener;

  protected class AccessibleAWTTextComponent
    extends AccessibleAWTComponent
    implements AccessibleText, TextListener
  {
    private static final long serialVersionUID = 3631432373506317811L;

    // Constructor
    // Adds a listener for tracking caret changes
    public AccessibleAWTTextComponent()
    {
      TextComponent.this.addTextListener(this);
    }

    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.TEXT;
    }

    public AccessibleStateSet getAccessibleStateSet()
    {
      // TODO: Docs say PropertyChangeEvent will fire if this state changes.
      // That means that the event has to fire when editable changes.
      AccessibleStateSet ss = super.getAccessibleStateSet();
      if (editable)
        ss.add(AccessibleState.EDITABLE);
      return ss;
    }

    public AccessibleText getAccessibleText()
    {
      return this;
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getIndexAtPoint(java.awt.Point)
     */
    public int getIndexAtPoint(Point point)
    {
      return TextComponent.this.getIndexAtPoint(point);
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getCharacterBounds(int)
     */
    public Rectangle getCharacterBounds(int index)
    {
      return TextComponent.this.getCharacterBounds(index);
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getCharCount()
     */
    public int getCharCount()
    {
      return text.length();
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getCaretPosition()
     */
    public int getCaretPosition()
    {
      return TextComponent.this.getCaretPosition();
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getAtIndex(int, int)
     */
    public String getAtIndex(int part, int index)
    {
      if (index < 0 || index >= text.length())
        return null;
      BreakIterator it = null;
      switch (part)
      {
        case CHARACTER:
          return text.substring(index, index + 1);
        case WORD:
          it = BreakIterator.getWordInstance();
          break;
        case SENTENCE:
          it = BreakIterator.getSentenceInstance();
          break;
        default:
          return null;
      }
          it.setText(text);
          int start = index;
          if (!it.isBoundary(index))
            start = it.preceding(index);
          int end = it.following(index);
          if (end == -1)
            return text.substring(index);
          else
            return text.substring(index, end);
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getAfterIndex(int, int)
     */
    public String getAfterIndex(int part, int index) {
      if (index < 0 || index >= text.length())
        return null;
      BreakIterator it = null;
      switch (part)
      {
        case CHARACTER:
          return text.substring(index, index + 1);
        case WORD:
          it = BreakIterator.getWordInstance();
          break;
        case SENTENCE:
          it = BreakIterator.getSentenceInstance();
          break;
        default:
          return null;
      }
          it.setText(text);
          int start = index;
          if (!it.isBoundary(index))
            start = it.following(index);
          // Make sure there was a complete unit.  I.e. if index is in the middle
          // of a word, return null if there is no word after the that one.
          if (start == -1)
            return null;
          int end = it.following(start);
          if (end == -1)
            return text.substring(index);
          else
            return text.substring(index, end);
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getBeforeIndex(int, int)
     */
    public String getBeforeIndex(int part, int index)
    {
      if (index < 1 || index >= text.length())
        return null;
      BreakIterator it = null;
      switch (part)
      {
        case CHARACTER:
          return text.substring(index - 1, index);
        case WORD:
          it = BreakIterator.getWordInstance();
          break;
        case SENTENCE:
          it = BreakIterator.getSentenceInstance();
          break;
        default:
          return null;
      }
          it.setText(text);
          int end = index;
          if (!it.isBoundary(index))
            end = it.preceding(index);
          // Make sure there was a complete unit.  I.e. if index is in the middle
          // of a word, return null if there is no word before that one.
          if (end == -1)
            return null;
          int start = it.preceding(end);
          if (start == -1)
            return text.substring(0, end);
          else
            return text.substring(start, end);
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getCharacterAttribute(int)
     */
    public AttributeSet getCharacterAttribute(int index)
    {
      // FIXME: I suspect this really gets filled in by subclasses.
      return null;
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getSelectionStart()
     */
    public int getSelectionStart() {
      // TODO Auto-generated method stub
      return selectionStart;
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getSelectionEnd()
     */
    public int getSelectionEnd()
    {
      return selectionEnd;
    }

    /* (non-Javadoc)
     * @see javax.accessibility.AccessibleText#getSelectedText()
     */
    public String getSelectedText()
    {
      if (selectionEnd - selectionStart > 0)
        return text.substring(selectionStart, selectionEnd);
      else
        return null;
    }

    /* (non-Javadoc)
     * @see java.awt.event.TextListener#textValueChanged(java.awt.event.TextEvent)
     */
    public void textValueChanged(TextEvent event)
    {
      // TODO Auto-generated method stub

    }

  }


  TextComponent(String text)
  {
    if (text == null)
      this.text = "";
    else
      this.text = text;

    this.editable = true;
  }


  /**
   * Returns the text in this component
   *
   * @return The text in this component.
   */
  public synchronized String getText()
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      text = tcp.getText();

    return(text);
  }

  /**
   * Sets the text in this component to the specified string.
   *
   * @param text The new text for this component.
   */
  public synchronized void setText(String text)
  {
    if (text == null)
      text = "";

    this.text = text;

    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      tcp.setText(text);
    setCaretPosition(0);
  }

  /**
   * Returns a string that contains the text that is currently selected.
   *
   * @return The currently selected text region.
   */
  public synchronized String getSelectedText()
  {
    String alltext = getText();
    int start = getSelectionStart();
    int end = getSelectionEnd();

    return(alltext.substring(start, end));
  }

  /**
   * Returns the starting position of the selected text region.
   * If the text is not selected then caret position is returned.
   *
   * @return The starting position of the selected text region.
   */
  public synchronized int getSelectionStart()
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      selectionStart = tcp.getSelectionStart();

    return(selectionStart);
  }

  /**
   * Sets the starting position of the selected region to the
   * specified value.  If the specified value is out of range, then it
   * will be silently changed to the nearest legal value.
   *
   * @param selectionStart The new start position for selected text.
   */
  public synchronized void setSelectionStart(int selectionStart)
  {
    select(selectionStart,
           (getSelectionEnd() < selectionStart)
                              ? selectionStart : getSelectionEnd());
  }

  /**
   * Returns the ending position of the selected text region.
   * If the text is not selected, then caret position is returned
   *
   * @return The ending position of the selected text region.
   */
  public synchronized int getSelectionEnd()
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      selectionEnd = tcp.getSelectionEnd();

    return(selectionEnd);
  }

  /**
   * Sets the ending position of the selected region to the
   * specified value.  If the specified value is out of range, then it
   * will be silently changed to the nearest legal value.
   *
   * @param selectionEnd The new start position for selected text.
   */
  public synchronized void setSelectionEnd(int selectionEnd)
  {
    select(getSelectionStart(), selectionEnd);
  }

  /**
   * This method sets the selected text range to the text between the
   * specified start and end positions.  Illegal values for these
   * positions are silently fixed.
   *
   * @param selectionStart The new start position for the selected text.
   * @param selectionEnd The new end position for the selected text.
   */
  public synchronized void select(int selectionStart, int selectionEnd)
  {
    if (selectionStart < 0)
      selectionStart = 0;

    if (selectionStart > getText().length())
      selectionStart = text.length();

    if (selectionEnd > text.length())
      selectionEnd = text.length();

    if (selectionStart > selectionEnd)
      selectionStart = selectionEnd;

    this.selectionStart = selectionStart;
    this.selectionEnd = selectionEnd;

    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      tcp.select(selectionStart, selectionEnd);
  }

  /**
   * Selects all of the text in the component.
   */
  public synchronized void selectAll()
  {
    select(0, getText().length());
  }

  /**
   * Returns the current caret position in the text.
   *
   * @return The caret position in the text.
   */
  public synchronized int getCaretPosition()
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      return(tcp.getCaretPosition());
    else
      return(0);
  }

  /**
   * Sets the caret position to the specified value.
   *
   * @param caretPosition The new caret position.
   *
   * @exception IllegalArgumentException If the value supplied for position
   * is less than zero.
   *
   * @since 1.1
   */
  public synchronized void setCaretPosition(int caretPosition)
  {
    if (caretPosition < 0)
      throw new IllegalArgumentException();

    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      tcp.setCaretPosition(caretPosition);
  }

  /**
   * Tests whether or not this component's text can be edited.
   *
   * @return <code>true</code> if the text can be edited, <code>false</code>
   * otherwise.
   */
  public boolean isEditable()
  {
    return(editable);
  }

  /**
   * Sets whether or not this component's text can be edited.
   *
   * @param editable <code>true</code> to enable editing of the text,
   * <code>false</code> to disable it.
   */
  public synchronized void setEditable(boolean editable)
  {
    this.editable = editable;

    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      tcp.setEditable(editable);
  }

  /**
   * Notifies the component that it should destroy its native peer.
   */
  public void removeNotify()
  {
    super.removeNotify();
  }

  /**
   * Adds a new listener to the list of text listeners for this
   * component.
   *
   * @param listener The listener to be added.
   */
  public synchronized void addTextListener(TextListener listener)
  {
    textListener = AWTEventMulticaster.add(textListener, listener);

    enableEvents(AWTEvent.TEXT_EVENT_MASK);
  }

  /**
   * Removes the specified listener from the list of listeners
   * for this component.
   *
   * @param listener The listener to remove.
   */
  public synchronized void removeTextListener(TextListener listener)
  {
    textListener = AWTEventMulticaster.remove(textListener, listener);
  }

  /**
   * Processes the specified event for this component.  Text events are
   * processed by calling the <code>processTextEvent()</code> method.
   * All other events are passed to the superclass method.
   *
   * @param event The event to process.
   */
  protected void processEvent(AWTEvent event)
  {
    if (event instanceof TextEvent)
      processTextEvent((TextEvent)event);
    else
      super.processEvent(event);
  }

  /**
   * Processes the specified text event by dispatching it to any listeners
   * that are registered.  Note that this method will only be called
   * if text event's are enabled.  This will be true if there are any
   * registered listeners, or if the event has been specifically
   * enabled using <code>enableEvents()</code>.
   *
   * @param event The text event to process.
   */
  protected void processTextEvent(TextEvent event)
  {
    if (textListener != null)
      textListener.textValueChanged(event);
  }

  void dispatchEventImpl(AWTEvent e)
  {
    if (e.id <= TextEvent.TEXT_LAST
        && e.id >= TextEvent.TEXT_FIRST
        && (textListener != null
            || (eventMask & AWTEvent.TEXT_EVENT_MASK) != 0))
      processEvent(e);
    else
      super.dispatchEventImpl(e);
  }

  /**
   * Returns a debugging string.
   *
   * @return A debugging string.
   */
  protected String paramString()
  {
    return(getClass().getName() + "(text=" + getText() + ")");
  }

  /**
   * Returns an array of all the objects currently registered as FooListeners
   * upon this <code>TextComponent</code>. FooListeners are registered using
   * the addFooListener method.
   *
   * @exception ClassCastException If listenerType doesn't specify a class or
   * interface that implements java.util.EventListener.
   */
  public <T extends EventListener> T[] getListeners(Class<T> listenerType)
  {
    if (listenerType == TextListener.class)
      return AWTEventMulticaster.getListeners(textListener, listenerType);

    return super.getListeners(listenerType);
  }

  /**
   * Returns all text listeners registered to this object.
   */
  public TextListener[] getTextListeners()
  {
    return (TextListener[]) getListeners(TextListener.class);
  }

  /**
   * Gets the AccessibleContext associated with this <code>TextComponent</code>.
   * The context is created, if necessary.
   *
   * @return the associated context
   */
  public AccessibleContext getAccessibleContext()
  {
    /* Create the context if this is the first request */
    if (accessibleContext == null)
      accessibleContext = new AccessibleAWTTextComponent();
    return accessibleContext;
  }


  // Provide AccessibleAWTTextComponent access to several peer functions that
  // aren't publicly exposed.  This is package-private to avoid an accessor
  // method.
  synchronized int getIndexAtPoint(Point p)
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      return tcp.getIndexAtPoint(p.x, p.y);
    return -1;
  }

  synchronized Rectangle getCharacterBounds(int i)
  {
    TextComponentPeer tcp = (TextComponentPeer) getPeer();
    if (tcp != null)
      return tcp.getCharacterBounds(i);
    return null;
  }

  /**
   * All old mouse events for this component should
   * be ignored.
   *
   * @return true to ignore all old mouse events.
   */
  static boolean ignoreOldMouseEvents()
  {
    return true;
  }

} // class TextComponent
