/*******************************************************************************
 * 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.pagedesigner.ui.common;

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

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.common.IFileFolderConstants;
import org.eclipse.jst.pagedesigner.common.logging.Logger;
import org.eclipse.jst.pagedesigner.common.utils.WebrootUtil;
import org.eclipse.jst.pagedesigner.editors.pagedesigner.PageDesignerResources;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * This dialog shows IFile type resources within a IProject domain for
 * selection. The client can prvide the suffixs of files to filter when
 * candidates are shown on the tree,
 * 
 * @author mengbo
 */
public class CommonResourceDialog extends TreeViewerSelectionDialog {
	private static final int WEBROOT_FOLDER_DEPTH = 2;

	// CommonResourceDialog.statusMessage = Please select an image file
	private static final String STATUS_MESSAGE = PageDesignerResources
			.getInstance().getString("CommonResourceDialog.statusMessage"); //$NON-NLS-1$

	private String _suffixs[] = null;

	private CommonResourceFilter _filter;

	/** Create the logger for this class */
	private static Logger _log = PDPlugin.getLogger(CommonResourceDialog.class);

	// The content provider
	class ProjectFileDialogContentProvider implements ITreeContentProvider {
		/**
		 * The visual part that is using this content provider is about to be
		 * disposed. Deallocate all allocated SWT resources.
		 */
		public void dispose() {
		}

		/**
		 * @see ITreeContentProvider#getChildren
		 */
		public Object[] getChildren(Object element) {
			if (element instanceof IWorkspace) {
				IWorkspaceRoot root = ((IWorkspace) element).getRoot();
				IProject[] projects = root.getProjects();
				return projects;
			} else if (element instanceof IContainer) {
				if (element instanceof IProject) {
					IContainer container = (IContainer) element;
					if (container.isAccessible()) {
						try {
							IResource[] members = container.members();
							return members;
						} catch (CoreException e) {
							// "Error.CommonResourceDialog.0.1" = "Error in
							// project memeber querying"
							// "Error.CommonResourceDialog.0.2" = "Please refer
							// to the log for details"
							PDPlugin
									.getAlerts()
									.error(
											"Error.CommonResourceDialog.0.1", "Error.CommonResourceDialog.0.2"); //$NON-NLS-1$ //$NON-NLS-2$
							// Error.ProjectFileDialogContentProvider.0 = Core
							// error, you may need to restart the application
							_log
									.error(
											"Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
						}
					}
				} else if (element instanceof IFolder) {
					// Process the folder container
					IContainer container = (IContainer) element;
					if (container.isAccessible()) {
						try {
							// Filter all the files under the project and only
							// show
							// the folder in the container selection dialog
							List children = new ArrayList();
							IResource[] members = container.members();
							for (int i = 0; i < members.length; i++) {
								if (!members[i].getName().equals(
										IFileFolderConstants.FOLDER_WEBINF)
										&& !members[i]
												.getName()
												.equals(
														IFileFolderConstants.FOLDER_METAINF)) {
									children.add(members[i]);
								}
							}
							return children.toArray();
						} catch (CoreException e) {
							// "Error.CommonResourceDialog.0.1" = "Error in
							// project memeber querying"
							// "Error.CommonResourceDialog.0.2" = "Please refer
							// to the log for details"
							PDPlugin
									.getAlerts()
									.error(
											"Error.CommonResourceDialog.0.1", "Error.CommonResourceDialog.0.2"); //$NON-NLS-1$ //$NON-NLS-2$
							// Error.ProjectFileDialogContentProvider.0 = core
							// error, you may need to restart the application
							_log
									.error(
											"Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
						}
					}
				}
			}
			return new Object[0];
		}

		/**
		 * @see ITreeContentProvider#getElements
		 */
		public Object[] getElements(Object element) {
			return getChildren(element);
		}

		/**
		 * @see ITreeContentProvider#getParent
		 */
		public Object getParent(Object element) {
			if (element instanceof IResource) {
				return ((IResource) element).getParent();
			}
			return null;
		}

		/**
		 * @see ITreeContentProvider#hasChildren
		 */
		public boolean hasChildren(Object element) {
			return getChildren(element).length > 0;
		}

		/**
		 * @see IContentProvider#inputChanged
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

	}

	// The default resource filter
	class CommonResourceFilter extends ViewerFilter {
		private String _suffixs[] = { IFileFolderConstants.EXT_PROPERTIES };

		Logger _log = PDPlugin.getLogger(CommonResourceFilter.class);

		private IProject _project;

		/**
		 * @return Returns the _suffixs.
		 */
		public String[] getSuffixs() {
			return _suffixs;
		}

		/**
		 * @param _suffixs
		 *            The _suffixs to set.
		 */
		public void setSuffixs(String[] _suffixs) {
			this._suffixs = _suffixs;
		}

		public CommonResourceFilter(IProject project) {
			_project = project;
		}

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

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer,
		 *      java.lang.Object, java.lang.Object)
		 */
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			// TODO: This logic can be improved by add caching mechanism
			if (element instanceof IWorkspace) {
				return true;
			} else if (element instanceof IFile) {
				if (Arrays.asList(_suffixs).contains(
						((IFile) element).getFileExtension())) {
					return true;
				}
			} else if (element instanceof IContainer) {
				if (!((IContainer) element).isAccessible()) {
					return false;
				}
				if (element instanceof IProject) {
					IProject container = (IProject) element;
					if (isWebAppProject(container)
							&& this.isSameProject(container, _project)) {
						return true;
					} else {
						return false;
					}
				} else if (element instanceof IFolder) {
					IContainer container = (IContainer) element;
					try {
						if (container.getName().equals(
								IFileFolderConstants.FOLDER_WEBINF)
								|| container.getName().equals(
										IFileFolderConstants.FOLDER_METAINF)) {
							return false;
						}
						IResource[] members = container.members();
						for (int i = 0; i < members.length; i++) {
							{
								if (select(viewer, members[i].getParent(),
										members[i])) {
									return true;
								}
							}
						}
					} catch (CoreException e) {
						// "Error.ImgFileFilter.0" = "Error in filtering the
						// tree", "Error.ImgFileFilter.2 = ""CoreException is
						// thrown, please refer to error log for details"
						// "Error.ProjectFileDialogContentProvider.0" = core
						// error, show alert dialog to user.
						PDPlugin
								.getAlerts()
								.detailError(
										"Error.ImgFileFilter.0", "Error.ImgFileFilter.2"); //$NON-NLS-2$
						_log.error(
								"Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
						return false;
					}
				}
			}
			// we don't select any other types of resources.
			return false;
		}

		/**
		 * Determines if a project is a Web Application project by the presence
		 * of an associated Web Application Nature.
		 * 
		 * @return boolean - True, when project is a Web Application project
		 */
		private boolean isWebAppProject(IProject project) {
			return WebrootUtil.isValidWebProject(project);
		}

		private boolean isSameProject(IProject orig, IProject dst) {
			String currentProjectName = ((IProject) orig).getFullPath()
					.toString().trim();
			String projectName = dst.getFullPath().toString().trim();
			return projectName.equalsIgnoreCase(currentProjectName);
		}
	}

	/**
	 * This is a dialog for common resource selection, the resouce supported
	 * include IFolder, IProject, IFile, user can provide
	 * 
	 * @param parentShell
	 * @param project
	 */
	public CommonResourceDialog(Shell parentShell, IProject project) {
		super(parentShell, STATUS_MESSAGE);
		setContentProvider(new ProjectFileDialogContentProvider());
		setLabelProvider(WorkbenchLabelProvider
				.getDecoratingWorkbenchLabelProvider());
		_filter = new CommonResourceFilter(project);
		setFilter(_filter);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#findInputElement()
	 */
	protected Object findInputElement() {
		return ResourcesPlugin.getWorkspace();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#isValidSelection(java.lang.Object)
	 */
	protected boolean isValidSelection(Object selection) {
		if (getContainerFullPath(selection) == null) {
			return false;
		} else {
			int depth = getContainerFullPath(selection).segmentCount();
			// The location is within WEBROOT PATH?
			if ((selection instanceof IFile) && depth >= WEBROOT_FOLDER_DEPTH) {
				// Null means no filter is set
				if (_suffixs == null) {
					return true;
				}
				// The extension is supported?
				else if (_suffixs != null
						&& Arrays.asList(_suffixs).contains(
								((IFile) selection).getFileExtension())) {
					return true;
				}
			}
			// None of above conditions, invalid.
			return false;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.dialogs.SelectionDialog#getResult()
	 */
	public Object[] getResult() {
		Object[] objects = super.getResult();
		if (objects == null || objects.length == 0) {
			return null;
		}
		// Only one element is set by us.
		IPath returnValue = getWebRelatedPath(objects[0]);
		if (returnValue != null) {
			if (!(returnValue.toString().startsWith(
					IFileFolderConstants.PATH_SEPARATOR) || returnValue
					.toString().startsWith("\\"))) {
				Path tempPath = new Path(IFileFolderConstants.PATH_SEPARATOR
						+ returnValue.toString());
				returnValue = tempPath;
			}
		}
		return new Object[] { returnValue };
	}

	public IPath getContainerFullPath(Object _selectedElement) {
		if (_selectedElement == null) {
			return null;
		} else if (_selectedElement instanceof IContainer) {
			return ((IContainer) _selectedElement).getFullPath();
		} else if (_selectedElement instanceof IFile) {
			return ((IFile) _selectedElement).getFullPath();
		}
		return null;
	}

	public IPath getWebRelatedPath(Object _selectedElement) {
		IPath result = null;
		if (_selectedElement == null) {
			return null;
		} else if (_selectedElement instanceof IContainer) {
			result = ((IContainer) _selectedElement).getFullPath();
		} else if (_selectedElement instanceof IFile) {
			result = ((IFile) _selectedElement).getFullPath();
		}
		if (result != null) {
			if (result.segmentCount() > 2) {
				result = result.removeFirstSegments(2);
			}
		}
		return result;
	}

	/**
	 * @param _suffixs
	 *            The _suffixs to set.
	 */
	public void setSuffixs(String[] suffixs) {
		this._suffixs = suffixs;
		_filter.setSuffixs(suffixs);
	}
}
