/*******************************************************************************
 * 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.views.tasklist;

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

import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
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.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
import org.eclipse.ui.internal.views.tasklist.TaskListMessages;

class FiltersDialog extends TrayDialog {
    /**
     * ID for the Reset button
     */
    static final int RESET_ID = IDialogConstants.CLIENT_ID;

    static final int SELECT_ID = IDialogConstants.CLIENT_ID + 1;

    private static class EnumValue {
        private int value;

        private String text;

        private Image image;

        EnumValue(int value, String text, Image image) {
            this.value = value;
            this.text = text;
            this.image = image;
        }

        int getValue() {
            return value;
        }

        String getText() {
            return text;
        }

        Image getImage() {
            return image;
        }
    }

    private static class EnumType {
        private EnumValue[] values;

        EnumType(EnumValue[] values) {
            this.values = values;
        }

        EnumValue[] getValues() {
            return values;
        }
    }

    private EnumType severityType;

    private EnumType priorityType;

    private EnumType completionType;

    private class CheckboxEnumGroup {
        private EnumType type;

        private Button enableButton;

        private Button[] valueButtons;

        CheckboxEnumGroup(Composite parent, String text, EnumType type) {
            this.type = type;
            // although not needed for layout, this composite is needed to get the tab order right
            Composite enableComposite = new Composite(parent, SWT.NONE);
            enableComposite
                    .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            enableComposite.setLayout(new FillLayout());
            enableButton = new Button(enableComposite, SWT.CHECK);
            enableButton.addSelectionListener(selectionListener);
            enableButton.setText(text);
            Composite valueComposite = new Composite(parent, SWT.NONE);
            valueComposite
                    .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            valueComposite.setLayout(new FillLayout());
            EnumValue[] values = type.getValues();
            valueButtons = new Button[values.length];
            for (int i = 0; i < values.length; ++i) {
                Button valueButton = new Button(valueComposite, SWT.CHECK);
                valueButton.setText(values[i].getText());
                valueButtons[i] = valueButton;
            }
        }

        boolean getEnabled() {
            return enableButton.getEnabled();
        }

        void setEnabled(boolean enabled) {
            enableButton.setEnabled(enabled);
            updateEnabledState();
        }

        boolean getSelection() {
            return enableButton.getSelection();
        }

        void setSelection(boolean selected) {
            enableButton.setSelection(selected);
            updateEnabledState();
        }

        void updateEnabledState() {
            boolean enabled = enableButton.isEnabled()
                    && enableButton.getSelection();
            for (int i = 0; i < valueButtons.length; ++i) {
                valueButtons[i].setEnabled(enabled);
            }
        }

        int getValueMask() {
            int mask = 0;
            EnumValue[] values = type.getValues();
            for (int i = 0; i < valueButtons.length; ++i) {
                if (valueButtons[i].getSelection()) {
                    mask |= (1 << values[i].getValue());
                }
            }
            return mask;
        }

        void setValueMask(int mask) {
            EnumValue[] values = type.getValues();
            for (int i = 0; i < values.length; ++i) {
                valueButtons[i]
                        .setSelection((mask & (1 << values[i].getValue())) != 0);
            }
        }
    }

    private class LabelComboTextGroup {
        Label label;

        Combo combo;

        Text text;

        LabelComboTextGroup(Composite parent, String labelText,
                String[] comboStrings, String initialText, int widthHint) {
            Font font = parent.getFont();
            Composite group = new Composite(parent, SWT.NONE);
            GridLayout layout = new GridLayout();
            layout.numColumns = 3;
            //Set the margin width to 0 in order to line up with other items
            layout.marginWidth = 0;
            group.setLayout(layout);
            group.setFont(font);
            label = new Label(group, SWT.NONE);
            label.setText(labelText);
            label.setFont(font);
            combo = createCombo(group, comboStrings, 0);
            text = new Text(parent, SWT.SINGLE | SWT.BORDER);
            GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
            gridData.widthHint = widthHint;
            text.setLayoutData(gridData);
            text.setFont(font);
            text.setText(initialText);
        }
    }

    /**
     * Creates and manages a group of widgets for selecting a working 
     * set task filter.
     */
    private class WorkingSetGroup {
        private Button button;

        /**
         * Creates the working set filter selection widgets.
         * 
         * @param parent the parent composite of the working set widgets
         */
        WorkingSetGroup(Composite parent) {
            // radio button has to be part of main radio button group
            button = createRadioButton(parent, TaskListMessages.TaskList_noWorkingSet);
            GridData data = new GridData(GridData.FILL_HORIZONTAL);
            button.setLayoutData(data);

            Composite composite = new Composite(parent, SWT.NONE);
            composite.setFont(parent.getFont());
            GridLayout layout = new GridLayout();
            Button radio = new Button(parent, SWT.RADIO);
            layout.marginWidth = radio.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
            layout.marginHeight = 0;
            radio.dispose();
            composite.setLayout(layout);
            createButton(composite, SELECT_ID, TaskListMessages.TaskList_workingSetSelect, false);
        }

        /**
         * Returns wether or not a working set filter should be used
         * 
         * @return 
         * 	true=a working set filter should be used
         * 	false=a working set filter should not be used
         */
        boolean getSelection() {
            return button.getSelection();
        }

        /**
         * Returns the selected working set filter or null if none 
         * is selected.
         * 
         * @return the selected working set filter or null if none 
         * 	is selected.
         */
        IWorkingSet getWorkingSet() {
            return (IWorkingSet) button.getData();
        }

        /**
         * Sets the working set filter selection.
         * 
         * @param selected true=a working set filter should be used
         * 	false=no working set filter should be used
         */
        void setSelection(boolean selected) {
            button.setSelection(selected);
            if (selected) {
                anyResourceButton.setSelection(false);
                anyResourceInSameProjectButton.setSelection(false);
                selectedResourceButton.setSelection(false);
                selectedResourceAndChildrenButton.setSelection(false);
            }
        }

        /**
         * Opens the working set selection dialog.
         */
        void selectPressed() {
            IWorkingSetSelectionDialog dialog = PlatformUI.getWorkbench()
                    .getWorkingSetManager().createWorkingSetSelectionDialog(
                            getShell(), false);
            IWorkingSet workingSet = getWorkingSet();

            if (workingSet != null) {
                dialog.setSelection(new IWorkingSet[] { workingSet });
            }
            if (dialog.open() == Window.OK) {
                IWorkingSet[] result = dialog.getSelection();
                if (result != null && result.length > 0) {
                    setWorkingSet(result[0]);
                } else {
                    setWorkingSet(null);
                }
                if (getSelection() == false) {
                    setSelection(true);
                }
            }
        }

        /**
         * Sets the specified working set.
         * 
         * @param workingSet the working set 
         */
        void setWorkingSet(IWorkingSet workingSet) {
            button.setData(workingSet);
            if (workingSet != null) {
                button.setText(NLS.bind(TaskListMessages.TaskList_workingSet,  workingSet.getLabel()));
            } else {
                button.setText(TaskListMessages.TaskList_noWorkingSet);
            }
        }
    }

    private TasksFilter filter;

    MarkerTypesModel markerTypesModel = new MarkerTypesModel();

    private MarkerType[] markerTypes;

    private CheckboxTreeViewer typesViewer;

    Button anyResourceButton;

    Button anyResourceInSameProjectButton; // added by cagatayk@acm.org

    Button selectedResourceButton;

    Button selectedResourceAndChildrenButton;

    private WorkingSetGroup workingSetGroup;

    private LabelComboTextGroup descriptionGroup;

    private CheckboxEnumGroup severityGroup;

    private CheckboxEnumGroup priorityGroup;

    private CheckboxEnumGroup completionGroup;

    private Button filterOnMarkerLimit;

    private Text markerLimit;

    SelectionListener selectionListener = new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e) {
            FiltersDialog.this.widgetSelected(e);
        }
    };

    private ICheckStateListener checkStateListener = new ICheckStateListener() {
        public void checkStateChanged(CheckStateChangedEvent event) {
            FiltersDialog.this.checkStateChanged(event);
        }
    };

    /**
     * Creates a new filters dialog.
     * 
     * @param parentShell the parent shell
     */
    public FiltersDialog(Shell parentShell) {
        super(parentShell);
        initTypes();
    }

    /* (non-Javadoc)
     * Method declared on Dialog.
     */
    protected void buttonPressed(int buttonId) {
        if (RESET_ID == buttonId) {
            resetPressed();
        } else if (SELECT_ID == buttonId) {
            workingSetGroup.selectPressed();
        } else {
            super.buttonPressed(buttonId);
        }
    }

    /**
     * Check state change.
     * 
     * @param event the event
     */
    public void checkStateChanged(CheckStateChangedEvent event) {
        MarkerType type = (MarkerType) event.getElement();
        typesViewer.setSubtreeChecked(type, event.getChecked());
        MarkerType[] allSupertypes = type.getAllSupertypes();
        for (int i = 0; i < allSupertypes.length; ++i) {
            typesViewer.setChecked(allSupertypes[i], false);
        }
        updateEnabledState();
    }

    /* (non-Javadoc)
     * Method declared on Window.
     */
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(TaskListMessages.TaskList_filter);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
				ITaskListHelpContextIds.FILTERS_DIALOG);
    }

    /**
     * Creates the area showing filtering criteria on attribute values.
     *
     * @param parent the parent composite
     */
    void createAttributesArea(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        composite.setLayout(layout);
        composite.setFont(parent.getFont());

        String[] filters = {
                TaskListMessages.TaskList_contains, TaskListMessages.TaskList_doesNotContain }; 
        descriptionGroup = new LabelComboTextGroup(composite, TaskListMessages.TaskList_whereDescription, filters, "", 200);//$NON-NLS-1$ 
        severityGroup = new CheckboxEnumGroup(composite, TaskListMessages.TaskList_severity_label, severityType); 
        priorityGroup = new CheckboxEnumGroup(composite, TaskListMessages.TaskList_priority_label, priorityType); 
        completionGroup = new CheckboxEnumGroup(composite, TaskListMessages.TaskList_status_label, completionType); 
    }

    void createResetArea(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setFont(parent.getFont());
        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));

        Button reset = new Button(composite, SWT.PUSH);
        reset.setText(TaskListMessages.TaskList_resetText);
        reset.setData(new Integer(RESET_ID));

        reset.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                buttonPressed(((Integer) event.widget.getData()).intValue());
            }
        });

        reset.setFont(composite.getFont());
        setButtonLayoutData(reset);
    }

    /**
     * Creates a check box button with the given parent and text.
     *
     * @param parent the parent composite
     * @param text the text for the check box
     * @param grabRow <code>true</code>to grab the remaining horizontal space, <code>false</code> otherwise
     * @return the check box button
     */
    Button createCheckbox(Composite parent, String text, boolean grabRow) {
        Button button = new Button(parent, SWT.CHECK);
        if (grabRow) {
            GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
            button.setLayoutData(gridData);
        }
        button.setText(text);
        button.addSelectionListener(selectionListener);
        button.setFont(parent.getFont());
        return button;
    }

    /**
     * Creates a combo box with the given parent, items, and selection
     *
     * @param parent the parent composite
     * @param items the items for the combo box
     * @param selectionIndex the index of the item to select
     * @return the combo box
     */
    Combo createCombo(Composite parent, String[] items, int selectionIndex) {
        Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
        combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        combo.setFont(parent.getFont());
        combo.setItems(items);
        combo.select(selectionIndex);
        combo.addSelectionListener(selectionListener);
        return combo;
    }

    /* (non-Javadoc)
     * Method declared on Dialog.
     */
    protected Control createDialogArea(Composite parent) {
        Composite composite = (Composite) super.createDialogArea(parent);
        createMarkerLimitArea(composite);
        createTypesArea(composite);
        createResourceArea(composite);
        createAttributesArea(composite);
        createResetArea(composite);
        createSeparatorLine(composite);

        updateUIFromFilter(getFilter());

        return composite;
    }

    /**
     * Creates a separator line above the OK/Cancel buttons bar
     * 
     * @param parent the parent composite
     */
    void createSeparatorLine(Composite parent) {
        // Build the separator line
        Label separator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 1;
        separator.setLayoutData(gd);
    }

    /**
     * Creates a radio button with the given parent and text.
     *
     * @param parent the parent composite
     * @param text the text for the check box
     * @return the radio box button
     */
    Button createRadioButton(Composite parent, String text) {
        Button button = new Button(parent, SWT.RADIO);
        button.setText(text);
        button.setFont(parent.getFont());
        button.addSelectionListener(selectionListener);
        return button;
    }

    /**
     * Creates the area showing which resources should be considered.
     *
     * @param parent the parent composite
     */
    void createResourceArea(Composite parent) {
        Composite group = new Composite(parent, SWT.NONE);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        group.setLayout(new GridLayout());
        group.setFont(parent.getFont());
        anyResourceButton = createRadioButton(group, TaskListMessages.TaskList_anyResource);
        anyResourceInSameProjectButton = createRadioButton(group,
                TaskListMessages.TaskList_anyResourceInSameProject);// added by cagatayk@acm.org
        selectedResourceButton = createRadioButton(group, TaskListMessages.TaskList_selectedResource); 
        selectedResourceAndChildrenButton = createRadioButton(group,
                TaskListMessages.TaskList_selectedAndChildren); 
        workingSetGroup = new WorkingSetGroup(group);
    }

    /**
     * Creates the area showing which marker types should be included.
     *
     * @param parent the parent composite
     */
    void createTypesArea(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        GridLayout layout = new GridLayout();
        composite.setLayout(layout);

        Label label = new Label(composite, SWT.NONE);
        label.setText(TaskListMessages.TaskList_showItemsOfType);

        typesViewer = new CheckboxTreeViewer(composite);
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = 100;
        typesViewer.getControl().setLayoutData(gridData);
        typesViewer.setContentProvider(getContentProvider());
        typesViewer.setLabelProvider(getLabelProvider());
        typesViewer.setComparator(getViewerComparator());
        typesViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
        typesViewer.addCheckStateListener(checkStateListener);
        typesViewer.setInput(getMarkerTypes());
    }

    ITreeContentProvider getContentProvider() {
        return new ITreeContentProvider() {
            public void inputChanged(Viewer viewer, Object oldInput,
                    Object newInput) {
            }

            public void dispose() {
            }

            public Object[] getElements(Object inputElement) {
                return new Object[] {
                        markerTypesModel.getType(IMarker.PROBLEM),
                        markerTypesModel.getType(IMarker.TASK) };
            }

            public Object[] getChildren(Object parentElement) {
                MarkerType type = (MarkerType) parentElement;
                return type.getSubtypes();
            }

            public Object getParent(Object element) {
                return null;
            }

            public boolean hasChildren(Object element) {
                return getChildren(element).length > 0;
            }
        };
    }

    void createMarkerLimitArea(Composite parent) {
        Font font = parent.getFont();
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        composite.setFont(font);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        composite.setLayout(layout);
        filterOnMarkerLimit = createCheckbox(composite, TaskListMessages.TaskList_limitVisibleTasksTo, false);
        filterOnMarkerLimit.setLayoutData(new GridData());
        markerLimit = new Text(composite, SWT.SINGLE | SWT.BORDER);
        markerLimit.setTextLimit(6);
        GridData gridData = new GridData();
        gridData.widthHint = convertWidthInCharsToPixels(10);
        markerLimit.setLayoutData(gridData);
        markerLimit.setFont(font);
    }

    /**
     * Returns the filter which this dialog is configuring.
     *
     * @return the filter
     */
    public TasksFilter getFilter() {
        if (filter == null) {
			filter = new TasksFilter();
		}
        return filter;
    }

    ILabelProvider getLabelProvider() {
        return new LabelProvider() {
            public String getText(Object element) {
                MarkerType type = (MarkerType) element;
                return type.getLabel();
            }
        };
    }

    /**
     * Returns the marker types to display.
     *
     * @return the marker types to display
     */
    MarkerType[] getMarkerTypes() {
        if (markerTypes == null) {
            ArrayList typesList = new ArrayList();
            MarkerType[] types = markerTypesModel.getTypes();
            for (int i = 0; i < types.length; ++i) {
                MarkerType type = types[i];
                if (type.getLabel().length() > 0) {
                    if (type.isSubtypeOf(markerTypesModel
                            .getType(IMarker.PROBLEM))
                            || type.isSubtypeOf(markerTypesModel
                                    .getType(IMarker.TASK))) {
                        typesList.add(type);
                    }
                }
            }
            Collections.sort(typesList, new Comparator() {
                Collator collator = Collator.getInstance();

                public int compare(Object o1, Object o2) {
                    return collator.compare(((MarkerType) o1).getLabel(),
                            ((MarkerType) o2).getLabel());
                }
            });
            markerTypes = new MarkerType[typesList.size()];
            typesList.toArray(markerTypes);
        }
        return markerTypes;
    }

    /**
     * Returns the ids of the selected marker types.
     *
     * @return the ids of the selected marker types
     */
    String[] getSelectedTypes() {
        Object[] checked = typesViewer.getCheckedElements();
        ArrayList list = new ArrayList();
        for (int i = 0; i < checked.length; ++i) {
            MarkerType type = (MarkerType) checked[i];
            // Skip it if any supertypes have already been included.
            // Relies on getCheckedElements() using a pre-order traversal 
            // so parents are earlier in the list.
            boolean found = false;
            for (int j = list.size(); --j >= 0;) {
                if (type.isSubtypeOf((MarkerType) list.get(j))) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                list.add(type);
            }
        }
        String[] types = new String[list.size()];
        for (int i = 0; i < list.size(); ++i) {
            types[i] = ((MarkerType) list.get(i)).getId();
        }
        return types;
    }

    private ViewerComparator getViewerComparator() {
        return new ViewerComparator() {
            public int compare(Viewer viewer, Object e1, Object e2) {
                MarkerType t1 = (MarkerType) e1;
                MarkerType t2 = (MarkerType) e2;
                return getComparator().compare(t1.getLabel(), t2.getLabel());
            }
        };
    }

    /**
     * Returns the id of the marker type at the given index
     *
     * @param typeIndex the index of the marker type in the UI list
     * @return the id of the marker type at the given index
     */
    String getTypeId(int typeIndex) {
        return getMarkerTypes()[typeIndex].getId();
    }

    /**
     * Returns the index of the given marker type
     *
     * @param markerType the marker type id
     * @return the index of the marker type
     */
    int getTypeIndex(String markerType) {
        MarkerType[] types = getMarkerTypes();
        for (int i = 0; i < types.length; ++i) {
            String id = types[i].getId();
            if (id == null ? markerType == null : id.equals(markerType)) {
				return i;
			}
        }
        return -1;
    }

    void initTypes() {
        severityType = new EnumType(
                new EnumValue[] {
                        new EnumValue(
                                IMarker.SEVERITY_ERROR,
                                TaskListMessages.TaskList_severity_error, MarkerUtil.getImage("error")),//$NON-NLS-1$
                        new EnumValue(
                                IMarker.SEVERITY_WARNING,
                                TaskListMessages.TaskList_severity_warning, MarkerUtil.getImage("warn")),//$NON-NLS-1$
                        new EnumValue(
                                IMarker.SEVERITY_INFO,
                                TaskListMessages.TaskList_severity_info, MarkerUtil.getImage("info"))  //$NON-NLS-1$
                });

        priorityType = new EnumType(
                new EnumValue[] {
                        new EnumValue(
                                IMarker.PRIORITY_HIGH,
                                TaskListMessages.TaskList_priority_high, MarkerUtil.getImage("hprio")), //$NON-NLS-1$
                        new EnumValue(IMarker.PRIORITY_NORMAL, TaskListMessages.TaskList_priority_normal, null), 
                        new EnumValue(
                                IMarker.PRIORITY_LOW,
                                TaskListMessages.TaskList_priority_low, MarkerUtil.getImage("lprio")) //$NON-NLS-1$
                });

        completionType = new EnumType(new EnumValue[] {
                new EnumValue(1, TaskListMessages.TaskList_status_completed, null), 
                new EnumValue(0, TaskListMessages.TaskList_status_notCompleted, null) 
                });
    }

    /**
     * Updates the filter from the UI state.
     * Must be done here rather than by extending open()
     * because after super.open() is called, the widgetry is disposed.
     */
    protected void okPressed() {
        try {
            int parseResult = Integer.parseInt(this.markerLimit.getText());

            if (parseResult < 1) {
                throw new NumberFormatException();
            }

            updateFilterFromUI(getFilter());
            super.okPressed();
        } catch (NumberFormatException eNumberFormat) {
            MessageBox messageBox = new MessageBox(getShell(), SWT.OK
                    | SWT.APPLICATION_MODAL | SWT.ICON_ERROR);
            messageBox.setText(TaskListMessages.TaskList_titleMarkerLimitInvalid);
            messageBox.setMessage(TaskListMessages.TaskList_messageMarkerLimitInvalid); 
            messageBox.open();

            if (markerLimit.forceFocus()) {
                markerLimit.setSelection(0, markerLimit.getCharCount());
                markerLimit.showSelection();
            }
        }
    }

    /**
     * Handles a press of the Reset button.
     * Updates the UI state to correspond to a reset filter,
     * but doesn't actually reset our filter.
     */
    void resetPressed() {
        updateUIFromFilter(new TasksFilter());
    }

    /**
     * Returns whether any of the selected types are a subtype of the given type.
     */
    boolean selectionIncludesSubtypeOf(String type) {
        MarkerType superType = markerTypesModel.getType(type);
        if (superType == null) {
            return false;
        }
        Object[] checked = typesViewer.getCheckedElements();
        for (int i = 0; i < checked.length; ++i) {
            if (((MarkerType) checked[i]).isSubtypeOf(superType)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Sets the filter which this dialog is to configure.
     *
     * @param filter the filter
     */
    public void setFilter(TasksFilter filter) {
        this.filter = filter;
    }

    /**
     * Sets the selected marker types.
     *
     * @param typeIds the ids of the marker types to select
     */
    void setSelectedTypes(String[] typeIds) {
        typesViewer.setCheckedElements(new MarkerType[0]);
        for (int i = 0; i < typeIds.length; ++i) {
            MarkerType type = markerTypesModel.getType(typeIds[i]);
            if (type != null) {
                typesViewer.setSubtreeChecked(type, true);
            }
        }
    }

    /**
     * Updates the enabled state of the widgetry.
     */
    void updateEnabledState() {
        markerLimit.setEnabled(filterOnMarkerLimit.getSelection());
        boolean isProblemSelected = selectionIncludesSubtypeOf(IMarker.PROBLEM);
        boolean isTaskSelected = selectionIncludesSubtypeOf(IMarker.TASK);
        severityGroup.setEnabled(isProblemSelected);
        priorityGroup.setEnabled(isTaskSelected);
        completionGroup.setEnabled(isTaskSelected);
    }

    /**
     * Updates the given filter from the UI state.
     *
     * @param tasksFilter the filter to update
     */
    void updateFilterFromUI(TasksFilter tasksFilter) {

        tasksFilter.types = getSelectedTypes();

        if (selectedResourceButton.getSelection()) {
			tasksFilter.onResource = TasksFilter.ON_SELECTED_RESOURCE_ONLY;
		} else if (selectedResourceAndChildrenButton.getSelection()) {
			tasksFilter.onResource = TasksFilter.ON_SELECTED_RESOURCE_AND_CHILDREN;
		} else if (anyResourceInSameProjectButton.getSelection()) {
			tasksFilter.onResource = TasksFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT;
		} else if (workingSetGroup.getSelection()) {
			tasksFilter.onResource = TasksFilter.ON_WORKING_SET;
		} else {
			tasksFilter.onResource = TasksFilter.ON_ANY_RESOURCE;
		}

        tasksFilter.workingSet = workingSetGroup.getWorkingSet();
        tasksFilter.descriptionFilterKind = descriptionGroup.combo
                .getSelectionIndex();
        tasksFilter.descriptionFilter = descriptionGroup.text.getText();
        tasksFilter.filterOnDescription = !tasksFilter.descriptionFilter
                .equals("");//$NON-NLS-1$

        tasksFilter.filterOnSeverity = severityGroup.getSelection();
        tasksFilter.severityFilter = severityGroup.getValueMask();

        tasksFilter.filterOnPriority = priorityGroup.getSelection();
        tasksFilter.priorityFilter = priorityGroup.getValueMask();

        tasksFilter.filterOnCompletion = completionGroup.getSelection();
        tasksFilter.completionFilter = completionGroup.getValueMask();

        int limit = TasksFilter.DEFAULT_MARKER_LIMIT;

        try {
            limit = Integer.parseInt(this.markerLimit.getText());
        } catch (NumberFormatException eNumberFormat) {
        }

        tasksFilter.setMarkerLimit(limit);
        tasksFilter.setFilterOnMarkerLimit(filterOnMarkerLimit.getSelection());
    }

    /**
     * Updates the UI state from the given filter.
     *
     * @param tasksFilter the filter to use
     */
    void updateUIFromFilter(TasksFilter tasksFilter) {

        setSelectedTypes(tasksFilter.types);

        int on = tasksFilter.onResource;
        anyResourceButton.setSelection(on == TasksFilter.ON_ANY_RESOURCE);
        anyResourceInSameProjectButton
                .setSelection(on == TasksFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT); // added by cagatayk@acm.org
        selectedResourceButton
                .setSelection(on == TasksFilter.ON_SELECTED_RESOURCE_ONLY);
        selectedResourceAndChildrenButton
                .setSelection(on == TasksFilter.ON_SELECTED_RESOURCE_AND_CHILDREN);
        workingSetGroup.setSelection(on == TasksFilter.ON_WORKING_SET);
        workingSetGroup.setWorkingSet(tasksFilter.workingSet);

        descriptionGroup.combo.select(tasksFilter.descriptionFilterKind);
        descriptionGroup.text.setText(tasksFilter.descriptionFilter);

        severityGroup.setSelection(tasksFilter.filterOnSeverity);
        severityGroup.setValueMask(tasksFilter.severityFilter);

        priorityGroup.setSelection(tasksFilter.filterOnPriority);
        priorityGroup.setValueMask(tasksFilter.priorityFilter);

        completionGroup.setSelection(tasksFilter.filterOnCompletion);
        completionGroup.setValueMask(tasksFilter.completionFilter);

        markerLimit.setText("" + tasksFilter.getMarkerLimit()); //$NON-NLS-1$
        filterOnMarkerLimit.setSelection(tasksFilter.getFilterOnMarkerLimit());

        updateEnabledState();
    }

    /**
     * Handles selection on a check box or combo box.
     */
    void widgetSelected(SelectionEvent e) {
        updateEnabledState();
    }
}
