/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.views.tasklist;

import java.text.Collator;
import java.util.*;

import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
import org.eclipse.ui.help.WorkbenchHelp;

class FiltersDialog extends Dialog {
	/**
	 * 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.getString("TaskList.noWorkingSet")); //$NON-NLS-1$
			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.getString("TaskList.workingSetSelect"), false); //$NON-NLS-1$
		}
		/**
		 * 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(TaskListMessages.format(
					"TaskList.workingSet", 					//$NON-NLS-1$
					new Object[] {workingSet.getName()})); 
			}
			else {
				button.setText(TaskListMessages.getString("TaskList.noWorkingSet")); //$NON-NLS-1$
			}
		}
	}

	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.
	 */
	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);
		}
	}

	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.getString("TaskList.filter")); //$NON-NLS-1$
		WorkbenchHelp.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.getString("TaskList.contains"), TaskListMessages.getString("TaskList.doesNotContain")}; //$NON-NLS-2$ //$NON-NLS-1$
		descriptionGroup = new LabelComboTextGroup(composite, TaskListMessages.getString("TaskList.whereDescription"), filters, "", 200);//$NON-NLS-2$ //$NON-NLS-1$
		severityGroup = new CheckboxEnumGroup(composite, TaskListMessages.getString("TaskList.severity.label"), severityType); //$NON-NLS-1$
		priorityGroup = new CheckboxEnumGroup(composite, TaskListMessages.getString("TaskList.priority.label"), priorityType); //$NON-NLS-1$
		completionGroup = new CheckboxEnumGroup(composite, TaskListMessages.getString("TaskList.status.label"), completionType); //$NON-NLS-1$
	}

	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.getString("TaskList.resetText")); //$NON-NLS-1$
		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.getString("TaskList.anyResource")); //$NON-NLS-1$
		anyResourceInSameProjectButton = createRadioButton(group, TaskListMessages.getString("TaskList.anyResourceInSameProject")); //$NON-NLS-1$ // added by cagatayk@acm.org
		selectedResourceButton = createRadioButton(group, TaskListMessages.getString("TaskList.selectedResource")); //$NON-NLS-1$
		selectedResourceAndChildrenButton = createRadioButton(group, TaskListMessages.getString("TaskList.selectedAndChildren")); //$NON-NLS-1$
		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.getString("TaskList.showItemsOfType")); //$NON-NLS-1$
		
		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.setSorter(getSorter());
		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.getString(
				"TaskList.limitVisibleTasksTo"), false); //$NON-NLS-1$
		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;
	}

	ViewerSorter getSorter() {
		return new ViewerSorter() {
			public int compare(Viewer viewer, Object e1, Object e2) {
				MarkerType t1 = (MarkerType) e1;
				MarkerType t2 = (MarkerType) e2;
				return collator.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.getString("TaskList.severity.error"), MarkerUtil.getImage("error")),//$NON-NLS-2$ //$NON-NLS-1$
				new EnumValue(IMarker.SEVERITY_WARNING, TaskListMessages.getString("TaskList.severity.warning"), MarkerUtil.getImage("warn")),//$NON-NLS-2$ //$NON-NLS-1$
				new EnumValue(IMarker.SEVERITY_INFO, TaskListMessages.getString("TaskList.severity.info"), MarkerUtil.getImage("info"))//$NON-NLS-2$ //$NON-NLS-1$
			}
		);
		
		priorityType = new EnumType(
			new EnumValue[] {
				new EnumValue(IMarker.PRIORITY_HIGH, TaskListMessages.getString("TaskList.priority.high"), MarkerUtil.getImage("hprio")),//$NON-NLS-2$ //$NON-NLS-1$
				new EnumValue(IMarker.PRIORITY_NORMAL, TaskListMessages.getString("TaskList.priority.normal"), null), //$NON-NLS-1$
				new EnumValue(IMarker.PRIORITY_LOW, TaskListMessages.getString("TaskList.priority.low"), MarkerUtil.getImage("lprio"))//$NON-NLS-2$ //$NON-NLS-1$
			}
		);
	
		completionType = new EnumType(
			new EnumValue[] {
				new EnumValue(1, TaskListMessages.getString("TaskList.status.completed"), null), //$NON-NLS-1$
				new EnumValue(0, TaskListMessages.getString("TaskList.status.notCompleted"), null) //$NON-NLS-1$
			}
		);
	}

	/**
	 * 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.getString(
					"TaskList.titleMarkerLimitInvalid")); //$NON-NLS-1$
			messageBox.setMessage(TaskListMessages.getString(
					"TaskList.messageMarkerLimitInvalid")); //$NON-NLS-1$
			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 filter 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()) // added by cagatayk@acm.org
			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 filter 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();
	}
}
