/* TextComponent.java -- Widgets for entering text
   Copyright (C) 1999, 2002, 2003 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;

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
{

/*
 * Static Variables
 */

// Constant for serialization
private static final long serialVersionUID = -2214773872412987419L;

/*
 * Instance Variables
 */

/**
  * @serial Indicates whether or not this component is editable.
  */
private boolean editable;

/**
  * @serial The starting position of the selected text region.
  */
private int selectionStart;

/**
  * @serial The ending position of the selected text region.
  */
private int selectionEnd;

/**
  * @serial The text in the component
  */
private 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
  {
    // 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
      
    }
    
  }

/*************************************************************************/

/*
 * Constructors
 */

TextComponent(String text)
{
  this.text = text;
  this.editable = true;
}

/*************************************************************************/

/*
 * Instance Methods
 */

/**
  * 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());
}

/*************************************************************************/

/**
  * 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 > getSelectionEnd())
    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 EventListener[] getListeners (Class 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.
  private synchronized int
  getIndexAtPoint(Point p)
  {
    TextComponentPeer tcp = (TextComponentPeer)getPeer();
    if (tcp != null)
      return tcp.getIndexAtPoint(p.x, p.y);
    return -1;
  }
  
  private synchronized Rectangle
  getCharacterBounds(int i)
  {
    TextComponentPeer tcp = (TextComponentPeer)getPeer();
    if (tcp != null)
      return tcp.getCharacterBounds(i);
    return null;
  }
  
  


} // class TextComponent

