/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.debug.ui.interpreters;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin;
import org.eclipse.dltk.internal.ui.util.SWTUtil;
import org.eclipse.dltk.internal.ui.util.TableLayoutComposite;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.IInterpreterInstallType;
import org.eclipse.dltk.launching.InterpreterSearcher;
import org.eclipse.dltk.launching.InterpreterStandin;
import org.eclipse.dltk.launching.ScriptRuntime;
import org.eclipse.dltk.ui.util.PixelConverter;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * A composite that displays installed InterpreterEnvironment's in a table.
 * InterpreterEnvironments can be added, removed, edited, and searched for.
 * <p>
 * This block implements ISelectionProvider - it sends selection change events
 * when the checked InterpreterEnvironment in the table changes, or when the
 * "use default" button check state changes.
 * </p>
 * @
 */
public abstract class InterpretersBlock
		implements IAddInterpreterDialogRequestor, ISelectionProvider {

	/**
	 * This block's control
	 */
	private Composite fControl;

	/**
	 * Interpreters being displayed
	 */
	protected List<IInterpreterInstall> fInterpreters = new ArrayList<>();

	/**
	 * The main list control
	 */
	protected CheckboxTableViewer fInterpreterList;

	// Action buttons
	private Button fAddButton;
	private Button fRemoveButton;
	private Button fEditButton;
	private Button fCopyButton;
	private Button fSearchButton;

	private Combo fEnvironments;

	/**
	 * Environment to checked interpreter.
	 */
	private Map<IEnvironment, IInterpreterInstall> checkedInterpreters = new HashMap<>();

	// index of column used for sorting
	private int fSortColumn = 0;

	/**
	 * Selection listeners (checked InterpreterEnvironment changes)
	 */
	private ListenerList<ISelectionChangedListener> fSelectionListeners = new ListenerList<>();

	/**
	 * Previous selection
	 */
	private ISelection fPrevSelection = new StructuredSelection();

	private Table fTable;

	/**
	 * Content provider to show a list of InterpreterEnvironments
	 */
	class InterpretersContentProvider implements IStructuredContentProvider {
		@Override
		public Object[] getElements(Object input) {
			return getCurrentInterprers();
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput,
				Object newInput) {
		}

		@Override
		public void dispose() {
		}
	}

	/**
	 * Label provider for installed InterpreterEnvironments table.
	 */
	class InterpreterLabelProvider extends LabelProvider
			implements ITableLabelProvider {

		/**
		 * @see ITableLabelProvider#getColumnText(Object, int)
		 */
		@Override
		public String getColumnText(Object element, int columnIndex) {
			if (element instanceof IInterpreterInstall) {
				IInterpreterInstall interp = (IInterpreterInstall) element;
				switch (columnIndex) {
				case 0:
					return interp.getName();
				case 1:
					return interp.getInterpreterInstallType().getName();
				case 2:
					return interp.getRawInstallLocation().toOSString();
				}
			}
			return element.toString();
		}

		/**
		 * @see ITableLabelProvider#getColumnImage(Object, int)
		 */
		@Override
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex == 0) {
				// TODO: instert interpreter logo here
			}
			return null;
		}

	}

	@Override
	public void addSelectionChangedListener(
			ISelectionChangedListener listener) {
		fSelectionListeners.add(listener);
	}

	@Override
	public ISelection getSelection() {
		return new StructuredSelection(fInterpreterList.getCheckedElements());
	}

	@Override
	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		fSelectionListeners.remove(listener);
	}

	@Override
	public void setSelection(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			if (!selection.equals(fPrevSelection)) {
				fPrevSelection = selection;
				Object interp = ((IStructuredSelection) selection)
						.getFirstElement();
				if (interp == null) {
					fInterpreterList.setCheckedElements(new Object[0]);
				} else {
					fInterpreterList
							.setCheckedElements(new Object[] { interp });
					IInterpreterInstall install = (IInterpreterInstall) interp;
					checkedInterpreters.put(install.getEnvironment(), install);
					fInterpreterList.reveal(interp);
				}
				fireSelectionChanged();
			}
		}
	}

	/**
	 * Creates this block's control in the given control.
	 *
	 * @param ancestor
	 *                            containing control
	 * @param useManageButton
	 *                            whether to present a single 'manage...' button
	 *                            to the user that opens the installed
	 *                            InterpreterEnvironments pref page for
	 *                            InterpreterEnvironment management, or to
	 *                            provide 'add, remove, edit, and search'
	 *                            buttons.
	 */
	public void createControl(Composite ancestor) {

		Composite parent = new Composite(ancestor, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight = 0;
		layout.marginWidth = 0;

		Font font = ancestor.getFont();
		parent.setFont(font);
		parent.setLayout(layout);

		fControl = parent;

		GridData data;

		Composite env = new Composite(parent, SWT.NONE);
		GridLayout layout2 = new GridLayout(2, false);
		layout2.marginLeft = -5;
		layout2.marginRight = -5;
		layout2.marginTop = -5;
		layout2.marginBottom = -5;
		env.setLayout(layout2);
		data = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		data.horizontalSpan = 2;
		env.setLayoutData(data);
		Label environmentLabel = new Label(env, SWT.NONE);
		environmentLabel.setText(InterpretersMessages.InterpretersBlock_host);
		this.fEnvironments = new Combo(env, SWT.DROP_DOWN | SWT.READ_ONLY);
		data = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		this.fEnvironments.setLayoutData(data);
		environments = EnvironmentManager.getEnvironments();
		String[] items = new String[environments.length];
		int local = 0;
		for (int i = 0; i < items.length; i++) {
			items[i] = environments[i].getName();
			if (environments[i].isLocal()) {
				local = i;
			}
		}
		this.fEnvironments.setItems(items);
		this.fEnvironments.select(local);

		this.fEnvironments.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Object install = checkedInterpreters
						.get(getCurrentEnvironment());
				fInterpreterList.refresh();
				if (install != null) {
					fInterpreterList
							.setCheckedElements(new Object[] { install });
				} else {
					fInterpreterList.setCheckedElements(new Object[0]);
				}
			}
		});

		// Label tableLabel = new Label(parent, SWT.NONE);
		// tableLabel.setText(InterpretersMessages.InstalledInterpretersBlock_15
		// );
		// data = new GridData();
		// data.horizontalSpan = 2;
		// tableLabel.setLayoutData(data);
		// tableLabel.setFont(font);

		PixelConverter conv = new PixelConverter(parent);
		data = new GridData(GridData.FILL_BOTH);
		data.widthHint = conv.convertWidthInCharsToPixels(50);
		TableLayoutComposite tblComposite = new TableLayoutComposite(parent,
				SWT.NONE);
		tblComposite.setLayoutData(data);
		fTable = new Table(tblComposite,
				SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);

		data = new GridData(GridData.FILL_BOTH);
		data.widthHint = 450;
		fTable.setLayoutData(data);
		fTable.setFont(font);

		fTable.setHeaderVisible(true);
		fTable.setLinesVisible(true);

		TableColumn column1 = new TableColumn(fTable, SWT.NULL);
		column1.setText(InterpretersMessages.InstalledInterpretersBlock_0);
		column1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				sortByName();
			}
		});
		column1.setWidth(conv.convertWidthInCharsToPixels(15));

		TableColumn column2 = new TableColumn(fTable, SWT.NULL);
		column2.setText(InterpretersMessages.InstalledInterpretersBlock_2);
		column2.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				sortByType();
			}
		});
		column2.setWidth(conv.convertWidthInCharsToPixels(15));

		TableColumn column3 = new TableColumn(fTable, SWT.NULL);
		column3.setText(InterpretersMessages.InstalledInterpretersBlock_1);
		column3.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				sortByLocation();
			}
		});
		column3.setWidth(conv.convertWidthInCharsToPixels(20));

		fInterpreterList = new CheckboxTableViewer(fTable);
		fInterpreterList.setLabelProvider(new InterpreterLabelProvider());
		fInterpreterList.setContentProvider(new InterpretersContentProvider());
		// by default, sort by name
		sortByName();

		fInterpreterList.addSelectionChangedListener(evt -> enableButtons());

		fInterpreterList.addCheckStateListener(event -> {
			if (event.getChecked()) {
				setCheckedInterpreter((IInterpreterInstall) event.getElement());
			} else {
				setCheckedInterpreter(null);
			}
		});

		fInterpreterList.addDoubleClickListener(e -> {
			if (!fInterpreterList.getSelection().isEmpty()) {
				editInterpreter();
			}
		});
		fTable.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				if (event.character == SWT.DEL && event.stateMask == 0) {
					if (fRemoveButton.getEnabled())
						removeInterpreters();
				}
			}
		});

		fTable.layout();

		buttons = new Composite(parent, SWT.NULL);
		buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttons.setLayout(layout);
		buttons.setFont(font);

		fAddButton = createPushButton(buttons,
				InterpretersMessages.InstalledInterpretersBlock_3);
		fAddButton.addListener(SWT.Selection, evt -> addInterpreter());

		fEditButton = createPushButton(buttons,
				InterpretersMessages.InstalledInterpretersBlock_4);
		fEditButton.addListener(SWT.Selection, evt -> editInterpreter());

		fCopyButton = createPushButton(buttons,
				InterpretersMessages.InstalledInterpretersBlock_16);
		fCopyButton.addListener(SWT.Selection, evt -> copyInterpreter());

		fRemoveButton = createPushButton(buttons,
				InterpretersMessages.InstalledInterpretersBlock_5);
		fRemoveButton.addListener(SWT.Selection, evt -> removeInterpreters());

		// copied from ListDialogField.CreateSeparator()
		Label separator = new Label(buttons, SWT.NONE);
		separator.setVisible(false);
		GridData gd = new GridData();
		gd.horizontalAlignment = GridData.FILL;
		gd.verticalAlignment = GridData.BEGINNING;
		gd.heightHint = 4;
		separator.setLayoutData(gd);

		fSearchButton = createPushButton(buttons,
				InterpretersMessages.InstalledInterpretersBlock_6);
		fSearchButton.addListener(SWT.Selection, evt -> search());

		fillWithWorkspaceInterpreters();
		enableButtons();
		fAddButton.setEnabled(ScriptRuntime
				.getInterpreterInstallTypes(getCurrentNature()).length > 0);
	}

	/**
	 * Fire current selection
	 */
	private void fireSelectionChanged() {
		SelectionChangedEvent event = new SelectionChangedEvent(this,
				getSelection());
		for (ISelectionChangedListener listener : fSelectionListeners) {
			listener.selectionChanged(event);
		}
	}

	/**
	 * Sorts by Interpreter type, and name within type.
	 */
	private void sortByType() {
		fInterpreterList.setComparator(new ViewerComparator() {
			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				if ((e1 instanceof IInterpreterInstall)
						&& (e2 instanceof IInterpreterInstall)) {
					IInterpreterInstall left = (IInterpreterInstall) e1;
					IInterpreterInstall right = (IInterpreterInstall) e2;
					String leftType = left.getInterpreterInstallType()
							.getName();
					String rightType = right.getInterpreterInstallType()
							.getName();
					int res = leftType.compareToIgnoreCase(rightType);
					if (res != 0) {
						return res;
					}
					return left.getName().compareToIgnoreCase(right.getName());
				}
				return super.compare(viewer, e1, e2);
			}

			@Override
			public boolean isSorterProperty(Object element, String property) {
				return true;
			}
		});
		fSortColumn = 3;
	}

	/**
	 * Sorts by Interpreter name.
	 */
	private void sortByName() {
		fInterpreterList.setComparator(new ViewerComparator() {
			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				if ((e1 instanceof IInterpreterInstall)
						&& (e2 instanceof IInterpreterInstall)) {
					IInterpreterInstall left = (IInterpreterInstall) e1;
					IInterpreterInstall right = (IInterpreterInstall) e2;
					return left.getName().compareToIgnoreCase(right.getName());
				}
				return super.compare(viewer, e1, e2);
			}

			@Override
			public boolean isSorterProperty(Object element, String property) {
				return true;
			}
		});
		fSortColumn = 1;
	}

	/**
	 * Sorts by Interpreter location.
	 */
	private void sortByLocation() {
		fInterpreterList.setComparator(new ViewerComparator() {
			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				if ((e1 instanceof IInterpreterInstall)
						&& (e2 instanceof IInterpreterInstall)) {
					IInterpreterInstall left = (IInterpreterInstall) e1;
					IInterpreterInstall right = (IInterpreterInstall) e2;
					return left.getInstallLocation().toString()
							.compareToIgnoreCase(
									right.getInstallLocation().toString());
				}
				return super.compare(viewer, e1, e2);
			}

			@Override
			public boolean isSorterProperty(Object element, String property) {
				return true;
			}
		});
		fSortColumn = 2;
	}

	protected void enableButtons() {
		IStructuredSelection selection = fInterpreterList
				.getStructuredSelection();
		int selectionCount = selection.size();
		fEditButton.setEnabled(selectionCount == 1);
		fCopyButton.setEnabled(selectionCount > 0);
		if (selectionCount > 0) {
			Iterator<?> iterator = selection.iterator();
			while (iterator.hasNext()) {
				IInterpreterInstall install = (IInterpreterInstall) iterator
						.next();
				if (isContributed(install)) {
					fRemoveButton.setEnabled(false);
					return;
				}
			}
			fRemoveButton.setEnabled(true);
		} else {
			fRemoveButton.setEnabled(false);
		}
	}

	protected Button createPushButton(Composite parent, String label) {
		return SWTUtil.createPushButton(parent, label, null);
	}

	private boolean isContributed(IInterpreterInstall install) {
		return ScriptRuntime.isContributedInterpreterInstall(install.getId());
	}

	/**
	 * Returns this block's control
	 *
	 * @return control
	 */
	public Control getControl() {
		return fControl;
	}

	/**
	 * Sets the InterpreterEnvironments to be displayed in this block
	 *
	 * @param Interpreters
	 *                         InterpreterEnvironments to be displayed
	 */
	protected void setInterpreters(IInterpreterInstall[] Interpreters) {
		fInterpreters.clear();
		for (int i = 0; i < Interpreters.length; i++) {
			fInterpreters.add(Interpreters[i]);
		}
		fInterpreterList.setInput(fInterpreters);
		fInterpreterList.refresh();
	}

	/**
	 * Returns the InterpreterEnvironments currently being displayed in this
	 * block
	 *
	 * @return InterpreterEnvironments currently being displayed in this block
	 */
	public IInterpreterInstall[] getInterpreters() {
		return fInterpreters
				.toArray(new IInterpreterInstall[fInterpreters.size()]);
	}

	public IInterpreterInstall[] getCurrentInterprers() {
		IEnvironment environment = getCurrentEnvironment();
		List<IInterpreterInstall> result = new ArrayList<>();
		for (Iterator<IInterpreterInstall> iterator = fInterpreters
				.iterator(); iterator.hasNext();) {
			IInterpreterInstall install = iterator.next();
			if (install.getInstallLocation().getEnvironmentId()
					.equals(environment.getId())) {
				result.add(install);
			}
		}
		return result.toArray(new IInterpreterInstall[result.size()]);
	}

	/**
	 * @see IAddInterpreterDialogRequestor#isDuplicateName(String)
	 */
	@Override
	public boolean isDuplicateName(String name,
			IInterpreterInstall editedInterpreter) {
		for (int i = 0; i < fInterpreters.size(); i++) {
			IInterpreterInstall interpreter = fInterpreters.get(i);
			if (interpreter.getName().equals(name)) {
				if (interpreter != editedInterpreter) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * @see IAddInterpreterDialogRequestor#isDuplicateName(String)
	 */
	public boolean isDuplicate(IFileHandle location) {
		for (int i = 0; i < fInterpreters.size(); i++) {
			IInterpreterInstall interpreter = fInterpreters.get(i);
			if (interpreter.getInstallLocation().equals(location)) {
				return true;
			}
		}
		return false;
	}

	private void removeInterpreters() {
		IStructuredSelection selection = fInterpreterList
				.getStructuredSelection();
		IInterpreterInstall[] Interpreters = new IInterpreterInstall[selection
				.size()];
		Iterator<?> iter = selection.iterator();
		int i = 0;
		while (iter.hasNext()) {
			Interpreters[i] = (IInterpreterInstall) iter.next();
			i++;
		}
		removeInterpreters(Interpreters);
	}

	/**
	 * Removes the given Interpreters from the table.
	 *
	 * @param Interpreters
	 */
	public void removeInterpreters(IInterpreterInstall[] Interpreters) {
		IStructuredSelection prev = (IStructuredSelection) getSelection();
		for (int i = 0; i < Interpreters.length; i++) {
			fInterpreters.remove(Interpreters[i]);
		}
		fInterpreterList.refresh();
		IStructuredSelection curr = (IStructuredSelection) getSelection();
		if (!curr.equals(prev)) {
			IInterpreterInstall[] installs = getInterpreters();
			if (curr.size() == 0 && installs.length == 1) {
				// pick a default Interpreter automatically
				setSelection(new StructuredSelection(installs[0]));
			} else {
				fireSelectionChanged();
			}
		}
	}

	/**
	 * Search for installed interpreters in the file system
	 */
	protected void search() {

		// choose a root directory for the search
		// ignore installed locations
		final Set<IFileHandle> exstingLocations = new HashSet<>();
		Iterator<IInterpreterInstall> iter = fInterpreters.iterator();
		while (iter.hasNext()) {
			exstingLocations.add(iter.next().getInstallLocation());
		}

		// search
		final InterpreterSearcher searcher = new InterpreterSearcher();

		final IEnvironment currentEnvironment = getCurrentEnvironment();

		IRunnableWithProgress r = monitor -> {
			try {
				monitor.beginTask(
						InterpretersMessages.InstalledInterpretersBlock_11,
						IProgressMonitor.UNKNOWN);

				searcher.search(currentEnvironment, getCurrentNature(),
						exstingLocations, 1, monitor);
			} finally {
				monitor.done();
			}
		};

		try {
			ProgressMonitorDialog progress = new ProgressMonitorDialog(
					getShell()) {

				@Override
				protected void createCancelButton(Composite parent) {
					super.createCancelButton(parent);
					cancel.setText(InterpretersMessages.InterpretersBlock_0);
				}

			};
			progress.run(true, true, r);
		} catch (InvocationTargetException e) {
			DLTKDebugUIPlugin.log(e);
		} catch (InterruptedException e) {
			return; // cancelled
		}
		final int[] widths = { 15, 15 };
		if (!searcher.hasResults()) {
			MessageDialog.openInformation(getShell(),
					InterpretersMessages.InstalledInterpretersBlock_12,
					InterpretersMessages.InstalledInterpretersBlock_113);
		} else {
			final IFileHandle[] locations = searcher.getFoundFiles();
			final IInterpreterInstallType[] types = searcher
					.getFoundInstallTypes();
			boolean added = false;
			for (int i = 0; i < locations.length; ++i) {
				final IFileHandle file = locations[i];
				final IInterpreterInstallType type = types[i];
				if (isDuplicate(file)) {
					continue;
				}
				added = true;

				IInterpreterInstall interpreter = new InterpreterStandin(type,
						createUniqueId(type));
				final String name = file.getName();

				String nameCopy = name;
				int j = 1;
				while (isDuplicateName(nameCopy, null)) {
					nameCopy = name + '(' + (j++) + ')';
				}
				if (widths[0] < nameCopy.length()) {
					widths[0] = nameCopy.length() + 2;
				}
				if (widths[1] < type.getName().length()) {
					widths[1] = type.getName().length() + 2;
				}
				interpreter.setName(nameCopy);
				interpreter.setInstallLocation(file);
				interpreterAdded(interpreter);
			}
			if (!added) {
				MessageDialog.openInformation(getShell(),
						InterpretersMessages.InstalledInterpretersBlock_12,
						InterpretersMessages.InstalledInterpretersBlock_113);
			}
			fTable.getDisplay().asyncExec(() -> {
				PixelConverter conv = new PixelConverter(fTable);
				for (int i = 0; i < 2; i++) {
					int nw1 = conv.convertWidthInCharsToPixels(widths[i]);
					TableColumn cl0 = fTable.getColumn(i);
					if (cl0.getWidth() < nw1) {
						cl0.setWidth(nw1);
					}
				}
				fTable.layout();
			});
		}
	}

	protected Shell getShell() {
		return getControl().getShell();
	}

	/**
	 * Sets the checked InterpreterEnvironment, possible <code>null</code>
	 *
	 * @param interpreter
	 *                        InterpreterEnvironment or <code>null</code>
	 */
	public void setCheckedInterpreter(IInterpreterInstall interpreter) {
		if (interpreter == null) {
			setSelection(new StructuredSelection());
		} else {
			if (interpreter.getEnvironment().equals(getCurrentEnvironment())) {
				setSelection(new StructuredSelection(interpreter));
			}
			checkedInterpreters.put(interpreter.getEnvironment(), interpreter);
		}
	}

	/**
	 * Returns the checked Interpreter or <code>null</code> if none.
	 *
	 * @return the checked Interpreter or <code>null</code> if none
	 */
	public IInterpreterInstall[] getCheckedInterpreters() {
		Collection<IInterpreterInstall> values = checkedInterpreters.values();
		IInterpreterInstall[] installs = new IInterpreterInstall[values.size()];
		int i = 0;
		for (Iterator<IInterpreterInstall> iterator = values
				.iterator(); iterator.hasNext();) {
			installs[i] = iterator.next();
			++i;
		}
		return installs;
	}

	/**
	 * Persist table settings into the give dialog store, prefixed with the
	 * given key.
	 *
	 * @param settings
	 *                      dialog store
	 * @param qualifier
	 *                      key qualifier
	 */
	public void saveColumnSettings(IDialogSettings settings, String qualifier) {
		int columnCount = fTable.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			settings.put(qualifier + ".columnWidth" + i, //$NON-NLS-1$
					fTable.getColumn(i).getWidth());
		}
		settings.put(qualifier + ".sortColumn", fSortColumn); //$NON-NLS-1$
	}

	/**
	 * Restore table settings from the given dialog store using the given key.
	 *
	 * @param settings
	 *                      dialog settings store
	 * @param qualifier
	 *                      key to restore settings from
	 */
	public void restoreColumnSettings(IDialogSettings settings,
			String qualifier) {
		fInterpreterList.getTable().layout(true);
		restoreColumnWidths(settings, qualifier);
		try {
			fSortColumn = settings.getInt(qualifier + ".sortColumn"); //$NON-NLS-1$
		} catch (NumberFormatException e) {
			fSortColumn = 1;
		}
		switch (fSortColumn) {
		case 1:
			sortByName();
			break;
		case 2:
			sortByLocation();
			break;
		case 3:
			sortByType();
			break;
		}
	}

	private void restoreColumnWidths(IDialogSettings settings,
			String qualifier) {
		int columnCount = fTable.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			int width = -1;

			try {
				width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$
			} catch (NumberFormatException e) {
			}

			if (width <= 0) {
				fTable.getColumn(i).pack();
			} else {
				fTable.getColumn(i).setWidth(width);
			}
		}
	}

	/**
	 * Populates the InterpreterEnvironment table with existing
	 * InterpreterEnvironments defined in the workspace.
	 */
	protected void fillWithWorkspaceInterpreters() {
		// fill with interpreters
		List<InterpreterStandin> standins = new ArrayList<>();
		IInterpreterInstallType[] types = ScriptRuntime
				.getInterpreterInstallTypes(getCurrentNature());
		for (int i = 0; i < types.length; i++) {
			IInterpreterInstallType type = types[i];
			IInterpreterInstall[] installs = type.getInterpreterInstalls();
			if (installs != null)
				for (int j = 0; j < installs.length; j++) {
					IInterpreterInstall install = installs[j];
					standins.add(new InterpreterStandin(install));
				}
		}
		setInterpreters(
				standins.toArray(new IInterpreterInstall[standins.size()]));
	}

	@Override
	public void interpreterAdded(IInterpreterInstall Interpreter) {
		fInterpreters.add(Interpreter);
		fInterpreterList.refresh();

		IInterpreterInstall[] installs = getCurrentInterprers();
		if (installs.length == 1) {
			// pick a default Interpreter automatically
			setSelection(new StructuredSelection(installs[0]));
		}
		fireSelectionChanged();
		packColumns();
	}

	protected void packColumns() {
		final int columnCount = fTable.getColumnCount();
		for (int i = 0; i < columnCount; ++i) {
			fTable.getColumn(i).pack();
		}
	}

	// Make sure that InterpreterStandin ids are unique if multiple calls to
	// System.currentTimeMillis()
	// happen very quickly
	private static String fgLastUsedID;

	private IEnvironment[] environments;

	protected Composite buttons;

	/**
	 * Find a unique Interpreter id. Check existing 'real' Interpreters, as well
	 * as the last id used for a InterpreterStandin.
	 */
	protected String createUniqueId(IInterpreterInstallType InterpreterType) {
		String id = null;
		do {
			id = String.valueOf(System.currentTimeMillis());
		} while (InterpreterType.findInterpreterInstall(id) != null
				|| id.equals(fgLastUsedID));
		fgLastUsedID = id;
		return id;
	}

	/**
	 * Compares the given name against current names and adds the appropriate
	 * numerical suffix to ensure that it is unique.
	 *
	 * @param name
	 *                 the name with which to ensure uniqueness
	 * @return the unique version of the given name
	 *
	 */
	protected String generateName(String name) {
		if (!isDuplicateName(name, null)) {
			return name;
		}

		if (name.matches(".*\\(\\d*\\)")) { //$NON-NLS-1$
			int start = name.lastIndexOf('(');
			int end = name.lastIndexOf(')');
			String stringInt = name.substring(start + 1, end);
			int numericValue = Integer.parseInt(stringInt);
			String newName = name.substring(0, start + 1) + (numericValue + 1)
					+ ")"; //$NON-NLS-1$
			return generateName(newName);
		} else {
			return generateName(name + " (1)"); //$NON-NLS-1$
		}
	}

	abstract protected String getCurrentNature();

	/**
	 * Creates the {@link IInterpreterInstall} add/edit dialog. Should be
	 * overridden.
	 *
	 * @param environment
	 * @param standin
	 * @return @
	 */
	protected IScriptInterpreterDialog createInterpreterDialog(
			IEnvironment environment, IInterpreterInstall standin) {
		// backwards compatible implementation
		final AddScriptInterpreterDialog dialog = createInterpreterDialog(
				standin);
		if (dialog != null) {
			dialog.setEnvironment(environment);
		}
		return dialog;
	}

	/**
	 * @param standin
	 * @return
	 * @deprecated createInterpreterDialog(IEnvironment,IInterpreterInstall)
	 *             method above should be overridden. This one is kept for
	 *             compatibility purposes only.
	 */
	@Deprecated
	protected AddScriptInterpreterDialog createInterpreterDialog(
			IInterpreterInstall standin) {
		return null;
	}

	protected void copyInterpreter() {
		IStructuredSelection selection = fInterpreterList
				.getStructuredSelection();
		Iterator<?> it = selection.iterator();

		ArrayList<InterpreterStandin> newEntries = new ArrayList<>();
		while (it.hasNext()) {
			IInterpreterInstall selectedInterpreter = (IInterpreterInstall) it
					.next();

			// duplicate & add Interpreter
			InterpreterStandin standin = new InterpreterStandin(
					selectedInterpreter, createUniqueId(
							selectedInterpreter.getInterpreterInstallType()));
			standin.setName(generateName(selectedInterpreter.getName()));
			IScriptInterpreterDialog dialog = createInterpreterDialog(
					getCurrentEnvironment(), standin);
			if (dialog == null)
				return;
			dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_18);
			if (!dialog.execute()) {
				return;
			}
			newEntries.add(standin);
			fInterpreters.add(standin);
		}
		fInterpreterList.refresh();
		fInterpreterList
				.setSelection(new StructuredSelection(newEntries.toArray()));
	}

	/**
	 * Bring up a dialog that lets the user create a new Interpreter definition.
	 */
	protected void addInterpreter() {
		IScriptInterpreterDialog dialog = createInterpreterDialog(
				getCurrentEnvironment(), null);
		if (dialog == null)
			return;
		dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_7);
		if (!dialog.execute()) {
			return;
		}
		fInterpreterList.refresh();
	}

	protected void editInterpreter() {
		IStructuredSelection selection = (IStructuredSelection) fInterpreterList
				.getSelection();
		IInterpreterInstall install = (IInterpreterInstall) selection
				.getFirstElement();

		if (install == null) {
			return;
		}

		IScriptInterpreterDialog dialog = createInterpreterDialog(
				getCurrentEnvironment(), install);
		if (dialog == null)
			return;
		dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_8);
		if (!dialog.execute()) {
			return;
		}
		fInterpreterList.refresh(install);
	}

	public IEnvironment getCurrentEnvironment() {
		if (fEnvironments == null) {
			return EnvironmentManager.getLocalEnvironment();
		}
		return environments[fEnvironments.getSelectionIndex()];
	}

	public int getEnvironmentsCount() {
		return environments.length;
	}

}
