/*******************************************************************************
 * Copyright (c) 2007, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.contextlaunching;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.ILaunchHistoryChangedListener;
import org.eclipse.debug.internal.ui.ILaunchLabelChangedListener;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
import org.eclipse.debug.ui.ILaunchGroup;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.internal.WorkbenchWindow;

import com.ibm.icu.text.MessageFormat;

/**
 * This manager is used to calculate the labels for the current resource or for the current
 * state of the launch history, depending on the enabled status of contextual launching. More specifically
 * if contextual launching is enabled the calculated labels are for the current resource, otherwise
 * the calculated labels are for the current state of the launch history.
 *
 * Any actions interested in being notified of launch label updates need to register with this manager, and implement
 * the <code>ILaunchLabelChangedListener</code> interface.
 *
 * @see ILaunchLabelChangedListener
 * @see org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction
 *
 * @since 3.3
 */
@SuppressWarnings("restriction")
public class LaunchingResourceManager implements IPropertyChangeListener, IWindowListener, ISelectionListener, ILaunchHistoryChangedListener, ILaunchesListener2 {

	/**
	 *The set of label update listeners
	 */
	private ListenerList<ILaunchLabelChangedListener> fLabelListeners = new ListenerList<>();

	/**
	 * The map of ToolBars that have mouse tracker listeners associated with them:
	 * stored as Map<IWorkbenchWindow, ToolBar>
	 */
	private HashMap<IWorkbenchWindow, ToolBar> fToolbars = new HashMap<>();

	/**
	 * the map of current labels
	 */
	private HashMap<ILaunchGroup, String> fCurrentLabels = new HashMap<>();

	/**
	 * The selection has changed and we need to update the labels
	 */
	private boolean fUpdateLabel = true;

	/**
	 * Set of windows that have been opened and that we have registered selection listeners with
	 */
	private HashSet<IWorkbenchWindow> fWindows = new HashSet<>();

	/**
	 * Cache of IResource -> ILaunchConfiguration[] used during a tooltip update job.
	 * The cache is cleared after each tooltip update job is complete.
	 */
	private HashMap<IResource, ILaunchConfiguration[]> fConfigCache = new HashMap<>();

	/**
	 * Cache of IResource -> LaunchShortcutExtension used during a tooltip update job.
	 * The cache is cleared after each tooltip update job is complete.
	 */
	private HashMap<IResource, List<LaunchShortcutExtension>> fExtCache = new HashMap<>();

	/**
	 * Constant denoting the empty string;
	 */
	private static final String EMPTY_STRING = IInternalDebugCoreConstants.EMPTY_STRING;

	/**
	 * Provides a mouse tracker listener for the launching main toolbar
	 */
	private MouseTrackAdapter fMouseListener = new MouseTrackAdapter() {
		@Override
		public void mouseEnter(MouseEvent e) {
			if(fUpdateLabel) {
				fUpdateLabel = false;
				fCurrentLabels.clear();
				Job job = new Job("Compute launch button tooltip") { //$NON-NLS-1$
					@Override
					protected IStatus run(IProgressMonitor monitor) {
						computeLabels();
						fConfigCache.clear();
						fExtCache.clear();
						return Status.OK_STATUS;
					}
				};
				job.setSystem(true);
				job.schedule();
			}
		}
	};

	/**
	 * Returns if context launching is enabled
	 * @return if context launching is enabled
	 */
	public static boolean isContextLaunchEnabled() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH);
	}

	/**
	 * Returns if context launching is enabled or not. Context launching is enabled iff:
	 * <ul>
	 * <li>The preference is turned on</li>
	 * <li>the launch group id is not <code>org.eclipse.ui.externaltools.launchGroup</code></li>
	 * </ul>
	 * @param launchgroupid the id of the {@link ILaunchGroup}
	 * @return <code>true</code> if context launching is enabled <code>false</code> otherwise
	 */
	public static boolean isContextLaunchEnabled(String launchgroupid) {
		return isContextLaunchEnabled() && !"org.eclipse.ui.externaltools.launchGroup".equals(launchgroupid); //$NON-NLS-1$
	}

	/**
	 * Allows an <code>AbstractLaunchHistoryAction</code> to register with this manager to be notified
	 * of a context (<code>IResource</code>) change and have its updateToolTip(..) method called back to.
	 * <br><br>
	 * Obeys the contract of listener addition as outlined in {@link ListenerList#add(Object)}
	 * @param listener the {@link ILaunchLabelChangedListener} to add
	 */
	public void addLaunchLabelUpdateListener(ILaunchLabelChangedListener listener) {
		fLabelListeners.add(listener);
	}

	/**
	 * Removes the specified <code>AbstractLaunchHistoryAction</code> from the listing of registered
	 * listeners
	 * <br><br>
	 * Obeys the contract of listener removal as outlined in {@link ListenerList#remove(Object)}
	 * @param listener the {@link ILaunchLabelChangedListener} to remove
	 */
	public void removeLaunchLabelChangedListener(ILaunchLabelChangedListener listener) {
		fLabelListeners.remove(listener);
	}

	/**
	 * Returns the current resource label to be displayed.
	 *
	 * @param group the launch group to get the label for
	 * @return the current resource label;
	 */
	public String getLaunchLabel(ILaunchGroup group) {
		return fCurrentLabels.get(group);
	}

	/**
	 * Returns if the parent project should be checked automatically
	 * @return true if the parent project should checked automatically, false otherwise
	 */
	protected boolean shouldCheckParent() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_PARENT_PROJECT);
	}

	/**
	 * Returns if the the last launch configuration should be launched if the selected resource is not launchable and context launching is enabled
	 * @return true if the last launched should be launched, false otherwise
	 */
	protected boolean shouldLaunchLast() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE);
	}

	/**
	 * Computes the current listing of labels for the given <code>IResource</code> context change or the
	 * current launch history changed event
	 */
	protected void computeLabels() {
		ILaunchGroup group = null;
		ILaunchConfiguration config = null;
		String label = null;

		SelectedResourceManager srm = SelectedResourceManager.getDefault();
		IStructuredSelection selection = srm.getCurrentSelection();
		List<LaunchShortcutExtension> shortcuts = null;
		IResource resource = srm.getSelectedResource();
		for (ILaunchLabelChangedListener iLaunchLabelChangedListener : fLabelListeners) {
			group = iLaunchLabelChangedListener.getLaunchGroup();
			if(group != null) {
				if(isContextLaunchEnabled(group.getIdentifier())) {
					shortcuts = getShortcutsForSelection(selection, group.getMode());
					if(resource == null) {
						resource = getLaunchableResource(shortcuts, selection);
					}
					label = getLabel(selection, resource, shortcuts, group);
				}
				else {
					config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
					if(config != null) {
						label = appendLaunched(config);
					}
				}
				fCurrentLabels.put(group, label);
				label = null;
			}
		}
		notifyLabelChanged();
	}

	/**
	 * Notifies all registered listeners that the known labels have changed
	 */
	protected void notifyLabelChanged() {
		for (ILaunchLabelChangedListener iLaunchLabelChangedListener : fLabelListeners) {
			iLaunchLabelChangedListener.labelChanged();
		}
	}

	/**
	 * Appends the text '(already running)' to the tooltip label if there is a launch currently
	 * running (not terminated) with the same backing launch configuration as the one specified
	 * @param config the {@link ILaunchConfiguration} to check for running state
	 * @return the appended string for the tooltip label or the configuration name (default)
	 */
	private String appendLaunched(ILaunchConfiguration config) {
		ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
		boolean launched = false;
		ILaunchConfiguration tmp = null;
		for(int i = 0; i < launches.length; i++) {
			tmp = launches[i].getLaunchConfiguration();
			if(tmp != null) {
				if(!launches[i].isTerminated() && tmp.equals(config)) {
					launched = true;
					break;
				}
			}
		}
		if(launched) {
			return MessageFormat.format(ContextMessages.LaunchingResourceManager_0, new Object[] { config.getName() });
		}
		return config.getName();
	}

	/**
	 * Returns the label for the last launched configuration or and empty string if there was no last launch.
	 * @param group the {@link ILaunchGroup} to get the label for
	 * @return the name of the last launched configuration, altered with '(running)' if needed, or the empty
	 * string if there is no last launch.
	 */
	protected String getlastLaunchedLabel(ILaunchGroup group) {
		ILaunchConfiguration config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
		if(config != null) {
			return appendLaunched(config);
		}
		return EMPTY_STRING;
	}

	/**
	 * Returns the label for the specified resource or the empty string, never <code>null</code>
	 *
	 * @param selection the current {@link IStructuredSelection}
	 * @param resource the backing {@link IResource} for the selection
	 * @param shortcuts the list of {@link ILaunchShortcut}s to consider
	 * @param group the {@link ILaunchGroup} to launch using
	 * @return the label for the resource or the empty string, never <code>null</code>
	 */
	protected String getLabel(IStructuredSelection selection, IResource resource, List<LaunchShortcutExtension> shortcuts, ILaunchGroup group) {
		List<LaunchShortcutExtension> sc = pruneShortcuts(shortcuts, resource, group.getMode());
		LaunchConfigurationManager lcm = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
		//see if the context is a shared configuration
		ILaunchConfiguration config = lcm.isSharedConfig(resource);
		if(config != null) {
			return appendLaunched(config);
		}
		List<ILaunchConfiguration> configs = getParticipatingLaunchConfigurations(selection, resource, sc, group.getMode());
		int csize = configs.size();
		if(csize == 1) {
			return appendLaunched(configs.get(0));
		}
		else if(csize > 1) {
			config = lcm.getMRUConfiguration(configs, group, resource);
			if(config != null) {
				return appendLaunched(config);
			}
			else {
				return ContextMessages.ContextRunner_14;
			}
		}
		else {
			List<LaunchShortcutExtension> exts = fExtCache.get(resource);
			if(exts == null && resource != null) {
				fExtCache.put(resource, sc);
			}
			int esize = sc.size();
			if(esize == 0) {
				if(resource != null && shouldCheckParent()) {
					IProject project = resource.getProject();
					if(project != null && !project.equals(resource)) {
						return getLabel(selection, project, sc, group);
					}
				}
				else if(shouldLaunchLast() || resource == null) {
					return getlastLaunchedLabel(group);
				}
				else {
					return ContextMessages.ContextRunner_15;
				}
			}
			if(esize == 1) {
				if(resource != null) {
					return resource.getName();
				}
				else {
					return MessageFormat.format(ContextMessages.LaunchingResourceManager_1, new Object[] { sc.get(0).getLabel() });
				}
			}
			else {
				return ContextMessages.ContextRunner_14;
			}
		}
	}

	/**
	 * Prunes the original listing of shortcuts
	 * @param shortcuts the original listing of <code>LaunchShortcutExtension</code>s
	 * @param resource the derived resource
	 * @param mode the mode we are wanting to launch in
	 * @return the list of {@link ILaunchShortcut}s to consider
	 *
	 * @since 3.4
	 */
	protected List<LaunchShortcutExtension> pruneShortcuts(List<LaunchShortcutExtension> shortcuts, IResource resource, String mode) {
		List<LaunchShortcutExtension> list = new ArrayList<>(shortcuts);
		if(resource == null) {
			LaunchShortcutExtension ext = null;
			for (ListIterator<LaunchShortcutExtension> iter = list.listIterator(); iter.hasNext();) {
				ext = iter.next();
				if(!ext.isParticipant()) {
					iter.remove();
				}
			}
		}
		else {
			list = getShortcutsForSelection(new StructuredSelection(resource), mode);
		}
		return list;
	}

	/**
	 * Computes the current resources context, given all of the launch shortcut participants
	 * and the current selection
	 * @param shortcuts the list of {@link ILaunchShortcut} to ask for mapped resources
	 * @param selection the current workbench {@link IStructuredSelection}
	 * @return The set of resources who care about this launch
	 *
	 * @since 3.4
	 */
	public IResource getLaunchableResource(List<LaunchShortcutExtension> shortcuts, IStructuredSelection selection) {
		if(selection != null && !selection.isEmpty()) {
			ArrayList<IResource> resources = new ArrayList<>();
			IResource resource = null;
			Object o = selection.getFirstElement();
			for (LaunchShortcutExtension ext : shortcuts) {
				if(o instanceof IEditorPart) {
					resource = ext.getLaunchableResource((IEditorPart) o);
				}
				else {
					resource = ext.getLaunchableResource(selection);
				}
				if(resource != null && !resources.contains(resource)) {
					resources.add(resource);
					resource = null;
				}
			}
			if(resources.size() > 0) {
				return resources.get(0);
			}
		}
		return null;
	}

	/**
	 * Returns the launch shortcuts that apply to the current <code>IStructuredSelection</code>
	 * @param selection the current selection
	 * @param mode the mode
	 * @return the list of shortcuts that apply to the given selection and mode or an empty listing, never <code>null</code>
	 *
	 * @since 3.4
	 */
	public List<LaunchShortcutExtension> getShortcutsForSelection(IStructuredSelection selection, String mode) {
		ArrayList<LaunchShortcutExtension> list = new ArrayList<>();
		List<LaunchShortcutExtension> sc = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchShortcuts();
		List<IEditorInput> ctxt = new ArrayList<>();
		// work around to bug in Structured Selection that returns actual underlying array in selection
		// @see bug 211646
		ctxt.addAll(selection.toList());
		Object o = selection.getFirstElement();
		if(o instanceof IEditorPart) {
			ctxt.set(0, ((IEditorPart)o).getEditorInput());
		}
		IEvaluationContext context = DebugUIPlugin.createEvaluationContext(ctxt);
		context.addVariable("selection", ctxt); //$NON-NLS-1$
		for (LaunchShortcutExtension ext : sc) {
			try {
				if(ext.evalEnablementExpression(context, ext.getContextualLaunchEnablementExpression()) &&
						ext.getModes().contains(mode) && !WorkbenchActivityHelper.filterItem(ext)) {
					if(!list.contains(ext)) {
						list.add(ext);
					}
				}
			}
			catch(CoreException ce) {}
		}
		return list;
	}

	/**
	 * Returns a listing of all launch configurations that want to participate in the contextual
	 * launch of the specified resource or specified selection
	 * @param resource the underlying resource
	 * @param selection the current selection in the workbench
	 * @param shortcuts the listing of shortcut extensions that apply to the current context
	 * @param mode the mode
	 * @return a listing of all launch configurations wanting to participate in the current launching
	 *
	 * @since 3.4
	 */
	public List<ILaunchConfiguration> getParticipatingLaunchConfigurations(IStructuredSelection selection, IResource resource, List<LaunchShortcutExtension> shortcuts, String mode) {
		List<ILaunchConfiguration> configs = new ArrayList<>();
		int voteDefault = 0;
		if(selection != null) {
			Object o = selection.getFirstElement();
			LaunchShortcutExtension ext = null;
			ILaunchConfiguration[] cfgs = null;
			for(int i = 0; i < shortcuts.size(); i++) {
				ext = shortcuts.get(i);
				if(o instanceof IEditorPart) {
					cfgs = ext.getLaunchConfigurations((IEditorPart)o);
				}
				else {
					 cfgs = ext.getLaunchConfigurations(selection);
				}
				if (cfgs == null) {
					Set<String> types = ext.getAssociatedConfigurationTypes();
					addAllToList(configs, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getApplicableLaunchConfigurations(types.toArray(new String[types.size()]), resource));
					voteDefault++;
				} else {
					if(cfgs.length > 0) {
						for(int j = 0; j < cfgs.length; j++) {
							configs.add(cfgs[j]);
						}
					}
				}
			}
		}
		if (voteDefault == shortcuts.size()) {
			// consider default configurations if no configurations were contributed
			addAllToList(configs, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getApplicableLaunchConfigurations(null, resource));
		}
		Iterator<ILaunchConfiguration> iterator = configs.iterator();
		while (iterator.hasNext()) {
			ILaunchConfiguration config = iterator.next();
			try {
				Set<String> modes = config.getModes();
				modes.add(mode);
				if (!config.getType().supportsModeCombination(modes)) {
					iterator.remove();
				}
			}
			catch (CoreException e) {}
		}
		return configs;
	}

	/**
	 * Adds all of the items in the given object array to the given collection.
	 * Does nothing if either the collection or array is <code>null</code>.
	 * @param list the {@link List} to append to
	 * @param values the array of {@link Object}s to add to the list
	 */
	private void addAllToList(List<ILaunchConfiguration> list, ILaunchConfiguration[] configs) {
		if (list == null || configs == null) {
			return;
		}
		for (int i = 0; i < configs.length; i++) {
			if (!list.contains(configs[i])) {
				list.add(configs[i]);
			}
		}
	}

	/**
	 * Starts up the manager
	 */
	public void startup() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		if(workbench != null) {
			workbench.addWindowListener(this);
			// initialize for already open windows
			IWorkbenchWindow[] workbenchWindows = workbench.getWorkbenchWindows();
			for (int i = 0; i < workbenchWindows.length; i++) {
				if (workbenchWindows[i].getSelectionService() != null) {
					windowOpened(workbenchWindows[i]);
				}
			}
		}
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		DebugUIPlugin.getDefault().getLaunchConfigurationManager().addLaunchHistoryListener(this);
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
	}

	/**
	 * Shutdown and clean up the manager
	 */
	public void shutdown() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		if(workbench != null) {
			workbench.removeWindowListener(this);
		}
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		DebugUIPlugin.getDefault().getLaunchConfigurationManager().removeLaunchHistoryListener(this);
		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		for (IWorkbenchWindow window : fWindows) {
			window.getSelectionService().removeSelectionListener(this);
		}
		// set fUpdateLabel to false so that mouse track listener will do nothing if called
		// before the asynchronous execution disposes them
		fUpdateLabel = false;
		for (Entry<IWorkbenchWindow, ToolBar> entry : fToolbars.entrySet()) {
			final ToolBar bar = entry.getValue();
			if(bar != null && !bar.isDisposed()) {
				final MouseTrackAdapter listener = fMouseListener;
				DebugUIPlugin.getStandardDisplay().asyncExec(() -> bar.removeMouseTrackListener(listener));

			}
		}
		fWindows.clear();
		fToolbars.clear();
		fLabelListeners.clear();
		fCurrentLabels.clear();
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowActivated(IWorkbenchWindow window) {
		if(!fToolbars.containsKey(window)) {
			addMouseListener(window);
		}
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowClosed(IWorkbenchWindow window) {
		ToolBar bar = fToolbars.remove(window);
		if(bar != null && !bar.isDisposed()) {
			bar.removeMouseTrackListener(fMouseListener);
		}
		if(fWindows.remove(window)) {
			window.getSelectionService().removeSelectionListener(this);
		}
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowDeactivated(IWorkbenchWindow window) {}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowOpened(IWorkbenchWindow window) {
		if(fWindows.add(window)) {
			window.getSelectionService().addSelectionListener(this);
		}
	}

	/**
	 * Adds a mouse listener to the launch toolbar
	 *
	 * @param window the {@link IWorkbenchWindow} to work with
	 */
	private void addMouseListener(IWorkbenchWindow window) {
		ICoolBarManager cmgr = ((WorkbenchWindow)window).getCoolBarManager2();
		if(cmgr != null) {
			IContributionItem item = cmgr.find("org.eclipse.debug.ui.launchActionSet"); //$NON-NLS-1$
			if(item instanceof ToolBarContributionItem) {
				ToolBarManager tmgr = (ToolBarManager) ((ToolBarContributionItem)item).getToolBarManager();
				ToolBar bar = tmgr.getControl();
				if(bar != null && !bar.isDisposed()) {
					bar.addMouseTrackListener(fMouseListener);
					fToolbars.put(window, bar);
				}
			}
		}
	}

	/**
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		if(event.getProperty().equals(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH) ||
				event.getProperty().equals(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE)) {
			if(isContextLaunchEnabled()) {
				windowActivated(DebugUIPlugin.getActiveWorkbenchWindow());
			}
			fUpdateLabel = true;
		}
	}

	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		if(isContextLaunchEnabled()) {
			fUpdateLabel = true;
		}
	}

	@Override
	public void launchHistoryChanged() {
		//this always must be set to true, because as the history is loaded these events are fired, and we need to
		//update on workspace load.
		fUpdateLabel = true;
	}

	@Override
	public void launchesTerminated(ILaunch[] launches) {
		fUpdateLabel = true;
	}

	@Override
	public void launchesAdded(ILaunch[] launches) {
		fUpdateLabel = true;
	}

	@Override
	public void launchesChanged(ILaunch[] launches) {}

	@Override
	public void launchesRemoved(ILaunch[] launches) {
		//we want to ensure that even if a launch is removed from the debug view
		//when it is not terminated we update the label just in case.
		//bug 195232
		for(int i = 0; i < launches.length; i++) {
			if(!launches[i].isTerminated()) {
				fUpdateLabel = true;
				return;
			}
		}
	}
}
