/*******************************************************************************
 * Copyright (c) 2000, 2013 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
 *     Martin Karpisek (martin.karpisek@gmail.com) - bug 229474
 *******************************************************************************/
package org.eclipse.ant.internal.ui.launchConfigurations;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.ant.internal.ui.AntUIImages;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.InternalTargetFilter;
import org.eclipse.ant.launching.IAntLaunchConstants;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
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.jobs.ISchedulingRule;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
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.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import com.ibm.icu.text.MessageFormat;

/**
 * Launch configuration tab which allows the user to choose the targets from an Ant buildfile that will be executed when the configuration is
 * launched.
 */
public class AntTargetsTab extends AbstractLaunchConfigurationTab {

	private AntTargetNode fDefaultTarget = null;
	private AntTargetNode[] fAllTargets = null;
	private List<AntTargetNode> fOrderedTargets = null;

	private CheckboxTableViewer fTableViewer = null;
	private Label fSelectionCountLabel = null;
	private Text fTargetOrderText = null;
	private Button fOrderButton = null;
	private Button fFilterInternalTargets;
	private InternalTargetFilter fInternalTargetFilter = null;
	private Button fSortButton;

	private ILaunchConfiguration fLaunchConfiguration;
	private int fSortDirection = 0;
	private boolean fInitializing = false;

	/**
	 * Sort direction constants.
	 */
	public final static int SORT_NONE = 0;
	public final static int SORT_NAME = 1;
	public final static int SORT_NAME_REVERSE = -1;
	public final static int SORT_DESCRIPTION = 2;
	public final static int SORT_DESCRIPTION_REVERSE = -2;

	/**
	 * A comparator which can sort targets by name or description, in forward or reverse order.
	 */
	private class AntTargetsComparator extends ViewerComparator {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			if (!(e1 instanceof AntTargetNode && e2 instanceof AntTargetNode)) {
				return super.compare(viewer, e1, e2);
			}
			if (fSortDirection == SORT_NONE) {
				return 0;
			}
			String string1, string2;
			int result = 0;
			if (fSortDirection == SORT_NAME || fSortDirection == SORT_NAME_REVERSE) {
				string1 = ((AntTargetNode) e1).getLabel();
				string2 = ((AntTargetNode) e2).getLabel();
			} else {
				string1 = ((AntTargetNode) e1).getTarget().getDescription();
				string2 = ((AntTargetNode) e2).getTarget().getDescription();
			}
			if (string1 != null && string2 != null) {
				result = getComparator().compare(string1, string2);
			} else if (string1 == null) {
				result = 1;
			} else if (string2 == null) {
				result = -1;
			}
			if (fSortDirection < 0) { // reverse sort
				if (result == 0) {
					result = -1;
				} else {
					result = -result;
				}
			}
			return result;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createControl(Composite parent) {
		Font font = parent.getFont();

		Composite comp = new Composite(parent, SWT.NONE);
		setControl(comp);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_TARGETS_TAB);
		GridLayout topLayout = new GridLayout();
		comp.setLayout(topLayout);
		GridData gd = new GridData(GridData.FILL_BOTH);
		comp.setLayoutData(gd);
		comp.setFont(font);

		createTargetsTable(comp);
		createSelectionCount(comp);

		Composite buttonComposite = new Composite(comp, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.verticalSpacing = 0;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonComposite.setLayout(layout);
		buttonComposite.setFont(font);

		createSortTargets(buttonComposite);
		createFilterInternalTargets(buttonComposite);

		createVerticalSpacer(comp, 1);
		createTargetOrder(comp);
		Dialog.applyDialogFont(parent);
	}

	/**
	 * Creates the selection count widget
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createSelectionCount(Composite parent) {
		fSelectionCountLabel = new Label(parent, SWT.NONE);
		fSelectionCountLabel.setFont(parent.getFont());
		fSelectionCountLabel.setText(AntLaunchConfigurationMessages.AntTargetsTab_0_out_of_0_selected_2);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		fSelectionCountLabel.setLayoutData(gd);
	}

	/**
	 * Creates the widgets that display the target order
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createTargetOrder(Composite parent) {
		Font font = parent.getFont();

		Label label = new Label(parent, SWT.NONE);
		label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Target_execution_order__3);
		label.setFont(font);

		Composite orderComposite = new Composite(parent, SWT.NONE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		orderComposite.setLayoutData(gd);
		GridLayout layout = new GridLayout(2, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		orderComposite.setLayout(layout);
		orderComposite.setFont(font);

		fTargetOrderText = new Text(orderComposite, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
		fTargetOrderText.setFont(font);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.heightHint = 40;
		gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
		fTargetOrderText.setLayoutData(gd);

		fOrderButton = createPushButton(orderComposite, AntLaunchConfigurationMessages.AntTargetsTab__Order____4, null);
		gd = (GridData) fOrderButton.getLayoutData();
		gd.verticalAlignment = GridData.BEGINNING;
		fOrderButton.setFont(font);
		fOrderButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				handleOrderPressed();
			}
		});
	}

	/**
	 * Creates the toggle to filter internal targets from the table
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createFilterInternalTargets(Composite parent) {
		fFilterInternalTargets = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_12);
		fFilterInternalTargets.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				handleFilterTargetsSelected();
			}
		});
	}

	/**
	 * Creates the toggle to sort targets in the table
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createSortTargets(Composite parent) {
		fSortButton = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_14);
		fSortButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				handleSortTargetsSelected();
			}
		});
	}

	/**
	 * The filter targets button has been toggled. If it's been turned on, filter out internal targets. Else, restore internal targets to the table.
	 */
	private void handleFilterTargetsSelected() {
		boolean filter = fFilterInternalTargets.getSelection();
		if (filter) {
			fTableViewer.addFilter(getInternalTargetsFilter());
		} else {
			fTableViewer.removeFilter(getInternalTargetsFilter());
		}

		// Must refresh before updating selection count because the selection
		// count's "hidden" reporting needs the content provider to be queried
		// first to count how many targets are hidden.
		updateSelectionCount();
		if (!fInitializing) {
			updateLaunchConfigurationDialog();
		}
	}

	private ViewerFilter getInternalTargetsFilter() {
		if (fInternalTargetFilter == null) {
			fInternalTargetFilter = new InternalTargetFilter();
		}
		return fInternalTargetFilter;
	}

	/**
	 * The button to sort targets has been toggled. Set the tab's sorting as appropriate.
	 */
	private void handleSortTargetsSelected() {
		setSort(fSortButton.getSelection() ? SORT_NAME : SORT_NONE);
	}

	/**
	 * Sets the sorting of targets in this tab. See the sort constants defined above.
	 * 
	 * @param column
	 *            the column which should be sorted on
	 */
	private void setSort(int column) {
		fSortDirection = column;
		fTableViewer.refresh();
		if (!fInitializing) {
			updateLaunchConfigurationDialog();
		}
	}

	/**
	 * The target order button has been pressed. Prompt the user to reorder the selected targets.
	 */
	private void handleOrderPressed() {
		TargetOrderDialog dialog = new TargetOrderDialog(getShell(), fOrderedTargets.toArray(new AntTargetNode[fOrderedTargets.size()]));
		int ok = dialog.open();
		if (ok == Window.OK) {
			fOrderedTargets.clear();
			Object[] targets = dialog.getTargets();
			for (int i = 0; i < targets.length; i++) {
				fOrderedTargets.add((AntTargetNode) targets[i]);
				updateSelectionCount();
				updateLaunchConfigurationDialog();
			}
		}
	}

	/**
	 * Creates the table which displays the available targets
	 * 
	 * @param parent
	 *            the parent composite
	 */
	private void createTargetsTable(Composite parent) {
		Font font = parent.getFont();
		Label label = new Label(parent, SWT.NONE);
		label.setFont(font);
		label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Check_targets_to_e_xecute__1);

		final Table table = new Table(parent, SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION);

		GridData data = new GridData(GridData.FILL_BOTH);
		int availableRows = availableRows(parent);
		data.heightHint = table.getItemHeight() * (availableRows / 20);
		data.widthHint = 250;
		table.setLayoutData(data);
		table.setFont(font);

		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		TableLayout tableLayout = new TableLayout();
		ColumnWeightData weightData = new ColumnWeightData(30, true);
		tableLayout.addColumnData(weightData);
		weightData = new ColumnWeightData(70, true);
		tableLayout.addColumnData(weightData);
		table.setLayout(tableLayout);

		final TableColumn column1 = new TableColumn(table, SWT.NULL);
		column1.setText(AntLaunchConfigurationMessages.AntTargetsTab_Name_5);

		final TableColumn column2 = new TableColumn(table, SWT.NULL);
		column2.setText(AntLaunchConfigurationMessages.AntTargetsTab_Description_6);

		// TableLayout only sizes columns once. If showing the targets
		// tab as the initial tab, the dialog isn't open when the layout
		// occurs and the column size isn't computed correctly. Need to
		// recompute the size of the columns once all the parent controls
		// have been created/sized.
		// HACK Bug 139190
		getShell().addShellListener(new ShellAdapter() {
			@Override
			public void shellActivated(ShellEvent e) {
				if (!table.isDisposed()) {
					int tableWidth = table.getSize().x;
					if (tableWidth > 0) {
						int c1 = tableWidth / 3;
						column1.setWidth(c1);
						column2.setWidth(tableWidth - c1);
					}
					getShell().removeShellListener(this);
				}
			}
		});

		fTableViewer = new CheckboxTableViewer(table);
		fTableViewer.setLabelProvider(new TargetTableLabelProvider());
		fTableViewer.setContentProvider(new AntModelContentProvider());
		fTableViewer.setComparator(new AntTargetsComparator());

		fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				ISelection selection = event.getSelection();
				if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
					IStructuredSelection ss = (IStructuredSelection) selection;
					Object element = ss.getFirstElement();
					boolean checked = !fTableViewer.getChecked(element);
					fTableViewer.setChecked(element, checked);
					updateOrderedTargets(element, checked);
				}
			}
		});

		fTableViewer.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				updateOrderedTargets(event.getElement(), event.getChecked());
			}
		});

		TableColumn[] columns = fTableViewer.getTable().getColumns();
		for (int i = 0; i < columns.length; i++) {
			final int index = i;
			columns[index].addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					if (fSortButton.getSelection()) {
						// index 0 => sort_name (1)
						// index 1 => sort_description (2)
						int column = index + 1;
						if (column == fSortDirection) {
							column = -column; // invert the sort when the same column is selected twice in a row
						}
						setSort(column);
					}
				}
			});
		}
	}

	/**
	 * Return the number of rows available in the current display using the current font.
	 * 
	 * @param parent
	 *            The Composite whose Font will be queried.
	 * @return int The result of the display size divided by the font size.
	 */
	private int availableRows(Composite parent) {

		int fontHeight = (parent.getFont().getFontData())[0].getHeight();
		int displayHeight = parent.getDisplay().getClientArea().height;

		return displayHeight / fontHeight;
	}

	/**
	 * Updates the ordered targets list in response to an element being checked or unchecked. When the element is checked, it's added to the list.
	 * When unchecked, it's removed.
	 * 
	 * @param element
	 *            the element in question
	 * @param checked
	 *            whether the element has been checked or unchecked
	 */
	private void updateOrderedTargets(Object element, boolean checked) {
		if (checked) {
			fOrderedTargets.add((AntTargetNode) element);
		} else {
			fOrderedTargets.remove(element);
		}
		updateSelectionCount();
		updateLaunchConfigurationDialog();
	}

	/**
	 * Updates the selection count widget to display how many targets are selected (example, "1 out of 6 selected") and filtered.
	 */
	private void updateSelectionCount() {
		Object[] checked = fTableViewer.getCheckedElements();
		String numSelected = Integer.toString(checked.length);

		int all = fAllTargets == null ? 0 : fAllTargets.length;
		int visible = fTableViewer.getTable().getItemCount();
		String total = Integer.toString(visible);
		int numHidden = all - visible;
		if (numHidden > 0) {
			fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab_13, new Object[] { numSelected,
					String.valueOf(all), String.valueOf(numHidden) }));
		} else {
			fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab__0__out_of__1__selected_7, new Object[] {
					numSelected, total }));
		}

		fOrderButton.setEnabled(checked.length > 1);

		StringBuffer buffer = new StringBuffer();
		Iterator<AntTargetNode> iter = fOrderedTargets.iterator();
		while (iter.hasNext()) {
			buffer.append(iter.next().getTargetName());
			buffer.append(", "); //$NON-NLS-1$
		}
		if (buffer.length() > 2) {
			// remove trailing comma
			buffer.setLength(buffer.length() - 2);
		}
		fTargetOrderText.setText(buffer.toString());
	}

	/**
	 * Returns all targets in the buildfile.
	 * 
	 * @return all targets in the buildfile
	 */
	private AntTargetNode[] getTargets() {
		if (fAllTargets == null || isDirty()) {
			fAllTargets = null;
			fDefaultTarget = null;
			setDirty(false);
			setErrorMessage(null);
			setMessage(null);

			final String expandedLocation = validateLocation();
			if (expandedLocation == null) {
				return fAllTargets;
			}
			final CoreException[] exceptions = new CoreException[1];
			try {
				IRunnableWithProgress operation = new IRunnableWithProgress() {
					/*
					 * (non-Javadoc)
					 * 
					 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
					 */
					@Override
					public void run(IProgressMonitor monitor) {
						try {
							fAllTargets = AntUtil.getTargets(expandedLocation, fLaunchConfiguration);
						}
						catch (CoreException ce) {
							exceptions[0] = ce;
						}
					}
				};

				IRunnableContext context = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				if (context == null) {
					context = getLaunchConfigurationDialog();
				}

				ISchedulingRule rule = null;
				if (!ResourcesPlugin.getWorkspace().isTreeLocked()) {
					// only set a scheduling rule if not in a resource change callback
					rule = AntUtil.getFileForLocation(expandedLocation, null);
				}
				PlatformUI.getWorkbench().getProgressService().runInUI(context, operation, rule);
			}
			catch (InvocationTargetException e) {
				AntUIPlugin.log("Internal error occurred retrieving targets", e.getTargetException()); //$NON-NLS-1$
				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1);
				fAllTargets = null;
				return null;
			}
			catch (InterruptedException e) {
				AntUIPlugin.log("Internal error occurred retrieving targets", e); //$NON-NLS-1$
				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1);
				fAllTargets = null;
				return null;
			}

			if (exceptions[0] != null) {
				IStatus exceptionStatus = exceptions[0].getStatus();
				IStatus[] children = exceptionStatus.getChildren();
				StringBuffer message = new StringBuffer(exceptions[0].getMessage());
				for (int i = 0; i < children.length; i++) {
					message.append(' ');
					IStatus childStatus = children[i];
					message.append(childStatus.getMessage());
				}
				setErrorMessage(message.toString());
				fAllTargets = null;
				return fAllTargets;
			}

			if (fAllTargets == null) {
				// if an error was not thrown during parsing then having no targets is valid (Ant 1.6.*)
				return fAllTargets;
			}

			AntTargetNode target = fAllTargets[0];
			AntProjectNode projectNode = target.getProjectNode();
			setErrorMessageFromNode(projectNode);
			for (int i = 0; i < fAllTargets.length; i++) {
				target = fAllTargets[i];
				if (target.isDefaultTarget()) {
					fDefaultTarget = target;
				}
				setErrorMessageFromNode(target);
			}
		}

		return fAllTargets;
	}

	private void setErrorMessageFromNode(AntElementNode node) {
		if (getErrorMessage() != null) {
			return;
		}
		if (node.isErrorNode() || node.isWarningNode()) {
			String message = node.getProblemMessage();
			if (message != null) {
				setErrorMessage(message);
			} else {
				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_0);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	@Override
	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
		// do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void initializeFrom(ILaunchConfiguration configuration) {
		fInitializing = true;
		fLaunchConfiguration = configuration;
		fOrderedTargets = new ArrayList<>();
		setErrorMessage(null);
		setMessage(null);
		setDirty(true);
		boolean hideInternal = false;
		try {
			hideInternal = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, false);
		}
		catch (CoreException e) {
			AntUIPlugin.log(e);
		}
		fFilterInternalTargets.setSelection(hideInternal);
		handleFilterTargetsSelected();
		int sort = SORT_NONE;
		try {
			sort = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, sort);
		}
		catch (CoreException e) {
			AntUIPlugin.log(e);
		}
		fSortButton.setSelection(sort != SORT_NONE);
		setSort(sort);
		String configTargets = null;
		String newLocation = null;

		try {
			configTargets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null);
			newLocation = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null);
		}
		catch (CoreException ce) {
			AntUIPlugin.log(AntLaunchConfigurationMessages.AntTargetsTab_Error_reading_configuration_12, ce);
		}

		if (newLocation == null) {
			fAllTargets = null;
			initializeForNoTargets();
			return;
		}

		AntTargetNode[] allTargetNodes = getTargets();
		if (allTargetNodes == null) {
			initializeForNoTargets();
			return;
		}

		String[] targetNames = AntUtil.parseRunTargets(configTargets);
		if (targetNames.length == 0) {
			fTableViewer.setAllChecked(false);
			setExecuteInput(allTargetNodes);
			if (fDefaultTarget != null) {
				fOrderedTargets.add(fDefaultTarget);
				fTableViewer.setChecked(fDefaultTarget, true);
				updateSelectionCount();
				updateLaunchConfigurationDialog();
			}
			fInitializing = false;
			return;
		}

		setExecuteInput(allTargetNodes);
		fTableViewer.setAllChecked(false);
		for (int i = 0; i < targetNames.length; i++) {
			for (int j = 0; j < fAllTargets.length; j++) {
				if (targetNames[i].equals(fAllTargets[j].getTargetName())) {
					fOrderedTargets.add(fAllTargets[j]);
					fTableViewer.setChecked(fAllTargets[j], true);
				}
			}
		}
		updateSelectionCount();
		fInitializing = false;
	}

	private void initializeForNoTargets() {
		setExecuteInput(new AntTargetNode[0]);
		fTableViewer.setInput(new AntTargetNode[0]);
		fInitializing = false;
	}

	/**
	 * Sets the execute table's input to the given input.
	 */
	private void setExecuteInput(Object input) {
		fTableViewer.setInput(input);
		updateSelectionCount();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	@Override
	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
		// attribute added in 3.0, so null must be used instead of false for backwards compatibility
		if (fFilterInternalTargets.getSelection()) {
			configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, true);
		} else {
			configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, (String) null);
		}
		// attribute added in 3.0, so null must be used instead of 0 for backwards compatibility
		if (fSortDirection != SORT_NONE) {
			configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, fSortDirection);
		} else {
			configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, (String) null);
		}

		if (fOrderedTargets.size() == 1) {
			AntTargetNode item = fOrderedTargets.get(0);
			if (item.isDefaultTarget()) {
				configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null);
				return;
			}
		} else if (fOrderedTargets.size() == 0) {
			configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null);
			return;
		}

		StringBuffer buff = new StringBuffer();
		Iterator<AntTargetNode> iter = fOrderedTargets.iterator();
		String targets = null;
		while (iter.hasNext()) {
			AntTargetNode item = iter.next();
			buff.append(item.getTargetName());
			buff.append(',');
		}
		if (buff.length() > 0) {
			targets = buff.toString();
		}

		configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, targets);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
	 */
	@Override
	public String getName() {
		return AntLaunchConfigurationMessages.AntTargetsTab_Tar_gets_14;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
	 */
	@Override
	public Image getImage() {
		return AntUIImages.getImage(IAntUIConstants.IMG_TAB_ANT_TARGETS);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public boolean isValid(ILaunchConfiguration launchConfig) {
		if (fAllTargets == null || isDirty()) {
			if (getErrorMessage() != null && !isDirty()) {
				// error in parsing;
				return false;
			}
			// targets not up to date and no error message...we have not parsed recently
			initializeFrom(launchConfig);
			if (getErrorMessage() != null) {
				// error in parsing;
				return false;
			}
		}

		setErrorMessage(null);
		return super.isValid(launchConfig);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#setDirty(boolean)
	 */
	@Override
	protected void setDirty(boolean dirty) {
		// provide package visibility
		super.setDirty(dirty);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	@Override
	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
		if (isDirty()) {
			super.activated(workingCopy);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	@Override
	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
		if (fOrderedTargets.size() == 0) {
			// set the dirty flag so that the state will be reinitialized on activation
			setDirty(true);
		}
	}

	private String validateLocation() {
		String expandedLocation = null;
		String location = null;
		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
		try {
			location = fLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null);
			if (location == null) {
				return null;
			}

			expandedLocation = manager.performStringSubstitution(location);
			if (expandedLocation == null) {
				return null;
			}
			File file = new File(expandedLocation);
			if (!file.exists()) {
				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_15);
				return null;
			}
			if (!file.isFile()) {
				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_16);
				return null;
			}

			return expandedLocation;

		}
		catch (CoreException e1) {
			if (location != null) {
				try {
					manager.validateStringVariables(location);
					setMessage(AntLaunchConfigurationMessages.AntTargetsTab_17);
					return null;
				}
				catch (CoreException e2) {// invalid variable
					setErrorMessage(e2.getStatus().getMessage());
					return null;
				}
			}

			setErrorMessage(e1.getStatus().getMessage());
			return null;
		}
	}

	protected boolean isTargetSelected() {
		return !fOrderedTargets.isEmpty();
	}
}
