/**
 * <copyright> 
 *
 * Copyright (c) 2002-2004 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 *
 * </copyright>
 *
 * $Id: AbstractCommand.java,v 1.1 2005/04/15 23:31:25 david_williams Exp $
 */
package org.eclipse.emf.common.command;


import java.util.Collection;
import java.util.Collections;


/**
 * An abstract implementation of a basic command. Each derived class
 * <bold>must</bold> implement {@link Command#execute} and
 * {@link Command#redo}, <bold>must</bold> either implement {@link #undo} or
 * implement {@link #canUndo} to return false, and <bold>must</bold> either
 * override {@link #prepare} (this is the preferred approach) or can override
 * {@link #canExecute} directly.
 * 
 * <p>
 * It is very convenient to use prepare, as it is guaranteed to be called only
 * once just before canExecute is to be tested. It can be implemented to
 * create any additional commands that need to be executed, and the result it
 * yields becomes the permanent cached return value for canExecute.
 * 
 */
public abstract class AbstractCommand implements Command {
	/**
	 * Keeps track of whether prepare needs to be called. It is tested in
	 * {@link #canExecute} so that {@link #prepare} is called exactly once to
	 * ready the command for execution.
	 */
	protected boolean isPrepared;

	/**
	 * Keeps track of whether the command is executable. It is set in
	 * {@link #canExecute} to the result of calling {@link #prepare}.
	 */
	protected boolean isExecutable;

	/**
	 * Holds a short textual description of the command as returned by
	 * {@link #getDescription} and set by {@link #setDescription}.
	 */
	protected String description;

	/**
	 * Holds the label of the command as returned by {@link #getLabel} and set
	 * by {@link #setLabel}.
	 */
	protected String label;

	/**
	 * Creates an empty instance.
	 */
	protected AbstractCommand() {
	}

	/**
	 * Creates an instance with the given label.
	 * 
	 * @param label
	 *            the label.
	 */
	protected AbstractCommand(String label) {
		this.label = label;
	}

	/**
	 * Creates and instance with the given label and description.
	 * 
	 * @param label
	 *            the label.
	 * @param description
	 *            the description.
	 */
	protected AbstractCommand(String label, String description) {
		this.label = label;
		this.description = description;
	}

	/**
	 * Called at most once in {@link #canExecute} to give the command an
	 * opportunity to ready itself for execution. The returned value is stored
	 * in {@link #canExecute}. In other words, you can override this method
	 * to initialize and to yield a cached value for the all subsequent calls
	 * to canExecute.
	 * 
	 * @return whether the command is executable.
	 */
	protected boolean prepare() {
		return false;
	}

	/**
	 * Calls {@link #prepare}, caches the result in {@link #isExecutable},
	 * and sets {@link #isPrepared} to <code>true</code>; from then on, it
	 * will yield the value of isExecutable.
	 * 
	 * @return whether the command can execute.
	 */
	public boolean canExecute() {
		if (!isPrepared) {
			isExecutable = prepare();
			isPrepared = true;
		}

		return isExecutable;
	}

	/**
	 * Returns <code>true</code> because most command should be undoable.
	 * 
	 * @return <code>true</code>.
	 */
	public boolean canUndo() {
		return true;
	}

	/**
	 * Throws a runtime exception.
	 * 
	 * @exception UnsupportedOperationException
	 *                always.
	 */
	public void undo() {
		throw new RuntimeException("_EXC_Method_not_implemented");
	}

	/**
	 * Returns an empty list.
	 * 
	 * @return an empty list.
	 */
	public Collection getResult() {
		return Collections.EMPTY_LIST;
	}

	/**
	 * Returns an empty list.
	 * 
	 * @return an empty list.
	 */
	public Collection getAffectedObjects() {
		return Collections.EMPTY_LIST;
	}

	/*
	 * Javadoc copied from interface.
	 */
	public String getLabel() {
		return label == null ? "_UI_AbstractCommand_label" : label;
	}

	/**
	 * Sets the label after construction.
	 * 
	 * @param label
	 *            the new label.
	 */
	public void setLabel(String label) {
		this.label = label;
	}

	/*
	 * Javadoc copied from interface.
	 */
	public String getDescription() {
		return description == null ? "_UI_AbstractCommand_description" : description;
	}

	/**
	 * Sets the description after construction.
	 * 
	 * @param description
	 *            the new description.
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * Creates a new compound command, containing this command and the given
	 * command, that delegates chain to {@link CompoundCommand#append}.
	 * 
	 * @param command
	 *            the command to chain with this one.
	 * @return a new chained compound command.
	 */
	public Command chain(Command command) {
		class ChainedCompoundCommand extends CompoundCommand {
			public ChainedCompoundCommand() {
			}

			public Command chain(Command c) {
				append(c);
				return this;
			}
		}

		CompoundCommand result = new ChainedCompoundCommand();
		result.append(this);
		result.append(command);
		return result;
	}

	/*
	 * Javadoc copied from interface.
	 */
	public void dispose() {
	}

	/**
	 * Returns an abbreviated name using this object's own class' name,
	 * without package qualification, followed by a space separated list of
	 * <tt>field:value</tt> pairs.
	 * 
	 * @return string representation.
	 */
	public String toString() {
		String className = getClass().getName();
		int lastDotIndex = className.lastIndexOf('.');
		StringBuffer result = new StringBuffer(lastDotIndex == -1 ? className : className.substring(lastDotIndex + 1));
		result.append(" (label: " + label + ")");
		result.append(" (description: " + description + ")");
		result.append(" (isPrepared: " + isPrepared + ")");
		result.append(" (isExecutable: " + isExecutable + ")");

		return result.toString();
	}

	/**
	 * A marker interface implemented by commands that don't dirty the model.
	 */
	public static interface NonDirtying {
	}
}
