package org.eclipse.gmf.tooling.runtime.part;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.tooling.runtime.LogHelper;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.handlers.HandlerUtil;

/**
 * @since 3.2
 */
public abstract class DefaultCreateShortcutHandler extends AbstractHandler {

	private final LogHelper myLogHelper;

	private final PreferencesHint myPreferencesHint;

	public DefaultCreateShortcutHandler(LogHelper logHelper, PreferencesHint preferencesHint) {
		myLogHelper = logHelper;
		myPreferencesHint = preferencesHint;
	}

	public abstract ICommand createShortcutDecorationCommand(View view, TransactionalEditingDomain editingDomain, List<CreateViewRequest.ViewDescriptor> descriptors);

	public abstract DefaultElementChooserDialog createChooserDialog(Shell parentShell, View view);

	public Object execute(org.eclipse.core.commands.ExecutionEvent event) throws org.eclipse.core.commands.ExecutionException {
		IEditorPart diagramEditor = HandlerUtil.getActiveEditorChecked(event);
		Shell shell = diagramEditor.getEditorSite().getShell();
		assert diagramEditor instanceof DiagramEditor;
		TransactionalEditingDomain editingDomain = ((DiagramEditor) diagramEditor).getEditingDomain();
		ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
		assert selection instanceof IStructuredSelection;
		assert ((IStructuredSelection) selection).size() == 1;
		assert ((IStructuredSelection) selection).getFirstElement() instanceof EditPart;
		EditPart selectedDiagramPart = (EditPart) ((IStructuredSelection) selection).getFirstElement();
		final View view = (View) selectedDiagramPart.getModel();

		Point d2dCursorBeforeDialog = getLastClickPosition(shell, event);
		DefaultElementChooserDialog chooserDialog = createChooserDialog(shell, view);
		int result = chooserDialog.open();
		if (result != Window.OK) {
			return null;
		}

		List<EObject> allSelectedObjects = getEObjectsByURI(chooserDialog.getSelectedModelElementURIs(), editingDomain);
		if (allSelectedObjects.isEmpty()) {
			return null;
		}

		DropObjectsRequest request = createDragDropRequest(allSelectedObjects, d2dCursorBeforeDialog);
		Command gefCommand = selectedDiagramPart.getCommand(request);
		ICommand iCommand;
		if (gefCommand != null && gefCommand.canExecute()) {
			iCommand = new CommandProxy(gefCommand);
		} else {
			iCommand = createCompositeCommand(allSelectedObjects, view, editingDomain);
		}

		if (iCommand != null) {
			try {
				OperationHistoryFactory.getOperationHistory().execute(iCommand, new NullProgressMonitor(), null);
			} catch (ExecutionException e) {
				myLogHelper.logError("Unable to create shortcut", e); //$NON-NLS-1$
				throw e;
			}
		}

		return null;
	}

	private List<EObject> getEObjectsByURI(List<URI> selectedModelElementURIs, TransactionalEditingDomain editingDomain) {
		List<EObject> result = new ArrayList<EObject>();
		for (URI nextURI : selectedModelElementURIs) {
			try {
				EObject next = editingDomain.getResourceSet().getEObject(nextURI, true);
				if (next != null) {
					result.add(next);
				}
			} catch (WrappedException e) {
				myLogHelper.logError("Exception while loading object: " + nextURI.toString(), e); //$NON-NLS-1$
			}
		}
		return result;
	}

	private CompositeTransactionalCommand createCompositeCommand(List<EObject> allSelectedObjects, View view, TransactionalEditingDomain editingDomain) {
		CompositeTransactionalCommand result = new CompositeTransactionalCommand(editingDomain, "Add Shortcuts");
		List<ViewDescriptor> goodDescriptors = new ArrayList<CreateViewRequest.ViewDescriptor>(allSelectedObjects.size());
		for (EObject next : allSelectedObjects) {
			CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(new EObjectAdapter(next), Node.class, null, myPreferencesHint);
			ICommand createCommand = new CreateCommand(editingDomain, viewDescriptor, view);
			if (createCommand.canExecute()) {
				result.add(createCommand);
				goodDescriptors.add(viewDescriptor);
			}
		}
		if (result.isEmpty()) {
			return null;
		}
		ICommand addDecoration = createShortcutDecorationCommand(view, editingDomain, goodDescriptors);
		if (addDecoration != null) {
			result.add(addDecoration);
		}
		return result;
	}

	private DropObjectsRequest createDragDropRequest(List<EObject> allSelectedObjects, Point d2dCursorBeforeDialog) {
		DropObjectsRequest req = new DropObjectsRequest();
		req.setObjects(allSelectedObjects);
		req.setAllowedDetail(DND.DROP_COPY);
		req.setRequiredDetail(DND.DROP_COPY);
		req.setLocation(d2dCursorBeforeDialog);
		return req;
	}

	private Point getLastClickPosition(Shell shell, ExecutionEvent event) {
		Point fromSourceProvider = (Point) HandlerUtil.getVariable(event, LastClickPositionProvider.SOURCE_LAST_CLICK);
		if (fromSourceProvider != null) {
			return fromSourceProvider;
		}
		return new Point(0, 0);
	}
}
