//------------------------------------------------------------------------------
// 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.ui.dialogs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.common.ui.util.MsgDialog;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.TransientGroupItemProvider;
import org.eclipse.epf.library.edit.category.StandardCategoriesItemProvider;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand.MoveOperation;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;


/**
 * Dialog for moving MethodElement within MethodLibrary.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MoveDialog extends Dialog implements ISelectionChangedListener {

	private TreeViewer treeViewer;

	private Collection elements;

	// private IStructuredSelection selection;

	private boolean lockedUI = false;

	// The progress monitor
	private ProgressMonitorPart progressMonitorPart;

	private EditingDomain editingDomain;

	private Object destination;

	private Cursor waitCursor;

	private boolean moving;

	public MoveDialog(Shell parentShell, Collection elementsToMove,
			EditingDomain editingDomain) {
		super(parentShell);
		this.editingDomain = editingDomain;

		// filter out the predefined elements to prevent them from getting moved
		//
		elements = new ArrayList();
		for (Iterator iter = elementsToMove.iterator(); iter.hasNext();) {
			Object element = iter.next();
			Object e = TngUtil.unwrap(element);
			if (e instanceof MethodElement
					&& TngUtil.isPredefined((MethodElement) e)) {
				continue;
			}
			elements.add(element);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);

		GridLayout layout = (GridLayout) composite.getLayout();
		layout.marginWidth = 10;
		layout.marginHeight = 10;

		Label label = new Label(composite, SWT.NONE);
		label.setText(AuthoringUIResources.MoveDialog_destination_text); 
		GridData layoutData = new GridData(SWT.BEGINNING);
		label.setLayoutData(layoutData);

		treeViewer = new TreeViewer(composite, SWT.SINGLE | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.BORDER);
		AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE
				.getNavigatorView_ComposedAdapterFactory();
		treeViewer.setLabelProvider(new AdapterFactoryLabelProvider(
				adapterFactory));
		treeViewer.setContentProvider(new AdapterFactoryContentProvider(
				adapterFactory));
		treeViewer.addSelectionChangedListener(this);
		// treeViewer.addDoubleClickListener(this);

		GridData spec = new GridData(GridData.FILL_BOTH);
		{
			spec.widthHint = 300;
			spec.heightHint = 300;
			treeViewer.getControl().setLayoutData(spec);
		}

		treeViewer.setInput(LibraryService.getInstance().getCurrentMethodLibrary());

		// Insert a progress monitor
		GridLayout pmlayout = new GridLayout();
		pmlayout.numColumns = 1;
		progressMonitorPart = createProgressMonitorPart(composite, pmlayout);
		progressMonitorPart
				.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		progressMonitorPart.setVisible(false);

		waitCursor = parent.getShell().getDisplay().getSystemCursor(
				SWT.CURSOR_WAIT);

		return composite;
	}

	protected ProgressMonitorPart createProgressMonitorPart(
			Composite composite, GridLayout pmlayout) {
		return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
			String currentTask = null;

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.wizard.ProgressMonitorPart#setBlocked(org.eclipse.core.runtime.IStatus)
			 */
			public void setBlocked(IStatus reason) {
				super.setBlocked(reason);
				if (!lockedUI)// Do not show blocked if we are locking the UI
					getBlockedHandler().showBlocked(getShell(), this, reason,
							currentTask);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.wizard.ProgressMonitorPart#clearBlocked()
			 */
			public void clearBlocked() {
				super.clearBlocked();
				if (!lockedUI)// Do not vlear if we never set it
					getBlockedHandler().clearBlocked();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.wizard.ProgressMonitorPart#beginTask(java.lang.String,
			 *      int)
			 */
			public void beginTask(String name, int totalWork) {
				super.beginTask(name, totalWork);
				currentTask = name;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.wizard.ProgressMonitorPart#setTaskName(java.lang.String)
			 */
			public void setTaskName(String name) {
				super.setTaskName(name);
				currentTask = name;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.wizard.ProgressMonitorPart#subTask(java.lang.String)
			 */
			public void subTask(String name) {
				super.subTask(name);
				// If we haven't got anything yet use this value for more
				// context
				if (currentTask == null)
					currentTask = name;
			}
		};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(AuthoringUIResources.MoveDialog_move_text); 
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		destination = TngUtil.unwrap(((IStructuredSelection) event
				.getSelection()).getFirstElement());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
	 */
	protected void okPressed() {
		if (doMove()) {
			super.okPressed();
		}
	}

	private boolean isValidDestination() {
		// preventing moving elements to category
		//
		if (destination instanceof ContentCategory) {
			return false;
		}

		// do not allow moving into Standard Categories
		if (destination instanceof StandardCategoriesItemProvider) {
			return false;
		}

		// check containers for compatible types will not work if we want to move a sub-artifact
		// to a content package
		//
		
//		// do not allow move if destination is not the same type as every
//		// elements' eContainer
//		Object realDest = destination;
//		if (destination instanceof TransientContentPackageItemProvider) {
//			realDest = ((TransientContentPackageItemProvider) destination)
//					.getTarget();
//		}
//		if (destination instanceof TransientGroupItemProvider) {
//			realDest = ((TransientGroupItemProvider) destination).getTarget();
//		}		
//		try {
//			for (Iterator iter = elements.iterator(); iter.hasNext();) {
//				Object e = iter.next();
//				if (e instanceof EObject) {
//					if (!realDest.getClass().isInstance(
//							((EObject) e).eContainer()))
//						return false;
//				}
//			}
//		} catch (Exception ex) {
//			AuthoringUIPlugin.getDefault().getLogger().logError(ex);
//			return false;
//		}
		
		//Do not allow moving into a destination which is 
		//locked through extended locker.
		if(ViewHelper.isExtendedLocked(destination)){
			return false;
		}	
		if (DependencyChecker.newCheck) {
			if (destination instanceof VariabilityElement) {
				if (! DependencyChecker.checkCircularForMovingVariabilityElement
						((VariabilityElement) destination, elements)) {
					return false;
				}
			}			
		}
		// Sub Artifact circular check code
		else if(destination instanceof Artifact){
			return DependencyChecker.checkCircularForArtifacts((Artifact)destination, 
					elements);
		}		
		
		Command addCommand = AddCommand.create(editingDomain, destination,
				null, elements);
		boolean result;
		try {
			result = addCommand.canExecute();
		}
		finally {
			addCommand.dispose();
		}
		if (!result) {
			return false;
		}

		if (destination instanceof TransientGroupItemProvider) {
			destination = ((TransientGroupItemProvider) destination)
					.getTarget();
		}

		// IStatus status = UserInteractionHelper.checkModify((EObject)
		// destination, getShell());
		// if (status.isOK()) {
		// return true;
		// }
		// else {
		// AuthoringUIPlugin.getDefault().getMsgDialog().display(
		// AuthoringUIResources.getString("AuthoringUIPlugin.moveDialog.title"),
		// //$NON-NLS-1$
		// status);
		// return false;
		// }

		return true;
	}

	/**
	 * @return
	 */
	private boolean doMove() {
		if (destination == null) {
			String title = AuthoringUIResources.errorDialog_title; 
			String problem = AuthoringUIResources.MoveDialog_nomove_destination_problem_msg; 
			String msg = AuthoringUIResources.MoveDialog_selectdestination_text; 
			MsgDialog dialog = AuthoringUIPlugin.getDefault().getMsgDialog();
			dialog.displayError(title, problem, msg); 
			return false;
		}
		if (!isValidDestination()) {
			String title = AuthoringUIResources.errorDialog_title; 
			String problem = AuthoringUIResources.MoveDialog_invalid_move_destination_problem_msg; 
			String msg = AuthoringUIResources.MoveDialog_validdestination_text; 
			MsgDialog dialog = AuthoringUIPlugin.getDefault().getMsgDialog();
			dialog.displayError(title, problem, msg); 
			return false;
		} else {
			IStatus status = UserInteractionHelper.checkModify(
					(EObject) destination, getShell());
			if (!status.isOK()) {
				String title = AuthoringUIResources.errorDialog_title; 
				String msg = AuthoringUIResources.MoveDialog_cannotModifyDestination; 
				MsgDialog dialog = AuthoringUIPlugin.getDefault()
						.getMsgDialog();
				dialog.displayError(title, msg, status); 
				return false;
			}
		}

		moving = true;
		final Shell shell = getShell();
		shell.setCursor(waitCursor);

		getButton(IDialogConstants.OK_ID).setEnabled(false);
		getButton(IDialogConstants.CANCEL_ID).setEnabled(false);
		treeViewer.getControl().setEnabled(false);

		progressMonitorPart.setVisible(true);
		progressMonitorPart
				.beginTask(
						AuthoringUIResources.MoveDialog_moving_text, IProgressMonitor.UNKNOWN); 
		MoveOperation moveOp = null;
		try {
			// create command
			//
			Command command = AddCommand.create(editingDomain, destination,
					null, elements);

			moveOp = new MoveOperation(command, progressMonitorPart, shell);
			moveOp.run();
		} finally {
			moving = false;
			progressMonitorPart.done();

			// clear cursor
			if (shell != null && !shell.isDisposed()) {
				shell.setCursor(null);
			}
		}

		if (moveOp != null) {
			IStatus status = moveOp.getStatus();
			if (!status.isOK()) {
				String title = AuthoringUIResources.dialogs_MoveDialog_errorTitle; 
				String message = AuthoringUIResources.dialogs_MoveDialog_errorMessage; 
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						title, message, status);
				if (moveOp.reloadNeeded()) {
					ViewHelper.reloadCurrentLibrary(shell, null);
				}
			}
		}

		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#close()
	 */
	public boolean close() {
		if (moving)
			return false;
		return super.close();
	}

}
