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