/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Anton Leherbauer (Wind River Systems)
 *******************************************************************************/
package org.eclipse.cdt.internal.ui.workingsets;

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

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.actions.SelectionConverter;
import org.eclipse.cdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
import org.eclipse.cdt.internal.ui.viewsupport.DecoratingCLabelProvider;
import org.eclipse.cdt.ui.CElementGrouping;
import org.eclipse.cdt.ui.CElementSorter;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
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 C element working set page allows the user to create
 * and edit a C element working set.
 * <p>
 * Working set elements are presented as a C element tree.
 * </p>
 *
 */
public class CElementWorkingSetPage extends WizardPage implements IWorkingSetPage {

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

	private final static int SIZING_SELECTION_WIDGET_WIDTH = 50;
	private final static int SIZING_SELECTION_WIDGET_HEIGHT = 200;

	private Text fWorkingSetName;
	private CheckboxTreeViewer fTree;
	private IWorkingSet fWorkingSet;
	private boolean fFirstCheck; // set to true if selection is set in setSelection
	private ITreeContentProvider fTreeContentProvider;

	/**
	 * Creates a new instance of the receiver.
	 */
	public CElementWorkingSetPage() {
		super(PAGE_ID, PAGE_TITLE, CPluginImages.DESC_WIZABAN_C_APP);
		setDescription(WorkingSetMessages.CElementWorkingSetPage_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.NULL);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		setControl(composite);

		Label label = new Label(composite, SWT.WRAP);
		label.setText(WorkingSetMessages.CElementWorkingSetPage_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.CElementWorkingSetPage_content);
		gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
		label.setLayoutData(gd);

		fTree = new CheckboxTreeViewer(composite);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
		gd.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
		gd.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
		fTree.getControl().setLayoutData(gd);

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

		AppearanceAwareLabelProvider cElementLabelProvider = new AppearanceAwareLabelProvider(
				AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS,
				AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | CElementImageProvider.SMALL_ICONS);

		fTree.setLabelProvider(new DecoratingCLabelProvider(cElementLabelProvider));
		fTree.setComparator(new CElementSorter());
		fTree.setUseHashlookup(true);

		fTree.setInput(CoreModel.create(CUIPlugin.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));
			}
		});

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

		Dialog.applyDialogFont(composite);
		// TODO Set help for the page
		//		CUIHelp.setHelp(fTree, ICHelpContextIds.C_WORKING_SET_PAGE);
	}

	/*
	 * @see org.eclipse.ui.dialogs.IWorkingSetPage#finish()
	 */
	@Override
	public void finish() {
		String workingSetName = fWorkingSetName.getText();
		ArrayList<Object> 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();
			HashSet<IProject> closedWithChildren = new HashSet<>(elements.size());
			for (IAdaptable oldItem : oldItems) {
				IResource oldResource = null;
				if (oldItem instanceof IResource) {
					oldResource = (IResource) oldItem;
				} else {
					oldResource = oldItem.getAdapter(IResource.class);
				}
				if (oldResource != null && oldResource.isAccessible() == false) {
					IProject project = oldResource.getProject();
					if (closedWithChildren.contains(project) || elements.contains(project)) {
						elements.add(oldItem);
						elements.remove(project);
						closedWithChildren.add(project);
					}
				}
			}
			fWorkingSet.setName(workingSetName);
			fWorkingSet.setElements(elements.toArray(new IAdaptable[elements.size()]));
		}
	}

	/*
	 * @see org.eclipse.ui.dialogs.IWorkingSetPage#getSelection()
	 */
	@Override
	public IWorkingSet getSelection() {
		return fWorkingSet;
	}

	/**
	 * Called when the checked state of a tree item changes.
	 *
	 * @param event the checked state change event.
	 */
	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, true);
			}
			updateParentState(element, state);
			validateInput();
		});
	}

	private boolean isExpandable(Object element) {
		return (element instanceof ICProject || element instanceof ICContainer || element instanceof CElementGrouping
				|| element instanceof ICModel || element instanceof IContainer);
	}

	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;

		updateObjectState(parent, baseChildState);
	}

	private void updateObjectState(Object element, boolean baseChildState) {

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

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

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

		updateParentState(element, baseChildState);
	}

	/**
	 * Sets the checked state of tree items based on the initial
	 * working set, if any.
	 */
	private void initializeCheckedState() {
		BusyIndicator.showWhile(getShell().getDisplay(), () -> {
			Object[] elements;
			if (fWorkingSet == null) {
				// Use current part's selection for initialization
				IWorkbenchPage page = CUIPlugin.getActivePage();
				if (page == null)
					return;

				IWorkbenchPart part = CUIPlugin.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) {
							ICElement ce = ((IResource) elements[i1]).getAdapter(ICElement.class);
							if (ce != null && ce.exists() && ce.getCProject().isOnSourceRoot((IResource) elements[i1]))
								elements[i1] = ce;
						}
					}
				} catch (CModelException e) {
					return;
				}
			} else
				elements = fWorkingSet.getElements();

			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;
					} else {
						// for backwards compatibility: adapt to ICElement if possible
						if (CoreModel.hasCNature(project)) {
							ICElement cElement = CoreModel.getDefault().create((IResource) element1);
							if (cElement != null) {
								elements[i2] = cElement;
							}
						}
					}
				} else if (element1 instanceof ICElement) {
					ICProject cProject = ((ICElement) element1).getCProject();
					if (cProject != null && !cProject.getProject().isAccessible())
						elements[i2] = cProject.getProject();
				}
			}
			fTree.setCheckedElements(elements);
			HashSet<Object> parents = new HashSet<>();
			for (Object element2 : elements) {
				if (isExpandable(element2))
					setSubtreeChecked(element2, true, true);

				if (element2 instanceof IAdaptable) {
					IResource resource = ((IAdaptable) element2).getAdapter(IResource.class);
					if (resource != null && !resource.isAccessible())
						continue;
				}
				Object parent = fTreeContentProvider.getParent(element2);
				if (parent != null)
					parents.add(parent);
			}

			for (Object object : parents)
				updateObjectState(object, true);
		});
	}

	/*
	 * @see org.eclipse.ui.dialogs.IWorkingSetPage#setSelection(org.eclipse.ui.IWorkingSet)
	 */
	@Override
	public void setSelection(IWorkingSet workingSet) {
		if (workingSet == null) {
			throw new IllegalArgumentException("Working set must not be null"); //$NON-NLS-1$
		}
		fWorkingSet = workingSet;
		if (getContainer() != null && fWorkingSetName != null) {
			fFirstCheck = false;
			fWorkingSetName.setText(workingSet.getName());
			initializeCheckedState();
			validateInput();
		}
	}

	/**
	 * Sets the checked state of the container's members.
	 *
	 * @param parent the parent whose children should be checked/unchecked
	 * @param state true=check all members in the container. false=uncheck all
	 * 	members in the container.
	 * @param checkExpandedState true=recurse into sub-containers and set the
	 * 	checked state. false=only set checked state of members of this container
	 */
	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);
		}
	}

	/**
	 * Validates the working set name and the checked state of the
	 * resource tree.
	 */
	void validateInput() {
		String errorMessage = null;
		String newText = fWorkingSetName.getText();

		if (newText.equals(newText.trim()) == false) {
			errorMessage = WorkingSetMessages.CElementWorkingSetPage_warning_nameMustNotBeEmpty;
		}
		if (newText.isEmpty()) {
			if (fFirstCheck) {
				setPageComplete(false);
				fFirstCheck = false;
				return;
			}
			errorMessage = WorkingSetMessages.CElementWorkingSetPage_warning_nameMustNotBeEmpty;
		}

		fFirstCheck = false;

		if (errorMessage == null && (fWorkingSet == null || newText.equals(fWorkingSet.getName()) == false)) {
			IWorkingSet[] workingSets = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets();
			for (IWorkingSet workingSet : workingSets) {
				if (newText.equals(workingSet.getName())) {
					errorMessage = WorkingSetMessages.CElementWorkingSetPage_warning_workingSetExists;
				}
			}
		}

		if (errorMessage == null && fTree.getCheckedElements().length == 0) {
			String infoMessage = WorkingSetMessages.CElementWorkingSetPage_warning_resourceMustBeChecked;
			setMessage(infoMessage, INFORMATION);
		}
		setErrorMessage(errorMessage);
		setPageComplete(errorMessage == null);
	}

	/**
	 * Collects all checked elements of the given parent.
	 *
	 * @param checkedElements the output, list of checked elements
	 * @param parent the parent to collect checked elements in
	 */
	private void findCheckedElements(List<Object> checkedElements, Object parent) {
		Object[] children = fTreeContentProvider.getChildren(parent);
		for (Object element : children) {
			if (fTree.getGrayed(element))
				findCheckedElements(checkedElements, element);
			else if (fTree.getChecked(element))
				checkedElements.add(element);
		}
	}
}
