/* AbstractTableModel.java --
   Copyright (C) 2002, 2004, 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.undo;

import javax.swing.UIManager;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;


/**
 * A manager for providing an application&#x2019;s undo/redo
 * functionality.
 *
 * <p>Tyipcally, an application will create only one single instance
 * of UndoManager. When the user performs an undoable action, for
 * instance changing the color of an object from green to blue, the
 * application registers an {@link UndoableEdit} object with the
 * <code>UndoManager</code>. To implement the &#x201c;undo&#x201d; and
 * &#x201c;redo&#x201d; menu commands, the application invokes the
 * UndoManager&#x2019;s {@link #undo} and {@link #redo} methods.  The
 * human-readable text of these menu commands is provided by {@link
 * #getUndoPresentationName} and {@link #getRedoPresentationName},
 * respectively. To determine whether the menu item should be
 * selectable or greyed out, use {@link #canUndo} and {@link
 * #canRedo}.
 *
 * <p>The UndoManager will only keep a specified number of editing
 * actions, the <em>limit</em>. The value of this parameter can be
 * retrieved by calling {@link #getLimit} and set with {@link
 * #setLimit}.  If more UndoableEdits are added to the UndoManager,
 * the oldest actions will be discarded.
 *
 * <p>Some applications do not provide separate menu commands for
 * &#x201c;undo&#x201d; and &#x201c;redo.&#x201d; Instead, they
 * have just a single command whose text switches between the two.
 * Such applications would use an UndoManager with a <code>limit</code>
 * of 1. The text of this combined menu item is available via
 * {@link #getUndoOrRedoPresentationName}, and it is implemented
 * by calling {@link #undoOrRedo}.
 *
 * <p><b>Thread Safety:</b> In constrast to the other classes of the
 * <code>javax.swing.undo</code> package, the public methods of an
 * <code>UndoManager</code> are safe to call from concurrent threads.
 * The caller does not need to perform external synchronization, and
 * {@link javax.swing.event.UndoableEditEvent} sources do not need to
 * broadcast their events from inside the Swing worker thread.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public class UndoManager
  extends CompoundEdit
  implements UndoableEditListener
{
  /**
   * The unique ID for serializing instances of this class. Determined
   * using the <code>serialver</code> tool of Sun JDK 1.4.1_01 on
   * GNU/Linux.
   */
  static final long serialVersionUID = -2077529998244066750L;


  /**
   * An index into the inherited {@link #edits} Vector that indicates
   * at which position newly added editing actions would get inserted.
   *
   * <p>Normally, the value of <code>indexOfNextAdd</code> equals
   * the number of UndoableEdits stored by this UndoManager, i.e.
   * <code>edits.size()</code>. For each call to {@link #undo},
   * <code>indexOfNextAdd</code> is decremented by one. For each
   * call to {@link #redo}, it is incremented again.
   */
  int indexOfNextAdd;


  /**
   * The maximum number of UndoableEdits stored by this UndoManager.
   */
  int limit;


  /**
   * Constructs an UndoManager.
   *
   * <p>The <code>limit</code> of the freshly constructed UndoManager
   * is 100.
   */
  public UndoManager()
  {
    limit = 100;
  }


  /**
   * Returns a string representation for this UndoManager. This may be
   * useful for debugging purposes. For the text of menu items, please
   * refer to {@link #getUndoPresentationName}, {@link
   * #getRedoPresentationName}, and {@link
   * #getUndoOrRedoPresentationName}.
   */
  public String toString()
  {
    return super.toString()
      + " limit: " + limit
      + " indexOfNextAdd: " + indexOfNextAdd;
  }


  /**
   * Puts this UndoManager into a state where it acts as a normal
   * {@link CompoundEdit}. It is unlikely that an application would
   * want to do this.
   */
  public synchronized void end()
  {
    super.end();
    trimEdits(indexOfNextAdd, edits.size() - 1);
  }


  /**
   * Returns how many edits this UndoManager can maximally hold.
   *
   * @see #setLimit
   */
  public synchronized int getLimit()
  {
    return limit;
  }


  /**
   * Changes the maximal number of edits that this UndoManager can
   * process. If there are currently more edits than the new limit
   * allows, they will receive a {@link UndoableEdit#die() die}
   * message in reverse order of addition.
   *
   * @param limit the new limit.
   *
   * @throws IllegalStateException if {@link #end()} has already been
   * called on this UndoManager.
   */
  public synchronized void setLimit(int limit)
  {
    if (!isInProgress())
      throw new IllegalStateException();

    this.limit = limit;
    trimForLimit();
  }


  /**
   * Discards all editing actions that are currently registered with
   * this UndoManager. Each {@link UndoableEdit} will receive a {@link
   * UndoableEdit#die() die message}.
   */
  public synchronized void discardAllEdits()
  {
    int size;

    size = edits.size();
    for (int i = size - 1; i >= 0; i--)
      ((UndoableEdit) edits.get(i)).die();
    indexOfNextAdd = 0;
    edits.clear();
  }


  /**
   * Called by various internal methods in order to enforce
   * the <code>limit</code> value.
   */
  protected void trimForLimit()
  {
    int high, s;

    s = edits.size();

    /* The Sun J2SE1.4.1_01 implementation can be observed to do
     * nothing (instead of throwing an exception) with a negative or
     * zero limit. It may be debatable whether this is the best
     * behavior, but we replicate it for sake of compatibility.
     */
    if (limit <= 0 || s <= limit)
      return;

    high = Math.min(indexOfNextAdd + limit/2 - 1, s - 1);
    trimEdits(high + 1, s - 1);
    trimEdits(0, high - limit);
  }


  /**
   * Discards a range of edits. All edits in the range <code>[from
   * .. to]</code> will receive a {@linkplain UndoableEdit#die() die
   * message} before being removed from the edits array.  If
   * <code>from</code> is greater than <code>to</code>, nothing
   * happens.
   *
   * @param from the lower bound of the range of edits to be
   * discarded.
   *
   * @param to the upper bound of the range of edits to be discarded.
   */
  protected void trimEdits(int from, int to)
  {
    if (from > to)
      return;

    for (int i = to; i >= from; i--)
        ((UndoableEdit) edits.get(i)).die();

    // Remove the range [from .. to] from edits. If from == to, which
    // is likely to be a very common case, we can do better than
    // creating a sub-list and clearing it.
    if (to == from)
      edits.remove(from);
    else
      edits.subList(from, to + 1).clear();

    if (indexOfNextAdd > to)
      indexOfNextAdd = indexOfNextAdd - to + from - 1;
    else if (indexOfNextAdd >= from)
      indexOfNextAdd = from;
  }


  /**
   * Determines which significant edit would be undone if {@link
   * #undo()} was called.
   *
   * @returns the significant edit that would be undone, or
   * <code>null</code> if no significant edit would be affected by
   * calling {@link #undo()}.
   */
  protected UndoableEdit editToBeUndone()
  {
    UndoableEdit result;

    for (int i = indexOfNextAdd - 1; i >= 0; i--)
      {
        result = (UndoableEdit) edits.get(i);
        if (result.isSignificant())
          return result;
      }

    return null;
  }


  /**
   * Determines which significant edit would be redone if {@link
   * #redo()} was called.
   *
   * @returns the significant edit that would be redone, or
   * <code>null</code> if no significant edit would be affected by
   * calling {@link #redo()}.
   */
  protected UndoableEdit editToBeRedone()
  {
    UndoableEdit result;

    for (int i = indexOfNextAdd; i < edits.size(); i++)
      {
        result = (UndoableEdit) edits.get(i);
        if (result.isSignificant())
          return result;
      }

    return null;
  }


  /**
   * Undoes all editing actions in reverse order of addition,
   * up to the specified action,
   *
   * @param edit the last editing action to be undone.
   */
  protected void undoTo(UndoableEdit edit)
    throws CannotUndoException
  {
    UndoableEdit cur;

    if (!edits.contains(edit))
      throw new CannotUndoException();

    while (true)
      {
        indexOfNextAdd -= 1;
        cur = (UndoableEdit) edits.get(indexOfNextAdd);
        cur.undo();
        if (cur == edit)
          return;
      }
  }


  /**
   * Redoes all editing actions in the same order as they were
   * added to this UndoManager, up to the specified action.
   *
   * @param edit the last editing action to be redone.
   */
  protected void redoTo(UndoableEdit edit)
    throws CannotRedoException
  {
    UndoableEdit cur;

    if (!edits.contains(edit))
      throw new CannotRedoException();

    while (true)
      {
        cur = (UndoableEdit) edits.get(indexOfNextAdd);
        indexOfNextAdd += 1;
        cur.redo();
        if (cur == edit)
          return;
      }
  }

  
  /**
   * Undoes or redoes the last action. If the last action has already
   * been undone, it will be re-done, and vice versa.
   *
   * <p>This is useful for applications that do not present a separate
   * undo and redo facility, but just have a single menu item for
   * undoing and redoing the very last action. Such applications will
   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
   */
  public synchronized void undoOrRedo()
    throws CannotRedoException, CannotUndoException
  {
    if (indexOfNextAdd == edits.size())
      undo();
    else
      redo();
  }


  /**
   * Determines whether it would be possible to either undo or redo
   * this editing action.
   *
   * <p>This is useful for applications that do not present a separate
   * undo and redo facility, but just have a single menu item for
   * undoing and redoing the very last action. Such applications will
   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
   *
   * @return <code>true</code> to indicate that this action can be
   * undone or redone; <code>false</code> if neither is possible at
   * the current time.
   */
  public synchronized boolean canUndoOrRedo()
  {
    return indexOfNextAdd == edits.size() ? canUndo() : canRedo();
  }


  /**
   * Undoes one significant edit action. If insignificant actions have
   * been posted after the last signficant action, the insignificant
   * ones will be undone first.
   *
   * <p>However, if {@link #end()} has been called on this
   * UndoManager, it will behave like a normal {@link
   * CompoundEdit}. In this case, all actions will be undone in
   * reverse order of addition. Typical applications will never call
   * {@link #end()} on their <code>UndoManager</code>.
   *
   * @throws CannotUndoException if no action can be undone.
   *
   * @see #canUndo()
   * @see #redo()
   * @see #undoOrRedo()
   */
  public synchronized void undo()
    throws CannotUndoException
  {
    if (!isInProgress())
      {
        super.undo();
        return;
      }

    UndoableEdit edit = editToBeUndone();
    if (edit == null)
      throw new CannotUndoException();

    undoTo(edit);
  }


  /**
   * Determines whether it would be possible to undo this editing
   * action.
   *
   * @return <code>true</code> to indicate that this action can be
   * undone; <code>false</code> otherwise.
   *
   * @see #undo()
   * @see #canRedo()
   * @see #canUndoOrRedo()
   */
  public synchronized boolean canUndo()
  {
    UndoableEdit edit;

    if (!isInProgress())
      return super.canUndo();

    edit = editToBeUndone();
    return edit != null && edit.canUndo();
  }



  /**
   * Redoes one significant edit action. If insignificant actions have
   * been posted in between, the insignificant ones will be redone
   * first.
   *
   * <p>However, if {@link #end()} has been called on this
   * UndoManager, it will behave like a normal {@link
   * CompoundEdit}. In this case, <em>all</em> actions will be redone
   * in order of addition. Typical applications will never call {@link
   * #end()} on their <code>UndoManager</code>.
   *
   * @throws CannotRedoException if no action can be redone.
   *
   * @see #canRedo()
   * @see #redo()
   * @see #undoOrRedo()
   */
  public synchronized void redo()
    throws CannotRedoException
  {
    if (!isInProgress())
      {
        super.redo();
        return;
      }

    UndoableEdit edit = editToBeRedone();
    if (edit == null)
      throw new CannotRedoException();

    redoTo(edit);
  }


  /**
   * Determines whether it would be possible to redo this editing
   * action.
   *
   * @return <code>true</code> to indicate that this action can be
   * redone; <code>false</code> otherwise.
   *
   * @see #redo()
   * @see #canUndo()
   * @see #canUndoOrRedo()
   */
  public synchronized boolean canRedo()
  {
    UndoableEdit edit;

    if (!isInProgress())
      return super.canRedo();

    edit = editToBeRedone();
    return edit != null && edit.canRedo();
  }


  /**
   * Registers an undoable editing action with this UndoManager.  If
   * the capacity <code>limit</code> is reached, the oldest action
   * will be discarded (and receives a {@linkplain UndoableEdit#die()
   * die message}. Equally, any actions that were undone (but not re-done)
   * will be discarded, too.
   *
   * @param edit the editing action that is added to this UndoManager.
   *
   * @return <code>true</code> if <code>edit</code> could be
   * incorporated; <code>false</code> if <code>edit</code> has not
   * been incorporated because {@link #end()} has already been called
   * on this <code>UndoManager</code>.
   */
  public synchronized boolean addEdit(UndoableEdit edit)
  {
    boolean result;

    // Discard any edits starting at indexOfNextAdd.
    trimEdits(indexOfNextAdd, edits.size() - 1);

    result = super.addEdit(edit);
    indexOfNextAdd = edits.size();
    trimForLimit();
    return result;
  }


  /**
   * Calculates a localized text for presenting the undo or redo
   * action to the user, for example in the form of a menu command.
   *
   * <p>This is useful for applications that do not present a separate
   * undo and redo facility, but just have a single menu item for
   * undoing and redoing the very last action. Such applications will
   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
   *
   * @return the redo presentation name if the last action has already
   * been undone, or the undo presentation name otherwise.
   *
   * @see #getUndoPresentationName()
   * @see #getRedoPresentationName()
   */
  public synchronized String getUndoOrRedoPresentationName()
  {
    if (indexOfNextAdd == edits.size())
      return getUndoPresentationName();
    else
      return getRedoPresentationName();
  }


  /**
   * Calculates a localized text for presenting the undo action
   * to the user, for example in the form of a menu command.
   */
  public synchronized String getUndoPresentationName()
  {
    UndoableEdit edit;

    if (!isInProgress())
      return super.getUndoPresentationName();

    edit = editToBeUndone();
    if (edit == null)
      return UIManager.getString("AbstractUndoableEdit.undoText");
    else
      return edit.getUndoPresentationName();
  }


  /**
   * Calculates a localized text for presenting the redo action
   * to the user, for example in the form of a menu command.
   */
  public synchronized String getRedoPresentationName()
  {
    UndoableEdit edit;

    if (!isInProgress())
      return super.getRedoPresentationName();

    edit = editToBeRedone();
    if (edit == null)
      return UIManager.getString("AbstractUndoableEdit.redoText");
    else
      return edit.getRedoPresentationName();
  }
  
  
  /**
   * Registers the edit action of an {@link UndoableEditEvent}
   * with this UndoManager.
   *
   * <p><b>Thread Safety:</b> This method may safely be invoked from
   * concurrent threads.  The caller does not need to perform external
   * synchronization. This means that {@link
   * javax.swing.event.UndoableEditEvent} sources do not need to broadcast
   * their events from inside the Swing worker thread.
   *
   * @param event the event whose <code>edit</code> will be
   * passed to {@link #addEdit}.
   *
   * @see UndoableEditEvent#getEdit()
   * @see #addEdit
   */
  public void undoableEditHappened(UndoableEditEvent event)
  {
    // Note that this method does not need to be synchronized,
    // because addEdit will obtain and release the mutex.
    addEdit(event.getEdit());
  }
}
