/*******************************************************************************
 * Copyright (c) 2000, 2009 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.debug.internal.ui.launchConfigurations;


import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.core.LaunchConfigurationWorkingCopy;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;

import com.ibm.icu.text.MessageFormat;

/**
 * A viewer that displays tabs for a launch configuration, with apply and revert
 * buttons.
 */
public class LaunchConfigurationTabGroupViewer {
	
	/**
	 * Containing launch dialog
	 */
	private ILaunchConfigurationDialog fDialog;
	
	/**
	 * The this viewer's input
	 */
	private Object fInput;
	
	/**
	 * The launch configuration (original) being edited
	 */
	private ILaunchConfiguration fOriginal;
	
	/**
	 * The working copy of the original
	 */
	private ILaunchConfigurationWorkingCopy fWorkingCopy;
	
	/**
	 * This view's control, which contains a composite area of controls
	 */
	private Composite fViewerControl;
	
	/**
	 * The composite which is hidden/displayed as tabs are required.
	 */
	private Composite fVisibleArea;
	
	/**
	 * Name label widget
	 */
	private Label fNameLabel;
	
	/**
	 * Name text widget
	 */
	private Text fNameWidget;
	
	/**
	 * Composite containing the launch config tab widgets
	 */
	private Composite fTabComposite;
	
	/**
	 * Tab folder
	 */
	private CTabFolder fTabFolder;
	
	/**
	 * The current tab group being displayed
	 */
	private ILaunchConfigurationTabGroup fTabGroup;

	/**
	 * The type of config tabs are currently displayed
	 * for
	 */
	private ILaunchConfigurationType fTabType;	
	
	/**
	 * Index of the active tab
	 */
	private int fCurrentTabIndex = -1;
	
	/**
	 * Apply & Revert buttons
	 */
	private Button fApplyButton;
	private Button fRevertButton;
	
	/**
	 * Whether tabs are currently being disposed or initialized
	 */
	private boolean fDisposingTabs = false;
	private boolean fInitializingTabs = false;

	/**
	 * The description of the currently selected launch configuration or
	 * launch configuration type or <code>null</code> if none.
	 */
	private String fDescription = null;
	
	/**
	 * A place holder for switching between the tabs for a config and the getting started tab
	 * @since 3.2
	 */
	private Composite fTabPlaceHolder = null;
	
	/**
	 * A link to allow users to select a valid set of launch options for the specified mode
	 * @since 3.3
	 */
    private Link fOptionsLink = null;

    /**
     * A label to indicate that the user needs to select an a launcher.
     * @since 3.5
     */
    private Label fOptionsErrorLabel = null;
    
	/**
	 * A new composite replacing the perspectives tab
	 * @since 3.2
	 */
	private Composite fGettingStarted = null;

	private ViewForm fViewform;
	
	/**
	 * Constructs a viewer in the given composite, contained by the given
	 * launch configuration dialog.
	 * 
	 * @param parent composite containing this viewer
	 * @param dialog containing launch configuration dialog
	 */
	public LaunchConfigurationTabGroupViewer(Composite parent, ILaunchConfigurationDialog dialog) {
		super();
		fDialog = dialog;
		createControl(parent);
	}
	
	/**
	 * Cleanup
	 */
	public void dispose() {
		disposeTabGroup();
	}

	/**
	 * Dispose the active tab group, if any.
	 */
	protected void disposeTabGroup() {
		if (fTabGroup != null) {
			fTabGroup.dispose();
			fTabGroup = null;
			fTabType = null;
		}
	}	
	
	/**
	 * Creates this viewer's control This area displays the name of the launch
	 * configuration currently being edited, as well as a tab folder of tabs
	 * that are applicable to the launch configuration.
	 *
	 * @return the composite used for launch configuration editing
	 */
	private void createControl(Composite parent) {
		fViewerControl = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;
		fViewerControl.setLayout(layout);
		GridData gd = new GridData(GridData.FILL_BOTH);
		fViewerControl.setLayoutData(gd);
		
        fViewform = new ViewForm(fViewerControl, SWT.FLAT | SWT.BORDER);
        layout = new GridLayout(1, false);
        layout.horizontalSpacing = 0;
        layout.verticalSpacing = 0;
        fViewform.setLayout(layout);
		gd = new GridData(GridData.FILL_BOTH);
		fViewform.setLayoutData(gd);
		fVisibleArea = fViewform;
        fViewform.setTopLeft(null);
        
        Composite mainComp = new Composite(fViewform, SWT.FLAT);
        layout = new GridLayout(1, false);
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        mainComp.setLayout(layout);
        fViewform.setContent(mainComp);

		fTabPlaceHolder = new Composite(mainComp, SWT.NONE);
		fTabPlaceHolder.setLayout(new StackLayout());
		gd = new GridData(GridData.FILL_BOTH);
		fTabPlaceHolder.setLayoutData(gd);
        
		fGettingStarted = new Composite(fTabPlaceHolder, SWT.NONE);
		fGettingStarted.setLayout(new GridLayout());
		gd = new GridData(GridData.FILL_BOTH);
		fGettingStarted.setLayoutData(gd);
		
		createGettingStarted(fGettingStarted);
		
		fTabComposite = new Composite(fTabPlaceHolder, SWT.NONE);
		layout = new GridLayout(2, false);
		layout.verticalSpacing = 10;
		layout.horizontalSpacing = 5;
		fTabComposite.setLayout(layout);
		gd = new GridData(GridData.FILL_BOTH);
		fTabComposite.setLayoutData(gd);
		
		fNameLabel = new Label(fTabComposite, SWT.HORIZONTAL | SWT.LEFT);
		fNameLabel.setText(LaunchConfigurationsMessages.LaunchConfigurationDialog__Name__16); 
        fNameLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
       
		fNameWidget = new Text(fTabComposite, SWT.SINGLE | SWT.BORDER);
        fNameWidget.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        fNameWidget.addModifyListener(new ModifyListener() {
    				public void modifyText(ModifyEvent e) {
    					if(!fInitializingTabs) {
    						handleNameModified();
    					}
    				}
    			}
    		);
    		
		createTabFolder(fTabComposite);
		
		Composite blComp = SWTFactory.createComposite(mainComp, mainComp.getFont(), 2, 1, GridData.FILL_HORIZONTAL);
		Composite linkComp = SWTFactory.createComposite(blComp, blComp.getFont(), 2, 1, GridData.FILL_HORIZONTAL);

	//a link for launch options
		fOptionsErrorLabel = new Label(linkComp, SWT.NONE);
        gd = new GridData();
        fOptionsErrorLabel.setLayoutData(gd);
        
		fOptionsLink = new Link(linkComp, SWT.WRAP);
		fOptionsLink.setFont(linkComp.getFont());
		gd = new GridData(SWT.LEFT);
		gd.grabExcessHorizontalSpace = true;
		fOptionsLink.setLayoutData(gd);
		fOptionsLink.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				//collect the options available
				try {
					if(!canLaunchWithModes()) {
						SelectLaunchModesDialog sld = new SelectLaunchModesDialog(getShell(), 
								getLaunchConfigurationDialog().getMode(), getWorkingCopy());
						if(sld.open() == IDialogConstants.OK_ID) {
							//set the options to the config
							Object[] res = sld.getResult();
							if(res != null) {
								Set modes = (Set) res[0];
								modes.remove(getLaunchConfigurationDialog().getMode());
								ILaunchConfigurationWorkingCopy wc = getWorkingCopy();
								wc.setModes(modes);
								refreshStatus();
							}
						}
					}
					else if(hasMultipleDelegates()) {
						SelectLaunchersDialog sldd = new SelectLaunchersDialog(getShell(), 
								getWorkingCopy().getType().getDelegates(getCurrentModeSet()), 
								getWorkingCopy(), 
								getLaunchConfigurationDialog().getMode());
						if(sldd.open() == IDialogConstants.OK_ID) {
							displayInstanceTabs(true);
							refreshStatus();
						}
					}
				} catch (CoreException ex) {}
			}
		});
		fOptionsLink.setVisible(false);
		
		Composite buttonComp = new Composite(blComp, SWT.NONE);
		GridLayout buttonCompLayout = new GridLayout();
		buttonCompLayout.numColumns = 2;
		buttonComp.setLayout(buttonCompLayout);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		buttonComp.setLayoutData(gd);
		
		fApplyButton = new Button(buttonComp, SWT.PUSH);
		fApplyButton.setText(LaunchConfigurationsMessages.LaunchConfigurationDialog__Apply_17); 
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		fApplyButton.setLayoutData(gd);
		SWTFactory.setButtonDimensionHint(fApplyButton);
		fApplyButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				handleApplyPressed();
			}
		});

		fRevertButton = new Button(buttonComp, SWT.PUSH);
		fRevertButton.setText(LaunchConfigurationsMessages.LaunchConfigurationDialog_Revert_2);   
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		fRevertButton.setLayoutData(gd);
		SWTFactory.setButtonDimensionHint(fRevertButton);
		fRevertButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				handleRevertPressed();
			}
		});
        Dialog.applyDialogFont(parent);
	}
	
	/**
	 * Creates some help text for the tab group launch types
	 * @param parent the parent composite
	 * @since 3.2
	 */
	private void createGettingStarted(Composite parent) {
		Font font = parent.getFont();
		GridData gd = null;
		int width = parent.getBounds().width - 30;
		SWTFactory.createWrapLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_1, 1, width);
		SWTFactory.createWrapCLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_2, DebugUITools.getImage(IInternalDebugUIConstants.IMG_ELCL_NEW_CONFIG), 1, width);
		SWTFactory.createWrapCLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_6, DebugUITools.getImage(IInternalDebugUIConstants.IMG_ELCL_DUPLICATE_CONFIG), 1, width);
		SWTFactory.createWrapCLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_4, DebugUITools.getImage(IInternalDebugUIConstants.IMG_ELCL_DELETE_CONFIG), 1, width);
        SWTFactory.createWrapCLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_8, DebugUITools.getImage(IInternalDebugUIConstants.IMG_ELCL_FILTER_CONFIGS), 1, width);
        SWTFactory.createWrapCLabel(parent, LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_3, DebugUITools.getImage(IInternalDebugUIConstants.IMG_OVR_TRANSPARENT), 1, width);
        
		SWTFactory.createHorizontalSpacer(parent, 2);
		Link link = new Link(parent, SWT.LEFT | SWT.WRAP);
		link.setText(LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_5);
		link.setFont(font);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.widthHint = width;
		link.setLayoutData(gd);
		link.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				SWTFactory.showPreferencePage("org.eclipse.debug.ui.PerspectivePreferencePage"); //$NON-NLS-1$
			}
		});
	}
	
	/**
	 * Creates the tab folder for displaying config instances
	 * @param parent
	 */
	private void createTabFolder(Composite parent) {
		if (fTabFolder == null) {
			ColorRegistry reg = JFaceResources.getColorRegistry();
			Color c1 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), //$NON-NLS-1$
				  c2 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END"); //$NON-NLS-1$
			fTabFolder = new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.FLAT);
			GridData gd = new GridData(GridData.FILL_BOTH);
			gd.horizontalSpan = 2;
			fTabFolder.setSelectionBackground(new Color[] {c1, c2},	new int[] {100}, true);
			fTabFolder.setSelectionForeground(reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); //$NON-NLS-1$
			fTabFolder.setSimple(PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
			fTabFolder.setLayoutData(gd);
	        fTabFolder.setBorderVisible(true);
			fTabFolder.setFont(parent.getFont());
			fTabFolder.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					if (!fInitializingTabs) {
						handleTabSelected();
						refresh();
					}
				}
			});	
		}
	}
	
	/**
	 * Returns the apply button
	 */
	protected Button getApplyButton() {
		return fApplyButton;
	}	

	/**
	 * Returns the revert button
	 */
	protected Button getRevertButton() {
		return fRevertButton;
	}	

	/**
	 * Sets the current name
	 */
	public void setName(String name) {
		if (getWorkingCopy() != null) {
			if (name == null) {
				fNameWidget.setText(IInternalDebugCoreConstants.EMPTY_STRING);
			}
			else {
				fNameWidget.setText(name.trim());
			}
			refreshStatus();
		}
	}	

	/**
	 * @see org.eclipse.jface.viewers.Viewer#getControl()
	 */
	public Control getControl() {
		return fViewerControl;
	}
	
	/**
	 * Returns the shell this viewer is contained in.
	 */
	private Shell getShell() {
		return getControl().getShell();
	}

	/**
	 * Returns the current input to the viewer. Input will 
	 * be one of {@link ILaunchConfiguration} or {@link ILaunchConfigurationType}
	 * 
	 * @return returns the current input 
	 */
	public Object getInput() {
		return fInput;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.Viewer#refresh()
	 */
	public void refresh() {
		if (fInitializingTabs) {
			return;
		}
		ILaunchConfigurationTab[] tabs = getTabs();
		if (tabs != null) {
			// update the working copy from the active tab
			boolean newwc = !getWorkingCopy().isDirty();
			ILaunchConfigurationTab tab = getActiveTab();
			if (tab != null) {
			    tab.performApply(getWorkingCopy());
			}
			if((fOriginal instanceof ILaunchConfigurationWorkingCopy) && newwc) {
				try {
					ILaunchConfigurationWorkingCopy copy = getWorkingCopy();
					if(copy != null) {
						copy.doSave();
					}
				} 
				catch (CoreException e) {DebugUIPlugin.log(e);}
			}
			updateButtons();
			// update error ticks
			CTabItem item = null;
			boolean error = false;
			Image image = null;
			for (int i = 0; i < tabs.length; i++) {
				item = fTabFolder.getItem(i);
				image = tabs[i].getImage();
				item.setImage(image);
				if(!tabs[i].isValid(getWorkingCopy())) {
					error = tabs[i].getErrorMessage() != null;
					if(error) {
						item.setImage(DebugUIPlugin.getDefault().getLaunchConfigurationManager().getErrorTabImage(tabs[i]));
					}
				}
			}
			showLink();
			getLaunchConfigurationDialog().updateMessage();
		}
	}
	
	/**
	 * Shows the link for either multiple launch delegates or bad launch mode combinations
	 * 
	 * @since 3.3
	 */
	private void showLink() {
		String text = null;
		if(!canLaunchWithModes()) {
			text = LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_13;
		}
		else if(hasMultipleDelegates()) {
			ILaunchDelegate delegate = getPreferredDelegate();
			if(delegate != null) {
				String name = delegate.getName();
				if(name == null) {
					text = LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_15;
				}
				else {
					text = MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_16, new String[] {name});
				}
			}
			else {
				text = LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_17;
			}
		}
		if(text != null) {
			fOptionsLink.setText(text);
		}
		fOptionsLink.setVisible(!canLaunchWithModes() || hasMultipleDelegates());
		if (hasDuplicateDelegates()) {
	        fOptionsErrorLabel.setImage(JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR));
		} else {
            fOptionsErrorLabel.setImage(null);
		}
		fViewform.layout(true, true);
	}
	
	/**
	 * Returns the preferred launch delegate for the current launch configuration and mode set
	 * @return the preferred launch delegate
	 * 
	 * @since 3.3
	 */
	protected ILaunchDelegate getPreferredDelegate() {
		ILaunchDelegate preferred = null;
		ILaunchConfigurationWorkingCopy config = getWorkingCopy();
		if(config != null) {
			try {
				Set modes = getCurrentModeSet();
				preferred = config.getPreferredDelegate(modes);
				if(preferred == null) {
					preferred = config.getType().getPreferredDelegate(modes);
				}
			}
			catch(CoreException ce) {DebugUIPlugin.log(ce);}
		}
		return preferred;
	}
	
	/**
	 * Returns the listing of modes for the current config
	 * @return the listing of modes for the current config
	 * @since 3.3
	 */
	private Set getCurrentModeSet() {
		Set set = new HashSet();
		ILaunchConfigurationWorkingCopy config = getWorkingCopy();
		if(config != null) {
			try {
				set.addAll(config.getModes());
				set.add(getLaunchConfigurationDialog().getMode());
			}
			catch(CoreException ce) {DebugUIPlugin.log(ce);}
		}
		return set;
	}
	
	/**
	 * updates the button states
	 */
	private void updateButtons() {
		boolean dirty = isDirty() && canSave();
		fApplyButton.setEnabled(dirty);
		fRevertButton.setEnabled(dirty);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.Viewer#setInput(java.lang.Object)
	 */
	public void setInput(final Object input) {
		if(DebugUIPlugin.getStandardDisplay().getThread().equals(Thread.currentThread())) {
			setInput0(input);
		}
		else {
			DebugUIPlugin.getStandardDisplay().syncExec(new Runnable() {
				public void run() {
					setInput0(input);
				}
			});
		}
		
	}
	/**
	 * Sets the input to the tab group viewer
	 * @param input the new input
	 * @since 3.3
	 */
	private void setInput0(Object input) {
		if (input == null) {
			if (fInput == null) {
				return;
			}
			inputChanged(input);
		} else {
			if (!input.equals(fInput)) {
				inputChanged(input);
			}
		}
	}
	
	/**
	 * The input has changed to the given object, possibly <code>null</code>.
	 * 
	 * @param input the new input, possibly <code>null</code>
	 */
	protected void inputChanged(Object input) {
		fInput = input;
		Runnable r = new Runnable() {
			public void run() {
				try {
					fVisibleArea.setRedraw(false);
					if (fInput instanceof ILaunchConfiguration) {
						ILaunchConfiguration configuration = (ILaunchConfiguration)fInput;
						boolean refreshtabs = !delegatesEqual(fWorkingCopy, configuration);
						fOriginal = configuration;
						fWorkingCopy = configuration.getWorkingCopy();
						displayInstanceTabs(refreshtabs);
					} else if (fInput instanceof ILaunchConfigurationType) {
						fDescription = getDescription((ILaunchConfigurationType)fInput);
						setNoInput();
					} else {
						setNoInput();
					}
				} catch (CoreException ce) {
					errorDialog(ce);
					setNoInput();
				}
				finally {
					refreshStatus();
					fVisibleArea.setRedraw(true);
				}
			}
		};
		BusyIndicator.showWhile(getShell().getDisplay(), r);
	}
	
	/**
	 * Sets the tab group viewer to have no input, this is the case when null is passed as an input type
	 * Setting no input is equivalent to resetting all items, clearing any messages and showing the 'getting started' pane
	 * @since 3.2 
	 */
	private void setNoInput() {
		fOriginal = null;
		fWorkingCopy = null;
		disposeExistingTabs();	
		updateButtons();
		updateVisibleControls(false);
		ILaunchConfigurationDialog lcd = getLaunchConfigurationDialog();
		if(lcd instanceof LaunchConfigurationsDialog) {
			if(((LaunchConfigurationsDialog)lcd).isTreeSelectionEmpty()) {
				fDescription = IInternalDebugCoreConstants.EMPTY_STRING;
			}
		}
	}
	
	/**
	 * Returns if the two configurations are using the same <code>ILaunchDelegate</code> or not
	 * @param config1
	 * @param config2
	 * @return true if the configurations are using the same <code>ILaunchDelegate</code> or false if they are not
	 * @since 3.3
	 */
	protected boolean delegatesEqual(ILaunchConfiguration config1, ILaunchConfiguration config2) {
		try {
			if(config1 == null || config2 == null) {
				return false;
			}
			Set modes = getCurrentModeSet();
			ILaunchDelegate d1 = config1.getPreferredDelegate(modes);
			if(d1 == null) {
				d1 = config1.getType().getPreferredDelegate(modes);
			}
			ILaunchDelegate d2 = config2.getPreferredDelegate(modes);
			if(d2 == null) {
				d2 = config2.getType().getPreferredDelegate(modes);
			}
			if(d1 != null) {
				return d1.equals(d2);
			}
		}
		catch(CoreException ce) {DebugUIPlugin.log(ce);}
		return false;
	}
	
	/**
	 * Updates the visibility of controls based on the status provided 
	 * @param visible the visibility status to be applied to the controls
	 */
	private void updateVisibleControls(boolean visible) {
		fApplyButton.setVisible(visible);
		fRevertButton.setVisible(visible);
		fOptionsLink.setVisible(visible);
		if(visible) {
			((StackLayout)fTabPlaceHolder.getLayout()).topControl = fTabComposite;
		}
		else {
			((StackLayout)fTabPlaceHolder.getLayout()).topControl = fGettingStarted;
		}
		fTabPlaceHolder.layout(true, true);
	}
	
    /**
     * sets the current widget focus to the 'Name' widget
     */
    protected void setFocusOnName() {
        fNameWidget.setFocus();
    }
    
	/**
	 * Displays tabs for the current working copy
	 */
	protected void displayInstanceTabs(boolean redrawTabs) {
		// Turn on initializing flag to ignore message updates
		fInitializingTabs = true;
		ILaunchConfigurationType type = null;
		try {
			type = getWorkingCopy().getType();
		} 
		catch (CoreException e) {
			errorDialog(e);
			fInitializingTabs = false;
			return;
		}
		if(redrawTabs) {
			showInstanceTabsFor(type);
		}
		// show the name area
		updateVisibleControls(true);

		// Retrieve the current tab group.  If there is none, clean up and leave
		ILaunchConfigurationTabGroup tabGroup = getTabGroup();
		if (tabGroup == null) {
			IStatus status = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), 0, MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_No_tabs_defined_for_launch_configuration_type__0__1, new String[]{type.getName()}), null); 
			CoreException e = new CoreException(status);
			errorDialog(e);
			fInitializingTabs = false;
			return;
		}

		// Update the tabs with the new working copy
		tabGroup.initializeFrom(getWorkingCopy());

		// Update the name field
		fNameWidget.setText(getWorkingCopy().getName());
		
		fCurrentTabIndex = fTabFolder.getSelectionIndex();

		// Turn off initializing flag to update message
		fInitializingTabs = false;
		
		if (!fVisibleArea.isVisible()) {
			fVisibleArea.setVisible(true);
		}	
	}
	
	/**
	 * Populate the tabs in the configuration edit area to be appropriate to the current
	 * launch configuration type.
	 */
	private void showInstanceTabsFor(ILaunchConfigurationType configType) {
		// try to keep on same tab
		Class tabKind = null;
		if (getActiveTab() != null) {
			tabKind = getActiveTab().getClass();
		}
		// Build the new tabs
		ILaunchConfigurationTabGroup group = null;
		try {
			group = createGroup();
		} catch (CoreException ce) {
			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.LaunchConfigurationDialog_Error_19, LaunchConfigurationsMessages.LaunchConfigurationDialog_Exception_occurred_creating_launch_configuration_tabs_27,ce); // 
			return;
		}
		disposeExistingTabs();
		fTabGroup = group;
		fTabType = configType;
		ILaunchConfigurationTab[] tabs = getTabs();
		CTabItem tab = null;
		String name = IInternalDebugCoreConstants.EMPTY_STRING;
		Control control = null;
		for (int i = 0; i < tabs.length; i++) {
			tab = new CTabItem(fTabFolder, SWT.BORDER);
			name = tabs[i].getName();
			if (name == null) {
				name = LaunchConfigurationsMessages.LaunchConfigurationDialog_unspecified_28; 
			}
			tab.setText(name);
			tab.setImage(tabs[i].getImage());
			tabs[i].createControl(tab.getParent());
			control = tabs[i].getControl();
			if (control != null) {
				tab.setControl(control);
			}
		}
		//set the default tab as the first one
		if (tabs.length > 0) {
		    setActiveTab(tabs[0]);
		}
		// select same tab as before, if possible
		for (int i = 0; i < tabs.length; i++) {
			if (tabs[i].getClass().equals(tabKind)) {
				setActiveTab(tabs[i]);
				break;
			}
		}
		fDescription = getDescription(configType);
	}	

	/**
	 * Returns the description of the given configuration type
	 * in the current mode or <code>null</code> if none.
	 * 
	 * @param configType the config type
	 * @return the description of the given configuration type or <code>null</code>
	 */
	private String getDescription(ILaunchConfigurationType configType) {
		String description = null;
		if(configType != null) {
			String mode = fDialog.getMode();
			description = LaunchConfigurationPresentationManager.getDefault().getDescription(configType, mode);
		}	
		if (description == null) {
			description = IInternalDebugCoreConstants.EMPTY_STRING;
		}
		return description;
	}
	
	/**
	 * Returns tab group for the given type of launch configuration.
	 * Tabs are initialized to be contained in this dialog.
	 *
	 * @exception CoreException if unable to instantiate a tab group
	 */
	protected ILaunchConfigurationTabGroup createGroup() throws CoreException {
		// Use a final Object array to store the tab group and any exception that
		// results from the Runnable
		final Object[] finalArray = new Object[2];
		Runnable runnable = new Runnable() {
			public void run() {
				ILaunchConfigurationTabGroup tabGroup = null;
				try {
					tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(getWorkingCopy(), getLaunchConfigurationDialog().getMode());
					finalArray[0] = tabGroup;
				} catch (CoreException ce) {
					finalArray[1] = ce;
					return;
				}
				tabGroup.createTabs(getLaunchConfigurationDialog(), getLaunchConfigurationDialog().getMode());
				ILaunchConfigurationTab[] tabs = tabGroup.getTabs();
				for (int i = 0; i < tabs.length; i++) {
					tabs[i].setLaunchConfigurationDialog(getLaunchConfigurationDialog());
				}
			}
		};

		// Creating the tabs can result in plug-in loading, so we show the busy cursor
		BusyIndicator.showWhile(getControl().getDisplay(), runnable);

		// Re-throw any CoreException if there was one
		if (finalArray[1] != null) {
			throw (CoreException)finalArray[1];
		}

		// Otherwise return the tab group
		return (ILaunchConfigurationTabGroup)finalArray[0];
	}	
	
	/**
	 * Returns the tabs currently being displayed, or
	 * <code>null</code> if none.
	 *
	 * @return currently displayed tabs, or <code>null</code>
	 */
	public ILaunchConfigurationTab[] getTabs() {
		if (getTabGroup() != null) {
			return getTabGroup().getTabs();
		}
		return null;
	}

	/**
	 * Returns the currently active <code>ILaunchConfigurationTab</code>
	 * being displayed, or <code>null</code> if there is none.
	 *
	 * @return currently active <code>ILaunchConfigurationTab</code>, or <code>null</code>.
	 */
	public ILaunchConfigurationTab getActiveTab() {
		ILaunchConfigurationTab[] tabs = getTabs();
		if (fTabFolder != null && tabs != null) {
			int pageIndex = fTabFolder.getSelectionIndex();
			if (pageIndex >= 0) {
				return tabs[pageIndex];
			}
		}
		return null;
	}
	
	/**
	 * Returns whether the launch configuration being edited is dirty (i.e.
	 * needs saving)
	 * 
	 * @return whether the launch configuration being edited needs saving
	 */
	public boolean isDirty() {
		ILaunchConfigurationWorkingCopy workingCopy = getWorkingCopy();
		if (workingCopy == null) {
			return false;
		}
		if(workingCopy.getParent() != null) {
			return !workingCopy.getParent().contentsEqual(workingCopy);
		}
		// Working copy hasn't been saved
		if (workingCopy.getOriginal() == null) {
			return true;
		}
		return fOriginal != null && !fOriginal.contentsEqual(workingCopy);
	}
	
	/**
	 * Update apply & revert buttons, as well as buttons and message on the
	 * launch config dialog.
	 */
	protected void refreshStatus() {
		if (!fInitializingTabs) {
			LaunchConfigurationsDialog lcd = (LaunchConfigurationsDialog) getLaunchConfigurationDialog();
			lcd.refreshStatus();
		}
	}	
	
	/**
	 * Returns the containing launch dialog
	 */
	protected ILaunchConfigurationDialog getLaunchConfigurationDialog() {
		return fDialog;
	}

	/**
	 * Returns the original launch configuration being edited, possibly
	 * <code>null</code>.
	 * 
	 * @return ILaunchConfiguration
	 */
	protected ILaunchConfiguration getOriginal() {
		return fOriginal;
	}
	
	/**
	 * Returns the working copy used to edit the original, possibly
	 * <code>null</code>.
 	 */
	protected ILaunchConfigurationWorkingCopy getWorkingCopy() {
		return fWorkingCopy;
	}
	
	/**
	 * Return whether the current configuration can be saved.
	 * <p>
	 * Note this is NOT the same thing as the config simply being valid. It
	 * is possible to save a config that does not validate. This method
	 * determines whether the config can be saved without causing a serious
	 * error. For example, a shared config that has no specified location would
	 * cause this method to return <code>false</code>.
	 * </p>
	 */
	public boolean canSave() {
		if (fInitializingTabs) {
			return false;
		}
		// First make sure that name doesn't prevent saving the config
		try {
			verifyName();
		} catch (CoreException ce) {
			return false;
		}

		// Next, make sure none of the tabs object to saving the config
		ILaunchConfigurationTab[] tabs = getTabs();
		if (tabs == null) {
			return false;
		}
		for (int i = 0; i < tabs.length; i++) {
			if (!tabs[i].canSave()) {
				return false;
			}
		}
		return true;
	}	
	
	/**
	 * @see ILaunchConfigurationDialog#canLaunch()
	 */
	public boolean canLaunch() {
		if(fInitializingTabs) {
			return false;
		}
		if (getWorkingCopy() == null) {
			return false;
		}
		try {
			verifyName();
		} catch (CoreException e) {
			return false;
		}

		ILaunchConfigurationTab[] tabs = getTabs();
		if (tabs == null) {
			return false;
		}
		for (int i = 0; i < tabs.length; i++) {
			if (!tabs[i].isValid(getWorkingCopy())) {
				return false;
			}
		}
		return true;
	}	
	
	/**
	 * Determines if the tab groups that is currently visible can launch with the currently selected
	 * set of options.
	 * 
	 * @return true if the dialog can launch with the given set of modes, false otherwise
	 * 
	 * @since 3.3
	 */
	public boolean canLaunchWithModes() {
		if(fInitializingTabs) {
			return false;
		}
		//check if selected options exist and that the selected combination can be launched
		try {
			ILaunchConfigurationWorkingCopy wc = getWorkingCopy();
			if(wc != null) {
				return wc.getType().supportsModeCombination(getCurrentModeSet());
			}
		}  catch (CoreException e) {
		}
		return true;
	}
	
	/**
	 * Returns if the type currently showing in the tab group viewer has duplicate launch delegates for the given set of modes.
	 * 
	 * The given set of modes comprises the current mode that the launch dialog was opened in as well as any modes that have been set on the launch
	 * configuration.
	 * @return the true if there are duplicates, false otherwise
	 * 
	 * @since 3.3
	 */
	public boolean hasDuplicateDelegates() {
		if(fInitializingTabs) {
			return false;
		}
		ILaunchConfiguration config = getWorkingCopy();
		if(config != null) {
			if(hasMultipleDelegates()) {
				return getPreferredDelegate() == null;
			}
		}
		return false;
	}
	
	/**
	 * Determines if the currently showing launch configuration has multiple launch delegates for the same mode set, but does not care
	 * if there has been a default selected yet or not
	 * @return true if the current launch configuration has multiple launch delegates, false otherwise
	 */
	private boolean hasMultipleDelegates() {
		ILaunchConfiguration config = getWorkingCopy();
		if(config != null) {
			try {
				Set modes = getCurrentModeSet();
				ILaunchDelegate[] delegates = LaunchConfigurationManager.filterLaunchDelegates(fTabType, modes);
				return delegates.length > 1;
			}
			catch (CoreException ce) {DebugUIPlugin.log(ce);}
		}
		return false;
	}
	
	/**
	 * Returns the current error message or <code>null</code> if none.
	 */
	public String getErrorMesssage() {
		if (fInitializingTabs) {
			return null;
		}
		
		if (getWorkingCopy() == null) {
			return null;
		}
		try {
			verifyName();
		} catch (CoreException ce) {
			return ce.getStatus().getMessage();
		}

		if(hasDuplicateDelegates()) {
		    return LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_18;
		}

		String message = null;
		ILaunchConfigurationTab activeTab = getActiveTab();
		if (activeTab == null) {
			return null;
		} 
		message = activeTab.getErrorMessage();
		if (message != null) {
			return message;
		}
		
		ILaunchConfigurationTab[] allTabs = getTabs();
		for (int i = 0; i < allTabs.length; i++) {
			ILaunchConfigurationTab tab = allTabs[i];
			if (tab == activeTab) {
				continue;
			}
			message = tab.getErrorMessage();
			if (message != null) {
				StringBuffer temp= new StringBuffer();
				temp.append('[');
				temp.append(DebugUIPlugin.removeAccelerators(tab.getName()));
				temp.append("]: "); //$NON-NLS-1$
				temp.append(message);
				return temp.toString();
			}
		}
		if(!canLaunchWithModes()) {
			Set modes = getCurrentModeSet();
			List names = LaunchConfigurationPresentationManager.getDefault().getLaunchModeNames(modes);
			return MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationTabGroupViewer_14, new String[]{names.toString()});
		}
		return null;
	}	
	
	/**
	 * Returns the current message or <code>null</code> if none.
	 * @return Returns an appropriate message for display to user. The message returned will be:
	 * The message defined by the visible tab,
	 * or The tab group description for the particular launch mode,
	 * or The generic tab group description,
	 * or <code>null</code> if no message is defined 
	 */
	public String getMessage() {
		if (fInitializingTabs) {
			return null;
		}
		
		String message = fDescription;
		
		ILaunchConfigurationTab tab = getActiveTab();
		if (tab != null) {
			String tabMessage = tab.getMessage();
			if (tabMessage != null) {
				message = tabMessage;
			}
		}
		
		return message;
	}	
		
	/**
	 * Verify that the launch configuration name is valid.
	 */
	protected void verifyName() throws CoreException {
		if (fNameWidget.isVisible()) {
			ILaunchManager mgr = DebugPlugin.getDefault().getLaunchManager();
			String currentName = fNameWidget.getText().trim();
	
			// If there is no name, complain
			if (currentName.length() < 1) {
				throw new CoreException(new Status(IStatus.ERROR,
													 DebugUIPlugin.getUniqueIdentifier(),
													 0,
													 LaunchConfigurationsMessages.LaunchConfigurationDialog_Name_required_for_launch_configuration_11, 
													 null));
			}
			try {
				mgr.isValidLaunchConfigurationName(currentName);
			}
			catch(IllegalArgumentException iae) {
				throw new CoreException(new Status(IStatus.ERROR,
						 DebugUIPlugin.getUniqueIdentifier(),
						 0,
						 iae.getMessage(),
						 null));
			}
			// Otherwise, if there's already a config with the same name, complain
			if (fOriginal != null && !fOriginal.getName().equals(currentName)) {
				Set reservednames = ((LaunchConfigurationsDialog)getLaunchConfigurationDialog()).getReservedNameSet();
				if (mgr.isExistingLaunchConfigurationName(currentName) || (reservednames != null ? reservednames.contains(currentName) : false)) {
					throw new CoreException(new Status(IStatus.ERROR,
														 DebugUIPlugin.getUniqueIdentifier(),
														 0,
														 LaunchConfigurationsMessages.LaunchConfigurationDialog_Launch_configuration_already_exists_with_this_name_12, 
														 null));
				}
			}
		}
	}		
	
	/**
	 * Remove the existing tabs that are showing 
	 */
	private void disposeExistingTabs() {
		fDisposingTabs = true;
        fTabFolder.dispose();
        fTabFolder = null;
		createTabFolder(fTabComposite);
		disposeTabGroup();
		fDisposingTabs = false;
	}	

	/**
	 * Returns the current tab group
	 *
	 * @return the current tab group, or <code>null</code> if none
	 */
	public ILaunchConfigurationTabGroup getTabGroup() {
		return fTabGroup;
	}
	
	/**
	 * Notification that a tab has been selected
	 *
	 * Disallow tab changing when the current tab is invalid.
	 * Update the config from the tab being left, and refresh
	 * the tab being entered.
	 */
	protected void handleTabSelected() {
		if (fDisposingTabs || fInitializingTabs) {
			return;
		}
		ILaunchConfigurationTab[] tabs = getTabs();
		if (fCurrentTabIndex == fTabFolder.getSelectionIndex() || tabs == null || tabs.length == 0 || fCurrentTabIndex > (tabs.length - 1)) {
			return;
		}
		if (fCurrentTabIndex != -1) {
			ILaunchConfigurationTab tab = tabs[fCurrentTabIndex];
			ILaunchConfigurationWorkingCopy wc = getWorkingCopy();
			if (wc != null) {
				tab.deactivated(wc);
				getActiveTab().activated(wc);
			}
		}
		fCurrentTabIndex = fTabFolder.getSelectionIndex();
	}
	
	/**
	 * Notification the name field has been modified
	 */
	protected void handleNameModified() {
		getWorkingCopy().rename(fNameWidget.getText().trim());
		refreshStatus();
	}		
	
	/**
	 * Notification that the 'Apply' button has been pressed
	 */
	protected boolean handleApplyPressed() {
		if(fOriginal != null && fOriginal.isReadOnly()) {
			IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {fOriginal.getFile()}, fViewerControl.getShell());
			if(!status.isOK()) {
				return false;
			}
		}
		Exception exception = null;
		try {
			// update launch config
			fInitializingTabs = true;
			// trim name
			String trimmed = fNameWidget.getText().trim();
			fNameWidget.setText(trimmed);
			if(fWorkingCopy == null) {
				fWorkingCopy = fOriginal.getWorkingCopy();
			}
			fWorkingCopy.rename(trimmed);
			getTabGroup().performApply(fWorkingCopy);
			if (isDirty()) {
				if(!fWorkingCopy.isLocal()) {
					IRunnableWithProgress runnable = new IRunnableWithProgress() {
						public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
							try {
								fOriginal = ((LaunchConfigurationWorkingCopy)fWorkingCopy).doSave(monitor);
							} 
							catch (CoreException e) {DebugUIPlugin.log(e);}
						}
					};
					getLaunchConfigurationDialog().run(true, false, runnable);
				}
				else {
					fOriginal = fWorkingCopy.doSave();
				}
			}
			updateButtons();
			fInitializingTabs = false;
		} 
		catch (CoreException e) {exception = e;} 
		catch (InvocationTargetException e) {exception = e;} 
		catch (InterruptedException e) {exception = e;} 
		if(exception != null) {
			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.LaunchConfigurationDialog_Launch_Configuration_Error_46, LaunchConfigurationsMessages.LaunchConfigurationDialog_Exception_occurred_while_saving_launch_configuration_47, exception); // 
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Notification that the 'Revert' button has been pressed
	 */
	protected void handleRevertPressed() {
		try {
			if(fTabGroup != null) {
				fTabGroup.initializeFrom(fOriginal);
				fNameWidget.setText(fOriginal.getName());
				fWorkingCopy = fOriginal.getWorkingCopy();
				refreshStatus();
			}
		} 
		catch (CoreException e) {DebugUIPlugin.log(e);}
	}	
	
	/**
	 * Show an error dialog on the given exception.
	 *
	 * @param exception
	 */
	protected void errorDialog(CoreException exception) {
		ErrorDialog.openError(getShell(), null, null, exception.getStatus());
	}	

	/**
	 * Sets the displayed tab to the given tab. Has no effect if the specified
	 * tab is not one of the tabs being displayed in the dialog currently.
	 * 
	 * @param tab the tab to display/activate
	 */
	public void setActiveTab(ILaunchConfigurationTab tab) {
		ILaunchConfigurationTab[] tabs = getTabs();
		if(tabs != null) {
			for (int i = 0; i < tabs.length; i++) {
				if (tabs[i].getClass().equals(tab.getClass())) {
					setActiveTab(i);
					return;
				}
			}
		}
	}
	
	/**
	 * Sets the displayed tab to the tab with the given index. Has no effect if
	 * the specified index is not within the limits of the tabs returned by
	 * <code>getTabs()</code>.
	 * 
	 * @param index the index of the tab to display
	 */
	public void setActiveTab(int index) {
		ILaunchConfigurationTab[] tabs = getTabs();
		if (index >= 0 && index < tabs.length) {
			fTabFolder.setSelection(index);
			handleTabSelected();
		}
	}

}
