/* JFormattedTextField.java --
   Copyright (C) 2003, 2004 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.event.FocusEvent;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;

import javax.swing.text.AbstractDocument;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import javax.swing.text.InternationalFormatter;
import javax.swing.text.NavigationFilter;
import javax.swing.text.NumberFormatter;

/**
 * A text field that makes use of a formatter to display and edit a specific
 * type of data. The value that is displayed can be an arbitrary object. The
 * formatter is responsible for displaying the value in a textual form and
 * it may allow editing of the value.
 *
 * Formatters are usually obtained using an instance of
 * {@link AbstractFormatterFactory}. This factory is responsible for providing
 * an instance of {@link AbstractFormatter} that is able to handle the
 * formatting of the value of the JFormattedTextField.
 *
 * @author Michael Koch
 * @author Anthony Balkissoon abalkiss at redhat dot com
 *
 * @since 1.4
 */
public class JFormattedTextField extends JTextField
{
  private static final long serialVersionUID = 5464657870110180632L;

  /**
   * An abstract base implementation for a formatter that can be used by
   * a JTextField. A formatter can display a specific type of object and
   * may provide a way to edit this value.
   */
  public abstract static class AbstractFormatter implements Serializable
  {
    private static final long serialVersionUID = -5193212041738979680L;

    private JFormattedTextField textField;

    public AbstractFormatter ()
    {
      //Do nothing here.
    }

    /**
     * Clones the AbstractFormatter and removes the association to any
     * particular JFormattedTextField.
     *
     * @return a clone of this formatter with no association to any particular
     * JFormattedTextField
     * @throws CloneNotSupportedException if the Object's class doesn't support
     * the {@link Cloneable} interface
     */
    protected Object clone()
      throws CloneNotSupportedException
    {
      // Clone this formatter.
      AbstractFormatter newFormatter = (AbstractFormatter) super.clone();

      // And remove the association to the JFormattedTextField.
      newFormatter.textField = null;
      return newFormatter;
    }

    /**
     * Returns a custom set of Actions that this formatter supports.  Should
     * be subclassed by formatters that have a custom set of Actions.
     *
     * @return <code>null</code>.  Should be subclassed by formatters that want
     * to install custom Actions on the JFormattedTextField.
     */
    protected Action[] getActions()
    {
      return null;
    }

    /**
     * Gets the DocumentFilter for this formatter.  Should be subclassed
     * by formatters wishing to install a filter that oversees Document
     * mutations.
     *
     * @return <code>null</code>.  Should be subclassed by formatters
     * that want to restrict Document mutations.
     */
    protected DocumentFilter getDocumentFilter()
    {
      // Subclasses should override this if they want to install a
      // DocumentFilter.
      return null;
    }

    /**
     * Returns the JFormattedTextField on which this formatter is
     * currently installed.
     *
     * @return the JFormattedTextField on which this formatter is currently
     * installed
     */
    protected JFormattedTextField getFormattedTextField()
    {
      return textField;
    }

    /**
     * Gets the NavigationFilter for this formatter.  Should be subclassed
     * by formatters (such as {@link DefaultFormatter}) that wish to
     * restrict where the cursor can be placed within the text field.
     *
     * @return <code>null</code>.  Subclassed by formatters that want to restrict
     * cursor location within the JFormattedTextField.
     */
    protected NavigationFilter getNavigationFilter()
    {
      // This should be subclassed if the formatter wants to install
      // a NavigationFilter on the JFormattedTextField.
      return null;
    }

    /**
     * Installs this formatter on the specified JFormattedTextField.  This
     * converts the current value to a displayable String and displays it,
     * and installs formatter specific Actions from <code>getActions</code>.
     * It also installs a DocumentFilter and NavigationFilter on the
     * JFormattedTextField.
     * <p>
     * If there is a <code>ParseException</code> this sets the text to an
     * empty String and marks the text field in an invalid state.
     *
     * @param textField the JFormattedTextField on which to install this
     * formatter
     */
    public void install(JFormattedTextField textField)
    {
      // Uninstall the current textfield.
      if (this.textField != null)
        uninstall();

      this.textField = textField;

      // Install some state on the text field, including display text,
      // DocumentFilter, NavigationFilter, and formatter specific Actions.
      if (textField != null)
        {
          try
          {
            // Set the text of the field.
            textField.setText(valueToString(textField.getValue()));
            Document doc = textField.getDocument();

            // Set the DocumentFilter for the field's Document.
            if (doc instanceof AbstractDocument)
              ((AbstractDocument) doc).setDocumentFilter(getDocumentFilter());

            // Set the NavigationFilter.
            textField.setNavigationFilter(getNavigationFilter());

            // Set the Formatter Actions
            // FIXME: Have to add the actions from getActions()
          }
          catch (ParseException pe)
          {
            // Set the text to an empty String and mark the field as invalid.
            textField.setText("");
            setEditValid(false);
          }
        }
    }

    /**
     * Clears the state installed on the JFormattedTextField by the formatter.
     * This resets the DocumentFilter, NavigationFilter, and any additional
     * Actions (returned by <code>getActions()</code>).
     */
    public void uninstall()
    {
      // Set the DocumentFilter for the field's Document.
      Document doc = textField.getDocument();
      if (doc instanceof AbstractDocument)
        ((AbstractDocument) doc).setDocumentFilter(null);
      textField.setNavigationFilter(null);
      // FIXME: Have to remove the Actions from getActions()
      this.textField = null;
    }

    /**
     * Invoke this method when invalid values are entered.  This forwards the
     * call to the JFormattedTextField.
     */
    protected void invalidEdit()
    {
      textField.invalidEdit();
    }

    /**
     * This method updates the <code>editValid</code> property of
     * JFormattedTextField.
     *
     * @param valid the new state for the <code>editValid</code> property
     */
    protected void setEditValid(boolean valid)
    {
      textField.editValid = valid;
    }

    /**
     * Parses <code>text</code> to return a corresponding Object.
     *
     * @param text the String to parse
     * @return an Object that <code>text</code> represented
     * @throws ParseException if there is an error in the conversion
     */
    public abstract Object stringToValue(String text)
      throws ParseException;

    /**
     * Returns a String to be displayed, based on the Object
     * <code>value</code>.
     *
     * @param value the Object from which to generate a String
     * @return a String to be displayed
     * @throws ParseException if there is an error in the conversion
     */
    public abstract String valueToString(Object value)
      throws ParseException;
  }

  /**
   * Delivers instances of an {@link AbstractFormatter} for
   * a specific value type for a JFormattedTextField.
   */
  public abstract static class AbstractFormatterFactory
  {
    public AbstractFormatterFactory()
    {
      // Do nothing here.
    }

    public abstract AbstractFormatter getFormatter(JFormattedTextField tf);
  }

  /** The possible focusLostBehavior options **/
  public static final int COMMIT = 0;
  public static final int COMMIT_OR_REVERT = 1;
  public static final int REVERT = 2;
  public static final int PERSIST = 3;

  /** The most recent valid and committed value **/
  private Object value;

  /** The behaviour for when this text field loses focus **/
  private int focusLostBehavior = COMMIT_OR_REVERT;

  /** The formatter factory currently being used **/
  private AbstractFormatterFactory formatterFactory;

  /** The formatter currently being used **/
  private AbstractFormatter formatter;

  // Package-private to avoid an accessor method.
  boolean editValid = true;

  /**
   * Creates a JFormattedTextField with no formatter factory.
   * <code>setValue</code> or <code>setFormatterFactory</code> will
   * properly configure this text field to edit a particular type
   * of value.
   */
  public JFormattedTextField()
  {
    this((AbstractFormatterFactory) null, null);
  }

  /**
   * Creates a JFormattedTextField that can handle the specified Format.
   * An appopriate AbstractFormatter and AbstractFormatterFactory will
   * be created for the specified Format.
   *
   * @param format the Format that this JFormattedTextField should be able
   * to handle
   */
  public JFormattedTextField(Format format)
  {
    this ();
    setFormatterFactory(getAppropriateFormatterFactory(format));
  }

  /**
   * Creates a JFormattedTextField with the specified formatter.  This will
   * create a {@link DefaultFormatterFactory} with this formatter as the default
   * formatter.
   *
   * @param formatter the formatter to use for this JFormattedTextField
   */
  public JFormattedTextField(AbstractFormatter formatter)
  {
    this(new DefaultFormatterFactory(formatter));
  }

  /**
   * Creates a JFormattedTextField with the specified formatter factory.
   *
   * @param factory the formatter factory to use for this JFormattedTextField
   */
  public JFormattedTextField(AbstractFormatterFactory factory)
  {
    setFormatterFactory(factory);
  }

  /**
   * Creates a JFormattedTextField with the specified formatter factory and
   * initial value.
   *
   * @param factory the initial formatter factory for this JFormattedTextField
   * @param value the initial value for the text field
   */
  public JFormattedTextField(AbstractFormatterFactory factory, Object value)
  {
    setFormatterFactory(factory);
    setValue(value);
  }

  /**
   * Creates a JFormattedTextField with the specified value.  This creates a
   * formatter and formatterFactory that are appropriate for the value.
   *
   * @param value the initial value for this JFormattedTextField
   */
  public JFormattedTextField(Object value)
  {
    setValue(value);
  }

  /**
   * Returns an AbstractFormatterFactory that will give an appropriate
   * AbstractFormatter for the given Format.
   * @param format the Format to match with an AbstractFormatter.
   * @return a DefaultFormatterFactory whose defaultFormatter is appropriate
   * for the given Format.
   */
  private AbstractFormatterFactory getAppropriateFormatterFactory(Format format)
  {
    AbstractFormatter newFormatter;
    if (format instanceof DateFormat)
      newFormatter = new DateFormatter((DateFormat) format);
    else if (format instanceof NumberFormat)
      newFormatter = new NumberFormatter ((NumberFormat) format);
    else
      newFormatter = new InternationalFormatter(format);

    return new DefaultFormatterFactory(newFormatter);
  }

  /**
   * Forces the current value from the editor to be set as the current
   * value.  If there is no current formatted this has no effect.
   *
   * @throws ParseException if the formatter cannot format the current value
   */
  public void commitEdit()
    throws ParseException
  {
    if (formatter == null)
      return;
    // Note: this code is a lot like setValue except that we don't want
    // to create a new formatter.
    Object oldValue = this.value;

    this.value = formatter.stringToValue(getText());
    editValid = true;

    firePropertyChange("value", oldValue, this.value);
  }

  /**
   * Gets the command list supplied by the UI augmented by the specific
   * Actions for JFormattedTextField.
   *
   * @return an array of Actions that this text field supports
   */
  public Action[] getActions()
  {
    // FIXME: Add JFormattedTextField specific actions
    // These are related to committing or cancelling edits.
    return super.getActions();
  }

  /**
   * Returns the behaviour of this JFormattedTextField upon losing focus.  This
   * is one of <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>,
   * <code>PERSIST</code>, or <code>REVERT</code>.
   * @return the behaviour upon losing focus
   */
  public int getFocusLostBehavior()
  {
    return focusLostBehavior;
  }

  /**
   * Returns the current formatter used for this JFormattedTextField.
   * @return the current formatter used for this JFormattedTextField
   */
  public AbstractFormatter getFormatter()
  {
    return formatter;
  }

  /**
   * Returns the factory currently used to generate formatters for this
   * JFormattedTextField.
   * @return the factory currently used to generate formatters
   */
  public AbstractFormatterFactory getFormatterFactory()
  {
    return formatterFactory;
  }

  public String getUIClassID()
  {
    return "FormattedTextFieldUI";
  }

  /**
   * Returns the last valid value.  This may not be the value currently shown
   * in the text field depending on whether or not the formatter commits on
   * valid edits and allows invalid input to be temporarily displayed.
   * @return the last committed valid value
   */
  public Object getValue()
  {
    return value;
  }

  /**
   * This method is used to provide feedback to the user when an invalid value
   * is input during editing.
   */
  protected void invalidEdit()
  {
    UIManager.getLookAndFeel().provideErrorFeedback(this);
  }

  /**
   * Returns true if the current value being edited is valid.  This property is
   * managed by the current formatted.
   * @return true if the value being edited is valid.
   */
  public boolean isEditValid()
  {
    return editValid;
  }

  /**
   * Processes focus events.  This is overridden because we may want to
   * change the formatted depending on whether or not this field has
   * focus.
   *
   * @param evt the FocusEvent
   */
  protected void processFocusEvent(FocusEvent evt)
  {
    super.processFocusEvent(evt);
    // Let the formatterFactory change the formatter for this text field
    // based on whether or not it has focus.
    setFormatter (formatterFactory.getFormatter(this));
  }

  /**
   * Associates this JFormattedTextField with a Document and propagates
   * a PropertyChange event to each listener.
   *
   * @param newDocument the Document to associate with this text field
   */
  public void setDocument(Document newDocument)
  {
    // FIXME: This method should do more than this.  Must do some handling
    // of the DocumentListeners.
    Document oldDocument = getDocument();

    if (oldDocument == newDocument)
      return;

    super.setDocument(newDocument);
  }

  /**
   * Sets the behaviour of this JFormattedTextField upon losing focus.
   * This must be <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>,
   * <code>PERSIST</code>, or <code>REVERT</code> or an
   * IllegalArgumentException will be thrown.
   *
   * @param behavior
   * @throws IllegalArgumentException if <code>behaviour</code> is not
   * one of the above
   */
  public void setFocusLostBehavior(int behavior)
  {
    if (behavior != COMMIT
        && behavior != COMMIT_OR_REVERT
        && behavior != PERSIST
        && behavior != REVERT)
      throw new IllegalArgumentException("invalid behavior");

    this.focusLostBehavior = behavior;
  }

  /**
   * Sets the formatter for this JFormattedTextField.  Normally the formatter
   * factory will take care of this, or calls to setValue will also make sure
   * that the formatter is set appropriately.
   *
   * @param formatter the AbstractFormatter to use for formatting the value for
   * this JFormattedTextField
   */
  protected void setFormatter(AbstractFormatter formatter)
  {
    AbstractFormatter oldFormatter = null;

    oldFormatter = this.formatter;

    if (oldFormatter != null)
      oldFormatter.uninstall();

    this.formatter = formatter;

    if (formatter != null)
      formatter.install(this);

    firePropertyChange("formatter", oldFormatter, formatter);
  }

  /**
   * Sets the factory from which this JFormattedTextField should obtain
   * its formatters.
   *
   * @param factory the AbstractFormatterFactory that will be used to generate
   * formatters for this JFormattedTextField
   */
  public void setFormatterFactory(AbstractFormatterFactory factory)
  {
    if (formatterFactory == factory)
      return;

    AbstractFormatterFactory oldFactory = formatterFactory;
    formatterFactory = factory;
    firePropertyChange("formatterFactory", oldFactory, factory);

    // Now set the formatter according to our new factory.
    if (formatterFactory != null)
      setFormatter(formatterFactory.getFormatter(this));
    else
      setFormatter(null);
  }

  /**
   * Sets the value that will be formatted and displayed.
   *
   * @param newValue the value to be formatted and displayed
   */
  public void setValue(Object newValue)
  {
    if (value == newValue)
      return;

    Object oldValue = value;
    value = newValue;

    // If there is no formatterFactory then make one.
    if (formatterFactory == null)
      setFormatterFactory(createFormatterFactory(newValue));

    // Set the formatter appropriately.  This is because there may be a new
    // formatterFactory from the line above, or we may want a new formatter
    // depending on the type of newValue (or if newValue is null).
    setFormatter (formatterFactory.getFormatter(this));
    firePropertyChange("value", oldValue, newValue);
  }

  /**
   * A helper method that attempts to create a formatter factory that is
   * suitable to format objects of the type like <code>value</code>.
   *
   * @param value an object which should be formatted by the formatter factory.
   *
   * @return a formatter factory able to format objects of the class of
   *     <code>value</code>
   */
  AbstractFormatterFactory createFormatterFactory(Object value)
  {
    AbstractFormatter formatter = null;
    if (value instanceof Date)
      formatter = new DateFormatter();
    else if (value instanceof Number)
      formatter = new NumberFormatter();
    else
      formatter = new DefaultFormatter();
    return new DefaultFormatterFactory(formatter);
  }
}
