/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common.ui.internal.dialogfield;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaElementComparator;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.jsf.common.ui.JSFUICommonPlugin;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;

/**
 * This class provides a source folder selection DialogFiled. There are two
 * conditions: 1. If you set the IProject instance, the source folder selection
 * will only be limited in the specified project 2. If you set null, the source
 * folder selection is allowed in all workspaces
 * 
 * 
 * @author mengbo
 * @version 1.5
 */
public class SourceFolderButtonDialogField extends StringButtonDialogField {
	/** Create the logger for this class */
	private static Logger _log = JSFUICommonPlugin
			.getLogger(SourceFolderButtonDialogField.class);

	/**
	 * package fragment root corresponding to the input type (can be null)
	 */
	private IPackageFragmentRoot _fCurrRoot;

	private IProject _project;

	/**
	 * @param project 
	 */
	public SourceFolderButtonDialogField(IProject project) {
		super(null);

		_project = project;

		setLabelText(DialogFieldResources.getInstance().getString(
				"SourceFolderButtonDialogField.container.label")); //$NON-NLS-1$

		setButtonLabel(DialogFieldResources.getInstance().getString(
				"SourceFolderButtonDialogField.container.button")); //$NON-NLS-1$

		setStringButtonAdapter(new IStringButtonAdapter() {
			public void changeControlPressed(DialogField field) {
				containerChangeControlPressed(field);
			}

		});
	}

	/**
	 * @return Returns the project.
	 */
	public IProject getProject() {
		return _project;
	}

	/**
	 * @param project
	 *            The project to set.
	 */
	public void setProject(IProject project) {
		this._project = project;
	}

	/**
	 * @param field
	 */
	protected void containerChangeControlPressed(DialogField field) {
		// take the current jproject as init element of the dialog
		IPackageFragmentRoot root = getPackageFragmentRoot();
		root = chooseSourceContainer(root);
		if (root != null) {
			setPackageFragmentRoot(root, true);
		}
	}

	/**
	 * Sets the current source folder (model and text field) to the given
	 * package fragment root.
	 * 
	 * @param root
	 *            The new root.
	 * @param canBeModified
	 *            if <code>false</code> the source folder field can not be
	 *            changed by the user. If <code>true</code> the field is
	 *            editable
	 */
	public void setPackageFragmentRoot(IPackageFragmentRoot root,
			boolean canBeModified) {
		_fCurrRoot = root;
		String str = (root == null) ? "" : root.getPath().makeRelative().toString(); //$NON-NLS-1$
		setText(str);
		setEnabled(canBeModified);
	}

	/**
	 * Returns the <code>IPackageFragmentRoot</code> that corresponds to the
	 * current value of the source folder field.
	 * 
	 * @return the IPackageFragmentRoot or <code>null</code> if the current
	 *         source folder value is not a valid package fragment root
	 * 
	 */
	public IPackageFragmentRoot getPackageFragmentRoot() {
		return _fCurrRoot;
	}

	/**
	 * Returns the current text of source folder text field.
	 * 
	 * @return the text of the source folder text field
	 */
	public String getPackageFragmentRootText() {
		return getText();
	}

	/**
	 * choose source container dialog
	 * 
	 * @param initElement
	 * @return
	 */
	private IPackageFragmentRoot chooseSourceContainer(IJavaElement initElement) {
		Class[] acceptedClasses = new Class[] { IPackageFragmentRoot.class,
				IJavaProject.class, };

		TypedElementSelectionValidator validator = new TypedElementSelectionValidator(
				acceptedClasses, false) {
            // TODO: never used
//			public boolean isSelectedValid(Object element) {
//				try {
//					if (element instanceof IJavaProject) {
//						IJavaProject jproject = (IJavaProject) element;
//						IPath path = jproject.getProject().getFullPath();
//						return (jproject.findPackageFragmentRoot(path) != null);
//					} else if (element instanceof IPackageFragmentRoot) {
//						return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
//					}
//					return true;
//				} catch (JavaModelException e) {
//					_log.error("JavaModelException"); // just log, no ui in
//					// validation
//				}
//				return false;
//			}
		};

		acceptedClasses = new Class[] { IJavaModel.class,
				IPackageFragmentRoot.class, IJavaProject.class, };
		ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
			public boolean select(Viewer viewer, Object parent, Object element) {
				if (element instanceof IPackageFragmentRoot) {
					try {
						return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
					} catch (JavaModelException e) {
						_log.error(e); // just log, no ui
						// in validation
						return false;
					}
				}
				return super.select(viewer, parent, element);
			}
		};

		StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider();
		ILabelProvider labelProvider = new JavaElementLabelProvider(
				JavaElementLabelProvider.SHOW_DEFAULT);
		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
				getShell(), labelProvider, provider);
		dialog.setValidator(validator);
		dialog.setComparator(new JavaElementComparator());
		// HibernateWizardPage.ChooseSourceContainerDialog.Title = Folder
		// Selection
		dialog
				.setTitle(DialogFieldResources
						.getInstance()
						.getString(
								"SourceFolderButtonDialogField.ChooseSourceContainerDialog.Title")); //$NON-NLS-1$
		// HibernateWizardPage.ChooseSourceContainerDialog.Description = Choose
		// a folder:
		dialog
				.setMessage(DialogFieldResources
						.getInstance()
						.getString(
								"SourceFolderButtonDialogField.ChooseSourceContainerDialog.Description")); //$NON-NLS-1$
		dialog.addFilter(filter);
		if (_project != null) {
			dialog.setInput(JavaCore.create(_project));
		} else {
			dialog.setInput(JavaCore.create(ResourcesPlugin.getWorkspace()
					.getRoot()));
		}
		dialog.setInitialSelection(initElement);

		if (dialog.open() == Window.OK) {
			Object element = dialog.getFirstResult();
			if (element instanceof IJavaProject) {
				IJavaProject jproject = (IJavaProject) element;
				return jproject.getPackageFragmentRoot(jproject.getProject());
			} else if (element instanceof IPackageFragmentRoot) {
				return (IPackageFragmentRoot) element;
			}
			return null;
		}
		return null;
	}

	/**
	 * This method updates the model and returns an error status. The underlying
	 * model is only valid if the returned status is OK.
	 * 
	 * @return the model's error status
	 */
	public IStatus getChangedStatus() {
		StatusInfo status = new StatusInfo();

		_fCurrRoot = null;
		String str = getPackageFragmentRootText();
		if (str.length() == 0) {
			// SourceFolderButtonDialogField.error.EnterContainerName = Folder
			// name is empty.
			status.setError(DialogFieldResources.getInstance().getString(
					"SourceFolderButtonDialogField.error.EnterContainerName")); //$NON-NLS-1$
			return status;
		}
		IPath path = new Path(str);
		IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(
				path);
		if (res != null) {
			int resType = res.getType();
			if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
				IProject proj = res.getProject();
				if (!proj.isOpen()) {
					status
							.setError(DialogFieldResources
									.getInstance()
									.getString(
											"SourceFolderButtonDialogField.error.ProjectClosed", proj.getFullPath().toString())); //$NON-NLS-1$
					return status;
				}
				if (_project != null && proj != _project) {
					// HibernateWizardPage.error.NotSameProject = The project
					// should be \''{0}\''.
					status
							.setError(DialogFieldResources
									.getInstance()
									.getString(
											"SourceFolderButtonDialogField.error.NotSameProject", _project.getName())); //$NON-NLS-1$
					return status;
				}
				IJavaProject jproject = JavaCore.create(proj);
				_fCurrRoot = jproject.getPackageFragmentRoot(res);
				if (res.exists()) {
					try {
						if (!proj.hasNature(JavaCore.NATURE_ID)) {
							if (resType == IResource.PROJECT) {
								status
										.setError(DialogFieldResources
												.getInstance()
												.getString(
														"SourceFolderButtonDialogField.warning.NotAJavaProject", proj.getName())); //$NON-NLS-1$
							} else {
								status
										.setWarning(DialogFieldResources
												.getInstance()
												.getString(
														"SourceFolderButtonDialogField.warning.NotInAJavaProject", proj.getName())); //$NON-NLS-1$
							}
							return status;
						}
					} catch (CoreException e) {
						status
								.setWarning(DialogFieldResources
										.getInstance()
										.getString(
												"SourceFolderButtonDialogField.warning.NotAJavaProject", proj.getName())); //$NON-NLS-1$
					}
					if (!jproject.isOnClasspath(_fCurrRoot)) {
						status
								.setWarning(DialogFieldResources
										.getInstance()
										.getString(
												"SourceFolderButtonDialogField.warning.NotOnClassPath", str)); //$NON-NLS-1$
					}
					if (_fCurrRoot.isArchive()) {
						status
								.setError(DialogFieldResources
										.getInstance()
										.getString(
												"SourceFolderButtonDialogField.error.ContainerIsBinary", str)); //$NON-NLS-1$
						return status;
					}
				}
				return status;
			}
            status.setError(DialogFieldResources.getInstance().getString(
                    "SourceFolderButtonDialogField.error.NotAFolder", str)); //$NON-NLS-1$
            return status;
		}
        status
                 .setError(DialogFieldResources
                        .getInstance()
                        .getString(
                                "SourceFolderButtonDialogField.error.ContainerDoesNotExist", str)); //$NON-NLS-1$
        return status;
	}

}
