/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 *     Serge Beauchamp (Freescale Semiconductor) - [229633] Group and Project Path Variable Support
 *     Helena Halperin (IBM) - bug #299212
 *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 430694
 *     Robert Roth <robert.roth.off@gmail.com> - Bug 57371
 *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 548799
 *******************************************************************************/
package org.eclipse.ui.internal.ide.dialogs;

import java.net.URI;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.resource.ResourceLocator;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;

import com.ibm.icu.text.Collator;

/**
 * A widget group that displays path variables.
 * Includes buttons to edit, remove existing variables and create new ones.
 *
 * @since 2.1
 */
public class PathVariablesGroup {
	/**
	 * Simple data structure that holds a path variable name/value pair.
	 */
	public static class PathVariableElement {
		/**
		 * The name of the element.
		 */
		public String name;

		/**
		 * The path of the element.
		 */
		public IPath path;
	}

	// sizing constants
	private static final int SIZING_SELECTION_PANE_WIDTH = 400;

	// parent shell
	private Shell shell;

	private Label variableLabel;

	private TableViewer variableTable;

	private Button addButton;

	private Button editButton;

	private Button removeButton;

	// used to compute layout sizes
	private FontMetrics fontMetrics;

	// create a multi select table
	private boolean multiSelect;

	// IResource.FILE and/or IResource.FOLDER
	private int variableType;

	// External listener called when the table selection changes
	private Listener selectionListener;

	// temporary collection for keeping currently defined variables
	private SortedMap<String, IPath> tempPathVariables;

	// set of removed variables' names
	private Set<String> removedVariableNames;

	// reference to the workspace's path variable manager
	private IPathVariableManager pathVariableManager;

	// if set to true, variables will be saved after each change
	private boolean saveVariablesOnChange = false;

	// file image
	private final Image FILE_IMG = PlatformUI.getWorkbench().getSharedImages()
			.getImage(ISharedImages.IMG_OBJ_FILE);

	// folder image
	private final Image FOLDER_IMG = PlatformUI.getWorkbench()
			.getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);

	private final Image BUILTIN_IMG = PlatformUI.getWorkbench()
			.getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
	// unknown (non-existent) image. created locally, dispose locally
	private Image imageUnknown;

	// current project for which the variables are being edited.
	// If null, the workspace variables are being edited instead.
	private IResource currentResource = null;

	private static final String PARENT_VARIABLE_NAME = "PARENT"; //$NON-NLS-1$

	/**
	 * Creates a new PathVariablesGroup.
	 *
	 * @param multiSelect create a multi select tree
	 * @param variableType the type of variables that are displayed in
	 * 	the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
	 * 	logically ORed together.
	 */
	public PathVariablesGroup(boolean multiSelect, int variableType) {
		this.multiSelect = multiSelect;
		this.variableType = variableType;
		pathVariableManager = ResourcesPlugin.getWorkspace()
				.getPathVariableManager();
		removedVariableNames = new HashSet<>();
		Collator ignoreCaseComparator = Collator.getInstance();
		tempPathVariables = new TreeMap<>(ignoreCaseComparator);
		// initialize internal model
		initTemporaryState();
	}

	/**
	 * Creates a new PathVariablesGroup.
	 *
	 * @param multiSelect create a multi select tree
	 * @param variableType the type of variables that are displayed in
	 * 	the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
	 * 	logically ORed together.
	 * @param selectionListener listener notified when the selection changes
	 * 	in the variables list.
	 */
	public PathVariablesGroup(boolean multiSelect, int variableType,
			Listener selectionListener) {
		this(multiSelect, variableType);
		this.selectionListener = selectionListener;
	}

	/**
	 * Opens a dialog for creating a new variable.
	 */
	private void addNewVariable() {
		// constructs a dialog for editing the new variable's current name and value
		PathVariableDialog dialog = new PathVariableDialog(shell,
				PathVariableDialog.NEW_VARIABLE, variableType,
				pathVariableManager, tempPathVariables.keySet());

		dialog.setResource(currentResource);
		// opens the dialog - just returns if the user cancels it
		if (dialog.open() == Window.CANCEL) {
			return;
		}

		// otherwise, adds the new variable (or updates an existing one) in the
		// temporary collection of currently defined variables
		String newVariableName = dialog.getVariableName();
		IPath newVariableValue = new Path(dialog.getVariableValue());
		tempPathVariables.put(newVariableName, newVariableValue);

		// the UI must be updated
		updateWidgetState();
		saveVariablesIfRequired();
	}

	/**
	 * Creates the widget group.
	 * Callers must call <code>dispose</code> when the group is no
	 * longer needed.
	 *
	 * @param parent the widget parent
	 * @return container of the widgets
	 */
	public Control createContents(Composite parent) {
		Font font = parent.getFont();

		if (imageUnknown == null) {
			ResourceLocator.imageDescriptorFromBundle(
							IDEWorkbenchPlugin.IDE_WORKBENCH,
					"$nl$/icons/full/obj16/warning.png").ifPresent(d -> imageUnknown = d.createImage()); //$NON-NLS-1$
		}
		initializeDialogUnits(parent);
		shell = parent.getShell();

		// define container & its layout
		Composite pageComponent = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		pageComponent.setLayout(layout);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = SIZING_SELECTION_PANE_WIDTH;
		pageComponent.setLayoutData(data);
		pageComponent.setFont(font);

		// layout the table & its buttons
		variableLabel = new Label(pageComponent, SWT.LEFT);
		if (currentResource == null)
			variableLabel.setText(IDEWorkbenchMessages.PathVariablesBlock_variablesLabel);
		else
			variableLabel.setText(NLS.bind(
									IDEWorkbenchMessages.PathVariablesBlock_variablesLabelForResource,
									currentResource.getName()));

		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		variableLabel.setLayoutData(data);
		variableLabel.setFont(font);

		int tableStyle = SWT.BORDER | SWT.FULL_SELECTION;
		if (multiSelect) {
			tableStyle |= SWT.MULTI;
		}

		Composite tableComposite = new Composite(pageComponent, SWT.NONE);
		data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.grabExcessHorizontalSpace = true;
		data.grabExcessVerticalSpace = true;
		tableComposite.setLayoutData(data);

		variableTable = new TableViewer(tableComposite, tableStyle);
		variableTable.getTable().addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateEnabledState();
				if (selectionListener != null) {
					selectionListener.handleEvent(new Event());
				}
			}
		});

		variableTable.getTable().setFont(font);
		ColumnViewerToolTipSupport.enableFor(variableTable, ToolTip.NO_RECREATE);

		TableViewerColumn nameColumn = new TableViewerColumn(variableTable, SWT.NONE);
		nameColumn.setLabelProvider(new NameLabelProvider());
		nameColumn.getColumn().setText(IDEWorkbenchMessages.PathVariablesBlock_nameColumn);

		TableViewerColumn valueColumn = new TableViewerColumn(variableTable, SWT.NONE);
		valueColumn.setLabelProvider(new ValueLabelProvider());
		valueColumn.getColumn().setText(IDEWorkbenchMessages.PathVariablesBlock_valueColumn);

		TableColumnLayout tableLayout = new TableColumnLayout();
		tableComposite.setLayout( tableLayout );

		tableLayout.setColumnData(nameColumn.getColumn(), new ColumnWeightData(150));
		tableLayout.setColumnData(valueColumn.getColumn(), new ColumnWeightData(280));

		variableTable.getTable().setHeaderVisible(true);
		data = new GridData(GridData.FILL_BOTH);
		data.heightHint = variableTable.getTable().getItemHeight() * 7;
		variableTable.getTable().setLayoutData(data);
		variableTable.getTable().setFont(font);

		variableTable.getTable().addMouseListener(new MouseListener() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				int itemsSelectedCount = variableTable.getTable().getSelectionCount();
				if (itemsSelectedCount == 1 && canChangeSelection())
					editSelectedVariable();
			}
			@Override
			public void mouseDown(MouseEvent e) { }
			@Override
			public void mouseUp(MouseEvent e) { }
		});
		variableTable.getTable().addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateEnabledState();
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				updateEnabledState();
			}
		});

		variableTable.getTable().setToolTipText(null);
		variableTable.setContentProvider(new ContentProvider());
		variableTable.setInput(this);
		createButtonGroup(pageComponent);
		return pageComponent;
	}

	class NameLabelProvider extends CellLabelProvider
	{
		@Override
		public String getToolTipText(Object element) {
			return null;
		}

		@Override
		public Point getToolTipShift(Object object) {
			return new Point(5, 5);
		}

		@Override
		public int getToolTipDisplayDelayTime(Object object) {
			return 0;
		}

		@Override
		public int getToolTipTimeDisplayed(Object object) {
			return 15000;
		}

		@Override
		public void update(ViewerCell cell) {
			String varName = (String) cell.getElement();
			cell.setText(varName);
			IPath value = tempPathVariables.get(varName);
			URI resolvedURI = pathVariableManager.resolveURI(URIUtil.toURI(value));
			IPath resolvedValue = URIUtil.toPath(resolvedURI);
			IFileInfo file = IDEResourceInfoUtils.getFileInfo(resolvedValue);
			if (!isBuiltInVariable(varName))
				cell.setImage(file.exists() ? (file.isDirectory() ? FOLDER_IMG : FILE_IMG) : imageUnknown);
			else
				cell.setImage(BUILTIN_IMG);
		}

	}

	class ValueLabelProvider extends CellLabelProvider
	{
		@Override
		public String getToolTipText(Object element) {
			IPath value = tempPathVariables.get(element);
			URI resolvedURI = pathVariableManager.resolveURI(URIUtil.toURI(value));
			IPath resolvedValue = URIUtil.toPath(resolvedURI);
			return TextProcessor.process(resolvedValue.toOSString());
		}

		@Override
		public Point getToolTipShift(Object object) {
			return new Point(5, 5);
		}

		@Override
		public int getToolTipDisplayDelayTime(Object object) {
			return 0;
		}

		@Override
		public int getToolTipTimeDisplayed(Object object) {
			return 15000;
		}

		@Override
		public void update(ViewerCell cell) {
			IPath value = tempPathVariables.get(cell.getElement());
			cell.setText(TextProcessor.process(removeParentVariable(value.toOSString())));
		}

	}

	/**
	 * Disposes the group's resources.
	 */
	public void dispose() {
		if (imageUnknown != null) {
			imageUnknown.dispose();
			imageUnknown = null;
		}
	}

	/**
	 * Opens a dialog for editing an existing variable.
	 *
	 * @see PathVariableDialog
	 */
	private void editSelectedVariable() {
		// retrieves the name and value for the currently selected variable
		TableItem item = variableTable.getTable().getItem(variableTable.getTable()
				.getSelectionIndex());
		String variableName = (String) item.getData();
		IPath variableValue = tempPathVariables.get(variableName);

		// constructs a dialog for editing the variable's current name and value
		PathVariableDialog dialog = new PathVariableDialog(shell,
				PathVariableDialog.EXISTING_VARIABLE, variableType,
				pathVariableManager, tempPathVariables.keySet());
		dialog.setVariableName(variableName);
		dialog.setVariableValue(variableValue.toOSString());
		dialog.setResource(currentResource);

		// opens the dialog - just returns if the user cancels it
		if (dialog.open() == Window.CANCEL) {
			return;
		}

		// the name can be changed, so we remove the current variable definition...
		removedVariableNames.add(variableName);
		tempPathVariables.remove(variableName);

		String newVariableName = dialog.getVariableName();
		IPath newVariableValue = new Path(dialog.getVariableValue());

		// and add it again (maybe with a different name)
		tempPathVariables.put(newVariableName, newVariableValue);

		// now we must refresh the UI state
		updateWidgetState();
		saveVariablesIfRequired();
	}

	/**
	 * Returns the enabled state of the group's widgets.
	 * Returns <code>true</code> if called prior to calling
	 * <code>createContents</code>.
	 *
	 * @return boolean the enabled state of the group's widgets.
	 * 	 <code>true</code> if called prior to calling <code>createContents</code>.
	 */
	public boolean getEnabled() {
		if (variableTable != null && !variableTable.getTable().isDisposed()) {
			return variableTable.getTable().getEnabled();
		}
		return true;
	}

	/**
	 * Automatically save the path variable list when new variables
	 * are added, changed, or removed by the user.
	 * @param value
	 *
	 */
	public void setSaveVariablesOnChange(boolean value) {
		saveVariablesOnChange = value;
	}

	private void saveVariablesIfRequired() {
		if (saveVariablesOnChange) {
			performOk();
		}
	}
	/**
	 * Returns the selected variables.
	 *
	 * @return the selected variables. Returns an empty array if
	 * 	the widget group has not been created yet by calling
	 * 	<code>createContents</code>
	 */
	public PathVariableElement[] getSelection() {
		if (variableTable == null) {
			return new PathVariableElement[0];
		}
		TableItem[] items = variableTable.getTable().getSelection();
		PathVariableElement[] selection = new PathVariableElement[items.length];

		for (int i = 0; i < items.length; i++) {
			String name = (String) items[i].getData();
			selection[i] = new PathVariableElement();
			selection[i].name = name;
			selection[i].path = tempPathVariables.get(name);
		}
		return selection;
	}

	/**
	 * Creates the add/edit/remove buttons
	 *
	 * @param parent the widget parent
	 */
	private void createButtonGroup(Composite parent) {
		Font font = parent.getFont();
		Composite groupComponent = new Composite(parent, SWT.NULL);
		GridLayout groupLayout = new GridLayout();
		groupLayout.marginWidth = 0;
		groupLayout.marginHeight = 0;
		groupComponent.setLayout(groupLayout);
		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		groupComponent.setLayoutData(data);
		groupComponent.setFont(font);

		addButton = new Button(groupComponent, SWT.PUSH);
		addButton.setText(IDEWorkbenchMessages.PathVariablesBlock_addVariableButton);
		addButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				addNewVariable();
			}
		});
		addButton.setFont(font);
		setButtonLayoutData(addButton);

		editButton = new Button(groupComponent, SWT.PUSH);
		editButton.setText(IDEWorkbenchMessages.PathVariablesBlock_editVariableButton);
		editButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				editSelectedVariable();
			}
		});
		editButton.setFont(font);
		setButtonLayoutData(editButton);

		removeButton = new Button(groupComponent, SWT.PUSH);
		removeButton.setText(IDEWorkbenchMessages.PathVariablesBlock_removeVariableButton);
		removeButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				removeSelectedVariables();
			}
		});
		removeButton.setFont(font);
		setButtonLayoutData(removeButton);
		updateEnabledState();
	}

	/**
	 * Initializes the computation of horizontal and vertical dialog units
	 * based on the size of current font.
	 * <p>
	 * This method must be called before <code>setButtonLayoutData</code>
	 * is called.
	 * </p>
	 *
	 * @param control a control from which to obtain the current font
	 */
	protected void initializeDialogUnits(Control control) {
		// Compute and store a font metric
		GC gc = new GC(control);
		gc.setFont(control.getFont());
		fontMetrics = gc.getFontMetrics();
		gc.dispose();
	}

	/**
	 * (Re-)Initialize collections used to mantain temporary variable state.
	 */
	private void initTemporaryState() {
		tempPathVariables.clear();
		for (String varName : pathVariableManager.getPathVariableNames()) {
			// hide the PARENT variable
			if (varName.equals(PARENT_VARIABLE_NAME))
				continue;
			try {
				URI uri = pathVariableManager.getURIValue(varName);
				// the value may not exist any more
				if (uri != null) {
					IPath value = URIUtil.toPath(uri);
					if (value != null) {
						boolean isFile = value.toFile().isFile();
						if ((isFile && (variableType & IResource.FILE) != 0)
								|| (isFile == false && (variableType & IResource.FOLDER) != 0)) {

							tempPathVariables.put(varName, value);
						}
					}
				}
			} catch (Exception e) {
				// do not present the variable
			}
		}
		removedVariableNames.clear();
	}

	/**
	 * Updates button enabled state, depending on the number of currently selected
	 * variables in the table.
	 */
	private void updateEnabledState() {
		int itemsSelectedCount = variableTable.getTable().getSelectionCount();
		editButton.setEnabled(itemsSelectedCount == 1 && canChangeSelection());
		removeButton.setEnabled(itemsSelectedCount > 0 && canChangeSelection());
	}

	private class ContentProvider implements IStructuredContentProvider {

		@Override
		public Object[] getElements(Object inputElement) {
			return tempPathVariables.keySet().toArray();
		}
	}

	/**
	 * Converts the ${PARENT-COUNT-VAR} format to "VAR/../../" format
	 * @param value
	 * @return the converted value
	 */
	private String removeParentVariable(String value) {
		return pathVariableManager.convertToUserEditableFormat(value, false);
	}

	/**
	 * Commits the temporary state to the path variable manager in response to user
	 * confirmation.
	 * @return boolean <code>true</code> if there were no problems.
	 * @see IPathVariableManager#setValue(String, IResource, URI)
	 */
	public boolean performOk() {
		try {
			// first process removed variables
			for (Iterator<String> removed = removedVariableNames.iterator(); removed
					.hasNext();) {
				String removedVariableName = removed.next();
				// only removes variables that have not been added again
				if (!tempPathVariables.containsKey(removedVariableName)) {
					pathVariableManager.setURIValue(removedVariableName, null);
				}
			}

			// then process the current collection of variables, adding/updating them
			for (Entry<String, IPath> entry : tempPathVariables.entrySet()) {
				String variableName = entry.getKey();
				IPath variableValue = entry.getValue();
				if (!isBuiltInVariable(variableName))
					pathVariableManager.setURIValue(variableName, URIUtil.toURI(variableValue));
			}
			// re-initialize temporary state
			initTemporaryState();

			// performOk accepted
			return true;
		} catch (CoreException ce) {
			ErrorDialog.openError(shell, null, null, ce.getStatus());
		}
		return false;
	}

	/**
	 * Removes the currently selected variables.
	 */
	private void removeSelectedVariables() {
		// remove each selected element
		for (int selectedIndex : variableTable.getTable().getSelectionIndices()) {
			TableItem selectedItem = variableTable.getTable().getItem(selectedIndex);
			String varName = (String) selectedItem.getData();
			removedVariableNames.add(varName);
			tempPathVariables.remove(varName);
		}
		updateWidgetState();
		saveVariablesIfRequired();
	}

	private boolean canChangeSelection() {
		for (int selectedIndex : variableTable.getTable().getSelectionIndices()) {
			TableItem selectedItem = variableTable.getTable().getItem(selectedIndex);
			String varName = (String) selectedItem.getData();
			if (isBuiltInVariable(varName))
				return false;
		}
		return true;
	}

	/**
	 * @param varName
	 *            the variable name to test
	 */
	private boolean isBuiltInVariable(String varName) {
		if (currentResource != null) {
			return !pathVariableManager.isUserDefined(varName);
		}
		return false;
	}

	/**
	 * Sets the <code>GridData</code> on the specified button to
	 * be one that is spaced for the current dialog page units. The
	 * method <code>initializeDialogUnits</code> must be called once
	 * before calling this method for the first time.
	 *
	 * @param button the button to set the <code>GridData</code>
	 * @return the <code>GridData</code> set on the specified button
	 */
	private GridData setButtonLayoutData(Button button) {
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
				IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
				SWT.DEFAULT, true).x);
		button.setLayoutData(data);
		return data;
	}

	/**
	 * Sets the enabled state of the group's widgets.
	 * Does nothing if called prior to calling <code>createContents</code>.
	 *
	 * @param enabled the new enabled state of the group's widgets
	 */
	public void setEnabled(boolean enabled) {
		if (variableTable != null && !variableTable.getTable().isDisposed()) {
			variableLabel.setEnabled(enabled);
			variableTable.getTable().setEnabled(enabled);
			addButton.setEnabled(enabled);
			if (enabled) {
				updateEnabledState();
			} else {
				editButton.setEnabled(enabled);
				removeButton.setEnabled(enabled);
			}
		}
	}

	/**
	 * Updates the widget's current state: refreshes the table with the current
	 * defined variables, selects the item corresponding to the given variable
	 * (selects the first item if <code>null</code> is provided) and updates
	 * the enabled state for the Add/Remove/Edit buttons.
	 *
	 */
	private void updateWidgetState() {
		variableTable.refresh();
		updateEnabledState();
	}

	/**
	 * @param resource
	 */
	public void setResource(IResource resource) {
		currentResource = resource;
		if (resource != null)
			pathVariableManager = resource.getPathVariableManager();
		else
			pathVariableManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
		removedVariableNames = new HashSet<>();
		tempPathVariables = new TreeMap<>();
		// initialize internal model
		initTemporaryState();
	}

	/**
	 * Reloads the path variables from the project description.
	 */
	public void reloadContent() {
		removedVariableNames = new HashSet<>();
		tempPathVariables = new TreeMap<>();
		initTemporaryState();
		if (variableTable != null)
			updateWidgetState();
	}
}
