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