/*******************************************************************************
 * Copyright (c) 2000, 2005 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
 *
 * 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.ui.internal.ide.dialogs;

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.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.DecoratedField;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.fieldassist.TextControlCreator;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
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.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
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.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetPage;
import org.eclipse.ui.internal.fieldassist.RequiredFieldColorer;
import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * A resource working set page allows the user to edit an 
 * existing working set and create a new working set.
 * <p>
 * Working set elements are presented as a simple resource tree.
 * </p>
 * 
 * @since 2.0
 */
public class ResourceWorkingSetPage extends WizardPage implements
        IWorkingSetPage {
    private final static int SIZING_SELECTION_WIDGET_WIDTH = 50;

    private final static int SIZING_SELECTION_WIDGET_HEIGHT = 200;

    private Text text;

    private CheckboxTreeViewer tree;

    private IWorkingSet workingSet;

    private boolean firstCheck = false; // set to true if selection is set in setSelection

    /**
     * Creates a new instance of the receiver.
     */
    public ResourceWorkingSetPage() {
        super(
                "resourceWorkingSetPage", //$NON-NLS-1$ 
                IDEWorkbenchMessages.ResourceWorkingSetPage_title,
                IDEInternalWorkbenchImages
                        .getImageDescriptor(IDEInternalWorkbenchImages.IMG_WIZBAN_RESOURCEWORKINGSET_WIZ));
        setDescription(IDEWorkbenchMessages.ResourceWorkingSetPage_description);
    }

    /**
     * Adds working set elements contained in the given container to the list
     * of checked resources.
     * 
     * @param collectedResources list of collected resources
     * @param container container to collect working set elements for
     */
    private void addWorkingSetElements(List collectedResources,
            IContainer container) {
        IAdaptable[] elements = workingSet.getElements();
        IPath containerPath = container.getFullPath();

        for (int i = 0; i < elements.length; i++) {
            IResource resource = null;

            if (elements[i] instanceof IResource) {
				resource = (IResource) elements[i];
			} else {
				resource = (IResource) elements[i].getAdapter(IResource.class);
			}

            if (resource != null) {
                IPath resourcePath = resource.getFullPath();
                if (containerPath.isPrefixOf(resourcePath)) {
					collectedResources.add(elements[i]);
				}
            }
        }
    }

    /**
     * Overrides method in WizardPage.
     * 
     * @see org.eclipse.jface.wizard.WizardPage#createControl(Composite)
     */
    public void createControl(Composite parent) {
        Font font = parent.getFont();
        Composite composite = new Composite(parent, SWT.NULL);
        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
        setControl(composite);

        PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
                IIDEHelpContextIds.WORKING_SET_RESOURCE_PAGE);
        Label label = new Label(composite, SWT.WRAP);
        label.setText(IDEWorkbenchMessages.ResourceWorkingSetPage_message);
        GridData data = new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL
                | GridData.VERTICAL_ALIGN_CENTER);
        label.setLayoutData(data);
        label.setFont(font);

        DecoratedField field = new DecoratedField(composite, 
        		SWT.SINGLE | SWT.BORDER, new TextControlCreator());
		field.addFieldDecoration(FieldDecorationRegistry.getDefault().getFieldDecoration(
				FieldDecorationRegistry.DEC_REQUIRED), SWT.BOTTOM
				| SWT.LEFT, false);

        text = (Text)field.getControl();
        field.getLayoutControl().setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL));
        text.setFont(font);
        text.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                validateInput();
            }
        });
        text.addFocusListener(new RequiredFieldColorer(text, new TextContentAdapter()));
        text.setFocus();

        label = new Label(composite, SWT.WRAP);
        label.setText(IDEWorkbenchMessages.ResourceWorkingSetPage_label_tree);
        data = new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL
                | GridData.VERTICAL_ALIGN_CENTER);
        label.setLayoutData(data);
        label.setFont(font);

        tree = new CheckboxTreeViewer(composite);
        tree.setUseHashlookup(true);
		final ITreeContentProvider treeContentProvider = new WorkbenchContentProvider();
        tree.setContentProvider(treeContentProvider);
        tree.setLabelProvider(new DecoratingLabelProvider(
                new WorkbenchLabelProvider(), IDEWorkbenchPlugin.getDefault()
                        .getWorkbench().getDecoratorManager()
                        .getLabelDecorator()));
        tree.setInput(IDEWorkbenchPlugin.getPluginWorkspace().getRoot());
        tree.setSorter(new ResourceSorter(ResourceSorter.NAME));

        data = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
        data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
        data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
        data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
        tree.getControl().setLayoutData(data);
        tree.getControl().setFont(font);

        tree.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                handleCheckStateChange(event);
            }
        });

        tree.addTreeListener(new ITreeViewerListener() {
            public void treeCollapsed(TreeExpansionEvent event) {
            }

            public void treeExpanded(TreeExpansionEvent event) {
                final Object element = event.getElement();
                if (tree.getGrayed(element) == false) {
					BusyIndicator.showWhile(getShell().getDisplay(),
                            new Runnable() {
                                public void run() {
                                    setSubtreeChecked((IContainer) element,
                                            tree.getChecked(element), false);
                                }
                            });
				}
            }
        });

		// Add select / deselect all buttons for bug 46669
		Composite buttonComposite = new Composite(composite, SWT.NONE);
		buttonComposite.setLayout(new GridLayout(2, false));
		buttonComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		
		Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
		selectAllButton.setText(IDEWorkbenchMessages.ResourceWorkingSetPage_selectAll_label);
		selectAllButton.setToolTipText(IDEWorkbenchMessages.ResourceWorkingSetPage_selectAll_toolTip);
		selectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent selectionEvent) {
				tree.setCheckedElements(treeContentProvider.getElements(tree.getInput()));
				validateInput();
			}
		});
		selectAllButton.setFont(font);
		setButtonLayoutData(selectAllButton);

		Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
		deselectAllButton.setText(IDEWorkbenchMessages.ResourceWorkingSetPage_deselectAll_label);
		deselectAllButton.setToolTipText(IDEWorkbenchMessages.ResourceWorkingSetPage_deselectAll_toolTip);
		deselectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent selectionEvent) {
				tree.setCheckedElements(new Object[0]);
				validateInput();
			}
		});
		deselectAllButton.setFont(font);
		setButtonLayoutData(deselectAllButton);
		
		initializeCheckedState();
        if (workingSet != null) {
            text.setText(workingSet.getName());
        }
        setPageComplete(false);
    }

    /**
     * Collects all checked resources in the specified container.
     * 
     * @param checkedResources the output, list of checked resources
     * @param container the container to collect checked resources in
     */
    private void findCheckedResources(List checkedResources,
            IContainer container) {
        IResource[] resources = null;
        try {
            resources = container.members();
        } catch (CoreException ex) {
            handleCoreException(
                    ex,
                    getShell(),
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error,
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error_updateCheckedState);
        }
        for (int i = 0; i < resources.length; i++) {
            if (tree.getGrayed(resources[i])) {
                if (resources[i].isAccessible()) {
					findCheckedResources(checkedResources,
                            (IContainer) resources[i]);
				} else {
					addWorkingSetElements(checkedResources,
                            (IContainer) resources[i]);
				}
            } else if (tree.getChecked(resources[i])) {
                checkedResources.add(resources[i]);
            }
        }
    }

    /**
     * Implements IWorkingSetPage.
     * 
     * @see org.eclipse.ui.dialogs.IWorkingSetPage#finish()
     */
    public void finish() {
        ArrayList resources = new ArrayList(10);
        findCheckedResources(resources, (IContainer) tree.getInput());
        if (workingSet == null) {
            IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
                    .getWorkingSetManager();
            workingSet = workingSetManager.createWorkingSet(
                    getWorkingSetName(), (IAdaptable[]) resources
                            .toArray(new IAdaptable[resources.size()]));
        } else {
            workingSet.setName(getWorkingSetName());
            workingSet.setElements((IAdaptable[]) resources
                    .toArray(new IAdaptable[resources.size()]));
        }
    }

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

    /**
     * Returns the name entered in the working set name field.
     * 
     * @return the name entered in the working set name field.
     */
    private String getWorkingSetName() {
        return text.getText();
    }

    /**
     * Called when the checked state of a tree item changes.
     * 
     * @param event the checked state change event.
     */
    private void handleCheckStateChange(final CheckStateChangedEvent event) {
        BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
            public void run() {
                IResource resource = (IResource) event.getElement();
                boolean state = event.getChecked();

                tree.setGrayed(resource, false);
                if (resource instanceof IContainer) {
                    setSubtreeChecked((IContainer) resource, state, true);
                }
                updateParentState(resource);
                validateInput();
            }
        });
    }

    /**
     * Displays an error message when a CoreException occured.
     * 
     * @param exception the CoreException 
     * @param shell parent shell for the message box
     * @param title the mesage box title
     * @param message additional error message
     */
    private void handleCoreException(CoreException exception, Shell shell,
            String title, String message) {
        IStatus status = exception.getStatus();
        if (status != null) {
            ErrorDialog.openError(shell, title, message, status);
        } else {
            MessageDialog
                    .openError(
                            shell,
                            IDEWorkbenchMessages.InternalError, exception.getLocalizedMessage());
        }
    }

    /**
     * Sets the checked state of tree items based on the initial 
     * working set, if any.
     */
    private void initializeCheckedState() {
        if (workingSet == null) {
			return;
		}

        BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
            public void run() {
                IAdaptable[] items = workingSet.getElements();
                tree.setCheckedElements(items);
                for (int i = 0; i < items.length; i++) {
                    IAdaptable item = items[i];
                    IContainer container = null;
                    IResource resource = null;

                    if (item instanceof IContainer) {
                        container = (IContainer) item;
                    } else {
                        container = (IContainer) item
                                .getAdapter(IContainer.class);
                    }
                    if (container != null) {
                        setSubtreeChecked(container, true, true);
                    }
                    if (item instanceof IResource) {
                        resource = (IResource) item;
                    } else {
                        resource = (IResource) item.getAdapter(IResource.class);
                    }
                    if (resource != null && resource.isAccessible() == false) {
                        IProject project = resource.getProject();
                        if (tree.getChecked(project) == false) {
							tree.setGrayChecked(project, true);
						}
                    } else {
                        updateParentState(resource);
                    }
                }
            }
        });
    }

    /**
     * Implements IWorkingSetPage.
     * 
     * @see org.eclipse.ui.dialogs.IWorkingSetPage#setSelection(IWorkingSet)
     */
    public void setSelection(IWorkingSet workingSet) {
        if (workingSet == null) {
            throw new IllegalArgumentException("Working set must not be null"); //$NON-NLS-1$
        }
        this.workingSet = workingSet;
        if (getShell() != null && text != null) {
            firstCheck = true;
            initializeCheckedState();
            text.setText(workingSet.getName());
        }
    }

    /**
     * Sets the checked state of the container's members.
     * 
     * @param container the container 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(IContainer container, boolean state,
            boolean checkExpandedState) {
        // checked state is set lazily on expand, don't set it if container is collapsed
        if (container.isAccessible() == false
                || (tree.getExpandedState(container) == false && state && checkExpandedState)) {
            return;
        }
        IResource[] members = null;
        try {
            members = container.members();
        } catch (CoreException ex) {
            handleCoreException(
                    ex,
                    getShell(),
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error,
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error_updateCheckedState);
        }
        for (int i = members.length - 1; i >= 0; i--) {
            IResource element = members[i];
            boolean elementGrayChecked = tree.getGrayed(element)
                    || tree.getChecked(element);

            if (state) {
                tree.setChecked(element, true);
                tree.setGrayed(element, false);
            } else {
                tree.setGrayChecked(element, false);
            }
            // unchecked state only needs to be set when the container is 
            // checked or grayed
            if (element instanceof IContainer && (state || elementGrayChecked)) {
                setSubtreeChecked((IContainer) element, state, true);
            }
        }
    }

    /**
     * Check and gray the resource parent if all resources of the 
     * parent are checked.
     * 
     * @param child the resource whose parent checked state should 
     * 	be set.
     */
    private void updateParentState(IResource child) {
        if (child == null || child.getParent() == null) {
			return;
		}

        IContainer parent = child.getParent();
        boolean childChecked = false;
        IResource[] members = null;
        try {
            members = parent.members();
        } catch (CoreException ex) {
            handleCoreException(
                    ex,
                    getShell(),
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error,
                    IDEWorkbenchMessages.ResourceWorkingSetPage_error_updateCheckedState);
        }
        for (int i = members.length - 1; i >= 0; i--) {
            if (tree.getChecked(members[i]) || tree.getGrayed(members[i])) {
                childChecked = true;
                break;
            }
        }
        tree.setGrayChecked(parent, childChecked);
        updateParentState(parent);
    }

    /**
     * Validates the working set name and the checked state of the 
     * resource tree.
     */
    private void validateInput() {
        String errorMessage = null;
        String infoMessage= null;
        String newText = text.getText();
        boolean showErrorMessage = true;

        if (newText.equals(newText.trim()) == false) {
            errorMessage = IDEWorkbenchMessages.ResourceWorkingSetPage_warning_nameWhitespace; 
        } else if (firstCheck) {
            firstCheck = false;
            return;
        }
        if (newText.equals("")) { //$NON-NLS-1$
            errorMessage = IDEWorkbenchMessages.ResourceWorkingSetPage_warning_nameMustNotBeEmpty;
            /*
             * Required field emphasis is already showing, so no need to
             * actually show an error.  This is a temporary hack.  We need
             * cleaner code for these cases where the button should still
             * be disabled but we don't want to show an error.
             * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=120238
             */
            showErrorMessage = false;
        }

        if (errorMessage == null
                && (workingSet == null || newText.equals(workingSet.getName()) == false)) {
            IWorkingSet[] workingSets = PlatformUI.getWorkbench()
                    .getWorkingSetManager().getWorkingSets();
            for (int i = 0; i < workingSets.length; i++) {
                if (newText.equals(workingSets[i].getName())) {
                    errorMessage = IDEWorkbenchMessages.ResourceWorkingSetPage_warning_workingSetExists;
                }
            }
        }
        if (infoMessage == null && tree.getCheckedElements().length == 0) {
        	infoMessage = IDEWorkbenchMessages.ResourceWorkingSetPage_warning_resourceMustBeChecked;
        }
        setMessage(infoMessage, INFORMATION);
        if (showErrorMessage) {
        	setErrorMessage(errorMessage);
        }
        setPageComplete(errorMessage == null);
    }
}
