/* JTextField.java --
   Copyright (C) 2002, 2004, 2005, 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 javax.swing;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleStateSet;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
import javax.swing.text.TextAction;

public class JTextField extends JTextComponent
  implements SwingConstants
{
  /**
   * AccessibleJTextField
   */
  protected class AccessibleJTextField extends AccessibleJTextComponent
  {
    private static final long serialVersionUID = 8255147276740453036L;

    /**
     * Constructor AccessibleJTextField
     */
    protected AccessibleJTextField()
    {
      super();
    }

    /**
     * Returns the accessible state of this <code>AccessibleJTextField</code>.
     *
     * @return the accessible state of this <code>AccessibleJTextField</code>
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleStateSet state = super.getAccessibleStateSet();
      // TODO: Figure out what state must be added here to the super's state.
      return state;
    }
  }

  private static final long serialVersionUID = 353853209832607592L;

  private static final Action[] actions;

  /**
   * Name of the action that gets sent when the content of the text field
   * gets accepted.
   */
  public static final String notifyAction = "notify-field-accept";
  
  static
    {
      actions = new Action[1];
      actions[0] = new TextAction(notifyAction)
      {
        public void actionPerformed(ActionEvent event)
        {
          JTextField textField = (JTextField) event.getSource();
          textField.fireActionPerformed();
        }
      };
    }
  
  private int columns;
  private int align;
  
  /** @since 1.3 */
  private Action action;

  /** @since 1.3 */
  private String actionCommand;
  
  private PropertyChangeListener actionPropertyChangeListener;

  /**
   * The horizontal visibility of the textfield.
   */
  private BoundedRangeModel horizontalVisibility;

  /**
   * Creates a new instance of <code>JTextField</code>.
   */
  public JTextField()
  {
    this(null, null, 0);
  }

  /**
   * Creates a new instance of <code>JTextField</code>.
   *
   * @param text the initial text
   */
  public JTextField(String text)
  {
    this(null, text, 0);
  }
  
  /**
   * Creates a new instance of <code>JTextField</code>.
   *
   * @param columns the number of columns
   *
   * @exception IllegalArgumentException if columns %lt; 0
   */
  public JTextField(int columns)
  {
    this(null, null, columns);
  }

  /**
   * Creates a new instance of <code>JTextField</code>.
   *
   * @param text the initial text
   * @param columns the number of columns
   *
   * @exception IllegalArgumentException if columns %lt; 0
   */
  public JTextField(String text, int columns)
  {
    this(null, text, columns);
  }

  /**
   * Creates a new instance of <code>JTextField</code>.
   *
   * @param doc the document to use
   * @param text the initial text
   * @param columns the number of columns
   *
   * @exception IllegalArgumentException if columns %lt; 0
   */
  public JTextField(Document doc, String text, int columns)
  {
    if (columns < 0)
      throw new IllegalArgumentException();

    this.columns = columns;

    // Initialize the horizontal visibility model.
    horizontalVisibility = new DefaultBoundedRangeModel();

    setDocument(doc == null ? createDefaultModel() : doc);

    if (text != null)
      setText(text);

    // default value for alignment
    align = LEADING;
  }

  /**
   * Creates the default model for this text field.
   * This implementation returns an instance of <code>PlainDocument</code>.
   *
   * @return a new instance of the default model
   */
  protected Document createDefaultModel()
  {
    return new PlainDocument();
  }

  /**
   * Sets the document to be used for this JTextField.
   *
   * This sets the document property <code>filterNewlines</code> to
   * <code>true</code> and then calls the super behaviour to setup a view and
   * revalidate the text field.
   *
   * @param doc the document to set
   */
  public void setDocument(Document doc)
  {
    doc.putProperty("filterNewlines", Boolean.TRUE);
    super.setDocument(doc);
  }

  /**
   * Returns the class ID for the UI.
   *
   * @return "TextFieldUI";
   */
  public String getUIClassID()
  {
    return "TextFieldUI";
  }

  /**
   * Adds a new listener object to this text field.
   *
   * @param listener the listener to add
   */
  public void addActionListener(ActionListener listener)
  {
    listenerList.add(ActionListener.class, listener);
  }

  /**
   * Removes a listener object from this text field.
   *
   * @param listener the listener to remove
   */
  public void removeActionListener(ActionListener listener)
  {
    listenerList.remove(ActionListener.class, listener);
  }

  /**
   * Returns all registered <code>ActionListener</code> objects.
   *
   * @return an array of listeners
   *
   * @since 1.4
   */
  public ActionListener[] getActionListeners()
  {
    return (ActionListener[]) getListeners(ActionListener.class);
  }

  /**
   * Sends an action event to all registered
   * <code>ActionListener</code> objects.
   */
  protected void fireActionPerformed()
  {
    ActionEvent event = new ActionEvent(this, 0, getText());
    ActionListener[] listeners = getActionListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].actionPerformed(event);
  }

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

  /**
   * Sets the number of columns and then invalidates the layout.
   * @param columns the number of columns
   * @throws IllegalArgumentException if columns < 0
   */
  public void setColumns(int columns)
  {
    if (columns < 0)
      throw new IllegalArgumentException();

    this.columns = columns;
    invalidate();
    //FIXME: do we need this repaint call?
    repaint();
  }

  /**
   * Returns the horizontal alignment, which is one of: JTextField.LEFT, 
   * JTextField.CENTER, JTextField.RIGHT, JTextField.LEADING, 
   * JTextField.TRAILING.
   * @return the horizontal alignment
   */
  public int getHorizontalAlignment()
  {
    return align;
  }

  /**
   * Sets the horizontal alignment of the text.  Calls invalidate and repaint
   * and fires a property change event.
   * @param newAlign must be one of: JTextField.LEFT, JTextField.CENTER,
   * JTextField.RIGHT, JTextField.LEADING, JTextField.TRAILING.
   * @throws IllegalArgumentException if newAlign is not one of the above.
   */
  public void setHorizontalAlignment(int newAlign)
  {
    //FIXME: should throw an IllegalArgumentException if newAlign is invalid
    if (align == newAlign)
      return;

    int oldAlign = align;
    align = newAlign;
    firePropertyChange("horizontalAlignment", oldAlign, newAlign);
    invalidate();
    repaint();
  }

  /**
   * Sets the current font and revalidates so the font will take effect.
   */
  public void setFont(Font newFont)
  {
    super.setFont(newFont);
    revalidate();
  }

  /**
   * Returns the preferred size.  If there is a non-zero number of columns, 
   * this is the number of columns multiplied by the column width, otherwise
   * it returns super.getPreferredSize().
   */
  public Dimension getPreferredSize()
  {
    Dimension size = super.getPreferredSize();

    if (columns != 0)
      {
        Insets i = getInsets();
        size.width = columns * getColumnWidth() + i.left + i.right;
      }

    return size;
  }

  /**
   * Returns the scroll offset in pixels.
   *
   * @return the scroll offset
   */
  public int getScrollOffset()
  {
    return horizontalVisibility.getValue();
  }

  /**
   * Sets the scroll offset in pixels.
   * 
   * @param offset the scroll offset
   */
  public void setScrollOffset(int offset)
  {
    // Automatically sets to the highest possible value if
    // offset is bigger than that.
    horizontalVisibility.setValue(
                                  Math.min(horizontalVisibility.getMaximum()
                                           - horizontalVisibility.getExtent(),
                                           offset));
    
  }

  /**
   * Returns the set of Actions that are commands for the editor.
   * This is the actions supported by this editor plus the actions
   * of the UI (returned by JTextComponent.getActions()).
   */
  public Action[] getActions()
  {
    return TextAction.augmentList(super.getActions(), actions);
  }

  public void postActionEvent()
  {
    String command = actionCommand != null ? actionCommand : getText();
    ActionEvent event = new ActionEvent(this, 0, command);
    ActionListener[] listeners = getActionListeners();

    for (int index = 0; index < listeners.length; ++index)
      listeners[index].actionPerformed(event);
  }
  
  /**
   * @since 1.3
   */
  public Action getAction()
  {
    return action;
  }

  /**
   * @since 1.3
   */
  public void setAction(Action newAction)
  {
    if (action == newAction)
      return;

    if (action != null)
      {
        removeActionListener(action);
        action.removePropertyChangeListener(actionPropertyChangeListener);
        actionPropertyChangeListener = null;
      }

    Action oldAction = action;
    action = newAction;

    if (action != null)
      {
        addActionListener(action);
        actionPropertyChangeListener = createActionPropertyChangeListener(action);
        action.addPropertyChangeListener(actionPropertyChangeListener);
      }

    //FIXME: is this a hack?  The horizontal alignment hasn't changed
    firePropertyChange("horizontalAlignment", oldAction, newAction);
  }

  /**
   * Sets the command string used in action events.
   * @since 1.3
   */
  public void setActionCommand(String command)
  {
    actionCommand = command;
  }

  /**
   * @since 1.3
   */
  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
  {
    return new PropertyChangeListener()
    {
      public void propertyChange(PropertyChangeEvent event)
      {
        // Update properties "action" and "horizontalAlignment".
        String name = event.getPropertyName();

        if (name.equals("enabled"))
          {
            boolean enabled = ((Boolean) event.getNewValue()).booleanValue();
            JTextField.this.setEnabled(enabled);
          }
        else if (name.equals(Action.SHORT_DESCRIPTION))
          {
            JTextField.this.setToolTipText((String) event.getNewValue());
          }
      }
    };
  }

  /**
   * 
   * @since 1.3
   */
  protected void configurePropertiesFromAction(Action action)
  {
    if (action != null)
      {
        setEnabled(action.isEnabled());
        setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
      }
    else
      {
        setEnabled(true);
        setToolTipText(null);
      }
  }

  /**
   * Returns the column width, which is the width of the character m
   * for the font in use.
   * @return the width of the character m for the font in use.
   */
  protected int getColumnWidth()
  {
    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
    return metrics.charWidth('m');
  }

  /**
   * Returns the accessible context associated with the <code>JTextField</code>.
   *
   * @return the accessible context associated with the <code>JTextField</code>
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJTextField();
    return accessibleContext;
  }

  /**
   * Returns the bounded range model that describes the horizontal visibility
   * of the text field in the case when the text does not fit into the
   * available space. The actual values of this model are managed by the look
   * and feel implementation.
   *
   * @return the bounded range model that describes the horizontal visibility
   */
  public BoundedRangeModel getHorizontalVisibility()
  {
    return horizontalVisibility;
  }

  /**
   * Returns <code>true</code>, unless this is embedded in a
   * <code>JViewport</code> in which case the viewport takes responsibility of
   * validating.
   *
   * @return <code>true</code>, unless this is embedded in a
   *         <code>JViewport</code> in which case the viewport takes
   *         responsibility of validating
   */
  public boolean isValidateRoot()
  {
    return ! (getParent() instanceof JViewport);
  }
  
  public void scrollRectToVisible(Rectangle r)
  {
    int v = horizontalVisibility.getValue();
    
    // The extent value is the inner width of the text field.
    int e = horizontalVisibility.getExtent();
    Insets i = getInsets();
    
    // The x value in the rectangle (usually) denotes the new location
    // of the caret. We check whether the location lies inside the left or
    // right border and scroll into the appropriate direction.
    // The calculation has to be shifted by the BoundedRangeModel's value
    // because that value was already used to calculate r.x (this happens
    // as part of a modelToView() call in FieldView).
    if (r.x < i.left)
      setScrollOffset(v + r.x - i.left);
    else if (r.x > e + i.left)
      setScrollOffset(r.x + v - e - i.left);
  }
  
}
