/*******************************************************************************
 * Copyright (c) 2000, 2007 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.update.internal.ui.views;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.operation.*;
import org.eclipse.jface.resource.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.branding.*;
import org.eclipse.ui.dialogs.*;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.*;
import org.eclipse.update.configuration.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.LocalSite;
import org.eclipse.update.internal.operations.*;
import org.eclipse.update.internal.ui.*;
import org.eclipse.update.internal.ui.model.*;
import org.eclipse.update.internal.ui.parts.*;
import org.eclipse.update.operations.*;
import org.osgi.framework.*;
import org.eclipse.core.runtime.Path;


/**
 * Insert the type's description here.
 * @see ViewPart
 */
public class ConfigurationView
	implements
		IInstallConfigurationChangedListener,
		IConfiguredSiteChangedListener,
		ILocalSiteChangedListener {
	private TreeViewer treeViewer;
	private DrillDownAdapter drillDownAdapter;
	private Action collapseAllAction;
	private static final String STATE_SHOW_UNCONF = "ConfigurationView.showUnconf"; //$NON-NLS-1$
	private static final String STATE_SHOW_SITES = "ConfigurationView.showSites"; //$NON-NLS-1$
	private static final String STATE_SHOW_NESTED_FEATURES =
		"ConfigurationView.showNestedFeatures"; //$NON-NLS-1$

	private Action showSitesAction;
	private Action showNestedFeaturesAction;
	private ReplaceVersionAction swapVersionAction;
	private FeatureStateAction featureStateAction;
	private UninstallFeatureAction uninstallFeatureAction;
	private UnconfigureAndUninstallFeatureAction unconfigureAndUninstallFeatureAction;
	private FeaturesStateAction featuresStateAction;
	private UninstallFeaturesAction uninstallFeaturesAction;
	private UnconfigureAndUninstallFeaturesAction unconfigureAndUninstallFeaturesAction;
	private InstallOptionalFeatureAction installOptFeatureAction;
	private Action showUnconfFeaturesAction;
	private RevertConfigurationAction revertAction;
	private ShowActivitiesAction showActivitiesAction;
	private Action propertiesAction;
	private SiteStateAction siteStateAction;
	private Action installationHistoryAction;
	private Action newExtensionLocationAction;
	private FindUpdatesAction findUpdatesAction;
	private SashForm splitter;
	private ConfigurationPreview preview;
	private Hashtable previewTasks;
	
	private IUpdateModelChangedListener modelListener;
	private boolean refreshLock = false;
	private Image eclipseImage;
	private boolean initialized;
	private ConfigurationManagerWindow configurationWindow;

	class ConfigurationSorter extends ViewerSorter {
		public int category(Object obj) {
			// sites
			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				if (csite.isProductSite())
					return 1;
				if (csite.isExtensionSite())
					return 2;
				return 3;
			}
			return super.category(obj);
		}
	}

	class LocalSiteProvider
		extends DefaultContentProvider
		implements ITreeContentProvider {
		public void inputChanged(
			Viewer viewer,
			Object oldInput,
			Object newInput) {
			if (newInput == null)
				return;
		}

		public Object[] getChildren(Object parent) {
			if (parent instanceof UpdateModel) {
				LocalSiteWorkbenchAdapter localSite = getUIReadyLocalSite(getLocalSite());
				return (localSite != null) ? new Object[] { localSite }
				: new Object[0];
			}

			if (parent instanceof ILocalSite) {
				Object[] csites = openLocalSite();
				if (showSitesAction.isChecked())
					return csites;
				ArrayList result = new ArrayList();
				boolean showUnconf = showUnconfFeaturesAction.isChecked();
				for (int i = 0; i < csites.length; i++) {
					IConfiguredSiteAdapter adapter =
						(IConfiguredSiteAdapter) csites[i];
					Object[] roots = getFeatures(adapter, !showUnconf);
					for (int j = 0; j < roots.length; j++) {
						result.add(roots[j]);
					}
				}
				return result.toArray();
			}

			if (parent instanceof IConfiguredSiteAdapter) {
				return getFeatures(
					(IConfiguredSiteAdapter) parent,
					!showUnconfFeaturesAction.isChecked());
			}
			if (parent instanceof ConfiguredFeatureAdapter
				&& showNestedFeaturesAction.isChecked()) {
				IFeatureAdapter[] nested =
					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
						null);
				if (showUnconfFeaturesAction.isChecked())
					return nested;
				ArrayList result = new ArrayList();
				for (int i = 0; i < nested.length; i++) {
					if (((ConfiguredFeatureAdapter) nested[i]).isConfigured())
						result.add(nested[i]);
				}
				return (IFeatureAdapter[]) result.toArray(
					new IFeatureAdapter[result.size()]);
			}
			return new Object[0];
		}

		public Object getParent(Object child) {
			return null;
		}
		public boolean hasChildren(Object parent) {
			if (parent instanceof ConfiguredFeatureAdapter) {
				if (!showNestedFeaturesAction.isChecked())
					return false;
				IFeatureAdapter[] features =
					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
						null);

				if (showUnconfFeaturesAction.isChecked())
					return features.length > 0;

				for (int i = 0; i < features.length; i++) {
					if (((ConfiguredFeatureAdapter) features[i])
						.isConfigured())
						return true;
				}
				return false;
			}
			if (parent instanceof ConfiguredSiteAdapter) {
				IConfiguredSite site =
					((ConfiguredSiteAdapter) parent).getConfiguredSite();
				if (site.isEnabled()) {
					if (!showUnconfFeaturesAction.isChecked())
						return site.getConfiguredFeatures().length > 0;
					return site.getFeatureReferences().length > 0;
				}
				return (showUnconfFeaturesAction.isChecked());
			}
			return true;
		}

		public Object[] getElements(Object input) {
			return getChildren(input);
		}
	}

	class LocalSiteLabelProvider extends LabelProvider {
		public String getText(Object obj) {
			if (obj instanceof ILocalSite) {
				IProduct product = Platform.getProduct();
				if (product != null)
					return product.getName();
				return UpdateUIMessages.ConfigurationView_current; 
			}

			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				ISite site = csite.getSite();
				return new File(site.getURL().getFile()).toString();
			}
			if (obj instanceof IFeatureAdapter) {
				try {
					IFeature feature = ((IFeatureAdapter) obj).getFeature(null);
					if (feature instanceof MissingFeature) {
						return NLS.bind(UpdateUIMessages.ConfigurationView_missingFeature, feature.getLabel());
					}
					String version = feature.getVersionedIdentifier().getVersion().toString();
					String pending = ""; //$NON-NLS-1$
					if (OperationsManager.findPendingOperation(feature)
						!= null)
						pending = UpdateUIMessages.ConfigurationView_pending; 
					return feature.getLabel() + " " + version + pending; //$NON-NLS-1$
				} catch (CoreException e) {
					return UpdateUIMessages.ConfigurationView_error; 
				}
			}
			return super.getText(obj);
		}

		public Image getImage(Object obj) {
			UpdateLabelProvider provider =
				UpdateUI.getDefault().getLabelProvider();
			if (obj instanceof ILocalSite)
				return eclipseImage;

			if (obj instanceof ConfiguredFeatureAdapter)
				return getFeatureImage(
					provider,
					(ConfiguredFeatureAdapter) obj);

			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				int flags =
					csite.isUpdatable() ? 0 : UpdateLabelProvider.F_LINKED;
				if (!csite.isEnabled())
					flags |= UpdateLabelProvider.F_UNCONFIGURED;
				return provider.get(
					provider.getLocalSiteDescriptor(csite),
					flags);
			}
			return null;
		}

		private Image getFeatureImage(
			UpdateLabelProvider provider,
			ConfiguredFeatureAdapter adapter) {
			try {
				IFeature feature = adapter.getFeature(null);
				if (feature instanceof MissingFeature) {
					if (((MissingFeature) feature).isOptional())
						return provider.get(
							UpdateUIImages.DESC_NOTINST_FEATURE_OBJ);
					return provider.get(
						UpdateUIImages.DESC_FEATURE_OBJ,
						UpdateLabelProvider.F_ERROR);
				}

				boolean efix = feature.isPatch();
				ImageDescriptor baseDesc =
					efix
						? UpdateUIImages.DESC_EFIX_OBJ
						: (adapter.isConfigured()
							? UpdateUIImages.DESC_FEATURE_OBJ
							: UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);

				int flags = 0;
				if (efix && !adapter.isConfigured())
					flags |= UpdateLabelProvider.F_UNCONFIGURED;
				if (OperationsManager.findPendingOperation(feature) == null) {
					ILocalSite localSite = getLocalSite();
					if (localSite != null) {
						int code =
							getStatusCode(
								feature,
								localSite.getFeatureStatus(feature));
						switch (code) {
							case IFeature.STATUS_UNHAPPY :
								flags |= UpdateLabelProvider.F_ERROR;
								break;
							case IFeature.STATUS_AMBIGUOUS :
								flags |= UpdateLabelProvider.F_WARNING;
								break;
							default :
								if (adapter.isConfigured()
									&& adapter.isUpdated())
									flags |= UpdateLabelProvider.F_UPDATED;
								break;
						}
					}
				}
				return provider.get(baseDesc, flags);
			} catch (CoreException e) {
				return provider.get(
					UpdateUIImages.DESC_FEATURE_OBJ,
					UpdateLabelProvider.F_ERROR);
			}
		}
	}

	class PreviewTask implements IPreviewTask {
		private String name;
		private String desc;
		private IAction action;
		public PreviewTask(String name, String desc, IAction action) {
			this.name = name;
			this.desc = desc;
			this.action = action;
		}
		public IAction getAction() {
			return action;
		}
		public String getName() {
			if (name != null)
				return name;
			return action.getText();
		}
		public String getDescription() {
			return desc;
		}
		public void setDescription(String desc) {
			this.desc = desc;
		}
		public void run() {
			action.run();
		}
		public boolean isEnabled() {
			return action.isEnabled();
		}
	}

	public ConfigurationView(ConfigurationManagerWindow window) {
		UpdateUI.getDefault().getLabelProvider().connect(this);
		configurationWindow=window;
		initializeImages();
	}

	private void initializeImages() {
		IProduct product = Platform.getProduct();
		if (product != null) {
			eclipseImage = getProductImage16(product);
		}
		if (eclipseImage==null) {
			ImageDescriptor edesc = UpdateUIImages.DESC_APP_OBJ;
			eclipseImage = UpdateUI.getDefault().getLabelProvider().get(edesc);
		}
	}
	
	private Image getProductImage16(IProduct product) {
		// Loop through the product window images and
		// pick the first whose size is 16x16 and does not
		// alpha transparency type.
		String windowImagesUrls = product.getProperty(IProductConstants.WINDOW_IMAGES);
		Image png=null, gif=null, other = null;
		if (windowImagesUrls != null ) {
			StringTokenizer st = new StringTokenizer(windowImagesUrls, ","); //$NON-NLS-1$
			while (st.hasMoreTokens()) {
				String windowImageURL = st.nextToken();
				ImageDescriptor edesc=null;
				try {
					edesc = ImageDescriptor.createFromURL(new URL(windowImageURL));
				} catch (MalformedURLException e) {
					// must be a path relative to the product bundle
					Bundle productBundle = product.getDefiningBundle();
					if (productBundle != null) { 
						URL url = FileLocator.find(productBundle, new Path(windowImageURL), null);
						if (url != null)
							edesc = ImageDescriptor.createFromURL(url);
					}
				}
				if (edesc!=null) {
					Image image = UpdateUI.getDefault().getLabelProvider().get(edesc);
					Rectangle bounds = image.getBounds();
					if (bounds.width==16 && bounds.height==16) {
						// avoid images with TRANSPARENCY_ALPHA
						//if (image.getImageData().getTransparencyType()!=SWT.TRANSPARENCY_ALPHA)
						//	return image;
						//Instead of returning, just store the image based on the
						// extension.
						if (windowImageURL.toLowerCase().endsWith(".gif")) //$NON-NLS-1$
							gif = image;
						else if (windowImageURL.toLowerCase().endsWith(".png")) //$NON-NLS-1$
							png = image;
						else
							other = image;
					}
				}
			}
		}
		Image choice = null;
		// Pick png first because of transparency
		if (png!=null) {
			choice = png;
		}
		// Pick other format
		else if (other!=null)
			choice = other;
		// Pick gif
		else if (gif!=null)
			choice = gif;
		return choice;
	}

	public void initProviders() {
		treeViewer.setContentProvider(new LocalSiteProvider());
		treeViewer.setLabelProvider(new LocalSiteLabelProvider());
		treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
		treeViewer.setSorter(new ConfigurationSorter());
		ILocalSite localSite = getLocalSite();
		if (localSite != null)
			localSite.addLocalSiteChangedListener(this);

		modelListener = new IUpdateModelChangedListener() {
			public void objectsAdded(Object parent, Object[] children) {
			}
			public void objectsRemoved(Object parent, Object[] children) {
			}
			public void objectChanged(final Object obj, String property) {
				if (refreshLock)
					return;
				Control control = getControl();
				if (!control.isDisposed()) {
					control.getDisplay().asyncExec(new Runnable() {
						public void run() {
							treeViewer.refresh();
							handleSelectionChanged(
								(IStructuredSelection) treeViewer
									.getSelection());
						}
					});
				}
			}
		};
		OperationsManager.addUpdateModelChangedListener(modelListener);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
			getControl(),
			"org.eclipse.update.ui.ConfigurationView"); //$NON-NLS-1$
	}

	private ILocalSite getLocalSite() {
		try {
			return SiteManager.getLocalSite();
		} catch (CoreException e) {
			UpdateUI.logException(e);
			return null;
		}
	}

	private Object[] openLocalSite() {
		final Object[][] bag = new Object[1][];
		BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
			public void run() {
				ILocalSite localSite = getLocalSite();
				if (localSite == null)
					return;
				IInstallConfiguration config =
					getLocalSite().getCurrentConfiguration();
				IConfiguredSite[] sites = config.getConfiguredSites();
				Object[] result = new Object[sites.length];
				for (int i = 0; i < sites.length; i++) {
					result[i] = new ConfiguredSiteAdapter(config, sites[i]);
				}
				if (!initialized) {
					config.addInstallConfigurationChangedListener(
						ConfigurationView.this);
					initialized = true;
				}
				bag[0] = result;
			}
		});
		return bag[0];
	}

	public void dispose() {
		UpdateUI.getDefault().getLabelProvider().disconnect(this);
		if (initialized) {
			ILocalSite localSite = getLocalSite();
			if (localSite != null) {
				localSite.removeLocalSiteChangedListener(this);
				IInstallConfiguration config =
					localSite.getCurrentConfiguration();
				config.removeInstallConfigurationChangedListener(this);
			}
			initialized = false;
		}
		OperationsManager.removeUpdateModelChangedListener(modelListener);
		if (preview != null)
			preview.dispose();
		//super.dispose();
	}

	protected void makeActions() {
		collapseAllAction = new Action() {
			public void run() {
				treeViewer.getControl().setRedraw(false);
				treeViewer.collapseToLevel(
					treeViewer.getInput(),
					TreeViewer.ALL_LEVELS);
				treeViewer.getControl().setRedraw(true);
			}
		};
		collapseAllAction.setText(UpdateUIMessages.ConfigurationView_collapseLabel); 
		collapseAllAction.setToolTipText(UpdateUIMessages.ConfigurationView_collapseTooltip); 
		collapseAllAction.setImageDescriptor(UpdateUIImages.DESC_COLLAPSE_ALL);

		drillDownAdapter = new DrillDownAdapter(treeViewer);

		featureStateAction = new FeatureStateAction(this.getConfigurationWindow().getShell(), ""); //$NON-NLS-1$
		featuresStateAction = new FeaturesStateAction(this.getConfigurationWindow().getShell(), ""); //$NON-NLS-1$

		siteStateAction = new SiteStateAction(getConfigurationWindow().getShell());

		revertAction = new RevertConfigurationAction(getConfigurationWindow().getShell(),UpdateUIMessages.ConfigurationView_revertLabel); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
			revertAction,
			"org.eclipse.update.ui.CofigurationView_revertAction"); //$NON-NLS-1$

		installationHistoryAction =
			new InstallationHistoryAction(getConfigurationWindow().getShell(),
				UpdateUIMessages.ConfigurationView_installHistory, 
				UpdateUIImages.DESC_HISTORY_OBJ);
		installationHistoryAction.setToolTipText(installationHistoryAction.getText());
		
		newExtensionLocationAction =
			new NewExtensionLocationAction(getConfigurationWindow().getShell(),
				UpdateUIMessages.ConfigurationView_extLocation, 
				UpdateUIImages.DESC_ESITE_OBJ);
		
		propertiesAction =
			new PropertyDialogAction(
				getConfigurationWindow(),
				treeViewer);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
			propertiesAction,
			"org.eclipse.update.ui.CofigurationView_propertiesAction"); //$NON-NLS-1$

		uninstallFeatureAction = new UninstallFeatureAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
		unconfigureAndUninstallFeatureAction = new UnconfigureAndUninstallFeatureAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
		
		uninstallFeaturesAction = new UninstallFeaturesAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
		unconfigureAndUninstallFeaturesAction = new UnconfigureAndUninstallFeaturesAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_unconfigureAndUninstall); 

		
		installOptFeatureAction =
			new InstallOptionalFeatureAction(
				getControl().getShell(),
				UpdateUIMessages.ConfigurationView_install); 

		swapVersionAction = new ReplaceVersionAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_anotherVersion); 

		findUpdatesAction =
			new FindUpdatesAction(configurationWindow, UpdateUIMessages.ConfigurationView_findUpdates); 

		showActivitiesAction = new ShowActivitiesAction(getControl().getShell(), UpdateUIMessages.ConfigurationView_showActivitiesLabel); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
			showActivitiesAction,
			"org.eclipse.update.ui.ConfigurationView_showActivitiesAction"); //$NON-NLS-1$

		makeShowUnconfiguredFeaturesAction();
		makeShowSitesAction();
		makeShowNestedFeaturesAction();
		makePreviewTasks();
		configurationWindow.setPropertiesActionHandler(propertiesAction);
	}

	private void makeShowNestedFeaturesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_NESTED_FEATURES, true);
		showNestedFeaturesAction = new Action() {
			public void run() {
				treeViewer.refresh();
				pref.setValue(
					STATE_SHOW_NESTED_FEATURES,
					showNestedFeaturesAction.isChecked());
			}
		};
		showNestedFeaturesAction.setText(UpdateUIMessages.ConfigurationView_showNestedFeatures); 
		showNestedFeaturesAction.setImageDescriptor(
			UpdateUIImages.DESC_SHOW_HIERARCHY);
		showNestedFeaturesAction.setDisabledImageDescriptor(
			UpdateUIImages.DESC_SHOW_HIERARCHY_D);

		showNestedFeaturesAction.setChecked(
			pref.getBoolean(STATE_SHOW_NESTED_FEATURES));
		showNestedFeaturesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showNestedTooltip); 
	}

	private void makeShowSitesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_SITES, true);
		showSitesAction = new Action() {
			public void run() {
				treeViewer.refresh();
				pref.setValue(STATE_SHOW_SITES, showSitesAction.isChecked());
				UpdateUI.getDefault().savePluginPreferences();
			}
		};
		showSitesAction.setText(UpdateUIMessages.ConfigurationView_showInstall); 
		showSitesAction.setImageDescriptor(UpdateUIImages.DESC_LSITE_OBJ);
		showSitesAction.setChecked(pref.getBoolean(STATE_SHOW_SITES));
		showSitesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showInstallTooltip); 
	}

	private void makeShowUnconfiguredFeaturesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_UNCONF, false);
		showUnconfFeaturesAction = new Action() {
			public void run() {
				pref.setValue(
					STATE_SHOW_UNCONF,
					showUnconfFeaturesAction.isChecked());
				UpdateUI.getDefault().savePluginPreferences();
				treeViewer.refresh();
			}
		};
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
			showUnconfFeaturesAction,
			"org.eclipse.update.ui.CofigurationView_showUnconfFeaturesAction"); //$NON-NLS-1$
		showUnconfFeaturesAction.setText(UpdateUIMessages.ConfigurationView_showDisabled); 
		showUnconfFeaturesAction.setImageDescriptor(
			UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);
		showUnconfFeaturesAction.setChecked(pref.getBoolean(STATE_SHOW_UNCONF));
		showUnconfFeaturesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showDisabledTooltip); 
	}

	protected void fillActionBars(ToolBarManager tbm) {
		tbm.add(showSitesAction);
		tbm.add(showNestedFeaturesAction);
		tbm.add(showUnconfFeaturesAction);
		tbm.add(new Separator());
		drillDownAdapter.addNavigationActions(tbm);
		tbm.add(new Separator());
		tbm.add(collapseAllAction);
		tbm.add(new Separator());
		tbm.add(installationHistoryAction);
	}

	protected Object getSelectedObject() {
		ISelection selection = treeViewer.getSelection();
		if (selection instanceof IStructuredSelection
			&& !selection.isEmpty()) {
			IStructuredSelection ssel = (IStructuredSelection) selection;
			
			if (ssel.size() == 1)
				return ssel.getFirstElement();
			else
				return ssel.toArray();
		}
		return null;
	}

	protected void fillContextMenu(IMenuManager manager) {
		Object obj = getSelectedObject();
		boolean areMultipleFeaturesSelected = true;
		
		if ( obj instanceof Object[]) {
			Object[] array = (Object[])obj;
			for( int i = 0; i < array.length; i++) {
				if (!(array[i] instanceof ConfiguredFeatureAdapter)) {
					areMultipleFeaturesSelected = false;
				}
			}
		} else {
			areMultipleFeaturesSelected = false;
		}

		if (obj instanceof ILocalSite) {
			manager.add(findUpdatesAction);
			manager.add(revertAction);
		} else if (obj instanceof IConfiguredSiteAdapter) {
			manager.add(siteStateAction);
		}

		if (obj instanceof ILocalSite
			|| obj instanceof IConfiguredSiteAdapter) {
			manager.add(new Separator());
			MenuManager mgr = new MenuManager(UpdateUIMessages.ConfigurationView_new); 
			mgr.add(newExtensionLocationAction);
			manager.add(mgr);
			manager.add(new Separator());
		} else if ( (obj instanceof ConfiguredFeatureAdapter) && !areMultipleFeaturesSelected){
			try {
				
				MenuManager mgr = new MenuManager(UpdateUIMessages.ConfigurationView_replaceWith); 
				
				manager.add(findUpdatesAction);
				manager.add(new Separator());
				
				mgr.add(swapVersionAction);
				manager.add(mgr);

				manager.add(featureStateAction);
				

				IFeature feature =
					((ConfiguredFeatureAdapter) obj).getFeature(null);
				if (feature instanceof MissingFeature) {
					manager.add(installOptFeatureAction);
				} else {
					boolean configured = ((ConfiguredFeatureAdapter)obj).isConfigured();
					if (!configured)
						manager.add(uninstallFeatureAction);
					else
						manager.add(unconfigureAndUninstallFeatureAction);
				}
				manager.add(new Separator());

			} catch (CoreException e) {
			}
		} else if (areMultipleFeaturesSelected) {

				manager.add(findUpdatesAction);
				manager.add(new Separator());

				manager.add(featuresStateAction);
				
				manager.add(uninstallFeaturesAction);
				manager.add(unconfigureAndUninstallFeaturesAction);
				
				manager.add(new Separator());

		}

		drillDownAdapter.addNavigationActions(manager);

		if (obj instanceof ILocalSite) {
			manager.add(new Separator());
			manager.add(installationHistoryAction);
		}

		if (obj instanceof IFeatureAdapter
			|| obj instanceof ILocalSite
			|| obj instanceof IConfiguredSiteAdapter) {
			manager.add(new Separator());
			manager.add(propertiesAction);
		}
	}

	public void installSiteAdded(IConfiguredSite csite) {
		asyncRefresh();
	}
	public void installSiteRemoved(IConfiguredSite site) {
		asyncRefresh();
	}
	public void featureInstalled(IFeature feature) {
		asyncRefresh();
	}
	public void featureRemoved(IFeature feature) {
		asyncRefresh();
	}
	public void featureConfigured(IFeature feature) {
	}

	public void featureUnconfigured(IFeature feature) {
	}

	public void currentInstallConfigurationChanged(IInstallConfiguration configuration) {
		asyncRefresh();
	}

	public void installConfigurationRemoved(IInstallConfiguration configuration) {
		asyncRefresh();
	}

	private void asyncRefresh() {
		Display display = SWTUtil.getStandardDisplay();
		if (display == null)
			return;
		if (getControl().isDisposed())
			return;
		display.asyncExec(new Runnable() {
			public void run() {
				if (!getControl().isDisposed())
					treeViewer.refresh();
			}
		});
	}

	private Object[] getFeatures(
		final IConfiguredSiteAdapter siteAdapter,
		final boolean configuredOnly) {
		final IConfiguredSite csite = siteAdapter.getConfiguredSite();
		final Object[][] bag = new Object[1][];
		refreshLock = true;

		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) {
				ArrayList result = new ArrayList();
				IFeatureReference[] refs;

				if (configuredOnly)
					refs = csite.getConfiguredFeatures();
				else {
					ISite site = csite.getSite();
					refs = site.getFeatureReferences();
				}
				monitor.beginTask(
					UpdateUIMessages.ConfigurationView_loading, 
					refs.length);

				for (int i = 0; i < refs.length; i++) {
					IFeatureReference ref = refs[i];
					IFeature feature;
					try {
						monitor.subTask(ref.getURL().toString());
						feature = ref.getFeature(null);
					} catch (CoreException e) {
						feature =
							new MissingFeature(ref.getSite(), ref.getURL());
					}
					monitor.worked(1);
					result.add(
						new ConfiguredFeatureAdapter(
							siteAdapter,
							feature,
							csite.isConfigured(feature),
							false,
							false));
				}
				monitor.done();
				bag[0] = getRootFeatures(result);
			}
		};

		try {
			if (configurationWindow.getShell().isVisible())
				configurationWindow.run(true, false, op);
			else
				op.run(new NullProgressMonitor());
		} catch (InterruptedException e) {
		} catch (InvocationTargetException e) {
		} finally {
			refreshLock = false;
		}
		return bag[0];
	}

	private Object[] getRootFeatures(ArrayList list) {
		ArrayList children = new ArrayList();
		ArrayList result = new ArrayList();
		try {
			for (int i = 0; i < list.size(); i++) {
				ConfiguredFeatureAdapter cf =
					(ConfiguredFeatureAdapter) list.get(i);
				IFeature feature = cf.getFeature(null);
				if (feature != null)
					addChildFeatures(
						feature,
						children,
						cf.isConfigured());
			}
			for (int i = 0; i < list.size(); i++) {
				ConfiguredFeatureAdapter cf =
					(ConfiguredFeatureAdapter) list.get(i);
				IFeature feature = cf.getFeature(null);
				if (feature != null
					&& isChildFeature(feature, children) == false)
					result.add(cf);
			}
		} catch (CoreException e) {
			return list.toArray();
		}
		return result.toArray();
	}

	private void addChildFeatures(
		IFeature feature,
		ArrayList children,
		boolean configured) {
		try {
			IIncludedFeatureReference[] included =
				feature.getIncludedFeatureReferences();
			for (int i = 0; i < included.length; i++) {
				IFeature childFeature;
				try {
					childFeature =
						included[i].getFeature(null);
				} catch (CoreException e) {
					childFeature = new MissingFeature(included[i]);
				}
				children.add(childFeature);
			}
		} catch (CoreException e) {
			UpdateUI.logException(e);
		}
	}

	private boolean isChildFeature(IFeature feature, ArrayList children) {
		for (int i = 0; i < children.size(); i++) {
			IFeature child = (IFeature) children.get(i);
			if (feature
				.getVersionedIdentifier()
				.equals(child.getVersionedIdentifier()))
				return true;
		}
		return false;
	}

	protected void handleDoubleClick(DoubleClickEvent e) {
		if (e.getSelection() instanceof IStructuredSelection) {
			IStructuredSelection ssel = (IStructuredSelection) e.getSelection();
			
			Object obj = ssel.getFirstElement();
			if (obj!=null)
				propertiesAction.run();
		}
	}

	public void createPartControl(Composite parent) {
		splitter = new SashForm(parent, SWT.HORIZONTAL);
		splitter.setLayoutData(new GridData(GridData.FILL_BOTH));
		Composite leftContainer = createLineContainer(splitter);
		Composite rightContainer = createLineContainer(splitter);
		createTreeViewer(leftContainer);
		makeActions();
		createVerticalLine(leftContainer);
		createVerticalLine(rightContainer);
		preview = new ConfigurationPreview(this);
		preview.createControl(rightContainer);
		preview.getControl().setLayoutData(
			new GridData(GridData.FILL_BOTH));
		splitter.setWeights(new int[] { 2, 3 });
		fillActionBars(getConfigurationWindow().getToolBarManager());

		treeViewer.expandToLevel(2);

		if (treeViewer.getTree().getItemCount() > 0) {
			TreeItem[] items = treeViewer.getTree().getItems();
			treeViewer.getTree().setSelection(new TreeItem[] { items[0] });
			handleSelectionChanged(new StructuredSelection(items[0].getData()));
		}
	}

	private void createTreeViewer(Composite parent) {
		treeViewer =
			new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		treeViewer.setUseHashlookup(true);
		initProviders();

		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				manager.add(new GroupMarker("additions")); //$NON-NLS-1$
				fillContextMenu(manager);
			}
		});

		treeViewer.getControl().setMenu(
			menuMgr.createContextMenu(treeViewer.getControl()));

		treeViewer
			.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				handleSelectionChanged(event);
			}
		});

		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				handleDoubleClick(event);
			}
		});

	}

	public TreeViewer getTreeViewer() {
		return treeViewer;
	}

	private Composite createLineContainer(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = layout.marginHeight = 0;
		layout.horizontalSpacing = 0;
		container.setLayout(layout);
		return container;
	}

	private void createVerticalLine(Composite parent) {
		Label line = new Label(parent, SWT.SEPARATOR | SWT.VERTICAL);
		GridData gd = new GridData(GridData.VERTICAL_ALIGN_FILL);
		gd.widthHint = 1;
		line.setLayoutData(gd);
	}

	public Control getControl() {
		return splitter;
	}

	private int getStatusCode(IFeature feature, IStatus status) {
		int code = status.getCode();
		if (code == IFeature.STATUS_UNHAPPY) {
			if (status.isMultiStatus()) {
				IStatus[] children = status.getChildren();
				for (int i = 0; i < children.length; i++) {
					IStatus child = children[i];
					if (child.isMultiStatus()
						|| child.getCode() != IFeature.STATUS_DISABLED)
						return code;
				}
				// If we are here, global status is unhappy
				// because one or more included features
				// is disabled.
				if (UpdateUtils.hasObsoletePatches(feature)) {
					// The disabled included features
					// are old patches that are now
					// subsumed by better versions of
					// the features they were designed to
					// patch.
					return IFeature.STATUS_HAPPY;
				}
			}
		}
		return code;
	}

	protected void handleSelectionChanged(IStructuredSelection ssel) {
		Object obj = ssel.getFirstElement();
		
		boolean areMultipleFeaturesSelected = true;
		
		if (ssel.size() > 1) {
			Object[] array = ssel.toArray();
			for( int i = 0; i < array.length; i++) {
				if (!(array[i] instanceof ConfiguredFeatureAdapter)) {
					areMultipleFeaturesSelected = false;
				}
			}
		} else {
			areMultipleFeaturesSelected = false;
		}
		
		if (ssel.size()>1)
			obj = null;
		
		if (obj!=null) {
			ILabelProvider labelProvider = (ILabelProvider)treeViewer.getLabelProvider();
			String text = labelProvider.getText(obj);
			//Image img = labelProvider.getImage(obj);
			Image img = null;
			configurationWindow.updateStatusLine(text, img);
		}
		else
			configurationWindow.updateStatusLine(null, null);
		
		if (areMultipleFeaturesSelected && (ssel.size() > 1)) {
			
			uninstallFeaturesAction.setSelection(ssel);
			uninstallFeaturesAction.setEnabled(uninstallFeatureAction.canExecuteAction());
			unconfigureAndUninstallFeaturesAction.setSelection(ssel);
			unconfigureAndUninstallFeaturesAction.setEnabled(unconfigureAndUninstallFeatureAction.canExecuteAction());
			featuresStateAction.setSelection(ssel);
			featuresStateAction.setEnabled(featuresStateAction.canExecuteAction());
			propertiesAction.setEnabled(false);
			preview.setSelection(ssel);
			return;
		}
		
		if (obj instanceof IFeatureAdapter) {
			try {
				propertiesAction.setEnabled(true);
				ConfiguredFeatureAdapter adapter = (ConfiguredFeatureAdapter) obj;
				IFeature feature = adapter.getFeature(null);

				boolean missing = feature instanceof MissingFeature;
				boolean enable = !missing
						&& ((adapter.isOptional() || !adapter.isIncluded()));

				uninstallFeatureAction.setSelection(ssel);
				uninstallFeatureAction.setEnabled(enable
						&& uninstallFeatureAction.canExecuteAction());
				unconfigureAndUninstallFeatureAction.setSelection(ssel);
				unconfigureAndUninstallFeatureAction.setEnabled(enable && unconfigureAndUninstallFeatureAction.canExecuteAction());
				if (adapter.isConfigured())
					setDescriptionOnTask(
							uninstallFeatureAction,
							adapter,
							UpdateUIMessages.ConfigurationView_uninstallDesc2);
				else
					setDescriptionOnTask(
							uninstallFeatureAction,
							adapter,
							UpdateUIMessages.ConfigurationView_uninstallDesc);

				featureStateAction.setSelection(ssel);
				featureStateAction.setEnabled(enable);
				swapVersionAction.setEnabled(false);
				if (enable) {
					IFeature[] features = UpdateUtils.getInstalledFeatures(
							feature, false);
					if (features.length > 1) {
						if (adapter.isConfigured()) {
							// We only enable replace action if configured
							// and selected. bug 74019
							swapVersionAction.setEnabled(true);
							swapVersionAction.setCurrentFeature(feature);
							swapVersionAction.setFeatures(features);
						} else {
							// If we are not configured and another version is
							// we want to disable StateAction. bug 74019
							features = UpdateUtils.getInstalledFeatures(
									feature, true);
							if (features.length > 0) {
								featureStateAction.setEnabled(false);
							}
						}
					}
				}

				findUpdatesAction.setEnabled(false);
				if (enable && adapter.isConfigured()) {
					if (feature.getUpdateSiteEntry() != null) {
						findUpdatesAction.setFeature(feature);
						findUpdatesAction.setEnabled(true);
					}
				}
				
				if (missing) {
					MissingFeature mf = (MissingFeature) feature;
					installOptFeatureAction.setEnabled(mf.isOptional()
							&& mf.getOriginatingSiteURL() != null);
					installOptFeatureAction.setFeature(mf);
				} else {
					installOptFeatureAction.setEnabled(false);
				}
			} catch (CoreException ex) {
				UpdateUI.logException(ex);
			}
		}
		if (obj instanceof ILocalSite) {
			propertiesAction.setEnabled(true);
			findUpdatesAction.setEnabled(true);
			findUpdatesAction.setFeature(null);
			ILocalSite site = getLocalSite();
			revertAction.setEnabled(site != null
					&& site.getConfigurationHistory().length > 1);
		} else if (obj instanceof IConfiguredSiteAdapter) {
			siteStateAction.setSite(((IConfiguredSiteAdapter) obj)
					.getConfiguredSite());
			siteStateAction.setEnabled(true);
		}
		
		if (areMultipleFeaturesSelected) {
			uninstallFeaturesAction.setSelection(ssel);
			uninstallFeaturesAction.setEnabled(uninstallFeatureAction.canExecuteAction());
			unconfigureAndUninstallFeaturesAction.setSelection(ssel);
			unconfigureAndUninstallFeaturesAction.setEnabled(unconfigureAndUninstallFeatureAction.canExecuteAction());
			featuresStateAction.setSelection(ssel);
			featuresStateAction.setEnabled(featuresStateAction.canExecuteAction());
		}
		
		preview.setSelection(ssel);
	}

	protected void handleSelectionChanged(SelectionChangedEvent e) {
		handleSelectionChanged(((IStructuredSelection) e.getSelection()));
	}

	private void setDescriptionOnTask(IAction action, ConfiguredFeatureAdapter adapter, String desc) {
		IPreviewTask[] tasks = getPreviewTasks(adapter);
		if (tasks == null)
			return;
		for (int i=0; i<tasks.length; i++)
			if (tasks[i].getAction() == action)
				tasks[i].setDescription(desc);
	}
	
	private void makePreviewTasks() {
		previewTasks = new Hashtable();
		Class key;
		ArrayList array = new ArrayList();
		// local site tasks
		key = ILocalSite.class;
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_updateLabel, 
				UpdateUIMessages.ConfigurationView_updateDesc, 
				findUpdatesAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_installHistLabel, 
				UpdateUIMessages.ConfigurationView_installHistDesc, 
				installationHistoryAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_activitiesLabel, 
				UpdateUIMessages.ConfigurationView_activitiesDesc, 
				showActivitiesAction));
		array.add(
				new PreviewTask(
					UpdateUIMessages.ConfigurationView_extLocLabel, 
					UpdateUIMessages.ConfigurationView_extLocDesc, 
					newExtensionLocationAction));
		array.add(
				new PreviewTask(
					UpdateUIMessages.ConfigurationView_revertPreviousLabel, 
					UpdateUIMessages.ConfigurationView_revertPreviousDesc, 
					revertAction));

		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));

		// configured site tasks
		array.clear();
		key = IConfiguredSiteAdapter.class;
		array.add(
			new PreviewTask(
				null,
				UpdateUIMessages.ConfigurationView_enableLocDesc, 
				siteStateAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_extLocLabel, 
				UpdateUIMessages.ConfigurationView_extLocDesc, 
				newExtensionLocationAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_propertiesLabel, 
				UpdateUIMessages.ConfigurationView_installPropDesc, 
				propertiesAction));
		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));

		// feature adapter tasks
		array.clear();
		key = IFeatureAdapter.class;
		array.add(
				new PreviewTask(
					UpdateUIMessages.ConfigurationView_scanLabel, 
					UpdateUIMessages.ConfigurationView_scanDesc, 
					findUpdatesAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_replaceVersionLabel, 
				UpdateUIMessages.ConfigurationView_replaceVersionDesc, 
				swapVersionAction));
		array.add(
			new PreviewTask(
				null,
				UpdateUIMessages.ConfigurationView_enableFeatureDesc, 
				featureStateAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_installOptionalLabel, 
				UpdateUIMessages.ConfigurationView_installOptionalDesc, 
				installOptFeatureAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_uninstallLabel, 
				UpdateUIMessages.ConfigurationView_uninstallDesc, 
				uninstallFeatureAction));
		array.add(
			new PreviewTask(
				UpdateUIMessages.ConfigurationView_featurePropLabel, 
				UpdateUIMessages.ConfigurationView_featurePropDesc, 
				propertiesAction));
		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));
	}

	public IPreviewTask[] getPreviewTasks(Object object) {
		IPreviewTask[] tasks = null;

		if (object instanceof IFeatureAdapter)
			tasks = (IPreviewTask[]) previewTasks.get(IFeatureAdapter.class);
		if (object instanceof ILocalSite)
			tasks = (IPreviewTask[]) previewTasks.get(ILocalSite.class);
		if (object instanceof IConfiguredSiteAdapter)
			tasks =
				(IPreviewTask[]) previewTasks.get(IConfiguredSiteAdapter.class);
		return (tasks != null) ? tasks : new IPreviewTask[0];
	}

	ConfigurationManagerWindow getConfigurationWindow(){
		return configurationWindow;
	}
	
	private LocalSiteWorkbenchAdapter getUIReadyLocalSite(ILocalSite localSite) {
			
		return new LocalSiteWorkbenchAdapter(localSite);
			
	}
	
	

}

class LocalSiteWorkbenchAdapter extends LocalSite implements IWorkbenchAdapter {
	
	private ILocalSite localSite;
	
	public LocalSiteWorkbenchAdapter(ILocalSite localSite) {
		this.localSite = localSite;
	}
	
	public Object[] getChildren(Object o) {
		return null;
	}

	public ImageDescriptor getImageDescriptor(Object object) {
		return null;
	}

	public String getLabel(Object o) {
		return Platform.getProduct().getName();
	}

	public Object getParent(Object o) {
		return null;
	}

	public void addConfiguration(IInstallConfiguration config) {
		localSite.addConfiguration(config);
	}

	public void addLocalSiteChangedListener(ILocalSiteChangedListener listener) {
		localSite.addLocalSiteChangedListener(listener);
	}

	public IInstallConfiguration addToPreservedConfigurations(IInstallConfiguration configuration) throws CoreException {
		return localSite.addToPreservedConfigurations(configuration);
	}

	public IInstallConfiguration cloneCurrentConfiguration() throws CoreException {
		return localSite.cloneCurrentConfiguration();
	}

	public IInstallConfiguration[] getConfigurationHistory() {
		return localSite.getConfigurationHistory();
	}

	public IInstallConfiguration getCurrentConfiguration() {
		return localSite.getCurrentConfiguration();
	}

	public IStatus getFeatureStatus(IFeature feature) throws CoreException {
		return localSite.getFeatureStatus(feature);
	}

	public int getMaximumHistoryCount() {
		return localSite.getMaximumHistoryCount();
	}

	public IInstallConfiguration[] getPreservedConfigurations() {
		return localSite.getPreservedConfigurations();
	}

	public void removeFromPreservedConfigurations(IInstallConfiguration configuration) {
		localSite.removeFromPreservedConfigurations(configuration);
	}

	public void removeLocalSiteChangedListener(ILocalSiteChangedListener listener) {
		localSite.removeLocalSiteChangedListener(listener);
	}

	public void revertTo(IInstallConfiguration configuration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException {
		localSite.revertTo(configuration, monitor, handler);
	}

	public boolean save() throws CoreException {
		return localSite.save();
	}

	public void setMaximumHistoryCount(int history) {
		localSite.setMaximumHistoryCount(history);
	}
	
}
