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

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.runtime.CoreException;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jst.jsf.common.ui.JSFUICommonPlugin;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.jsf.common.ui.internal.utils.WebrootUtil;
import org.eclipse.swt.SWT;
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.
 * 
 * The usage: Shell shell = new Shell(); IProject project = getProject();
 * CommonResourceDialog dlg = new CommonResourceDialog(shell, project);
 * dlg.setResourceDescription("image"); dlg.setSuffixs(new
 * String[]{"bmp","jpg","gif"}); if(dlg.open() == Window.OK) { IFile
 * selectedFile = (IFile)dlg.getResult()[0]; }
 * 
 * Note: In code above, what you get is an absolute resource path. You can use
 * <code>org.eclipse.wst.sse.core.util.PathHelper.convertToRelative(String input, String base)</code>
 * to convert a absolute resource path to a relative path based on one path.
 * 
 * @author mengbo
 */
public class CommonResourceDialog extends TreeViewerSelectionDialog {
	private static Logger _log = JSFUICommonPlugin
			.getLogger(CommonResourceDialog.class);

	// private static final String STATUS_MESSAGE_0 = CommonPlugin
	// .getResourceString("Dialog.CommonResourceDialog.StatusMessage0");
	// //$NON-NLS-1$

	private IProject _project = null;

	private String _suffixs[] = null;

	private CommonResourceFilter _filter = null;

	// The resource type resourceDescription, such as "image", "jsp", "java
	// class" etc.
	private String _resourceDescription = null;

	private IFolder _folder;

	// 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() {
            // nothing to dispose
		}

		/**
		 * @see ITreeContentProvider#getChildren
		 */
		public Object[] getChildren(Object element) {
			if (element instanceof Object[]) {
				return (Object[]) element;
			} else if (element instanceof IContainer) {
				IContainer container = (IContainer) element;
				if (container.isAccessible()) {
					try {
						return container.members();
					} catch (CoreException e) {
						_log.error(
								"Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
					}
				}

			}
			return new Object[0];
		}

		/**
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
		 */
		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 org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            // no viewer change support required
		}

	}

	// The default resource filter
	class CommonResourceFilter extends ViewerFilter {
		private String _suffixs[] = null;

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

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

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

		/*
		 * (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) {
			if (element instanceof IFile) {
				IFile file = (IFile) element;
				if (!WebrootUtil.isUnderWebContentFolder(file)) {
					return false;
				}
				if (isSuffixBlank()) {
					return true;
				}
				if (file.getFileExtension() != null) {
					if (Arrays.asList(_suffixs).contains(
							file.getFileExtension().toLowerCase())) {
						return true;
					}
				}
			} else if (element instanceof IContainer) {
				if (!((IContainer) element).isAccessible()) {
					return false;
				}
				if (element instanceof IProject) {
					return true;
				} else if (element instanceof IFolder) {
					IContainer container = (IContainer) element;
					try {
						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) {
						_log.error(
								"Error.ProjectFileDialogContentProvider.0", e); //$NON-NLS-1$
						return false;
					}
				}
			}
			return false;
		}

	}

	/**
	 * 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, int style) {
		super(parentShell, "", style);
		if (project == null) {
			throw new IllegalArgumentException(
					"Argument(project) cannot be null");
		}
		_project = project;
		setContentProvider(new ProjectFileDialogContentProvider());
		setLabelProvider(WorkbenchLabelProvider
				.getDecoratingWorkbenchLabelProvider());
		_filter = new CommonResourceFilter();
		setFilter(_filter);
		_project = project;
		setStatusMessage(getStatusMessage());
	}

	public CommonResourceDialog(Shell parentShell, IProject project) {
		this(parentShell, project, SWT.NONE);
	}

	/**
	 * This is a dialog for common resource selection, the resouce supported
	 * include IFolder, IProject, IFile, user can provide
	 * 
	 * @param parentShell
	 * @param folder 
	 * @param style 
	 */
	public CommonResourceDialog(Shell parentShell, IFolder folder, int style) {
		this(parentShell, (folder == null ? null : folder.getProject()), style);

		_folder = folder;

	}

	protected String getStatusMessage() {
		if (_resourceDescription == null) {
			return "";
		}
		return _resourceDescription;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#findInputElement()
	 */
	protected Object findInputElement() {
		if (_folder != null) {
			return new Object[] { _folder, };
		}
		return new Object[] { _project, };
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.ui.common.SelectionTreeViewerDialog#isValidSelection(java.lang.Object)
	 */
	protected boolean isValidSelection(Object selection) {
		if (selection instanceof Object[]) {
			for (int i = 0, n = ((Object[]) selection).length; i < n; i++) {
				if (isValidElement(((Object[]) selection)[i]) == true) {
					return true;
				}
			}
			return false;
		}
        return isValidElement(selection);
	}

	private boolean isValidElement(Object selection) {
		if ((selection instanceof IFile)) {
			// Null means no filter is set
			if (isSuffixBlank()) {
				return true;
			}
			// The extension is supported?
			else if (_suffixs != null
					&& Arrays.asList(_suffixs).contains(
							((IFile) selection).getFileExtension()
									.toLowerCase())) {
				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;
		}
		List list = new ArrayList();
		for (int i = 0; i < objects.length; i++) {
			if (objects[i] instanceof IFile) {
				list.add(objects[i]);
			}
		}
		return list.toArray();
	}

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

	private String[] convertTolowercase(String[] suffixs) {
		if (suffixs != null) {
			String[] newSuffixs = new String[suffixs.length];
			for (int i = 0; i < suffixs.length; i++) {
				newSuffixs[i] = suffixs[i].toLowerCase();
			}
			return newSuffixs;
		}
		return null;
	}

	public void setFilter(String[] suffixs, String sourceDescription) {
		setSuffixs(suffixs);
		setResourceDescription(sourceDescription);
	}

	/**
	 * @return Returns the sourceDescription.
	 */
	public String getResourceDescription() {
		return _resourceDescription;
	}

	/**
	 * @param sourceDescription
	 *            The sourceDescription to set.
	 */
	public void setResourceDescription(String sourceDescription) {
		this._resourceDescription = sourceDescription;
		setStatusMessage(getStatusMessage());
	}

	private boolean isSuffixBlank() {
		boolean isSuffixBlank = false;
		if (_suffixs == null) {
			isSuffixBlank = true;
		} else {
			int count = 0;
			for (int i = 0, size = _suffixs.length; i < size; i++) {
				if (_suffixs[i] != null && !"".equals(_suffixs[i])) {
					count++;
					break;
				}
			}
			if (count == 0) {
				isSuffixBlank = true;
			}
		}
		return isSuffixBlank;
	}
}
