/*******************************************************************************
 * Copyright (c) 2000, 2017 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.ui.workingsets;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.ui.actions.SelectionConverter;
import org.eclipse.dltk.internal.ui.util.SWTUtil;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.ModelElementSorter;
import org.eclipse.dltk.ui.ScriptElementImageProvider;
import org.eclipse.dltk.ui.ScriptElementLabels;
import org.eclipse.dltk.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.dltk.ui.viewsupport.StyledDecoratingModelLabelProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetPage;

/**
 * The Script working set page allows the user to create and edit a Script
 * working set.
 * <p>
 * Working set elements are presented as a Script element tree.
 * </p>
 *
 *
 */
public class ScriptWorkingSetPage extends WizardPage
		implements IWorkingSetPage {

	final private static String PAGE_TITLE = WorkingSetMessages.ScriptWorkingSetPage_title;
	final private static String PAGE_ID = "ScriptWorkingSetPage"; //$NON-NLS-1$

	private Text fWorkingSetName;
	private CheckboxTreeViewer fTree;
	private ITreeContentProvider fTreeContentProvider;

	private boolean fFirstCheck;
	private IWorkingSet fWorkingSet;

	/**
	 * Default constructor.
	 */
	public ScriptWorkingSetPage() {
		super(PAGE_ID, PAGE_TITLE,
				DLTKPluginImages.DESC_WIZBAN_SCRIPT_WORKINGSET);
		setDescription(
				WorkingSetMessages.ScriptWorkingSetPage_workingSet_description);
		fFirstCheck = true;
	}

	/*
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.
	 * widgets.Composite)
	 */
	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		setControl(composite);

		Label label = new Label(composite, SWT.WRAP);
		label.setText(WorkingSetMessages.ScriptWorkingSetPage_workingSet_name);
		GridData gd = new GridData(
				GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL
						| GridData.VERTICAL_ALIGN_CENTER);
		label.setLayoutData(gd);

		fWorkingSetName = new Text(composite, SWT.SINGLE | SWT.BORDER);
		fWorkingSetName.setLayoutData(new GridData(
				GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
		fWorkingSetName.addModifyListener(e -> validateInput());
		fWorkingSetName.setFocus();

		label = new Label(composite, SWT.WRAP);
		label.setText(
				WorkingSetMessages.ScriptWorkingSetPage_workingSet_content);
		gd = new GridData(
				GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL
						| GridData.VERTICAL_ALIGN_CENTER);
		label.setLayoutData(gd);

		fTree = new CheckboxTreeViewer(composite,
				SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
		gd.heightHint = convertHeightInCharsToPixels(15);
		fTree.getControl().setLayoutData(gd);

		fTreeContentProvider = new ScriptWorkingSetPageContentProvider();
		fTree.setContentProvider(fTreeContentProvider);

		AppearanceAwareLabelProvider fScriptElementLabelProvider = new AppearanceAwareLabelProvider(
				AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
						| ScriptElementLabels.P_COMPRESSED,
				AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS
						| ScriptElementImageProvider.SMALL_ICONS,
				DLTKUIPlugin.getDefault().getPreferenceStore());

		fTree.setLabelProvider(new StyledDecoratingModelLabelProvider(
				fScriptElementLabelProvider));
		fTree.setComparator(new ModelElementSorter());
		if (DLTKCore.DEBUG) {
			System.err
					.println("Add empty inner package filter support here..."); //$NON-NLS-1$
		}
		// fTree.addFilter(new EmptyInnerPackageFilter());
		fTree.setUseHashlookup(true);

		fTree.setInput(
				DLTKCore.create(ResourcesPlugin.getWorkspace().getRoot()));

		fTree.addCheckStateListener(event -> handleCheckStateChange(event));

		fTree.addTreeListener(new ITreeViewerListener() {
			@Override
			public void treeCollapsed(TreeExpansionEvent event) {
			}

			@Override
			public void treeExpanded(TreeExpansionEvent event) {
				final Object element = event.getElement();
				if (fTree.getGrayed(element) == false)
					BusyIndicator.showWhile(getShell().getDisplay(),
							() -> setSubtreeChecked(element,
									fTree.getChecked(element), false));
			}
		});

		// Add select / deselect all buttons for bug 46669
		Composite buttonComposite = new Composite(composite, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		buttonComposite.setLayout(layout);
		buttonComposite
				.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
		selectAllButton.setText(
				WorkingSetMessages.ScriptWorkingSetPage_selectAll_label);
		selectAllButton.setToolTipText(
				WorkingSetMessages.ScriptWorkingSetPage_selectAll_toolTip);
		selectAllButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent selectionEvent) {
				fTree.setCheckedElements(
						fTreeContentProvider.getElements(fTree.getInput()));
				validateInput();
			}
		});
		selectAllButton.setLayoutData(new GridData());
		SWTUtil.setButtonDimensionHint(selectAllButton);

		Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
		deselectAllButton.setText(
				WorkingSetMessages.ScriptWorkingSetPage_deselectAll_label);
		deselectAllButton.setToolTipText(
				WorkingSetMessages.ScriptWorkingSetPage_deselectAll_toolTip);
		deselectAllButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent selectionEvent) {
				fTree.setCheckedElements(new Object[0]);
				validateInput();
			}
		});
		deselectAllButton.setLayoutData(new GridData());
		SWTUtil.setButtonDimensionHint(deselectAllButton);

		if (fWorkingSet != null)
			fWorkingSetName.setText(fWorkingSet.getName());
		initializeCheckedState();
		validateInput();

		Dialog.applyDialogFont(composite);
		// Set help for the page
		if (DLTKCore.DEBUG) {
			System.err.println("Add help support here..."); //$NON-NLS-1$
		}
		// ScriptUIHelp.setHelp(fTree,
		// IScriptHelpContextIds.Script_WORKING_SET_PAGE);
	}

	/*
	 * Implements method from IWorkingSetPage
	 */
	@Override
	public IWorkingSet getSelection() {
		return fWorkingSet;
	}

	/*
	 * Implements method from IWorkingSetPage
	 */
	@Override
	public void setSelection(IWorkingSet workingSet) {
		Assert.isNotNull(workingSet, "Working set must not be null"); //$NON-NLS-1$
		fWorkingSet = workingSet;
		if (getContainer() != null && getShell() != null
				&& fWorkingSetName != null) {
			fFirstCheck = false;
			fWorkingSetName.setText(fWorkingSet.getName());
			initializeCheckedState();
			validateInput();
		}
	}

	/*
	 * Implements method from IWorkingSetPage
	 */
	@Override
	public void finish() {
		String workingSetName = fWorkingSetName.getText();
		ArrayList<IAdaptable> elements = new ArrayList<>(10);
		findCheckedElements(elements, fTree.getInput());
		if (fWorkingSet == null) {
			IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
					.getWorkingSetManager();
			fWorkingSet = workingSetManager.createWorkingSet(workingSetName,
					elements.toArray(new IAdaptable[elements.size()]));
		} else {
			// Add inaccessible resources
			IAdaptable[] oldItems = fWorkingSet.getElements();
			ArrayList closedWithChildren = new ArrayList(elements.size());
			for (int i = 0; i < oldItems.length; i++) {
				IResource oldResource = null;
				if (oldItems[i] instanceof IResource) {
					oldResource = (IResource) oldItems[i];
				} else {
					oldResource = oldItems[i].getAdapter(IResource.class);
				}
				if (oldResource != null
						&& oldResource.isAccessible() == false) {
					IProject project = oldResource.getProject();
					if (elements.contains(project)
							|| closedWithChildren.contains(project)) {
						elements.add(oldItems[i]);
						elements.remove(project);
						closedWithChildren.add(project);
					}
				}
			}
			fWorkingSet.setName(workingSetName);
			fWorkingSet.setElements(
					elements.toArray(new IAdaptable[elements.size()]));
		}
	}

	private void validateInput() {
		String errorMessage = null;
		String infoMessage = null;
		String newText = fWorkingSetName.getText();

		if (newText.equals(newText.trim()) == false)
			errorMessage = WorkingSetMessages.ScriptWorkingSetPage_warning_nameWhitespace;
		if (newText.equals("")) { //$NON-NLS-1$
			if (fFirstCheck) {
				setPageComplete(false);
				fFirstCheck = false;
				return;
			} else
				errorMessage = WorkingSetMessages.ScriptWorkingSetPage_warning_nameMustNotBeEmpty;
		}

		fFirstCheck = false;

		if (errorMessage == null && (fWorkingSet == null
				|| newText.equals(fWorkingSet.getName()) == false)) {
			IWorkingSet[] workingSets = PlatformUI.getWorkbench()
					.getWorkingSetManager().getWorkingSets();
			for (int i = 0; i < workingSets.length; i++) {
				if (newText.equals(workingSets[i].getName())) {
					errorMessage = WorkingSetMessages.ScriptWorkingSetPage_warning_workingSetExists;
				}
			}
		}

		if (!hasCheckedElement())
			infoMessage = WorkingSetMessages.ScriptWorkingSetPage_warning_resourceMustBeChecked;

		setMessage(infoMessage, INFORMATION);
		setErrorMessage(errorMessage);
		setPageComplete(errorMessage == null);
	}

	private boolean hasCheckedElement() {
		TreeItem[] items = fTree.getTree().getItems();
		for (int i = 0; i < items.length; i++) {
			if (items[i].getChecked())
				return true;
		}
		return false;
	}

	private void findCheckedElements(List checkedResources, Object parent) {
		Object[] children = fTreeContentProvider.getChildren(parent);
		for (int i = 0; i < children.length; i++) {
			if (fTree.getGrayed(children[i]))
				findCheckedElements(checkedResources, children[i]);
			else if (fTree.getChecked(children[i]))
				checkedResources.add(children[i]);
		}
	}

	void handleCheckStateChange(final CheckStateChangedEvent event) {
		BusyIndicator.showWhile(getShell().getDisplay(), () -> {
			IAdaptable element = (IAdaptable) event.getElement();
			boolean state = event.getChecked();
			fTree.setGrayed(element, false);
			if (isExpandable(element))
				setSubtreeChecked(element, state, state); // only check subtree
															// if state is set
															// to true

			updateParentState(element, state);
			validateInput();
		});
	}

	private void setSubtreeChecked(Object parent, boolean state,
			boolean checkExpandedState) {
		if (!(parent instanceof IAdaptable))
			return;
		IContainer container = ((IAdaptable) parent)
				.getAdapter(IContainer.class);
		if ((!fTree.getExpandedState(parent) && checkExpandedState)
				|| (container != null && !container.isAccessible()))
			return;

		Object[] children = fTreeContentProvider.getChildren(parent);
		for (int i = children.length - 1; i >= 0; i--) {
			Object element = children[i];
			if (state) {
				fTree.setChecked(element, true);
				fTree.setGrayed(element, false);
			} else
				fTree.setGrayChecked(element, false);
			if (isExpandable(element))
				setSubtreeChecked(element, state, true);
		}
	}

	private void updateParentState(Object child, boolean baseChildState) {
		if (child == null)
			return;
		if (child instanceof IAdaptable) {
			IResource resource = ((IAdaptable) child)
					.getAdapter(IResource.class);
			if (resource != null && !resource.isAccessible())
				return;
		}
		Object parent = fTreeContentProvider.getParent(child);
		if (parent == null)
			return;

		boolean allSameState = true;
		Object[] children = null;
		children = fTreeContentProvider.getChildren(parent);

		for (int i = children.length - 1; i >= 0; i--) {
			if (fTree.getChecked(children[i]) != baseChildState
					|| fTree.getGrayed(children[i])) {
				allSameState = false;
				break;
			}
		}

		fTree.setGrayed(parent, !allSameState);
		fTree.setChecked(parent, !allSameState || baseChildState);

		updateParentState(parent, baseChildState);
	}

	private void initializeCheckedState() {

		BusyIndicator.showWhile(getShell().getDisplay(), () -> {
			Object[] elements;
			if (fWorkingSet == null) {
				// Use current part's selection for initialization
				IWorkbenchPage page = DLTKUIPlugin.getActivePage();
				if (page == null)
					return;

				IWorkbenchPart part = DLTKUIPlugin.getActivePage()
						.getActivePart();
				if (part == null)
					return;

				try {
					elements = SelectionConverter.getStructuredSelection(part)
							.toArray();
					for (int i1 = 0; i1 < elements.length; i1++) {
						if (elements[i1] instanceof IResource) {
							IModelElement je = ((IResource) elements[i1])
									.getAdapter(IModelElement.class);
							if (je != null && je.exists()
									&& je.getScriptProject().isOnBuildpath(
											(IResource) elements[i1]))
								elements[i1] = je;
						}
					}
				} catch (ModelException e) {
					return;
				}
			} else
				elements = fWorkingSet.getElements();

			// Use closed project for elements in closed project
			for (int i2 = 0; i2 < elements.length; i2++) {
				Object element1 = elements[i2];
				if (element1 instanceof IResource) {
					IProject project = ((IResource) element1).getProject();
					if (!project.isAccessible())
						elements[i2] = project;
				}
				if (element1 instanceof IModelElement) {
					IScriptProject jProject = ((IModelElement) element1)
							.getScriptProject();
					if (jProject != null
							&& !jProject.getProject().isAccessible())
						elements[i2] = jProject.getProject();
				}
			}

			fTree.setCheckedElements(elements);
			for (int i3 = 0; i3 < elements.length; i3++) {
				Object element2 = elements[i3];
				if (isExpandable(element2))
					setSubtreeChecked(element2, true, true);

				updateParentState(element2, true);
			}
		});
	}

	private boolean isExpandable(Object element) {
		return (element instanceof IScriptProject
				|| element instanceof IProjectFragment
				|| element instanceof IScriptFolder
				|| element instanceof IScriptModel
				|| element instanceof IContainer);
	}
}
