/* UndoableEditSupport.java --
   Copyright (C) 2002, 2003, 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 java.util.Iterator;
import java.util.Vector;

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

/**
 * A helper class for supporting {@link
 * javax.swing.event.UndoableEditListener}.
 *
 * @author Andrew Selkirk (aselkirk@sympatico.ca)
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public class UndoableEditSupport
{
  /**
   * The number of times that {@link #beginUpdate()} has been called
   * without a matching call to {@link #endUpdate()}.
   */
  protected int updateLevel;


  /**
   * compoundEdit
   */
  protected CompoundEdit compoundEdit;


  /**
   * The currently registered listeners.
   */
  protected Vector listeners = new Vector();


  /**
   * The source of the broadcast UndoableEditEvents.
   */
  protected Object realSource;


  /**
   * Constructs a new helper for broadcasting UndoableEditEvents.  The
   * events will indicate the newly constructed
   * <code>UndoableEditSupport</code> instance as their source.
   *
   * @see #UndoableEditSupport(java.lang.Object)
   */
  public UndoableEditSupport()
  {
    realSource = this;
  }


  /**
   * Constructs a new helper for broadcasting UndoableEditEvents.
   *
   * @param realSource the source of the UndoableEditEvents that will
   * be broadcast by this helper. If <code>realSource</code> is
   * <code>null</code>, the events will indicate the newly constructed
   * <code>UndoableEditSupport</code> instance as their source.
   */
  public UndoableEditSupport(Object realSource)
  {
    if (realSource == null)
      realSource = this;
    this.realSource = realSource;
  }


  /**
   * Returns a string representation of this object that may be useful
   * for debugging.
   */
  public String toString()
  {
    // Note that often, this.realSource == this. Therefore, dumping
    // realSource without additional checks may lead to infinite
    // recursion. See Classpath bug #7119.
    return super.toString() + " updateLevel: " + updateLevel
      + " listeners: " + listeners + " compoundEdit: " + compoundEdit;
  }


  /**
   * Registers a listener.
   *
   * @param val the listener to be added.
   */
  public synchronized void addUndoableEditListener(UndoableEditListener val)
  {
    listeners.add(val);
  }


  /**
   * Unregisters a listener.
   * @param val the listener to be removed.
   */
  public synchronized void removeUndoableEditListener(UndoableEditListener val)
  {
    listeners.removeElement(val);
  }


  /**
   * Returns an array containing the currently registered listeners.
   */
  public synchronized UndoableEditListener[] getUndoableEditListeners()
  {
    UndoableEditListener[] result = new UndoableEditListener[listeners.size()];
    return (UndoableEditListener[]) listeners.toArray(result);
  }


  /**
   * Notifies all registered listeners that an {@link
   * UndoableEditEvent} has occured.
   *
   * <p><b>Lack of Thread Safety:</b> It is <em>not</em> safe to call
   * this method from concurrent threads, unless the call is protected
   * by a synchronization on this <code>UndoableEditSupport</code>
   * instance.
   *
   * @param edit the edit action to be posted.
   */
  protected void _postEdit(UndoableEdit edit)
  {
    UndoableEditEvent event;
    Iterator iter;

    // Do nothing if we have no listeners.
    if (listeners.isEmpty())
      return;

    event = new UndoableEditEvent(realSource, edit);

    // We clone the vector because this allows listeners to register
    // or unregister listeners in their undoableEditHappened method.
    // Otherwise, this would throw exceptions (in the case of
    // Iterator, a java.util.ConcurrentModificationException; in the
    // case of a direct loop over the Vector elements, some
    // index-out-of-bounds exception).
    iter = ((Vector) listeners.clone()).iterator();
    while (iter.hasNext())
      ((UndoableEditListener) iter.next()).undoableEditHappened(event);
  }


  /**
   * If {@link #beginUpdate} has been called (so that the current
   * update level is greater than zero), adds the specified edit
   * to {@link #compoundEdit}. Otherwise, notify listeners of the
   * edit by calling {@link #_postEdit(UndoableEdit)}.
   *
   * <p><b>Thread Safety:</b> It is safe to call this method from any
   * thread without external synchronization.
   *
   * @param edit the edit action to be posted.
   */
  public synchronized void postEdit(UndoableEdit edit)
  {
    if (compoundEdit != null)
      compoundEdit.addEdit(edit);
    else
      _postEdit(edit);
  }


  /**
   * Returns the current update level.
   */
  public int getUpdateLevel()
  {
    return updateLevel;
  }


  /**
   * Starts a (possibly nested) update session. If the current update
   * level is zero, {@link #compoundEdit} is set to the result of the
   * {@link #createCompoundEdit} method. In any case, the update level
   * is increased by one.
   *
   * <p><b>Thread Safety:</b> It is safe to call this method from any
   * thread without external synchronization.
   */
  public synchronized void beginUpdate()
  {
    if (compoundEdit == null)
      compoundEdit = createCompoundEdit();
    ++updateLevel;
  }


  /**
   * Creates a new instance of {@link CompoundEdit}. Called by {@link
   * #beginUpdate}. If a subclass wants {@link #beginUpdate} to work
   * on a specific {@link #compoundEdit}, it should override this
   * method.
   *
   * @returns a newly created instance of {@link CompoundEdit}.
   */
  protected CompoundEdit createCompoundEdit()
  {
    return new CompoundEdit();
  }


  /**
   * Ends an update session. If the terminated session was the
   * outermost session, {@link #compoundEdit} will receive an
   * <code>end</code> message, and {@link #_postEdit} gets called in
   * order to notify any listeners. Finally, the
   * <code>compoundEdit</code> is discarded.
   *
   * <p><b>Thread Safety:</b> It is safe to call this method from any
   * thread without external synchronization.
   */
  public synchronized void endUpdate()
  {
    if (updateLevel == 0)
      throw new IllegalStateException();

    if (--updateLevel > 0)
      return;

    compoundEdit.end();
    _postEdit(compoundEdit);
    compoundEdit = null;
  }
}
