/*******************************************************************************
 * 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
 *******************************************************************************/

package org.eclipse.ui.internal.ide.dialogs;

import java.util.TreeSet;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.GlobalBuildAction;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.util.PrefUtil;

/**	
 * Page used to determine what order projects will be built in 
 * by the workspace.
 */
public class BuildOrderPreferencePage extends PreferencePage implements
        IWorkbenchPreferencePage {

    private IWorkbench workbench;

    private Button defaultOrderButton;

    private Label buildLabel;

    private List buildList;

    private Composite buttonComposite;

    private IntegerFieldEditor maxItersField;

    private String[] defaultBuildOrder;

    private String[] customBuildOrder;

    //Boolean to indicate if we have looked it up
    private boolean notCheckedBuildOrder = true;

    private final String UP_LABEL = IDEWorkbenchMessages.BuildOrderPreference_up;

    private final String DOWN_LABEL = IDEWorkbenchMessages.BuildOrderPreference_down;

    private final String ADD_LABEL = IDEWorkbenchMessages.BuildOrderPreference_add;

    private final String REMOVE_LABEL = IDEWorkbenchMessages.BuildOrderPreference_remove;

    private final String PROJECT_SELECTION_MESSAGE = IDEWorkbenchMessages.BuildOrderPreference_selectOtherProjects;

    private final String DEFAULTS_LABEL = IDEWorkbenchMessages.BuildOrderPreference_useDefaults;

    private final String LIST_LABEL = IDEWorkbenchMessages.BuildOrderPreference_projectBuildOrder;

    private final String NOTE_LABEL = IDEWorkbenchMessages.Preference_note;

    private final String REMOVE_MESSAGE = IDEWorkbenchMessages.BuildOrderPreference_removeNote;

    // whether or not the use defaults option was selected when Apply (or OK) was last pressed
    // (or when the preference page was opened). This represents the most recent applied state.
    private boolean defaultOrderInitiallySelected;

    private IPropertyChangeListener validityChangeListener = new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
            if (event.getProperty().equals(FieldEditor.IS_VALID))
                updateValidState();
        }
    };

    /**
     * Add another project to the list at the end.
     */
    private void addProject() {

        String[] currentItems = this.buildList.getItems();

        IProject[] allProjects = getWorkspace().getRoot().getProjects();

        ILabelProvider labelProvider = new LabelProvider() {
            public String getText(Object element) {
                return (String) element;
            }
        };

        SimpleListContentProvider contentsProvider = new SimpleListContentProvider();
        contentsProvider
                .setElements(sortedDifference(allProjects, currentItems));

        ListSelectionDialog dialog = new ListSelectionDialog(this.getShell(),
                this, contentsProvider, labelProvider,
                PROJECT_SELECTION_MESSAGE);

        if (dialog.open() != Window.OK)
            return;

        Object[] result = dialog.getResult();

        int currentItemsLength = currentItems.length;
        int resultLength = result.length;
        String[] newItems = new String[currentItemsLength + resultLength];

        System.arraycopy(currentItems, 0, newItems, 0, currentItemsLength);
        System
                .arraycopy(result, 0, newItems, currentItemsLength,
                        result.length);
        this.buildList.setItems(newItems);
    }

    /**
     * Updates the valid state of the page.
     */
    private void updateValidState() {
        setValid(maxItersField.isValid());
    }

    /**
     * Create the list of build paths. If the current build order is empty make the list empty
     * and disable it.
     * @param composite - the parent to create the list in
     * @param enabled - the boolean that indcates if the list will be sensitive initially or not
     */
    private void createBuildOrderList(Composite composite, boolean enabled) {

        Font font = composite.getFont();

        this.buildLabel = new Label(composite, SWT.NONE);
        this.buildLabel.setText(LIST_LABEL);
        this.buildLabel.setEnabled(enabled);
        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.horizontalSpan = 2;
        this.buildLabel.setLayoutData(gridData);
        this.buildLabel.setFont(font);

        this.buildList = new List(composite, SWT.BORDER | SWT.MULTI
                | SWT.H_SCROLL | SWT.V_SCROLL);
        this.buildList.setEnabled(enabled);
        GridData data = new GridData();
        //Set heightHint with a small value so the list size will be defined by 
        //the space available in the dialog instead of resizing the dialog to
        //fit all the items in the list.
        data.heightHint = buildList.getItemHeight();
        data.verticalAlignment = GridData.FILL;
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        data.grabExcessVerticalSpace = true;
        this.buildList.setLayoutData(data);
        this.buildList.setFont(font);
    }

    /**
     * Create the widgets that are used to determine the build order.
     *
     * @param parent the parent composite
     * @return the new control
     */
    protected Control createContents(Composite parent) {

    	PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
                IIDEHelpContextIds.BUILD_ORDER_PREFERENCE_PAGE);

        Font font = parent.getFont();

        //The main composite
        Composite composite = new Composite(parent, SWT.NULL);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        composite.setLayout(layout);
        GridData data = new GridData();
        data.verticalAlignment = GridData.FILL;
        data.horizontalAlignment = GridData.FILL;
        composite.setLayoutData(data);
        composite.setFont(font);

        String[] buildOrder = getCurrentBuildOrder();
        boolean useDefault = (buildOrder == null);

        createDefaultPathButton(composite, useDefault);
        // List always enabled so user can scroll list.
        // Only the buttons need to be disabled.
        createBuildOrderList(composite, true);
        createListButtons(composite, !useDefault);

        Composite noteComposite = createNoteComposite(font, composite,
                NOTE_LABEL, REMOVE_MESSAGE);
        GridData noteData = new GridData();
        noteData.horizontalSpan = 2;
        noteComposite.setLayoutData(noteData);

        createSpacer(composite);

        createMaxIterationsField(composite);

        createSpacer(composite);

        if (useDefault) {
            this.buildList.setItems(getDefaultProjectOrder());
        } else {
            this.buildList.setItems(buildOrder);
        }

        return composite;

    }

    /**
     * Adds in a spacer.
     * 
     * @param composite the parent composite
     */
    private void createSpacer(Composite composite) {
        Label spacer = new Label(composite, SWT.NONE);
        GridData spacerData = new GridData();
        spacerData.horizontalSpan = 2;
        spacer.setLayoutData(spacerData);
    }

    /**
     * Create the default path button. Set it to selected based on the current workspace
     * build path.
     * @param composite org.eclipse.swt.widgets.Composite
     * @param selected - the boolean that indicates the buttons initial state
     */
    private void createDefaultPathButton(Composite composite, boolean selected) {

        defaultOrderInitiallySelected = selected;

        this.defaultOrderButton = new Button(composite, SWT.LEFT | SWT.CHECK);
        this.defaultOrderButton.setSelection(selected);
        this.defaultOrderButton.setText(DEFAULTS_LABEL);
        SelectionListener listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                defaultsButtonSelected(defaultOrderButton.getSelection());
            }
        };
        this.defaultOrderButton.addSelectionListener(listener);

        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.horizontalSpan = 2;
        this.defaultOrderButton.setLayoutData(gridData);
        this.defaultOrderButton.setFont(composite.getFont());
    }

    /**
     * Create the buttons used to manipulate the list. These Add, Remove and Move Up or Down
     * the list items.
     * @param composite the parent of the buttons
     * @param enableComposite - boolean that indicates if a composite should be enabled
     */
    private void createListButtons(Composite composite, boolean enableComposite) {

        Font font = composite.getFont();

        //Create an intermeditate composite to keep the buttons in the same column
        this.buttonComposite = new Composite(composite, SWT.RIGHT);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        this.buttonComposite.setLayout(layout);
        GridData gridData = new GridData();
        gridData.verticalAlignment = GridData.FILL;
        gridData.horizontalAlignment = GridData.FILL;
        this.buttonComposite.setLayoutData(gridData);
        this.buttonComposite.setFont(font);

        Button upButton = new Button(this.buttonComposite, SWT.CENTER
                | SWT.PUSH);
        upButton.setText(UP_LABEL);
        upButton.setEnabled(enableComposite);
        upButton.setFont(font);
        setButtonLayoutData(upButton);

        SelectionListener listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                moveSelectionUp();
            }
        };
        upButton.addSelectionListener(listener);

        Button downButton = new Button(this.buttonComposite, SWT.CENTER
                | SWT.PUSH);
        downButton.setText(DOWN_LABEL);
        downButton.setEnabled(enableComposite);
        listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                moveSelectionDown();
            }
        };
        downButton.addSelectionListener(listener);
        downButton.setFont(font);
        setButtonLayoutData(downButton);

        Button addButton = new Button(this.buttonComposite, SWT.CENTER
                | SWT.PUSH);
        addButton.setText(ADD_LABEL);
        listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                addProject();
            }
        };
        addButton.addSelectionListener(listener);
        addButton.setEnabled(enableComposite);
        addButton.setFont(font);
        setButtonLayoutData(addButton);

        Button removeButton = new Button(this.buttonComposite, SWT.CENTER
                | SWT.PUSH);
        removeButton.setText(REMOVE_LABEL);
        listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                removeSelection();
            }
        };
        removeButton.addSelectionListener(listener);
        removeButton.setEnabled(enableComposite);
        removeButton.setFont(font);
        setButtonLayoutData(removeButton);

    }

    /**
     * Create the field for the maximum number of iterations in the presence
     * of cycles. 
     */
    private void createMaxIterationsField(Composite composite) {
        Composite maxItersComposite = new Composite(composite, SWT.NONE);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        maxItersComposite.setLayoutData(gd);
        maxItersComposite.setFont(composite.getFont());

        maxItersField = new IntegerFieldEditor(
                "", IDEWorkbenchMessages.BuildOrderPreference_maxIterationsLabel, maxItersComposite) { //$NON-NLS-1$
            protected void doLoad() {
                Text text = getTextControl();
                if (text != null) {
                    int value = getWorkspace().getDescription()
                            .getMaxBuildIterations();
                    text.setText(Integer.toString(value));
                }
            }

            protected void doLoadDefault() {
                Text text = getTextControl();
                if (text != null) {
                    int value = ResourcesPlugin.getPlugin()
                            .getPluginPreferences().getDefaultInt(
                                    ResourcesPlugin.PREF_MAX_BUILD_ITERATIONS);
                    text.setText(Integer.toString(value));
                }
                valueChanged();
            }

            protected void doStore() {
                // handled specially in performOK()
                throw new UnsupportedOperationException();
            }
        };
        maxItersField.setValidRange(1, Integer.MAX_VALUE);
        maxItersField.setPage(this);
        maxItersField.setPreferenceStore(getPreferenceStore());
        maxItersField.setPropertyChangeListener(validityChangeListener);
        maxItersField.load();
    }

    /**
     * The defaults button has been selected - update the other widgets as required.
     * @param selected - whether or not the defaults button got selected
     */
    private void defaultsButtonSelected(boolean selected) {
        if (selected) {
            setBuildOrderWidgetsEnablement(false);
            //Cache the current value as the custom order
            customBuildOrder = buildList.getItems();
            buildList.setItems(getDefaultProjectOrder());

        } else {
            setBuildOrderWidgetsEnablement(true);
            String[] buildOrder = getCurrentBuildOrder();
            if (buildOrder == null)
                buildList.setItems(getDefaultProjectOrder());
            else
                buildList.setItems(buildOrder);
        }
    }

    /**
     * Get the project names for the current custom build
     * order stored in the workspace description.
     * 
     * @return java.lang.String[] or null if there is no setting
     */
    private String[] getCurrentBuildOrder() {
        if (notCheckedBuildOrder) {
            customBuildOrder = getWorkspace().getDescription().getBuildOrder();
            notCheckedBuildOrder = false;
        }

        return customBuildOrder;
    }

    /**
     * Get the project names in the default build order
     * based on the current Workspace settings.
     * 
     * @return java.lang.String[]
     */
    private String[] getDefaultProjectOrder() {
        if (defaultBuildOrder == null) {
            IWorkspace workspace = getWorkspace();
            IWorkspace.ProjectOrder projectOrder = getWorkspace()
                    .computeProjectOrder(workspace.getRoot().getProjects());
            IProject[] foundProjects = projectOrder.projects;
            defaultBuildOrder = new String[foundProjects.length];
            int foundSize = foundProjects.length;
            for (int i = 0; i < foundSize; i++) {
                defaultBuildOrder[i] = foundProjects[i].getName();
            }
        }

        return defaultBuildOrder;
    }

    /**
     * Return the Workspace the build order is from.
     * @return org.eclipse.core.resources.IWorkspace
     */
    private IWorkspace getWorkspace() {
        return ResourcesPlugin.getWorkspace();
    }

    /**
     * Return whether or not searchElement is in testArray.
     */
    private boolean includes(String[] testArray, String searchElement) {

        for (int i = 0; i < testArray.length; i++) {
            if (searchElement.equals(testArray[i]))
                return true;
        }
        return false;

    }

    /**
     * See IWorkbenchPreferencePage. This class does nothing with he Workbench.
     */
    public void init(IWorkbench workbench) {
        this.workbench = workbench;
        setPreferenceStore(PrefUtil.getInternalPreferenceStore());
    }

    /**
     * Move the current selection in the build list down.
     */
    private void moveSelectionDown() {

        //Only do this operation on a single selection
        if (this.buildList.getSelectionCount() == 1) {
            int currentIndex = this.buildList.getSelectionIndex();
            if (currentIndex < this.buildList.getItemCount() - 1) {
                String elementToMove = this.buildList.getItem(currentIndex);
                this.buildList.remove(currentIndex);
                this.buildList.add(elementToMove, currentIndex + 1);
                this.buildList.select(currentIndex + 1);
            }
        }
    }

    /**
     * Move the current selection in the build list up.
     */
    private void moveSelectionUp() {

        int currentIndex = this.buildList.getSelectionIndex();

        //Only do this operation on a single selection
        if (currentIndex > 0 && this.buildList.getSelectionCount() == 1) {
            String elementToMove = this.buildList.getItem(currentIndex);
            this.buildList.remove(currentIndex);
            this.buildList.add(elementToMove, currentIndex - 1);
            this.buildList.select(currentIndex - 1);
        }
    }

    /**
     * Performs special processing when this page's Defaults button has been pressed.
     * In this case change the defaultOrderButton to have it's selection set to true.
     */
    protected void performDefaults() {
        this.defaultOrderButton.setSelection(true);
        defaultsButtonSelected(true);
        maxItersField.loadDefault();
        super.performDefaults();
    }

    /** 
     * OK has been pressed. If the defualt button is pressed then reset the build order to false;
     * otherwise set it to the contents of the list.
     */
    public boolean performOk() {

        String[] buildOrder = null;
        boolean useDefault = defaultOrderButton.getSelection();

        // if use defaults is turned off
        if (!useDefault)
            buildOrder = buildList.getItems();

        //Get a copy of the description from the workspace, set the build order and then
        //apply it to the workspace.
        IWorkspaceDescription description = getWorkspace().getDescription();
        description.setBuildOrder(buildOrder);
        description.setMaxBuildIterations(maxItersField.getIntValue());
        try {
            getWorkspace().setDescription(description);
        } catch (CoreException exception) {
            //failed - return false
            return false;
        }

        // Perform auto-build if use default is off (because
        // order could have changed) or if use default setting
        // was changed.
        if (!useDefault || (useDefault != defaultOrderInitiallySelected)) {
            defaultOrderInitiallySelected = useDefault;
            // If auto build is turned on, then do a global incremental
            // build on all the projects.
            if (ResourcesPlugin.getWorkspace().isAutoBuilding()) {
                GlobalBuildAction action = new GlobalBuildAction(workbench
                        .getActiveWorkbenchWindow(),
                        IncrementalProjectBuilder.INCREMENTAL_BUILD);
                action.doBuild();
            }
        }

        // Clear the custom build order cache
        customBuildOrder = null;

        return true;
    }

    /**
     * Remove the current selection in the build list.
     */
    private void removeSelection() {

        this.buildList.remove(this.buildList.getSelectionIndices());
    }

    /**
     * Set the widgets that select build order to be enabled or diabled.
     * @param value boolean
     */
    private void setBuildOrderWidgetsEnablement(boolean value) {

        // Only change enablement of buttons. Leave list alone
        // because you can't scroll it when disabled.
        Control[] children = this.buttonComposite.getChildren();
        for (int i = 0; i < children.length; i++) {
            children[i].setEnabled(value);
        }
    }

    /**
     * Return a sorted array of the names of the projects that are already in the currently 
     * displayed names.
     * @return String[]
     * @param allProjects - all of the projects in the workspace 
     * @param currentlyDisplayed - the names of the projects already being displayed
     */
    private String[] sortedDifference(IProject[] allProjects,
            String[] currentlyDisplayed) {

        TreeSet difference = new TreeSet();

        for (int i = 0; i < allProjects.length; i++) {
            if (!includes(currentlyDisplayed, allProjects[i].getName()))
                difference.add(allProjects[i].getName());
        }

        String[] returnValue = new String[difference.size()];
        difference.toArray(returnValue);
        return returnValue;
    }
}
