/* DefaultFormatter.java --
Copyright (C) 2005  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.text;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.text.ParseException;

import javax.swing.JFormattedTextField;

/**
 * The <code>DefaultFormatter</code> is a concrete formatter for use in
 * {@link JFormattedTextField}s.
 *
 * It can format arbitrary values by invoking
 * their {@link Object#toString} method.
 *
 * In order to convert a String back to
 * a value, the value class must provide a single argument constructor that
 * takes a String object as argument value. If no such constructor is found,
 * the String itself is passed back by #stringToValue.
 *
 * @author Roman Kennke (roman@kennke.org)
 */
public class DefaultFormatter extends JFormattedTextField.AbstractFormatter
  implements Cloneable, Serializable
{

  /**
   * A {@link DocumentFilter} that intercepts modification of the
   * JFormattedTextField's Document and commits the value depending
   * on the value of the <code>commitsOnValidEdit</code> property.
   *
   */
  // FIXME: Handle allowsInvalid and overwriteMode properties
  private class FormatterDocumentFilter
    extends DocumentFilter
  {
    /**
     * Invoked when text is removed from a text component.
     *
     * @param bypass the FilterBypass to use to mutate the document
     * @param offset the start position of the modification
     * @param length the length of the removed text
     *
     * @throws BadLocationException if offset or lenght are invalid in
     *     the Document
     */
    public void remove(DocumentFilter.FilterBypass bypass, int offset,
                        int length)
      throws BadLocationException
    {
      super.remove(bypass, offset, length);
      checkValidInput();
      commitIfAllowed();
    }

    /**
     * Invoked when text is inserted into a text component.
     *
     * @param bypass the FilterBypass to use to mutate the document
     * @param offset the start position of the modification
     * @param text the inserted text
     * @param attributes the attributes of the inserted text
     *
     * @throws BadLocationException if offset or lenght are invalid in
     *     the Document
     */
    public void insertString(DocumentFilter.FilterBypass bypass, int offset,
                              String text, AttributeSet attributes)
      throws BadLocationException
    {
      if (overwriteMode == true)
        replace(bypass, offset, text.length(), text, attributes);
      else
        super.insertString(bypass, offset, text, attributes);
      checkValidInput();
      commitIfAllowed();
    }

    /**
     * Invoked when text is replaced in a text component.
     *
     * @param bypass the FilterBypass to use to mutate the document
     * @param offset the start position of the modification
     * @param length the length of the removed text
     * @param text the inserted text
     * @param attributes the attributes of the inserted text
     *
     * @throws BadLocationException if offset or lenght are invalid in
     *     the Document
     */
    public void replace(DocumentFilter.FilterBypass bypass, int offset,
                         int length, String text, AttributeSet attributes)
      throws BadLocationException
    {
      super.replace(bypass, offset, length, text, attributes);
      checkValidInput();
      commitIfAllowed();
    }

    /**
     * Commits the value to the JTextTextField if the property
     * <code>commitsOnValidEdit</code> is set to <code>true</code>.
     */
    private void commitIfAllowed()
    {
      if (commitsOnValidEdit == true)
        try
          {
            getFormattedTextField().commitEdit();
          }
        catch (ParseException ex)
          {
            // ignore invalid edits
          }
    }

    /**
     * Checks if the value in the input field is valid. If the
     * property allowsInvalid is set to <code>false</code>, then
     * the string in the input field is not allowed to be entered.
     */
    private void checkValidInput()
    {
      JFormattedTextField ftf = getFormattedTextField();
      try
        {
          Object newval = stringToValue(ftf.getText());
        }
      catch (ParseException ex)
        {
          if (!allowsInvalid)
            {
              // roll back the input if invalid edits are not allowed
              try
                {
                  ftf.setText(valueToString(ftf.getValue()));
                }
              catch (ParseException pe)
                {
                  // if that happens, something serious must be wrong
                  AssertionError ae;
                  ae = new AssertionError("values must be parseable");
                  ae.initCause(pe);
                  throw ae;
                }
            }
        }
    }
  }

  /** The serialization UID (compatible with JDK1.5). */
  private static final long serialVersionUID = -355018354457785329L;

  /**
   * Indicates if the value should be committed after every
   * valid modification of the Document.
   */
  boolean commitsOnValidEdit;

  /**
   * If <code>true</code> newly inserted characters overwrite existing
   * values, otherwise insertion is done the normal way.
   */
  boolean overwriteMode;

  /**
   * If <code>true</code> invalid edits are allowed for a limited
   * time.
   */
  boolean allowsInvalid;

  /**
   * The class that is used for values.
   */
  Class valueClass;

  /**
   * Creates a new instance of <code>DefaultFormatter</code>.
   */
  public DefaultFormatter()
  {
    commitsOnValidEdit = false;
    overwriteMode = true;
    allowsInvalid = true;
  }

  /**
   * Installs the formatter on the specified {@link JFormattedTextField}.
   *
   * This method does the following things:
   * <ul>
   * <li>Display the value of #valueToString in the
   *  <code>JFormattedTextField</code></li>
   * <li>Install the Actions from #getActions on the <code>JTextField</code>
   * </li>
   * <li>Install the DocumentFilter returned by #getDocumentFilter</li>
   * <li>Install the NavigationFilter returned by #getNavigationFilter</li>
   * </ul>
   *
   * This method is typically not overridden by subclasses. Instead override
   * one of the mentioned methods in order to customize behaviour.
   *
   * @param ftf the {@link JFormattedTextField} in which this formatter
   *     is installed
   */
  public void install(JFormattedTextField ftf)
  {
    super.install(ftf);
  }

  /**
   * Returns <code>true</code> if the value should be committed after
   * each valid modification of the input field, <code>false</code> if
   * it should never be committed by this formatter.
   *
   * @return the state of the <code>commitsOnValidEdit</code> property
   *
   * @see #setCommitsOnValidEdit
   */
  public boolean getCommitsOnValidEdit()
  {
    return commitsOnValidEdit;
  }

  /**
   * Sets the value of the <code>commitsOnValidEdit</code> property.
   *
   * @param commitsOnValidEdit the new state of the
   *     <code>commitsOnValidEdit</code> property
   *
   * @see #getCommitsOnValidEdit
   */
  public void setCommitsOnValidEdit(boolean commitsOnValidEdit)
  {
    this.commitsOnValidEdit = commitsOnValidEdit;
  }

  /**
   * Returns the value of the <code>overwriteMode</code> property.
   * If that is set to <code>true</code> then newly inserted characters
   * overwrite existing values, otherwise the characters are inserted like
   * normal. The default is <code>true</code>.
   *
   * @return the value of the <code>overwriteMode</code> property
   */
  public boolean getOverwriteMode()
  {
    return overwriteMode;
  }

  /**
   * Sets the value of the <code>overwriteMode</code> property.
   *
   * If that is set to <code>true</code> then newly inserted characters
   * overwrite existing values, otherwise the characters are inserted like
   * normal. The default is <code>true</code>.
   *
   * @param overwriteMode the new value for the <code>overwriteMode</code>
   *     property
   */
  public void setOverwriteMode(boolean overwriteMode)
  {
    this.overwriteMode = overwriteMode;
  }

  /**
   * Returns whether or not invalid edits are allowed or not. If invalid
   * edits are allowed, the JFormattedTextField may temporarily contain invalid
   * characters.
   *
   * @return the value of the allowsInvalid property
   */
  public boolean getAllowsInvalid()
  {
    return allowsInvalid;
  }

  /**
   * Sets the value of the <code>allowsInvalid</code> property.
   *
   * @param allowsInvalid the new value for the property
   *
   * @see #getAllowsInvalid()
   */
  public void setAllowsInvalid(boolean allowsInvalid)
  {
    this.allowsInvalid = allowsInvalid;
  }

  /**
   * Returns the class that is used for values. When Strings are converted
   * back to values, this class is used to create new value objects.
   *
   * @return the class that is used for values
   */
  public Class<?> getValueClass()
  {
    return valueClass;
  }

  /**
   * Sets the class that is used for values.
   *
   * @param valueClass the class that is used for values
   *
   * @see #getValueClass()
   */
  public void setValueClass(Class<?> valueClass)
  {
    this.valueClass = valueClass;
  }

  /**
   * Converts a String (from the JFormattedTextField input) to a value.
   * In order to achieve this, the formatter tries to instantiate an object
   * of the class returned by #getValueClass() using a single argument
   * constructor that takes a String argument. If such a constructor cannot
   * be found, the String itself is returned.
   *
   * @param string the string to convert
   *
   * @return the value for the string
   *
   * @throws ParseException if the string cannot be converted into
   *     a value object (e.g. invalid input)
   */
  public Object stringToValue(String string)
    throws ParseException
  {
    Object value = string;
    Class valueClass = getValueClass();
    if (valueClass == null)
      {
        JFormattedTextField jft = getFormattedTextField();
        if (jft != null)
          valueClass = jft.getValue().getClass();
      }
    if (valueClass != null)
      try
        {
          Constructor constr = valueClass.getConstructor
                                             (new Class[]{String.class});
          value = constr.newInstance(new Object[]{ string });
        }
      catch (NoSuchMethodException ex)
        {
          // leave value as string
        }
      catch (Exception ex)
        {
          throw new ParseException(string, 0);
        }
    return value;
  }

  /**
   * Converts a value object into a String. This is done by invoking the
   * {@link Object#toString()} method on the value.
   *
   * @param value the value to be converted
   *
   * @return the string representation of the value
   *
   * @throws ParseException if the value cannot be converted
   */
  public String valueToString(Object value)
    throws ParseException
  {
    if (value == null)
      return "";
    return value.toString();
  }

  /**
   * Creates and returns a clone of this DefaultFormatter.
   *
   * @return a clone of this object
   *
   * @throws CloneNotSupportedException not thrown here
   */
  public Object clone()
    throws CloneNotSupportedException
  {
    return super.clone();
  }

  /**
   * Returns the DocumentFilter that is used to restrict input.
   *
   * @return the DocumentFilter that is used to restrict input
   */
  protected DocumentFilter getDocumentFilter()
  {
    return new FormatterDocumentFilter();
  }
}
