/* TextField.java -- A one line text entry field
   Copyright (C) 1999, 2002, 2004, 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.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.peer.ComponentPeer;
import java.awt.peer.TextFieldPeer;
import java.util.EventListener;

import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleStateSet;

/**
 * This class implements a single line text entry field widget
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public class TextField extends TextComponent
{
  
  /**
   * The number used to generate the name returned by getName.
   */
  private static transient long next_textfield_number;

  
  private static final long serialVersionUID = -2966288784432217853L;


  /**
   * @serial The number of columns in the text entry field.
   */
  private int columns;

  /**
   * @serial The character that is echoed when doing protected input
   */
  private char echoChar;

  // List of registered ActionListener's for this object.
  private ActionListener action_listeners;

  /**
   * Initializes a new instance of <code>TextField</code> that is empty
   * and has one column.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
   */
  public TextField()
  {
    this("", 0);
  }

  /**
   * Initializes a new instance of <code>TextField</code> containing
   * the specified text.  The number of columns will be equal to the
   * length of the text string.
   *
   * @param text The text to display in the field.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
   */
  public TextField(String text)
  {
    this(text, (text == null) ? 0 : text.length());
  }

  /**
   * Initializes a new instance of <code>TextField</code> that is empty
   * and has the specified number of columns.
   *
   * @param columns The number of columns in the text field.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
   */
  public TextField(int columns)
  {
    this("", columns);
  }

  /**
   * Initializes a new instance of <code>TextField</code> with the
   * specified text and number of columns.
   *
   * @param text The text to display in the field.
   * @param columns The number of columns in the field.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
   */
  public TextField(String text, int columns)
  {
    super(text);
  
    if (columns < 0)
      this.columns = 0;
    else
      this.columns = columns;

    if (GraphicsEnvironment.isHeadless())
      throw new HeadlessException ();
  }

  /**
   * Returns the number of columns in the field.
   *
   * @return The number of columns in the field.
   */
  public int getColumns()
  {
    return(columns);
  }

  /**
   * Sets the number of columns in this field to the specified value.
   *
   * @param columns The new number of columns in the field.
   *
   * @exception IllegalArgumentException If columns is less than zero.
   */
  public synchronized void setColumns(int columns)
  {
    if (columns < 0)
      throw new IllegalArgumentException("Value is less than zero: " +
                                         columns);

    this.columns = columns;
    // FIXME: How to we communicate this to our peer?
  }

  /**
   * Returns the character that is echoed to the screen when a text 
   * field is protected (such as when a password is being entered).
   *
   * @return The echo character for this text field.
   */
  public char getEchoChar()
  {
    return(echoChar);
  }

  /**
   * Sets the character that is echoed when protected input such as
   * a password is displayed.
   *
   * @param echoChar The new echo character.
   */
  public void setEchoChar(char echoChar)
  {
    setEchoCharacter(echoChar);
  }

  /**
   * Sets the character that is echoed when protected input such as
   * a password is displayed.
   *
   * @param echoChar The new echo character.
   *
   * @deprecated This method is deprecated in favor of 
   * <code>setEchoChar()</code>
   */
  public void setEchoCharacter(char echoChar)
  {
    this.echoChar = echoChar;

    TextFieldPeer peer = (TextFieldPeer) getPeer ();
    if (peer != null)
      peer.setEchoChar (echoChar);
  }

  /**
   * Tests whether or not this text field has an echo character set
   * so that characters the user type are not echoed to the screen.
   *
   * @return <code>true</code> if an echo character is set,
   * <code>false</code> otherwise.
   */
  public boolean echoCharIsSet()
  {
    if (echoChar == '\u0000')
      return(false);
    else
      return(true);
  }

  /**
   * Returns the minimum size for this text field.
   *
   * @return The minimum size for this text field.
   */
  public Dimension getMinimumSize()
  {
    return getMinimumSize (getColumns ());
  }

  /**
   * Returns the minimum size of a text field with the specified number
   * of columns.
   *
   * @param columns The number of columns to get the minimum size for.
   */
  public Dimension getMinimumSize(int columns)
  {
    return minimumSize(columns);
  }

  /**
   * Returns the minimum size for this text field.
   *
   * @return The minimum size for this text field.
   *
   * @deprecated This method is deprecated in favor of
   * <code>getMinimumSize()</code>.
   */
  public Dimension minimumSize()
  {
    return minimumSize(getColumns ());
  }

  /**
   * Returns the minimum size of a text field with the specified number
   * of columns.
   *
   * @param columns The number of columns to get the minimum size for.
   *
   * @deprecated This method is deprecated in favor of 
   * <code>getMinimumSize(int)</code>.
   */
  public Dimension minimumSize(int columns)
  {
    TextFieldPeer peer = (TextFieldPeer) getPeer ();
    if (peer == null)
      return null; // FIXME: What do we do if there is no peer?

    return peer.getMinimumSize (columns);
  }

  /**
   * Returns the preferred size for this text field.
   *
   * @return The preferred size for this text field.
   */
  public Dimension getPreferredSize()
  {
    return getPreferredSize(getColumns ());
  }

  /**
   * Returns the preferred size of a text field with the specified number
   * of columns.
   *
   * @param columns The number of columns to get the preferred size for.
   */
  public Dimension getPreferredSize(int columns)
  {
    return preferredSize(columns);
  }

  /**
   * Returns the preferred size for this text field.
   *
   * @return The preferred size for this text field.
   *
   * @deprecated This method is deprecated in favor of 
   * <code>getPreferredSize()</code>.
   */
  public Dimension preferredSize()
  {
    return preferredSize(getColumns ());
  }

  /**
   * Returns the preferred size of a text field with the specified number
   * of columns.
   *
   * @param columns The number of columns to get the preferred size for.
   *
   * @deprecated This method is deprecated in favor of 
   * <code>getPreferredSize(int)</code>.
   */
  public Dimension preferredSize(int columns)
  {
    TextFieldPeer peer = (TextFieldPeer) getPeer ();
    if (peer == null)
      return new Dimension (0, 0);

    return peer.getPreferredSize (columns);
  }

  /**
   * Notifies this object that it should create its native peer.
   */
  public void addNotify()
  {
    if (getPeer() != null)
      return;

    setPeer((ComponentPeer)getToolkit().createTextField(this));
    super.addNotify();
  }

  /**
   * Addes a new listener to the list of action listeners for this
   * object.
   *
   * @param listener The listener to add to the list.
   */
  public synchronized void addActionListener(ActionListener listener)
  {
    action_listeners = AWTEventMulticaster.add(action_listeners, listener);

    enableEvents(AWTEvent.ACTION_EVENT_MASK);
  }

  /**
   * Removes the specified listener from the list of action listeners
   * for this object.
   *
   * @param listener The listener to remove from the list.
   */
  public synchronized void removeActionListener(ActionListener listener)
  {
    action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
  }

  /**
   * Processes the specified event.  If the event is an instance of
   * <code>ActionEvent</code> then <code>processActionEvent()</code> is
   * called to process it, otherwise the event is sent to the
   * superclass.
   *
   * @param event The event to process.
   */
  protected void processEvent(AWTEvent event)
  {
    if (event instanceof ActionEvent)
      processActionEvent((ActionEvent)event);
    else
      super.processEvent(event);
  }

  /**
   * Processes an action event by calling any registered listeners.
   * Note to subclasses: This method is not called unless action events
   * are enabled on this object.  This will be true if any listeners
   * are registered, or if action events were specifically enabled
   * using <code>enableEvents()</code>.
   * 
   * @param event The event to process.
   */
  protected void processActionEvent(ActionEvent event)
  {
    if (action_listeners != null)
      action_listeners.actionPerformed(event);
  }

  void dispatchEventImpl(AWTEvent e)
  {
    if (e.id <= ActionEvent.ACTION_LAST 
        && e.id >= ActionEvent.ACTION_FIRST
        && (action_listeners != null 
	    || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
      processEvent(e);
    else
      super.dispatchEventImpl(e);
  }

 /**
  * Returns a debug string for this object.
  *
  * @return A debug string for this object.
  */
  protected String paramString()
  {
    return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
           getEchoChar());
  }

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

    return super.getListeners (listenerType);
  }

  /**
   * Return all ActionListeners register to this <code>TextField</code> object
   * as an array.
   *
   * @since 1.4
   */
  public ActionListener[] getActionListeners ()
  {
    return (ActionListener[]) getListeners (ActionListener.class);
  }
  
  /**
   * Generate a unique name for this <code>TextField</code>.
   *
   * @return A unique name for this <code>TextField</code>.
   */
  String generateName()
  {
    return "textfield" + getUniqueLong();
  }

  private static synchronized long getUniqueLong()
  {
    return next_textfield_number++;
  }

  protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
  {
    private static final long serialVersionUID = 6219164359235943158L;

    protected AccessibleAWTTextField()
    {
    }
    
    public AccessibleStateSet getAccessibleStateSet()
    {
      return super.getAccessibleStateSet();
    }
  }
  
  public AccessibleContext getAccessibleContext()
  {
    return new AccessibleAWTTextField();
  }

}
