/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 * 		Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font
 *   	should be activated and used by other components.
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.workingsets;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Shell;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
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.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
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.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;

import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
import org.eclipse.ui.dialogs.IWorkingSetNewWizard;
import org.eclipse.ui.dialogs.SelectionDialog;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;

public class WorkingSetConfigurationDialog extends SelectionDialog {

	private static class WorkingSetLabelProvider extends LabelProvider {
		private Map<ImageDescriptor, Image> fIcons;
		public WorkingSetLabelProvider() {
			fIcons= new Hashtable<>();
		}
		@Override
		public void dispose() {
			Iterator<Image> iterator= fIcons.values().iterator();
			while (iterator.hasNext()) {
				Image icon= iterator.next();
				icon.dispose();
			}
			super.dispose();
		}
		@Override
		public Image getImage(Object object) {
			Assert.isTrue(object instanceof IWorkingSet);
			IWorkingSet workingSet= (IWorkingSet)object;
			ImageDescriptor imageDescriptor= workingSet.getImageDescriptor();
			if (imageDescriptor == null)
				return null;
			Image icon= fIcons.get(imageDescriptor);
			if (icon == null) {
				icon= imageDescriptor.createImage();
				fIcons.put(imageDescriptor, icon);
			}
			return icon;
		}
		@Override
		public String getText(Object object) {
			Assert.isTrue(object instanceof IWorkingSet);
			IWorkingSet workingSet= (IWorkingSet)object;
			return BasicElementLabels.getWorkingSetLabel(workingSet);
		}
	}

	private List<IWorkingSet> fAllWorkingSets;
	private CheckboxTableViewer fTableViewer;

	private Button fNewButton;
	private Button fEditButton;
	private Button fRemoveButton;
	private Button fUpButton;
	private Button fDownButton;
	private Button fSelectAll;
	private Button fDeselectAll;

	/**
	 * Sort working sets button.
	 * 
	 * @since 3.5
	 */
	private Button fSortWorkingSet;

	private IWorkingSet[] fResult;
	private List<IWorkingSet> fAddedWorkingSets;
	private List<IWorkingSet> fRemovedWorkingSets;
	private Map<IWorkingSet, IWorkingSet> fEditedWorkingSets;
	private List<IWorkingSet> fRemovedMRUWorkingSets;

	private int nextButtonId= IDialogConstants.CLIENT_ID + 1;

	/**
	 * Value of sorted state of working sets.
	 * 
	 * @since 3.5
	 */
	private boolean fIsSortingEnabled;

	/**
	 * The working set comparator.
	 * 
	 * @since 3.5
	 */
	private WorkingSetComparator fComparator;

	public WorkingSetConfigurationDialog(Shell parentShell, IWorkingSet[] allWorkingSets, boolean isSortingEnabled) {
		super(parentShell);
		setTitle(WorkingSetMessages.WorkingSetConfigurationDialog_title);
		setMessage(WorkingSetMessages.WorkingSetConfigurationDialog_message);
		fAllWorkingSets= new ArrayList<>(allWorkingSets.length);
		fAllWorkingSets.addAll(Arrays.asList(allWorkingSets));
		fIsSortingEnabled= isSortingEnabled;
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.WORKING_SET_CONFIGURATION_DIALOG);
	}

	/**
	 * Returns the selected working sets
	 *
	 * @return the selected working sets
	 */
	public IWorkingSet[] getSelection() {
		return fResult;
	}

	/**
	 * Sets the initial selection
	 *
	 * @param workingSets the initial selection
	 */
	public void setSelection(IWorkingSet[] workingSets) {
		fResult= workingSets;
		setInitialSelections((Object[]) workingSets);
	}

	@Override
	protected Control createContents(Composite parent) {
		Control control= super.createContents(parent);
		setInitialSelection();
		updateButtonAvailability();
		return control;
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite= (Composite)super.createDialogArea(parent);

		createMessageArea(composite);
		Composite inner= new Composite(composite, SWT.NONE);
		inner.setLayoutData(new GridData(GridData.FILL_BOTH));
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		inner.setLayout(layout);
		createTableViewer(inner);
		createOrderButtons(inner);
		createModifyButtons(composite);
		updateSorting();
		fTableViewer.setInput(fAllWorkingSets);
		applyDialogFont(composite);

		return composite;
	}

	private void createTableViewer(Composite parent) {
		fTableViewer= CheckboxTableViewer.newCheckList(parent, SWT.BORDER | SWT.MULTI);
		fTableViewer.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				updateButtonAvailability();
			}
		});
		GridData data= new GridData(GridData.FILL_BOTH);
		data.heightHint= convertHeightInCharsToPixels(20);
		data.widthHint= convertWidthInCharsToPixels(50);
		fTableViewer.getTable().setLayoutData(data);

		fTableViewer.setLabelProvider(new WorkingSetLabelProvider());
		fTableViewer.setContentProvider(ArrayContentProvider.getInstance());
		fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				handleSelectionChanged();
			}
		});
		fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				if (fEditButton.isEnabled())
					editSelectedWorkingSet();
			}
		});
	}

	private void createModifyButtons(Composite composite) {
		Composite buttonComposite= new Composite(composite, SWT.RIGHT);
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		buttonComposite.setLayout(layout);
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
		data.grabExcessHorizontalSpace= true;
		composite.setData(data);

		fNewButton= createButton(buttonComposite, nextButtonId++,
			WorkingSetMessages.WorkingSetConfigurationDialog_new_label, false);
		fNewButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				createWorkingSet();
			}
		});

		fEditButton= createButton(buttonComposite, nextButtonId++,
			WorkingSetMessages.WorkingSetConfigurationDialog_edit_label, false);
		fEditButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				editSelectedWorkingSet();
			}
		});

		fRemoveButton= createButton(buttonComposite, nextButtonId++,
			WorkingSetMessages.WorkingSetConfigurationDialog_remove_label, false);
		fRemoveButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				removeSelectedWorkingSets();
			}
		});
	}

	private void createOrderButtons(Composite parent) {
		Composite buttons= new Composite(parent, SWT.NONE);
		buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		GridLayout layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		buttons.setLayout(layout);

		fUpButton= new Button(buttons, SWT.PUSH);
		fUpButton.setText(WorkingSetMessages.WorkingSetConfigurationDialog_up_label);
		setButtonLayoutData(fUpButton);
		fUpButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				moveUp(((IStructuredSelection)fTableViewer.getSelection()).toList());
			}
		});

		fDownButton= new Button(buttons, SWT.PUSH);
		fDownButton.setText(WorkingSetMessages.WorkingSetConfigurationDialog_down_label);
		setButtonLayoutData(fDownButton);
		fDownButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				moveDown(((IStructuredSelection)fTableViewer.getSelection()).toList());
			}
		});

		fSelectAll= new Button(buttons, SWT.PUSH);
		fSelectAll.setText(WorkingSetMessages.WorkingSetConfigurationDialog_selectAll_label);
		setButtonLayoutData(fSelectAll);
		fSelectAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				selectAll();
			}
		});

		fDeselectAll= new Button(buttons, SWT.PUSH);
		fDeselectAll.setText(WorkingSetMessages.WorkingSetConfigurationDialog_deselectAll_label);
		setButtonLayoutData(fDeselectAll);
		fDeselectAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				deselectAll();
			}
		});
		/**
		 * A check box that has persistence to sort the working sets alphabetically in the
		 * WorkingSetConfigurationDialog. It restores the unsorted order of the working sets when
		 * unchecked.
		 * 
		 * @since 3.5
		 */
		fSortWorkingSet= new Button(parent, SWT.CHECK);
		fSortWorkingSet.setText(WorkingSetMessages.WorkingSetConfigurationDialog_sort_working_sets);
		fSortWorkingSet.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, false));
		fSortWorkingSet.setSelection(fIsSortingEnabled);
		fSortWorkingSet.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fIsSortingEnabled= fSortWorkingSet.getSelection();
				updateButtonAvailability();
				updateSorting();
			}
		});
	}

	@Override
	protected void okPressed() {
		List<IWorkingSet> newResult= getResultWorkingSets();
		fResult= newResult.toArray(new IWorkingSet[newResult.size()]);
		if (fIsSortingEnabled) {
			Collections.sort(fAllWorkingSets, getComparator());
		}
		setResult(newResult);
		super.okPressed();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<IWorkingSet> getResultWorkingSets() {
		Object[] checked= fTableViewer.getCheckedElements();
		return new ArrayList(Arrays.asList(checked));
	}

	@Override
	protected void cancelPressed() {
		restoreAddedWorkingSets();
		restoreChangedWorkingSets();
		restoreRemovedWorkingSets();
		super.cancelPressed();
	}

	private void setInitialSelection() {
		List<Object[]> selections= getInitialElementSelections();
		if (!selections.isEmpty()) {
			fTableViewer.setCheckedElements(selections.toArray());
		}
	}

	private void createWorkingSet() {
		IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
		IWorkingSetNewWizard wizard= manager.createWorkingSetNewWizard(new String[] {IWorkingSetIDs.JAVA});
		// the wizard can't be null since we have at least the Java working set.
		WizardDialog dialog= new WizardDialog(getShell(), wizard);
		dialog.create();
		if (dialog.open() == Window.OK) {
			IWorkingSet workingSet= wizard.getSelection();
			if (WorkingSetModel.isSupportedAsTopLevelElement(workingSet)) {
				fAllWorkingSets.add(workingSet);
				fTableViewer.add(workingSet);
				fTableViewer.setSelection(new StructuredSelection(workingSet), true);
				fTableViewer.setChecked(workingSet, true);
				manager.addWorkingSet(workingSet);
				fAddedWorkingSets.add(workingSet);
			}
		}
	}

	private void editSelectedWorkingSet() {
		IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
		IWorkingSet editWorkingSet= (IWorkingSet)((IStructuredSelection)fTableViewer.getSelection()).getFirstElement();
		IWorkingSetEditWizard wizard= manager.createWorkingSetEditWizard(editWorkingSet);
		WizardDialog dialog= new WizardDialog(getShell(), wizard);
		IWorkingSet originalWorkingSet= fEditedWorkingSets.get(editWorkingSet);
		boolean firstEdit= originalWorkingSet == null;

		// save the original working set values for restoration when selection
		// dialog is cancelled.
		if (firstEdit) {
			originalWorkingSet=
				PlatformUI.getWorkbench().getWorkingSetManager().
				createWorkingSet(editWorkingSet.getName(), editWorkingSet.getElements());
		} else {
			fEditedWorkingSets.remove(editWorkingSet);
		}
		dialog.create();
		if (dialog.open() == Window.OK) {
			editWorkingSet= wizard.getSelection();
			if (fIsSortingEnabled)
				fTableViewer.refresh();
			else
				fTableViewer.update(editWorkingSet, null);

			// make sure ok button is enabled when the selected working set
			// is edited. Fixes bug 33386.
			updateButtonAvailability();
		}
		fEditedWorkingSets.put(editWorkingSet, originalWorkingSet);
	}

	/**
	 * Called when the selection has changed.
	 */
	void handleSelectionChanged() {
		updateButtonAvailability();
	}

	/**
	 * Overrides method in Dialog
	 *
	 * @see org.eclipse.jface.dialogs.Dialog#open()
	 */
	@Override
	public int open() {
		fAddedWorkingSets= new ArrayList<>();
		fRemovedWorkingSets= new ArrayList<>();
		fEditedWorkingSets= new HashMap<>();
		fRemovedMRUWorkingSets= new ArrayList<>();
		return super.open();
	}

	/**
	 * Removes the selected working sets from the workbench.
	 */
	private void removeSelectedWorkingSets() {
		ISelection selection= fTableViewer.getSelection();
		if (selection instanceof IStructuredSelection) {
			IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
			Iterator<?> iter= ((IStructuredSelection)selection).iterator();
			while (iter.hasNext()) {
				IWorkingSet workingSet= (IWorkingSet)iter.next();
				if (fAddedWorkingSets.contains(workingSet)) {
					fAddedWorkingSets.remove(workingSet);
				} else {
					IWorkingSet[] recentWorkingSets= manager.getRecentWorkingSets();
					for (int i= 0; i < recentWorkingSets.length; i++) {
						if (workingSet.equals(recentWorkingSets[i])) {
							fRemovedMRUWorkingSets.add(workingSet);
							break;
						}
					}
					fRemovedWorkingSets.add(workingSet);
				}
				fAllWorkingSets.remove(workingSet);
				manager.removeWorkingSet(workingSet);
			}
			fTableViewer.remove(((IStructuredSelection)selection).toArray());
		}
	}

	/**
	 * Removes newly created working sets from the working set manager.
	 */
	private void restoreAddedWorkingSets() {
		IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
		Iterator<IWorkingSet> iterator= fAddedWorkingSets.iterator();

		while (iterator.hasNext()) {
			manager.removeWorkingSet(iterator.next());
		}
	}

	/**
	 * Rolls back changes to working sets.
	 */
	private void restoreChangedWorkingSets() {
		Iterator<IWorkingSet> iterator= fEditedWorkingSets.keySet().iterator();

		while (iterator.hasNext()) {
			IWorkingSet editedWorkingSet= iterator.next();
			IWorkingSet originalWorkingSet= fEditedWorkingSets.get(editedWorkingSet);

			if (editedWorkingSet.getName().equals(originalWorkingSet.getName()) == false) {
				editedWorkingSet.setName(originalWorkingSet.getName());
			}
			if (editedWorkingSet.getElements().equals(originalWorkingSet.getElements()) == false) {
				editedWorkingSet.setElements(originalWorkingSet.getElements());
			}
		}
	}

	/**
	 * Adds back removed working sets to the working set manager.
	 */
	private void restoreRemovedWorkingSets() {
		IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
		Iterator<IWorkingSet> iterator= fRemovedWorkingSets.iterator();

		while (iterator.hasNext()) {
			manager.addWorkingSet(iterator.next());
		}
		iterator= fRemovedMRUWorkingSets.iterator();
		while (iterator.hasNext()) {
			manager.addRecentWorkingSet(iterator.next());
		}
	}

	/**
	 * Updates the modify buttons' enabled state based on the current seleciton.
	 */
	private void updateButtonAvailability() {
		IStructuredSelection selection= (IStructuredSelection) fTableViewer.getSelection();
		boolean hasSelection= !selection.isEmpty();
		boolean hasSingleSelection= selection.size() == 1;

		fRemoveButton.setEnabled(hasSelection && areAllGlobalWorkingSets(selection));
		fEditButton.setEnabled(hasSingleSelection && ((IWorkingSet)selection.getFirstElement()).isEditable());
		if (fUpButton != null) {
			fUpButton.setEnabled(canMoveUp());
		}
		if (fDownButton != null) {
			fDownButton.setEnabled(canMoveDown());
		}
	}

	private boolean areAllGlobalWorkingSets(IStructuredSelection selection) {
		Set<IWorkingSet> globals= new HashSet<>(Arrays.asList(PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets()));
		for (Iterator<?> iter= selection.iterator(); iter.hasNext();) {
			if (!globals.contains(iter.next()))
				return false;
		}
		return true;
	}

	private void moveUp(List<IWorkingSet> toMoveUp) {
		if (toMoveUp.size() > 0) {
			setElements(moveUp(fAllWorkingSets, toMoveUp));
			fTableViewer.reveal(toMoveUp.get(0));
		}
	}

	private void moveDown(List<IWorkingSet> toMoveDown) {
		if (toMoveDown.size() > 0) {
			setElements(reverse(moveUp(reverse(fAllWorkingSets), toMoveDown)));
			fTableViewer.reveal(toMoveDown.get(toMoveDown.size() - 1));
		}
	}

	private void setElements(List<IWorkingSet> elements) {
		fAllWorkingSets= elements;
		fTableViewer.setInput(fAllWorkingSets);
		updateButtonAvailability();
	}

	private List<IWorkingSet> moveUp(List<IWorkingSet> elements, List<IWorkingSet> move) {
		int nElements= elements.size();
		List<IWorkingSet> res= new ArrayList<>(nElements);
		IWorkingSet floating= null;
		for (int i= 0; i < nElements; i++) {
			IWorkingSet curr= elements.get(i);
			if (move.contains(curr)) {
				res.add(curr);
			} else {
				if (floating != null) {
					res.add(floating);
				}
				floating= curr;
			}
		}
		if (floating != null) {
			res.add(floating);
		}
		return res;
	}

	private List<IWorkingSet> reverse(List<IWorkingSet> p) {
		List<IWorkingSet> reverse= new ArrayList<>(p.size());
		for (int i= p.size() - 1; i >= 0; i--) {
			reverse.add(p.get(i));
		}
		return reverse;
	}

	private boolean canMoveUp() {
		if (!fIsSortingEnabled) {
			int[] indc= fTableViewer.getTable().getSelectionIndices();
			for (int i= 0; i < indc.length; i++) {
				if (indc[i] != i) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean canMoveDown() {
		if (!fIsSortingEnabled) {
			int[] indc= fTableViewer.getTable().getSelectionIndices();
			int k= fAllWorkingSets.size() - 1;
			for (int i= indc.length - 1; i >= 0; i--, k--) {
				if (indc[i] != k) {
					return true;
				}
			}
		}
		return false;
	}

	//---- select / deselect --------------------------------------------------

	private void selectAll() {
		fTableViewer.setAllChecked(true);
	}

	private void deselectAll() {
		fTableViewer.setAllChecked(false);
	}

	/**
	 * Returns the list of newly added working sets through this dialog.
	 * 
	 * @return the list of newly added working sets
	 * @since 3.5
	 */
	public List<IWorkingSet> getNewlyAddedWorkingSets() {
		return fAddedWorkingSets;
		
	}

	/**
	 * Returns whether sorting is enabled for working sets.
	 * 
	 * @return <code>true</code> if sorting is enabled, <code>false</code> otherwise
	 * @since 3.5
	 */
	public boolean isSortingEnabled() {
		return fIsSortingEnabled;
	}

	/**
	 * Returns the working set comparator.
	 * 
	 * @return the working set comparator
	 * @since 3.5
	 */
	private WorkingSetComparator getComparator() {
		if (fComparator == null) {
			fComparator= new WorkingSetComparator(true);
		}
		return fComparator;
	}

	/**
	 * Returns all the working sets.
	 * 
	 * @return all the working sets
	 * @since 3.7
	 */
	public IWorkingSet[] getAllWorkingSets() {
		return fAllWorkingSets.toArray(new IWorkingSet[fAllWorkingSets.size()]);
	}

	private void updateSorting() {
		if (fIsSortingEnabled) {
			fTableViewer.setComparator(new ViewerComparator() {
				@Override
				public int compare(Viewer viewer, Object e1, Object e2) {
					return WorkingSetConfigurationDialog.this.getComparator().compare((IWorkingSet) e1, (IWorkingSet) e2);
				}
			});
		} else {
			fTableViewer.setComparator(null);
		}
	}
}
