/******************************************************************************
 * Copyright (c) 2002, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation 
 *    Nicolas Rouquette (NASA) - Fix for Bug 260812. 
 ****************************************************************************/

package org.eclipse.gmf.runtime.diagram.ui.parts;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.ObjectUndoContext;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.common.core.command.ICompositeCommand;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes;
import org.eclipse.gmf.runtime.diagram.ui.internal.tools.ConnectionHandleTool;

/**
 * GEF command stack that delegates to an {@link IOperationHistory}.
 * 
 * @author sshaw
 * @author Tauseef A, Israr
 * @author ldamus
 */
public class DiagramCommandStack
    extends CommandStack {

    private Map stackToManager = new HashMap();

    private IDiagramEditDomain editDomain;

    private Command cmdRecent = null;

    private IOperationHistory delegate;

    private IUndoContext undoContext;

    private final class HistoryEventObject
        extends EventObject {

        private final OperationHistoryEvent event;

        private HistoryEventObject(OperationHistoryEvent event) {
            super(event.getHistory());
            this.event = event;
        }

        /**
         * Gets my operation history event.
         * 
         * @return my operation history event.
         */
        public OperationHistoryEvent getOperationHistoryEvent() {
            return event;
        }
    }

    /**
     * Initializes me with my diagram edit domain and undo context.
     * 
     * @param editDomain
     *            the editing domain assoicated with this stack
     * @param undoContext
     *            my undo context
     */
    public DiagramCommandStack(IDiagramEditDomain editDomain) {
        this.editDomain = editDomain;
    }

    /**
     * Adds a listener to this CommandStack.
     * 
     * @param listener
     *            The Object listening to this CommandStack.
     */
    public void addCommandStackListener(CommandStackListener listener) {

        final CommandStackListener csl = listener;
        // The removal of the listener here is done to avoid multiple
        // commandchangelisteners added to the commandmanager.
        // Tauseef Israr
        removeCommandStackListener(csl);

        IOperationHistoryListener cmcl = new IOperationHistoryListener() {

            public void historyNotification(OperationHistoryEvent event) {
                if (csl != null) {
                    csl.commandStackChanged(new HistoryEventObject(event));
                }
            }
        };

        stackToManager.put(csl, cmcl);
        getOperationHistory().addOperationHistoryListener(cmcl);
    }

    /**
     * Returns <code>true</code> if there is a Command to redo.
     * 
     * @return <code>true</code> if there is a Command to redo.
     */
    public boolean canRedo() {
        return getOperationHistory().canRedo(getUndoContext());
    }

    /**
     * Returns <code>true</code> if the last Command executed can be undone.
     * 
     * @return <code>true</code> if the last Command executed can be undone.
     */
    public boolean canUndo() {
        return getOperationHistory().canUndo(getUndoContext());
    }

    /**
     * Executes the given Command if it can execute.
     * 
     * @param command
     *            The Command to execute.
     */
    public void execute(Command command) {
        execute(command, null);
    }

    /**
     * Executes the given Command if it can execute.
     * 
     * @param command
     *            The Command to execute.
     * @param progressMonitor
     */
    public void execute(Command command, IProgressMonitor progressMonitor) {
        if (command == null || !command.canExecute())
            return;
        execute(getICommand(command), progressMonitor);
    }

    /**
     * exectus a the supplied command
     * 
     * @param command
     *            the command to execute
     */
    protected void execute(ICommand command) {
        execute(command, null);
    }

    /**
     * executes the supplied command
     * 
     * @param command
     *            the command to exectue
     * @param progressMonitor
     */
    protected void execute(ICommand command, IProgressMonitor progressMonitor) {

        if (progressMonitor != null) {
            try {
                command.addContext(getUndoContext());
                getOperationHistory().execute(command, progressMonitor, null);

            } catch (ExecutionException e) {
                Trace.catching(DiagramUIPlugin.getInstance(),
                    DiagramUIDebugOptions.EXCEPTIONS_CATCHING,
                    getClass(), "execute", e); //$NON-NLS-1$
                Log.error(DiagramUIPlugin.getInstance(),
                    DiagramUIStatusCodes.COMMAND_FAILURE, "execute", e); //$NON-NLS-1$
            } 
        } else {
            try {
                command.addContext(getUndoContext());
                getOperationHistory().execute(command,
                    new NullProgressMonitor(), null);

            } catch (ExecutionException e) {
                Trace.catching(DiagramUIPlugin.getInstance(),
                    DiagramUIDebugOptions.EXCEPTIONS_CATCHING,
                    getClass(), "execute", e); //$NON-NLS-1$
                Log.error(DiagramUIPlugin.getInstance(),
                    DiagramUIStatusCodes.COMMAND_FAILURE, "execute", e); //$NON-NLS-1$
            }
        }

    }
    

    /**
     * Converts a GEF {@link Command} into a GMF {@link ICommand}
     * 
     * @param command
     *            the GEF command
     * @return the GMF command
     */
    public static ICommand getICommand(Command command) {

        if (command instanceof CompoundCommand) {

            CompositeCommand composite = new CompositeCommand(
                command.getLabel());
            Object[] subCommands = ((CompoundCommand) command).getChildren();

            for (int i = 0; i < subCommands.length; i++) {
                composite.compose(getICommand((Command) subCommands[i]));
            }
            return composite.reduce();
        }

        if (command instanceof ICommandProxy) {
            return getICommand(((ICommandProxy) command).getICommand());
        }

        if (null != command) {
        	return new CommandProxy(command);
        } else {
        	return null;
        }
    }

    /**
     * Removes redundancies from <code>command</code> by stripping out layers
     * of command wrappers used to accomodate the use of GEF commands on an
     * {@link IOperationHistory} and {@link ICommand}s on the GEF
     * {@link CommandStack}.
     * 
     * @param command
     *            the command to be processed
     * @return a command representing the simplified form of the input command.
     *         May be a new command.
     */
    public static ICommand getICommand(ICommand command) {

        ICommand result = command;

        if (command instanceof ICompositeCommand) {
            // process composite command
            List processedCommands = new ArrayList();

            ICompositeCommand composite = (ICompositeCommand) command;

            if (!composite.isEmpty()) {

                for (Iterator i = composite.iterator(); i.hasNext();) {
                    IUndoableOperation nextOperation = (IUndoableOperation) i
                        .next();

                    // remove the next child from the composite
                    i.remove();

                    // convert any GEF commands to GMF commands
                    if (nextOperation instanceof ICommand) {
                        ICommand nextCommand = (ICommand) nextOperation;
                        processedCommands.add(getICommand(nextCommand));

                    } else {
                        processedCommands.add(nextOperation);
                    }
                }

                // add all the children back
                for (Iterator i = processedCommands.iterator(); i.hasNext();) {
                    composite.add((IUndoableOperation) i.next());
                }

                // reduce to the simplest equivalent form
                result = composite.reduce();
            }

        } else if (command instanceof CommandProxy) {
        	// process GEF command proxy
            return getICommand(((CommandProxy) command).getCommand());
        }

        return result;
    }

    /**
     * Returns the most recently executed command.
     * 
     * @return The most recently executed command.
     */
    public Command getMostRecentCommand() {
        return cmdRecent;
    }

    /**
     * getRedoCommand Returns the command at the top of the redo stack.
     * 
     * @see org.eclipse.gef.commands.CommandStack#getRedoCommand()
     */
    public Command getRedoCommand() {
        if (getOperationHistory().canRedo(getUndoContext())) {
            Command emptyCmd = new Command() {
                // empty
            };

            IUndoableOperation redo = getOperationHistory().getRedoOperation(
                getUndoContext());
            emptyCmd.setLabel(redo.getLabel());
            return emptyCmd;
        }

        return null;
    }

    /**
     * getUndoCommand() Returns the next command to be undone.
     * 
     * @see org.eclipse.gef.commands.CommandStack#getUndoCommand()
     */
    public Command getUndoCommand() {
        if (getOperationHistory().canUndo(getUndoContext())) {
            Command emptyCmd = new Command() {
                // empty
            };

            IUndoableOperation undo = getOperationHistory().getUndoOperation(
                getUndoContext());
            emptyCmd.setLabel(undo.getLabel());
            return emptyCmd;
        }

        return null;
    }

    /**
     * Executes the last undone Command.
     */
    public void redo() {
        cmdRecent = getRedoCommand();

        try {
            getOperationHistory().redo(getUndoContext(),
                new NullProgressMonitor(), null);

        } catch (ExecutionException e) {
            Trace.catching(DiagramUIPlugin.getInstance(),
                DiagramUIDebugOptions.EXCEPTIONS_CATCHING,
                ConnectionHandleTool.class, "redo", e); //$NON-NLS-1$
            Log.error(DiagramUIPlugin.getInstance(),
                DiagramUIStatusCodes.COMMAND_FAILURE, "redo", e); //$NON-NLS-1$
        }
    }

    /**
     * Removes the given CommandStackListener.
     * 
     * @param listener
     *            The object to be removed from the list of listeners.
     */
    public void removeCommandStackListener(CommandStackListener listener) {
        final CommandStackListener csl = listener;

        if (csl != null) {
            IOperationHistoryListener historyListener = (IOperationHistoryListener) stackToManager
                .get(csl);

            if (historyListener != null) {
                getOperationHistory().removeOperationHistoryListener(
                    historyListener);
            }
            // mgoyal: removing from stack manager
            stackToManager.remove(csl);
        }
    }

    /**
     * Undoes the last executed Command.
     */
    public void undo() {
        cmdRecent = getUndoCommand();

        try {
            getOperationHistory().undo(getUndoContext(),
                new NullProgressMonitor(), null);

        } catch (ExecutionException e) {
            Trace.catching(DiagramUIPlugin.getInstance(),
                DiagramUIDebugOptions.EXCEPTIONS_CATCHING,
                ConnectionHandleTool.class, "undo", e); //$NON-NLS-1$
            Log.error(DiagramUIPlugin.getInstance(),
                DiagramUIStatusCodes.COMMAND_FAILURE, "undo", e); //$NON-NLS-1$
        }
    }

    /**
     * Returns the editDomain.
     * 
     * @return IDiagramEditDomain
     */
    protected IDiagramEditDomain getDiagramEditDomain() {
        return editDomain;
    }

    /**
     * Gets my operation history delegate.
     * 
     * @return my operation history delegate
     */
    protected IOperationHistory getOperationHistory() {

        if (delegate == null) {
            delegate = OperationHistoryFactory.getOperationHistory();
        }
        return delegate;
    }

    /**
     * Sets my operation history delegate.
     * 
     * @param operationHistory
     *            my operation history delegate
     */
    public void setOperationHistory(IOperationHistory operationHistory) {
        this.delegate = operationHistory;
    }

    /**
     * Gets the return values of the given executed command
     * 
     * @param c
     *            The command
     * @return A collection of values returned by the given command
     */
    public static Collection getReturnValues(Command c) {
        if (c instanceof CompoundCommand) {
            CompoundCommand cc = (CompoundCommand) c;
            List l = new ArrayList(cc.size());
            for (Iterator i = cc.getCommands().iterator(); i.hasNext();)
                l.addAll(getReturnValues((Command) i.next()));
            return l;

        } else if (c instanceof ICommandProxy) {
            return getReturnValues((ICommandProxy) c);
        }
        return Collections.EMPTY_LIST;
    }

    /**
     * gets the return the values for the supplied command.
     * 
     * @param cmd
     *            command to use
     * @return a collection of return values
     */
    public static Collection getReturnValues(ICommandProxy cmd) {
        return getReturnValues(cmd.getICommand());
    }


    
    
    /**
     * gets the return the values for the supplied command.
     * @param cmd command to use
     * @return a collection of return values
     */
    public static Collection getReturnValues( CommandProxy cmd ) {
        return getReturnValues( cmd.getCommand() );
    }

    /**
     * gets the return the values for the supplied command.
     * 
     * @param cmd
     *            command to use
     * @return a collection of return values
     */
    public static Collection getReturnValues(ICommand cmd) {
        
        if (cmd instanceof ICompositeCommand) {
            ICompositeCommand cc = (ICompositeCommand) cmd;
            List l = new ArrayList();
            for (Iterator i = cc.iterator(); i.hasNext();) {
            	IUndoableOperation child = (IUndoableOperation) i.next();
            	if (child instanceof ICommand) {
            		l.addAll(getReturnValues((ICommand) child));
            	}
            }
            return l;
            
        } else if ( cmd instanceof CommandProxy ) { //
            // Need to recurse into the proxy command(s) since they
            // will not have set the CommandProxy result
            // This Could be moved into CommandProxy but
            // #getCommandResult() can no longer be final.
            return getReturnValues((CommandProxy)cmd);
        
        } else {
            CommandResult r = cmd.getCommandResult();
            Object o = r != null ? r.getReturnValue()
                : null;
            
            if (o instanceof Collection) {
                return (Collection) o;
                
            } else if (o != null) {
                return Collections.singletonList(o);
            }
        }
        
        return Collections.EMPTY_LIST;
    }

    /**
     * Gets my undo context. I add my context to all commands executed through
     * me.
     * 
     * @return my undo context
     */
    public IUndoContext getUndoContext() {

        if (undoContext == null) {
            undoContext = new ObjectUndoContext(this);
        }
        return undoContext;
    }
    
    /**
     * Sets my undo context.
     * 
     * @param undoContext
     *            my undo context
     */
    public void setUndoContext(IUndoContext undoContext) {
        this.undoContext = undoContext;
    }

    public void dispose() {
        // clean up the known listeners (if there is any remaining)
        // this will prevent clients from causing memory leaks
        Set entries = stackToManager.entrySet();
        for (Iterator iter = entries.iterator(); iter.hasNext();) {
            Map.Entry element = (Map.Entry) iter.next();
            IOperationHistoryListener historyListener = (IOperationHistoryListener) element.getValue();
            if (historyListener != null) {
                getOperationHistory().removeOperationHistoryListener(
                    historyListener);
            }
        }
        super.dispose();
    }

}