//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.gef.commands;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.epf.authoring.gef.util.Validation;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.diagram.model.Link;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.diagram.model.NodeContainer;
import org.eclipse.gef.commands.Command;

/**
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class DeleteCommand extends Command {

	private Command delegate;

	private static final String LABEL = AuthoringUIResources.gef_deleteCommand_label; //$NON-NLS-1$

	public static final String KEY_PERM_DELETE = "gef.ediagram.$perm"; //$NON-NLS-1$

	public DeleteCommand(boolean hardDelete) {
		super(LABEL);
	}

	public boolean canExecute() {
		return delegate != null && delegate.canExecute();
	}

	public void execute() {
		delegate.execute();
	}

	public Command setPartToBeDeleted(Object model) {
		if (model instanceof Node)
			delegate = new DeleteNodeCommand(model);
		else
			delegate = null;
		return this;
	}

	public void undo() {
		delegate.undo();
	}

	private static class DeleteNodeCommand extends Command {
		protected Map incomingConnectionsToSource;

		protected Map outgoingConnectionsToTarget;

		protected NodeContainer container;

		protected Node node;

		protected int index;

		public DeleteNodeCommand(Object node) {
			this.node = (Node) node;
			container = (NodeContainer) this.node.eContainer();
		}

		public void execute() {
			index = container.getNodes().indexOf(node);
			// There's always the possibility that this node has already been
			// deleted by the time this command is executed (eg., when the
			// package containing this class is also selected). Hence, we check
			// to see if the node exists in the diagram. If not, do nothing.
			if (index == -1)
				return;
			incomingConnectionsToSource = new HashMap();
			outgoingConnectionsToTarget = new HashMap();
			for (Iterator iter = node.getOutgoingConnections().iterator(); iter
					.hasNext();) {
				Link link = (Link) iter.next();
				outgoingConnectionsToTarget.put(link, link.getTarget());
				link.setTarget(null);
			}
			for (Iterator iter = node.getIncomingConnections().iterator(); iter
					.hasNext();) {
				Link link = (Link) iter.next();
				incomingConnectionsToSource.put(link, link.getSource());
				link.setSource(null);
			}
			// Commenting below two lines, Links get removed from the model
			// when link.setTarget(null) or link.setSource(null) is done.  For 
			// Node if we clear incoming/outgoing connections, Undo command will not work.
			
			//node.getOutgoingConnections().clear();
			//node.getIncomingConnections().clear();
			container.getNodes().remove(index);
		}

		public void undo() {
			if (index == -1)
				return;
			container.getNodes().add(index, node);
			for (Iterator iter = outgoingConnectionsToTarget.keySet()
					.iterator(); iter.hasNext();) {
				Link link = (Link) iter.next();
				link.setTarget((Node) outgoingConnectionsToTarget.get(link));
				link.setSource(node);
			}
			for (Iterator iter = incomingConnectionsToSource.keySet()
					.iterator(); iter.hasNext();) {
				Link link = (Link) iter.next();
				link.setTarget(node);
				link.setSource((Node) incomingConnectionsToSource.get(link));
			}
			outgoingConnectionsToTarget = null;
			incomingConnectionsToSource = null;
		}

		/**
		 * @see org.eclipse.gef.commands.Command#canExecute()
		 */
		public boolean canExecute() {
			if (Validation.checkDelete(node) != null)
				return false;
			return super.canExecute();
		}
	}
	/*
	 * Not in use. Need modification for future feature implementations. 
	 * Compound Command deletion do the recursive deletion and undo. 
	 */
//	private static class DeleteNodeCompoundCommand extends CompoundCommand {
//		protected Map incomingConnectionsToSource;
//
//		protected Map outgoingConnectionsToTarget;
//
//		protected NodeContainer container;
//
//		protected Node node;
//
//		protected int index;
//
//		public DeleteNodeCompoundCommand(Object node) {
//			this.node = (Node) node;
//			container = (NodeContainer) this.node.eContainer();
//			incomingConnectionsToSource = new HashMap();
//			outgoingConnectionsToTarget = new HashMap();
//			for (Iterator iter = this.node.getOutgoingConnections().iterator(); iter
//					.hasNext();) {
//				Link link = (Link) iter.next();
//				outgoingConnectionsToTarget.put(link, link.getTarget());
//				add(new DeleteLinkCommand( link, false));
//			}
//			for (Iterator iter = this.node.getIncomingConnections().iterator(); iter
//					.hasNext();) {
//				Link link = (Link) iter.next();
//				incomingConnectionsToSource.put(link, link.getSource());
//				add(new DeleteLinkCommand( link, false));
//			}
//		}
//
//		public void execute() {
//			index = container.getNodes().indexOf(node);
//			// There's always the possibility that this node has already been
//			// deleted by the time this command is executed (eg., when the
//			// package containing this class is also selected). Hence, we check
//			// to see if the node exists in the diagram. If not, do nothing.
//			if (index == -1)
//				return;
//
//			super.execute();
//			container.getNodes().remove(index);
//			
//		}
//
//		public void undo() {
//			if (index == -1)
//				return;
//			container.getNodes().add(index, node);
//			super.undo();
//		}
//
//		/**
//		 * @see org.eclipse.gef.commands.Command#canExecute()
//		 */
//		public boolean canExecute() {
//			if (Validation.checkDelete(node) != null)
//				return false;
//			return super.canExecute();
//		}
//	}

}