/*******************************************************************************
 * Copyright (c) 2001, 2004 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 API and implementation
 *******************************************************************************/
package org.eclipse.jem.internal.beaninfo.ui;
/*
 *  $RCSfile: BeaninfoEntrySearchpathDialog.java,v $
 *  $Revision: 1.5 $  $Date: 2005/02/15 23:02:54 $ 
 */

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.jdt.internal.ui.util.PixelConverter;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jem.internal.beaninfo.core.BeaninfoEntry;
import org.eclipse.jem.internal.beaninfo.core.SearchpathEntry;

/**
 * This dialog is used to display and modify the search path
 * within a BeaninfoEntry.
 * @version 	1.0
 * @author
 */
public class BeaninfoEntrySearchpathDialog extends Dialog {

	private class DialogAdapter implements IListAdapter {

		// -------- IListAdapter --------
		public void customButtonPressed(ListDialogField field, int index) {
			pageCustomButtonPressed(index);
		}

		public void selectionChanged(ListDialogField field) {
		}

		/**
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#doubleClicked(ListDialogField)
		 */
		public void doubleClicked(ListDialogField field) {
		}

	}

	protected BPBeaninfoListElement infoElement;
	protected IJavaProject jProject;
	protected ListDialogField listField;

	public BeaninfoEntrySearchpathDialog(
		Shell parentShell,
		BPBeaninfoListElement infoElement,
		IJavaProject jProject) {
		super(parentShell);

		this.infoElement = infoElement;
		this.jProject = jProject;

		DialogAdapter adapter = new DialogAdapter();

		String[] buttonLabels = new String[] {
			/* 0 */
			BeanInfoUIMessages.getString(BeanInfoUIMessages.BPB_SEARCHPATH_UP),
			/* 1 */
			BeanInfoUIMessages.getString(BeanInfoUIMessages.BPB_SEARCHPATH_DOWN),
			/* 2 */
			null,
			/* 3 */
			BeanInfoUIMessages.getString("SearchPathDialog.ChoosePackages"), //$NON-NLS-1$
			/* 4 */
			null,
			/* 5 */
			BeanInfoUIMessages.getString("SearchPathDialog.Remove") }; //$NON-NLS-1$

		listField = new ListDialogField(adapter, buttonLabels, new SearchPathListLabelProvider(jProject));
		listField.setLabelText(BeanInfoUIMessages.getString("SearchPathDialog.Desc.Label")); //$NON-NLS-1$
		listField.setUpButtonIndex(0);
		listField.setDownButtonIndex(1);
		listField.setRemoveButtonIndex(5);
	}

	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(
			MessageFormat.format(
				BeanInfoUIMessages.getString("SearchPathDialog.ModifySearchPaths"), //$NON-NLS-1$
				new Object[] { infoElement.getEntry().getPath().toString()}));
	}

	protected Control createDialogArea(Composite parent) {
		PixelConverter converter = new PixelConverter(parent);

		Composite composite = new Composite(parent, SWT.NONE);

		LayoutUtil.doDefaultLayout(
			composite,
			new DialogField[] { listField },
			true,
			SWT.DEFAULT,
			SWT.DEFAULT);
		int buttonBarWidth = converter.convertWidthInCharsToPixels(24);
		listField.setButtonsMinWidth(buttonBarWidth);

		updatePackagesList();

		return composite;
	}

	private void updatePackagesList() {
		if (infoElement.getEntry().getKind() == BeaninfoEntry.BIE_PLUGIN) {
			// We don't allow these to be updated. They should only be used through
			// registered mechanisms and we won't be showing them here normally.
			listField.setLabelText(BeanInfoUIMessages.getString("SearchPathDialog.NotEditable_INFO_")); //$NON-NLS-1$
			listField.setEnabled(false);
			return;
		}

		listField.setElements(Arrays.asList(infoElement.getSearchpaths()));
	}

	protected void pageCustomButtonPressed(int index) {
		if (index != 3)
			return;

		List elementsToAdd = choosePackages();

		if (elementsToAdd != null && !elementsToAdd.isEmpty()) {
			listField.addElements(elementsToAdd);
			listField.postSetSelection(new StructuredSelection(elementsToAdd));
		}
	}

	protected void okPressed() {
		if (listField.isEnabled()) {
			// If the field is not enabled, then there is no update to perform. We don't
			// want to accidentially wipe out the search paths in this case.

			// Override to put the list of elements back into the BPBeaninfoListElement
			// Until then they aren't actually updated.
			List paths = listField.getElements();
			infoElement.setSearchpaths(
				(BPSearchListElement[]) paths.toArray(new BPSearchListElement[paths.size()]));
		}
		super.okPressed();
	}

	/**
	 * Choose the packages that should be in the search path.
	 */
	private List choosePackages() {

		IPackageFragmentRoot[] roots = getBeaninfoRoots();
		List newPackageNames = new ArrayList();
		if (roots != null) {
			// It's within the workspace, so we can get the roots and packages.
			ISelectionStatusValidator validator = new PackagesWorkbookPage.ChoosePackagesSelectionValidator();

			// Show up to the package fragment, don't show any contents of it.
			Class[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IPackageFragment.class };
			Object[] rejectedFragments = getFilteredExistingEntries(roots);

			// Only show package fragments that have children (i.e. there classes in it, not interested
			// in intermediate ones that have no classes defined in them. Those are filtered out.
			TypedViewerFilter filter = new TypedViewerFilter(acceptedClasses, rejectedFragments) {
				public boolean select(Viewer viewer, Object parentElement, Object element) {
					if (super.select(viewer, parentElement, element)) {
						if (element instanceof IPackageFragment) {
							IPackageFragment pkg = (IPackageFragment) element;
							try {
								return pkg.hasChildren();
							} catch (JavaModelException e) {
							}
							return false;
						} else
							return true;
					}
					return false;
				}
			};

			ITreeContentProvider provider = new PackageOnlyContentProvider();

			ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
			ElementTreeSelectionDialog dialog =
				new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
			dialog.setTitle(BeanInfoUIMessages.getString(BeanInfoUIMessages.BPB_ADDSEARCHPATH_TITLE));

			dialog.setValidator(validator);
			dialog.setMessage(BeanInfoUIMessages.getString(BeanInfoUIMessages.BPB_ADDSEARCHPATH_DESC));
			dialog.addFilter(filter);
			dialog.setInput(Arrays.asList(getBeaninfoRoots()));

			if (dialog.open() == Window.OK) {
				Object[] elements = dialog.getResult();
				for (int i = 0; i < elements.length; i++) {
					newPackageNames.add(((IPackageFragment) elements[i]).getElementName());
				}
			}
		} else {
			// It's not within the workspace
			final List existingPackagenames = getFilteredExistingEntries();
			IInputValidator validator = new IInputValidator() {
				public String isValid(String newText) {
					if (existingPackagenames.contains(newText))
						return BeanInfoUIMessages.getString("SearchPathDialog.PackagePresent_INFO_"); //$NON-NLS-1$
						
					IStatus status = JavaConventions.validatePackageName(newText);
					return status.getSeverity() == IStatus.OK ? null : status.getMessage();
				}
			};
			InputDialog dialog = new InputDialog(getShell(), BeanInfoUIMessages.getString("SearchPathDialog.InputDialog.Title"), BeanInfoUIMessages.getString("SearchPathDialog.InputDialog.Message"), null, validator); //$NON-NLS-1$ //$NON-NLS-2$
			if (dialog.open() == Window.OK)
				newPackageNames.add(dialog.getValue());
		}

		if (newPackageNames.size() == 0)
			return Collections.EMPTY_LIST;

		List newElements = new ArrayList(newPackageNames.size());
		for (int i = 0; i < newPackageNames.size(); i++)
			newElements.add(
				new BPSearchListElement(new SearchpathEntry((String) newPackageNames.get(i)), false, false, false));
		return newElements;
	}
	/**
	 * Return the packagefragment roots for the given beaninfo entry.
	 * Return null if it can be handled (i.e. not in a project some where).
	 */
	protected IPackageFragmentRoot[] getBeaninfoRoots() {
		IPackageFragmentRoot[] roots = null;
		if (infoElement.getEntry().getKind() != BeaninfoEntry.BIE_PLUGIN) {
			IClasspathEntry resolved = JavaCore.getResolvedClasspathEntry(((BeaninfoEntry) infoElement.getEntry()).getClasspathEntry());
			IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(resolved.getPath());
			if (res != null && res.exists()) {
				if (res instanceof IProject) {
					// It is a project itself.
					IJavaProject jp = (IJavaProject) JavaCore.create(res);
					try {
						if (jp != null)
							roots = jp.getPackageFragmentRoots(); // All of the roots in the project are applicable.
					} catch (JavaModelException e) {
					}
				} else {
					// It is within another project
					IProject containingProject = res.getProject();
					IJavaProject jp = JavaCore.create(containingProject);
					if (jp != null) {
						// The roots if this is in the classpath of this project
						try {
							IPackageFragmentRoot root = jp.findPackageFragmentRoot(resolved.getPath());
							if (root != null)
								roots = new IPackageFragmentRoot[] { root };
						} catch (JavaModelException e) {
						}
					}
				}
			}
		}
		return roots;
	}

	/**
	 * Return the list of entries that already are in the search path
	 * so that they don't show up in the list.
	 */
	protected Object[] getFilteredExistingEntries(IPackageFragmentRoot[] roots) {
		List entries = listField.getElements();
		List fragments = new ArrayList(entries.size());
		Iterator itr = entries.iterator();
		while (itr.hasNext()) {
			BPSearchListElement elem = (BPSearchListElement) itr.next();
			fragments.addAll(getPackages(elem, roots));
		}
		return fragments.toArray();
	}
	
	/**
	 * Return the list of entries that already are in the search path
	 * so that they don't show up in the list. This one is just the package names.
	 */
	protected List getFilteredExistingEntries() {
		List entries = listField.getElements();
		List names = new ArrayList(entries.size());
		Iterator itr = entries.iterator();
		while (itr.hasNext()) {
			BPSearchListElement elem = (BPSearchListElement) itr.next();
			names.add(((SearchpathEntry) elem.getEntry()).getPackage());
		}
		return names;
	}

	protected List getPackages(BPSearchListElement element, IPackageFragmentRoot[] roots) {
		String packageName = ((SearchpathEntry) element.getEntry()).getPackage();
		if (packageName == null)
			return Collections.EMPTY_LIST;

		try {
			List packages = new ArrayList(10);
			for (int i = 0; i < roots.length; i++) {
				IJavaElement[] pfs = roots[i].getChildren();
				for (int j = 0; j < pfs.length; j++)
					if (pfs[j].getElementType() == IJavaElement.PACKAGE_FRAGMENT
						&& pfs[j].getElementName().equals(packageName)) {
						packages.add(pfs[j]);
						break;
					}
			}
			return packages;
		} catch (JavaModelException e) {
		}
		return Collections.EMPTY_LIST;
	}
}
