/*******************************************************************************
 * Copyright (c) 2000, 2003 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.views.navigator;

import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.*;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.part.PluginDropAdapter;
import org.eclipse.ui.part.ResourceTransfer;

/**
 * Implements drop behaviour for drag and drop operations
 * that land on the resource navigator.
 * 
 * @since 2.0
 */
public class NavigatorDropAdapter
	extends PluginDropAdapter
	implements IOverwriteQuery {
		
	/**
	 * A flag indicating that overwrites should always occur.
	 */
	private boolean alwaysOverwrite = false;
	
	/**
	 * The last valid operation.
	 */
	private int lastValidOperation = DND.DROP_NONE;

	/**
	 * Constructs a new drop adapter.
	 */
	public NavigatorDropAdapter(StructuredViewer viewer) {
		super(viewer);
	}

	/*
	 * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
	 */
	public void dragEnter(DropTargetEvent event) {
		if (FileTransfer.getInstance().isSupportedType(event.currentDataType) &&
			event.detail == DND.DROP_DEFAULT) {
			// default to copy when dragging from outside Eclipse. Fixes bug 16308.
			event.detail = DND.DROP_COPY;
		}		
		super.dragEnter(event);
	}
	/**
	 * Returns an error status with the given info.
	 */
	private IStatus error(String message) {
		return error(message, null);
	}
	
	/**
	 * Returns an error status with the given info.
	 */
	private IStatus error(String message, Throwable exception) {
		return new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, exception);
	}

	/**
	 * Returns the actual target of the drop, given the resource
	 * under the mouse.  If the mouse target is a file, then the drop actually 
	 * occurs in its parent.  If the drop location is before or after the
	 * mouse target and feedback is enabled, the target is also the parent.
	 */
	private IContainer getActualTarget(IResource mouseTarget) {
		/* if cursor is before or after mouseTarget, set target to parent */
		if (getFeedbackEnabled()) {
			if (getCurrentLocation() == LOCATION_BEFORE
				|| getCurrentLocation() == LOCATION_AFTER) {
				return mouseTarget.getParent();
			}
		}
		/* if cursor is on a file, return the parent */
		if (mouseTarget.getType() == IResource.FILE) {
			return mouseTarget.getParent();
		}
		/* otherwise the mouseTarget is the real target */
		return (IContainer) mouseTarget;
	}

	
	/**
	 * Returns the display
	 */
	private Display getDisplay() {
		return getViewer().getControl().getDisplay();
	}
	/**
	 * Returns the resource selection from the LocalSelectionTransfer.
	 * 
	 * @return the resource selection from the LocalSelectionTransfer
	 */
	private IResource[] getSelectedResources() {
		IResource[] selectedResources = null;
		
		ISelection selection = LocalSelectionTransfer.getInstance().getSelection();
		if (selection instanceof IStructuredSelection) {
			List selectionList = ((IStructuredSelection) selection).toList();
			selectedResources = (IResource[]) selectionList.toArray(new IResource[selectionList.size()]);
		}
		return selectedResources;		
	}
	
	/**
	 * Returns the shell
	 */
	private Shell getShell() {
		return getViewer().getControl().getShell();
	}
	
	/**
	 * Returns an error status with the given info.
	 */
	private IStatus info(String message) {
		return new Status(IStatus.INFO, PlatformUI.PLUGIN_ID, 0, message, null);
	}
	
	/**
	 * Adds the given status to the list of problems.  Discards
	 * OK statuses.  If the status is a multi-status, only its children
	 * are added.
	 */
	private void mergeStatus(MultiStatus status, IStatus toMerge) {
		if (!toMerge.isOK()) {
			status.merge(toMerge);
		}
	}
	
	/**
	 * Returns an status indicating success.
	 */
	private IStatus ok() {
		return new Status(Status.OK, PlatformUI.PLUGIN_ID, 0, ResourceNavigatorMessages.getString("DropAdapter.ok"), null); //$NON-NLS-1$
	}
	
	/**
	 * Opens an error dialog if necessary.  Takes care of
	 * complex rules necessary for making the error dialog look nice.
	 */
	private void openError(IStatus status) {
		if (status == null)
			return;

		String genericTitle = ResourceNavigatorMessages.getString("DropAdapter.title"); //$NON-NLS-1$
		int codes = IStatus.ERROR | IStatus.WARNING;

		//simple case: one error, not a multistatus
		if (!status.isMultiStatus()) {
			ErrorDialog.openError(getShell(), genericTitle, null, status, codes);
			return;
		}

		//one error, single child of multistatus
		IStatus[] children = status.getChildren();
		if (children.length == 1) {
			ErrorDialog.openError(
				getShell(),
				status.getMessage(),
				null,
				children[0],
				codes);
			return;
		}
		//several problems
		ErrorDialog.openError(getShell(), genericTitle, null, status, codes);
	}
	
	/**
	 * Perform the drop.
	 * @see DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
	 */
	public boolean performDrop(final Object data) {
		alwaysOverwrite = false;
		if (getCurrentTarget() == null || data == null) {
			return false;
		}
		boolean result = false;
		IStatus status = null;
		IResource[] resources = null;
		TransferData currentTransfer = getCurrentTransfer();
		if (LocalSelectionTransfer.getInstance().isSupportedType(currentTransfer)) {
			resources = getSelectedResources();
		} else if (ResourceTransfer.getInstance().isSupportedType(currentTransfer)) {
			resources = (IResource[]) data;
		} else if (FileTransfer.getInstance().isSupportedType(currentTransfer)) {
			status = performFileDrop(data);
			result = status.isOK();
		} else {
			result = NavigatorDropAdapter.super.performDrop(data);
		}
		if (resources != null) {
			if (getCurrentOperation() == DND.DROP_COPY)
				status = performResourceCopy(getShell(), resources);
			else
				status = performResourceMove(resources);
		}
		openError(status);
		return result;
	}
	
	/**
	 * Performs a drop using the FileTransfer transfer type.
	 */
	private IStatus performFileDrop(Object data) {
		MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 0, ResourceNavigatorMessages.getString("DropAdapter.problemImporting"), null); //$NON-NLS-1$
		mergeStatus(problems, validateTarget(getCurrentTarget(), getCurrentTransfer()));

		final IContainer target = getActualTarget((IResource) getCurrentTarget());
		final String[] names = (String[]) data;
		// Run the import operation asynchronously. 
		// Otherwise the drag source (e.g., Windows Explorer) will be blocked 
		// while the operation executes. Fixes bug 16478.
		Display.getCurrent().asyncExec(new Runnable() {
			public void run() {
				getShell().forceActive();
				CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(getShell());
				operation.copyFiles(names, target);
			}
		});
		return problems;
	}

	/**
	 * Performs a resource copy
	 */
	private IStatus performResourceCopy(Shell shell, IResource[] sources) {
		MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1, ResourceNavigatorMessages.getString("DropAdapter.problemsMoving"), null); //$NON-NLS-1$
		mergeStatus(problems, validateTarget(getCurrentTarget(), getCurrentTransfer()));

		IContainer target = getActualTarget((IResource) getCurrentTarget());
		CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(shell);
		operation.copyResources(sources, target);
		
		return problems;
	}

	/**
	 * Performs a resource move
	 */
	private IStatus performResourceMove(IResource[] sources) {
		MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1, ResourceNavigatorMessages.getString("DropAdapter.problemsMoving"), null); //$NON-NLS-1$
		mergeStatus(problems, validateTarget(getCurrentTarget(), getCurrentTransfer()));

		IContainer target = getActualTarget((IResource) getCurrentTarget());
		ReadOnlyStateChecker checker = new ReadOnlyStateChecker(
			getShell(), 
			ResourceNavigatorMessages.getString("MoveResourceAction.title"),			//$NON-NLS-1$
			ResourceNavigatorMessages.getString("MoveResourceAction.checkMoveMessage"));//$NON-NLS-1$	
		sources = checker.checkReadOnlyResources(sources);
		MoveFilesAndFoldersOperation operation = new MoveFilesAndFoldersOperation(getShell());
		operation.copyResources(sources, target);
		
		return problems;
	}
	
	/*
	 * @see IOverwriteQuery#queryOverwrite(String)
	 */
	public String queryOverwrite(String pathString) {
		if (alwaysOverwrite)
			return ALL;

		final String returnCode[] = { CANCEL };
		final String msg = ResourceNavigatorMessages.format("DropAdapter.overwriteQuery", new Object[] { pathString }); //$NON-NLS-1$
		final String[] options =
			{
				IDialogConstants.YES_LABEL,
				IDialogConstants.YES_TO_ALL_LABEL,
				IDialogConstants.NO_LABEL,
				IDialogConstants.CANCEL_LABEL };
		getDisplay().syncExec(new Runnable() {
			public void run() {
				MessageDialog dialog = new MessageDialog(getShell(), ResourceNavigatorMessages.getString("DropAdapter.question"), null, msg, MessageDialog.QUESTION, options, 0); //$NON-NLS-1$
				dialog.open();
				int returnVal = dialog.getReturnCode();
				String[] returnCodes = { YES, ALL, NO, CANCEL };
				returnCode[0] = returnVal < 0 ? CANCEL : returnCodes[returnVal];
			}
		});
		if (returnCode[0] == ALL)
			alwaysOverwrite = true;
		return returnCode[0];
	}
	
	/**
	 * This method is used to notify the action that some aspect of
	 * the drop operation has changed.
	 */
	public boolean validateDrop(
		Object target,
		int dragOperation,
		TransferData transferType) {
		
		if (dragOperation != DND.DROP_NONE) {
			lastValidOperation = dragOperation;
		}
		if (FileTransfer.getInstance().isSupportedType(transferType) &&
			lastValidOperation != DND.DROP_COPY) {
			// only allow copying when dragging from outside Eclipse
			return false;
		}
		if (super.validateDrop(target, dragOperation, transferType)) {
			return true;
		}
		return validateTarget(target, transferType).isOK();
	}
	
	/**
	 * Ensures that the drop target meets certain criteria
	 */
	private IStatus validateTarget(Object target, TransferData transferType) {
		if (!(target instanceof IResource)) {
			return info(ResourceNavigatorMessages.getString("DropAdapter.targetMustBeResource")); //$NON-NLS-1$
		}
		IResource resource = (IResource) target;
		if (!resource.isAccessible()) {
			return error(ResourceNavigatorMessages.getString("DropAdapter.canNotDropIntoClosedProject")); //$NON-NLS-1$
		}
		IContainer destination = getActualTarget(resource);
		if (destination.getType() == IResource.ROOT) {
			return error(ResourceNavigatorMessages.getString("DropAdapter.resourcesCanNotBeSiblings")); //$NON-NLS-1$
		}
		String message = null;
		// drag within Eclipse?
		if (LocalSelectionTransfer.getInstance().isSupportedType(transferType)) {
			IResource[] selectedResources = getSelectedResources();
			
			if (selectedResources == null)
				message = ResourceNavigatorMessages.getString("DropAdapter.dropOperationErrorOther"); //$NON-NLS-1$
			else {
				CopyFilesAndFoldersOperation operation;
				if (lastValidOperation == DND.DROP_COPY) {
					operation = new CopyFilesAndFoldersOperation(getShell());
				}
				else {
					operation = new MoveFilesAndFoldersOperation(getShell());
				}
				message = operation.validateDestination(destination, selectedResources);
			}
		} // file import?
		else if (FileTransfer.getInstance().isSupportedType(transferType)) {
			String[] sourceNames = (String[]) FileTransfer.getInstance().nativeToJava(transferType);
			if (sourceNames == null) {
				// source names will be null on Linux. Use empty names to do destination validation.
				// Fixes bug 29778
				sourceNames = new String[0];
			}				
			CopyFilesAndFoldersOperation copyOperation = new CopyFilesAndFoldersOperation(getShell());
			message = copyOperation.validateImportDestination(destination, sourceNames);
		}		
		if (message != null) {
			return error(message);
		}
		return ok();
	}
}
