/*******************************************************************************
 * Copyright (c) 2002 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 * IBM - Initial API and implementation
 ******************************************************************************/

package org.eclipse.team.internal.ccvs.ui;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.team.IMoveDeleteHook;
import org.eclipse.core.resources.team.IResourceTree;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
import org.eclipse.team.internal.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.ICVSResource;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.ui.IWorkbenchWindow;

public class CVSMoveDeleteHook implements IMoveDeleteHook {

	public interface IRunnableWithShell {
		public void run(Shell shell);
	}

	private void showDialog(final IRunnableWithShell runnable) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				IWorkbenchWindow window = CVSUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow();
				if (window != null) {
					runnable.run(window.getShell());
				} else {
					Display display = Display.getCurrent();
					Shell shell = new Shell(display);
					runnable.run(shell);
				}
			}
		});
	}
	
	/*
	 * Delete the file and return true if an outgoing deletion will result
	 * and the parent folder needs to remain 
	 */
	private boolean makeFileOutgoingDeletion(IResourceTree tree, IFile source, IFile destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
		// Delete or move the file
		if (destination == null) {
			tree.standardDeleteFile(source, updateFlags, monitor);
		} else {
			tree.standardMoveFile(source, destination, updateFlags, monitor);
		}
		// Indicate whether the parent folder must remain for outgoing deletions
		ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(source);
		boolean mustRemain;
		try {
			mustRemain = (cvsFile.isManaged() && ! cvsFile.getSyncInfo().isAdded());
		} catch (CVSException e) {
			tree.failed(e.getStatus());
			mustRemain = true;
		}
		return mustRemain;
	}
	
	/*
	 * Delete the files contained in the folder structure rooted at source.
	 * Return true if at least one file has been marked as an outgoing deletion and the parent folder must remain
	 */
	private boolean makeFolderOutgoingDeletion(IResourceTree tree, IFolder source, IFolder destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
		boolean fileFound = false;

		// Create the destination for a move
		if (destination != null && ! destination.exists()) {
			destination.create(false, true, monitor);
		}
		
		// Move or delete the children
		IResource[] members = source.members();
		for (int i = 0; i < members.length; i++) {
			IResource child = members[i];
			if (child.getType() == IResource.FOLDER) {
				// Determine the corresponding destination folder
				IFolder destFolder = null;
				if (destination != null) {
					destFolder = destination.getFolder(child.getFullPath().removeFirstSegments(source.getFullPath().segmentCount()));
				}
				
				// Try to delete/move the child
				if (makeFolderOutgoingDeletion(tree, (IFolder)child, destFolder, updateFlags, monitor)) {
					fileFound = true;
					// XXX Below line commented out for now
					// tree.failed(new CVSStatus(IStatus.WARNING, CVSStatus.FOLDER_NEEDED_FOR_FILE_DELETIONS, Policy.bind("CVSMoveDeleteHook.folderDeletionFailure", resource.getFullPath().toString()))); //$NON-NLS-1$
				}
			} else if (child.getType() == IResource.FILE) {
				IFile destFile = null;
				if (destination != null) {
					destFile = destination.getFile(child.getFullPath().removeFirstSegments(source.getFullPath().segmentCount()));
				}
				fileFound = makeFileOutgoingDeletion(tree, (IFile)child, destFile, updateFlags, monitor);
			}
		}

		// If there were no files, delete the folder
		if ( ! fileFound) {
			try {
				ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(source);
				// We we need to check if the folder already has outgoing deletions
				ICVSResource[] files = folder.members(ICVSFolder.FILE_MEMBERS);
				for (int i = 0; i < files.length; i++) {
					ICVSFile cvsFile = (ICVSFile)files[i];
					if (cvsFile.isManaged() && ! cvsFile.getSyncInfo().isAdded()) {
						fileFound = true;
						break;
					}		
				}
				// If there is still no file, we can delete the folder
				if ( ! fileFound) {
					tree.standardDeleteFolder(source, updateFlags, monitor);
					folder.unmanage(null);
				}
			} catch (CVSException e) {
				tree.failed(e.getStatus());
			}
		}
		return fileFound;
	}
	
	private boolean checkForTeamPrivate(final IResource resource) {
		if (resource.isTeamPrivateMember()) {
			showDialog(new IRunnableWithShell() {
				public void run(Shell shell) {
					ErrorDialog.openError(shell, Policy.bind("CVSMoveDeleteHook.Team_Private_Resource_1"), Policy.bind("CVSMoveDeleteHook.Deletion_of_team_private_resources_is_not_permitted_2", resource.getFullPath().toString()), null); //$NON-NLS-1$ //$NON-NLS-2$
				}
			});
			return true;
		} 
		return false;
	}
	
	private boolean deleteFile(
		final IResourceTree tree,
		final IFile source,
		final IFile destination,
		final int updateFlags,
		final String title,
		final String message,
		final IProgressMonitor monitor) {
		
		if (checkForTeamPrivate(source)) {
			return true;
		}
		
		final ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(source);
		ResourceSyncInfo info = null;
		try {
			info = cvsFile.getSyncInfo();
		} catch (CVSException e) {
		}
		if (info != null && ! info.isAdded()) {
			// prompt the user for choices: Mark as outgoing deletion or cancel
			final boolean[] performDelete = new boolean[] { ! CVSProviderPlugin.getPlugin().getPromptOnFileDelete()};
			if ( ! performDelete[0]){
				showDialog(new IRunnableWithShell() {
					public void run(Shell shell) {
						AvoidableMessageDialog dialog = new AvoidableMessageDialog(
							shell,
							title, 
							null,	// accept the default window icon
							message, 
							MessageDialog.QUESTION, 
							new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 
							0); 	// yes is the default
						performDelete[0] = dialog.open() == 0;
						if (performDelete[0]) {
							// The CVS core delta listener will mark the file as an outgoing deletion
							// so we just need to say that we didn't handle it. Core will delete the
							// file and the delta listener will do it's thing.
							CVSProviderPlugin.getPlugin().setPromptOnFileDelete( ! dialog.isDontShowAgain());
							CVSUIPlugin.getPlugin().getPreferenceStore().setValue(ICVSUIConstants.PREF_PROMPT_ON_FILE_DELETE, CVSProviderPlugin.getPlugin().getPromptOnFileDelete());
						}
					}
				});
			}
			if (performDelete[0]) {
				// Issue a delete for all child files
				// The CVS core delta listener will mark each file as an outgoing deletion
				// so we just need to delete each file and let the delta listener do its thing
				try {
					makeFileOutgoingDeletion(tree, source, destination, updateFlags, monitor);
				} catch (final CoreException e) {
					showDialog(new IRunnableWithShell() {
						public void run(Shell shell) {
							ErrorDialog.openError(shell, null, null, e.getStatus());
						}
					});
				}
			}
			return true;
		}
		return false;
	}
	
	private boolean deleteFolder(
		final IResourceTree tree,
		final IFolder source,
		final IFolder destination,
		final int updateFlags,
		final String title,
		final String message,
		final IProgressMonitor monitor) {
		
		if (checkForTeamPrivate(source)) {
			return true;
		}
		
		final ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(source);
		if (cvsFolder.isManaged()) {
			// prompt the user for choices: Mark as outgoing deletion or cancel
			final boolean[] performDelete = new boolean[] { ! CVSProviderPlugin.getPlugin().getPromptOnFolderDelete()};
			boolean dialogShown = false;
			if ( ! performDelete[0]) {
				dialogShown = true;
				showDialog(new IRunnableWithShell() {
					public void run(Shell shell) {
						AvoidableMessageDialog dialog = new AvoidableMessageDialog(
							shell,
							title, 
							null,	// accept the default window icon
							message, 
							MessageDialog.QUESTION, 
							new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 
							0); 	// yes is the default
						performDelete[0] = dialog.open() == 0;
						if (performDelete[0]) {
							CVSProviderPlugin.getPlugin().setPromptOnFolderDelete( ! dialog.isDontShowAgain());
							CVSUIPlugin.getPlugin().getPreferenceStore().setValue(ICVSUIConstants.PREF_PROMPT_ON_FOLDER_DELETE, CVSProviderPlugin.getPlugin().getPromptOnFolderDelete());
						}
					}
				});
			}
			if (performDelete[0]) {
				// Issue a delete for all child files
				// The CVS core delta listener will mark each file as an outgoing deletion
				// so we just need to delete each file and let the delta listener do its thing
				try {
					makeFolderOutgoingDeletion(tree, source, destination, updateFlags, monitor);
				} catch (final CoreException e) {
					showDialog(new IRunnableWithShell() {
						public void run(Shell shell) {
							ErrorDialog.openError(shell, null, null, e.getStatus());
						}
					});
				}
			}
			return true;
		}
		return false;
	}
	
	/**
	 * @see IMoveDeleteHook#deleteFile(IResourceTree, IFile, int, IProgressMonitor)
	 */
	public boolean deleteFile(
		final IResourceTree tree,
		final IFile file,
		int updateFlags,
		final IProgressMonitor monitor) {
		
		return deleteFile(tree, file, null, updateFlags, 
			Policy.bind("CVSMoveDeleteHook.deleteFileTitle"), //$NON-NLS-1$
			Policy.bind("CVSMoveDeleteHook.deleteFileMessage", file.getFullPath().toString()), //$NON-NLS-1$
			monitor);
	}

	/**
	 * @see IMoveDeleteHook#deleteFolder(IResourceTree, IFolder, int, IProgressMonitor)
	 */
	public boolean deleteFolder(
		final IResourceTree tree,
		final IFolder folder,
		final int updateFlags,
		final IProgressMonitor monitor) {
		
		return deleteFolder(tree, folder, null, updateFlags,
			Policy.bind("CVSMoveDeleteHook.deleteFolderTitle"), //$NON-NLS-1$
			Policy.bind("CVSMoveDeleteHook.deleteFolderMessage", folder.getFullPath().toString()), //$NON-NLS-1$
			monitor);
	}

	/**
	 * @see IMoveDeleteHook#deleteProject(IResourceTree, IProject, int, IProgressMonitor)
	 */
	public boolean deleteProject(
		IResourceTree tree,
		IProject project,
		int updateFlags,
		IProgressMonitor monitor) {
			
		// No special action needed
		return false;
	}

	/**
	 * @see IMoveDeleteHook#moveFile(IResourceTree, IFile, IFile, int, IProgressMonitor)
	 */
	public boolean moveFile(
		IResourceTree tree,
		IFile source,
		IFile destination,
		int updateFlags,
		IProgressMonitor monitor) {
			
		return deleteFile(tree, source, destination, updateFlags,
			Policy.bind("CVSMoveDeleteHook.moveFileTitle"), //$NON-NLS-1$
			Policy.bind("CVSMoveDeleteHook.moveFileMessage", source.getFullPath().toString()), //$NON-NLS-1$
			monitor);
	}

	/**
	 * @see IMoveDeleteHook#moveFolder(IResourceTree, IFolder, IFolder, int, IProgressMonitor)
	 */
	public boolean moveFolder(
		IResourceTree tree,
		IFolder source,
		IFolder destination,
		int updateFlags,
		IProgressMonitor monitor) {
			
		return deleteFolder(tree, source, destination, updateFlags,
			Policy.bind("CVSMoveDeleteHook.moveFolderTitle"), //$NON-NLS-1$
			Policy.bind("CVSMoveDeleteHook.moveFolderMessage", source.getFullPath().toString()), //$NON-NLS-1$
			monitor);
	}

	/**
	 * @see IMoveDeleteHook#moveProject(IResourceTree, IProject, IProjectDescription, int, IProgressMonitor)
	 */
	public boolean moveProject(
		IResourceTree tree,
		IProject source,
		IProjectDescription description,
		int updateFlags,
		IProgressMonitor monitor) {
			
		// No special action
		return false;
	}
}
