/*******************************************************************************
 * Copyright (c) 2000, 2006 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.dialogs;

import com.ibm.icu.text.Collator;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
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.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
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.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.decorators.DecoratorDefinition;
import org.eclipse.ui.internal.decorators.DecoratorManager;

/**
 * The DecoratorsPreferencePage is the preference page for enabling and disabling
 * the decorators in the image and for giving the user a description of the decorator.
 */
public class DecoratorsPreferencePage extends PreferencePage implements
        IWorkbenchPreferencePage {

    private Text descriptionText;

    private CheckboxTableViewer checkboxViewer;

    /**
     * @see PreferencePage#createContents(Composite)
     */
    protected Control createContents(Composite parent) {

        Font font = parent.getFont();

        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
				IWorkbenchHelpContextIds.DECORATORS_PREFERENCE_PAGE);

        Composite mainComposite = new Composite(parent, SWT.NONE);
        mainComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mainComposite.setFont(font);

        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.verticalSpacing = 10;
        mainComposite.setLayout(layout);

        Label topLabel = new Label(mainComposite, SWT.NONE);
        topLabel.setText(WorkbenchMessages.get().DecoratorsPreferencePage_explanation);
        topLabel.setFont(font);

        createDecoratorsArea(mainComposite);
        createDescriptionArea(mainComposite);
        populateDecorators();

        return mainComposite;
    }

    /** 
     * Creates the widgets for the list of decorators.
     */
    private void createDecoratorsArea(Composite mainComposite) {

        Font mainFont = mainComposite.getFont();
        Composite decoratorsComposite = new Composite(mainComposite, SWT.NONE);
        decoratorsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
        GridLayout decoratorsLayout = new GridLayout();
        decoratorsLayout.marginWidth = 0;
        decoratorsLayout.marginHeight = 0;
        decoratorsComposite.setLayout(decoratorsLayout);
        decoratorsComposite.setFont(mainFont);

        Label decoratorsLabel = new Label(decoratorsComposite, SWT.NONE);
        decoratorsLabel.setText(WorkbenchMessages.get().DecoratorsPreferencePage_decoratorsLabel);
        decoratorsLabel.setFont(mainFont);

        // Checkbox table viewer of decorators
        checkboxViewer = CheckboxTableViewer.newCheckList(decoratorsComposite,
                SWT.SINGLE | SWT.TOP | SWT.BORDER);
        checkboxViewer.getTable().setLayoutData(
                new GridData(GridData.FILL_BOTH));
        checkboxViewer.getTable().setFont(decoratorsComposite.getFont());
        checkboxViewer.setLabelProvider(new LabelProvider() {
            public String getText(Object element) {
                return ((DecoratorDefinition) element).getName();
            }
        });
        checkboxViewer.getTable().setFont(mainFont);

        checkboxViewer.setContentProvider(new IStructuredContentProvider() {
            private final Comparator comparer = new Comparator() {
                private Collator collator = Collator.getInstance();

                public int compare(Object arg0, Object arg1) {
                    String s1 = ((DecoratorDefinition) arg0).getName();
                    String s2 = ((DecoratorDefinition) arg1).getName();
                    return collator.compare(s1, s2);
                }
            };

            public void dispose() {
                //Nothing to do on dispose
            }

            public void inputChanged(Viewer viewer, Object oldInput,
                    Object newInput) {
            }

            public Object[] getElements(Object inputElement) {
                //Make an entry for each decorator definition
                Object[] elements = (Object[]) inputElement;
                Object[] results = new Object[elements.length];
                System.arraycopy(elements, 0, results, 0, elements.length);
                Collections.sort(Arrays.asList(results), comparer);
                return results;
            }

        });

        checkboxViewer
                .addSelectionChangedListener(new ISelectionChangedListener() {
                    public void selectionChanged(SelectionChangedEvent event) {
                        if (event.getSelection() instanceof IStructuredSelection) {
                            IStructuredSelection sel = (IStructuredSelection) event
                                    .getSelection();
                            DecoratorDefinition definition = (DecoratorDefinition) sel
                                    .getFirstElement();
                            if (definition == null) {
								clearDescription();
							} else {
								showDescription(definition);
							}
                        }
                    }
                });

        checkboxViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                checkboxViewer.setSelection(new StructuredSelection(event
                        .getElement()));
            }
        });
    }

    /** 
     * Creates the widgets for the description.
     */
    private void createDescriptionArea(Composite mainComposite) {

        Font mainFont = mainComposite.getFont();
        Composite textComposite = new Composite(mainComposite, SWT.NONE);
        textComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
        GridLayout textLayout = new GridLayout();
        textLayout.marginWidth = 0;
        textLayout.marginHeight = 0;
        textComposite.setLayout(textLayout);
        textComposite.setFont(mainFont);

        Label descriptionLabel = new Label(textComposite, SWT.NONE);
        descriptionLabel.setText(WorkbenchMessages.get().DecoratorsPreferencePage_description); 
        descriptionLabel.setFont(mainFont);

        descriptionText = new Text(textComposite, SWT.MULTI | SWT.WRAP
                | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL);
        descriptionText.setLayoutData(new GridData(GridData.FILL_BOTH));
        descriptionText.setFont(mainFont);
    }

    /**
     * Populates the list of decorators.
     */
    private void populateDecorators() {
        DecoratorDefinition[] definitions = getAllDefinitions();
        checkboxViewer.setInput(definitions);
        for (int i = 0; i < definitions.length; i++) {
            checkboxViewer.setChecked(definitions[i], definitions[i]
                    .isEnabled());
        }
    }

    /**
     * Show the selected description in the text.
     */
    private void showDescription(DecoratorDefinition definition) {
        if (descriptionText == null || descriptionText.isDisposed()) {
            return;
        }
        String text = definition.getDescription();
        if (text == null || text.length() == 0) {
			descriptionText.setText(WorkbenchMessages.get().PreferencePage_noDescription);
		} else {
			descriptionText.setText(text);
		}
    }

    /**
     * Clear the selected description in the text.
     */
    private void clearDescription() {
        if (descriptionText == null || descriptionText.isDisposed()) {
            return;
        }
        descriptionText.setText(""); //$NON-NLS-1$
    }

    /**
     * @see PreferencePage#performDefaults()
     */
    protected void performDefaults() {
        super.performDefaults();
        DecoratorManager manager = WorkbenchPlugin.getDefault()
				.getDecoratorManager();
        DecoratorDefinition[] definitions = manager
                .getAllDecoratorDefinitions();
        for (int i = 0; i < definitions.length; i++) {
            checkboxViewer.setChecked(definitions[i], definitions[i]
                    .getDefaultValue());
        }
    }

    /**
     * @see IPreferencePage#performOk()
     */
    public boolean performOk() {
        if (super.performOk()) {
            DecoratorManager manager = getDecoratorManager();
            //Clear the caches first to avoid unneccessary updates
            manager.clearCaches();
            DecoratorDefinition[] definitions = manager
                    .getAllDecoratorDefinitions();
            for (int i = 0; i < definitions.length; i++) {
                boolean checked = checkboxViewer.getChecked(definitions[i]);
                definitions[i].setEnabled(checked);

            }
            //Have the manager clear again as there may have been
            //extra updates fired by the enablement changes.
            manager.clearCaches();
            manager.updateForEnablementChange();
            return true;
        }
        return false;
    }

    /**
     * @see IWorkbenchPreferencePage#init(IWorkbench)
     */
    public void init(IWorkbench workbench) {
    }

    /**
     * Get the decorator definitions for the workbench.
     */
    private DecoratorDefinition[] getAllDefinitions() {
        return getDecoratorManager().getAllDecoratorDefinitions();
    }

    /**
     * Get the DecoratorManager being used for this page.
     * 
     * @return the decorator manager
     */
    private DecoratorManager getDecoratorManager() {
        return WorkbenchPlugin.getDefault().getDecoratorManager();
    }

}
