/*******************************************************************************
 * 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.markers.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;

/**
 * Dialog which allows user to modify all settings of an org.eclipse.ui.views.MarkerFilter object.
 * Not intended to be subclassed or instantiated by clients.
 */
public class DialogMarkerFilter extends Dialog {
	/**
	 * button IDs
	 */
	static final int RESET_ID = IDialogConstants.CLIENT_ID;
	static final int SELECT_WORKING_SET_ID = IDialogConstants.CLIENT_ID + 1;
	static final int SELECT_ALL_ID = IDialogConstants.CLIENT_ID + 2;
	static final int DESELECT_ALL_ID = IDialogConstants.CLIENT_ID + 3;
	
	private class TypesLabelProvider extends LabelProvider implements ITableLabelProvider {

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
		 */
		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
		 */
		public String getColumnText(Object element, int columnIndex) {
			if (!(element instanceof MarkerType)) {
				return ""; //$NON-NLS-1$
			}
			MarkerType type = (MarkerType) element;
			if (columnIndex == 0) {
				return type.getLabel();
			}
			if (columnIndex == 1) {
				String superTypes = ""; //$NON-NLS-1$
				MarkerType[] supers = type.getSupertypes();
				for (int i = 0; i < supers.length; i++) {
					superTypes += supers[i].getLabel();
					if (i < supers.length - 1) {
						superTypes += "; "; //$NON-NLS-1$
					}
				}
				return superTypes;
			}
			return ""; //$NON-NLS-1$
		}
	}

	/**
	 * Creates and manages a group of widgets for selecting a working 
	 * set marker filter.
	 */
	private class WorkingSetGroup {
		private Button button;
		private Button selectButton;
		/**
		 * 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, Messages.getString("filtersDialog.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);
			selectButton = createButton(composite, SELECT_WORKING_SET_ID, Messages.getString("filtersDialog.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) {
				markDirty();
				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(Messages.format(
					"filtersDialog.workingSet", 					//$NON-NLS-1$
					new Object[] {workingSet.getName()})); 
			}
			else {
				button.setText(Messages.getString("filtersDialog.noWorkingSet")); //$NON-NLS-1$
			}
		}
		void setEnabled(boolean enabled) {
			button.setEnabled(enabled);
			selectButton.setEnabled(enabled);
		}
	}

	private MarkerFilter filter;

	private CheckboxTableViewer typesViewer;
	private Button filterEnabledButton;
	private Button filterOnMarkerLimit;
	private Button anyResourceButton;
	private Button anyResourceInSameProjectButton;
	private Button selectedResourceButton;
	private Button selectedResourceAndChildrenButton;
	private Button selectAllButton;
	private Button deselectAllButton;
	private WorkingSetGroup workingSetGroup;
	private Text markerLimit;
	
	private boolean dirty = false;
	
	protected SelectionListener selectionListener = new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			DialogMarkerFilter.this.widgetSelected(e);
		}
	};

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

	/**
	 * Creates a new filters dialog.
	 */
	DialogMarkerFilter(Shell parentShell, MarkerFilter filter) {
		super(parentShell);
		this.filter = filter;
	}
	
	/* (non-Javadoc)
	 * Method declared on Dialog.
	 */
	protected void buttonPressed(int buttonId) {
		if (buttonId == RESET_ID) {
			resetPressed();
			markDirty();
		}
		else if (buttonId == SELECT_WORKING_SET_ID) {
			workingSetGroup.selectPressed();
		}
		else if (buttonId == SELECT_ALL_ID) {
			typesViewer.setAllChecked(true);
		}
		else if (buttonId == DESELECT_ALL_ID) {
			typesViewer.setAllChecked(false);
		}
		else {
			super.buttonPressed(buttonId);
		}
	}

	/**
	 * This method is called when a button is checked or unchecked. It updates the enablement
	 * state of all widgets and marks the dialog as dirty.
	 */
	void checkStateChanged(CheckStateChangedEvent event) {
		updateEnabledState();
		markDirty();
	}
		
	/**
	 * Method declared on Window.
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(Messages.getString("filtersDialog.title")); //$NON-NLS-1$
	}

	protected void createResetArea(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setFont(parent.getFont());
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;	
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
		
		Button reset = new Button(composite, SWT.PUSH);
		reset.setText(Messages.getString("restoreDefaults.text")); //$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
	 */
	protected 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
	 */
	protected 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;
	}

	/**
	 * Method declared on Dialog.
	 */
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		createOnOffArea(composite);
		createMarkerLimitArea(composite);
		createTypesArea(composite);
		createResourceArea(composite);
		createAttributesArea(composite);
		createResetArea(composite);
		createSeparatorLine(composite);	
	
		updateUIFromFilter();
		
		return composite;
	}

	/**
	 * Creates a separator line above the OK/Cancel buttons bar
	 * 
	 * @param parent the parent composite
	 */
	protected 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
	 */
	protected 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
	 */
	protected 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, Messages.getString("filtersDialog.anyResource")); //$NON-NLS-1$
		anyResourceInSameProjectButton = createRadioButton(group, Messages.getString("filtersDialog.anyResourceInSameProject")); //$NON-NLS-1$ // added by cagatayk@acm.org
		selectedResourceButton = createRadioButton(group, Messages.getString("filtersDialog.selectedResource")); //$NON-NLS-1$
		selectedResourceAndChildrenButton = createRadioButton(group, Messages.getString("filtersDialog.selectedAndChildren")); //$NON-NLS-1$
		workingSetGroup = new WorkingSetGroup(group);
	}

	/**
	 * Creates the area showing which marker types should be included.
	 *
	 * @param parent the parent composite
	 */
	protected void createTypesArea(Composite parent) {
		Font font = parent.getFont();
		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(Messages.getString("filtersDialog.showItemsOfType")); //$NON-NLS-1$
		label.setFont(font);
		
		Table table = new Table(composite, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		TableLayout tableLayout = new TableLayout();
		table.setLayout(tableLayout);
		tableLayout.addColumnData(new ColumnPixelData(150, true));
		TableColumn tc = new TableColumn(table, SWT.NONE, 0);
		tc.setText(Messages.getString("filtersDialog.type.columnHeader")); //$NON-NLS-1$
		tableLayout.addColumnData(new ColumnPixelData(224, true));
		tc = new TableColumn(table, SWT.NONE, 1);
		tc.setText(Messages.getString("filtersDialog.superTypecolumnHeader")); //$NON-NLS-1$
		typesViewer = new CheckboxTableViewer(table);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 105;
		gridData.widthHint = 350;
		typesViewer.getTable().setFont(font);
		typesViewer.getControl().setLayoutData(gridData);
		typesViewer.setContentProvider(getContentProvider());
		typesViewer.setLabelProvider(getLabelProvider());
		typesViewer.setSorter(getSorter());
		typesViewer.addCheckStateListener(checkStateListener);
		typesViewer.setInput(filter.getRootTypes().toArray());
		
		Composite buttonComposite = new Composite(composite, SWT.NONE);
		GridLayout buttonLayout = new GridLayout();
		buttonLayout.marginWidth = 0;
		buttonComposite.setLayout(buttonLayout);
		selectAllButton = createButton(buttonComposite, 
									   SELECT_ALL_ID, 
									   Messages.getString("filtersDialog.selectAll"), //$NON-NLS-1$ 
									   false);
		deselectAllButton = createButton(buttonComposite, 
										 DESELECT_ALL_ID, 
										 Messages.getString("filtersDialog.deselectAll"), //$NON-NLS-1$ 
										 false);
	}

	private IStructuredContentProvider getContentProvider() {
		return new IStructuredContentProvider() {
			public Object[] getElements(Object inputElement) {
				List roots = filter.getRootTypes();
				List elements = new ArrayList();
				for (int i = 0; i < roots.size(); i++) {
					Object obj = roots.get(i);
					if (obj instanceof MarkerType) {
						elements.add(obj);
						MarkerType[] subTypes = ((MarkerType) obj).getAllSubTypes();
						for (int j = 0; j < subTypes.length; j++) {
							MarkerType subType = subTypes[j];
							if (!elements.contains(subType)) {
								elements.add(subType);
							}
						}
					}
				}
				return elements.toArray();
			}
			public void dispose() {
			}
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			}
		};
	}
	
	/**
	 * Creates the filter enablement area.
	 * 
	 * @param parent the parent composite
	 */
	protected void createOnOffArea(Composite parent) {
		Font font = parent.getFont();
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		composite.setFont(font);
		composite.setLayout(new GridLayout());
		filterEnabledButton = createCheckbox(composite,
			Messages.getString("filtersDialog.onOff"), //$NON-NLS-1$
			false);
		filterEnabledButton.setFont(composite.getFont());
		filterEnabledButton.setLayoutData(new GridData());
		filterEnabledButton.addSelectionListener(selectionListener);
	}

	/**
	 * Creates the area where the user can specify a maximum number of items
	 * to display in the table.
	 * 
	 * @param parent the parent composite
	 */
	protected 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,
			Messages.getString("filtersDialog.limitVisibleMarkersTo"), //$NON-NLS-1$
			false);
		filterOnMarkerLimit.setFont(composite.getFont());
		filterOnMarkerLimit.setLayoutData(new GridData());
		filterOnMarkerLimit.addSelectionListener(selectionListener);
		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);
		markerLimit.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				markDirty();
			}
		});
	}
	
	/**
	 * This method is intended to be overridden by subclasses of FiltersDialog. The
	 * attributes area will be created just above the Restore Defaults button.
	 * 
	 * @param parent the parent Composite
	 */
	protected void createAttributesArea(Composite parent) {	
	}

	private ILabelProvider getLabelProvider() {
		return new TypesLabelProvider();
	}

	/**
	 * Returns the selected marker types.
	 *
	 * @return the selected marker types
	 */
	protected List getSelectedTypes() {
		return Arrays.asList(typesViewer.getCheckedElements());
	}

	protected 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());
			}
		};
	}

	/**
	 * 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 markerLimit = Integer.parseInt(this.markerLimit.getText());
	
			if (markerLimit < 1) {
				throw new NumberFormatException();
			}			
			
			updateFilterFromUI();
			super.okPressed();
		}
		catch (NumberFormatException eNumberFormat) {
			MessageBox messageBox = new MessageBox(getShell(), 
					SWT.OK | SWT.APPLICATION_MODAL | SWT.ICON_ERROR);
			messageBox.setText(Messages.getString(
					"filtersDialog.titleMarkerLimitInvalid")); //$NON-NLS-1$
			messageBox.setMessage(Messages.getString(
					"filtersDialog.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.
	 */
	protected void resetPressed() {
		filterEnabledButton.setSelection(MarkerFilter.DEFAULT_ACTIVATION_STATUS);
		filterOnMarkerLimit.setSelection(MarkerFilter.DEFAULT_FILTER_ON_MARKER_LIMIT);
		markerLimit.setText(String.valueOf(MarkerFilter.DEFAULT_MARKER_LIMIT));
		typesViewer.setAllChecked(true);
		int onResource = MarkerFilter.DEFAULT_ON_RESOURCE;
		anyResourceButton.setSelection(onResource == MarkerFilter.ON_ANY_RESOURCE);
		anyResourceInSameProjectButton.setSelection(onResource == MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT);
		selectedResourceButton.setSelection(onResource == MarkerFilter.ON_SELECTED_RESOURCE_ONLY);
		selectedResourceAndChildrenButton.setSelection(onResource == MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN);
		workingSetGroup.setSelection(onResource == MarkerFilter.ON_WORKING_SET);
		updateEnabledState();
	}

	/**
	 * Sets the selected marker types.
	 *
	 * @param markerTypes
	 */
	void setSelectedTypes(List markerTypes) {
		typesViewer.setCheckedElements(new Object[0]);
		for (int i = 0; i < markerTypes.size(); i++) {
			Object obj = markerTypes.get(i);
			if (obj instanceof MarkerType) {
				typesViewer.setChecked(obj, true);
			}
		}
	}

	/**
	 * Updates the enabled state of the widgetry.
	 */
	protected void updateEnabledState() {
		filterOnMarkerLimit.setEnabled(isFilterEnabled());
		markerLimit.setEnabled(isFilterEnabled() && filterOnMarkerLimit.getSelection());
		
		typesViewer.getTable().setEnabled(isFilterEnabled());
		selectAllButton.setEnabled(isFilterEnabled() && typesViewer.getTable().getItemCount() > 0);
		deselectAllButton.setEnabled(isFilterEnabled() && typesViewer.getTable().getItemCount() > 0);
		
		anyResourceButton.setEnabled(isFilterEnabled());
		anyResourceInSameProjectButton.setEnabled(isFilterEnabled());
		selectedResourceButton.setEnabled(isFilterEnabled());
		selectedResourceAndChildrenButton.setEnabled(isFilterEnabled());
		workingSetGroup.setEnabled(isFilterEnabled());
	}
	
	/**
	 * Updates the given filter from the UI state.
	 *
	 * @param filter the filter to update
	 */
	protected void updateFilterFromUI() {
		filter.setEnabled(filterEnabledButton.getSelection());
		
		filter.setSelectedTypes(getSelectedTypes());
		
		if (selectedResourceButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_SELECTED_RESOURCE_ONLY);
		else if (selectedResourceAndChildrenButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN);
		else if (anyResourceInSameProjectButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT);
		else if (workingSetGroup.getSelection())
			filter.setOnResource(MarkerFilter.ON_WORKING_SET);
		else
			filter.setOnResource(MarkerFilter.ON_ANY_RESOURCE);
	
		filter.setWorkingSet(workingSetGroup.getWorkingSet());

		int markerLimit = MarkerFilter.DEFAULT_MARKER_LIMIT;
		
		try {
			markerLimit = Integer.parseInt(this.markerLimit.getText());
		}
		catch (NumberFormatException e) {
		}
	
		filter.setMarkerLimit(markerLimit);	
		filter.setFilterOnMarkerLimit(filterOnMarkerLimit.getSelection());
	}

	/**
	 * Updates the UI state from the given filter.
	 *
	 * @param filter the filter to use
	 */
	protected void updateUIFromFilter() {
		filterEnabledButton.setSelection(filter.isEnabled());
		
		setSelectedTypes(filter.getSelectedTypes());
	
		int on = filter.getOnResource();
		anyResourceButton.setSelection(on == MarkerFilter.ON_ANY_RESOURCE);
		anyResourceInSameProjectButton.setSelection(on == MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT);
		selectedResourceButton.setSelection(on == MarkerFilter.ON_SELECTED_RESOURCE_ONLY);
		selectedResourceAndChildrenButton.setSelection(on == MarkerFilter.ON_SELECTED_RESOURCE_AND_CHILDREN);
		workingSetGroup.setSelection(on == MarkerFilter.ON_WORKING_SET);
		workingSetGroup.setWorkingSet(filter.getWorkingSet());
				
		markerLimit.setText("" + filter.getMarkerLimit()); //$NON-NLS-1$
		filterOnMarkerLimit.setSelection(filter.getFilterOnMarkerLimit());
	
		updateEnabledState();
	}

	/**
	 * Handles selection on a check box or combo box.
	 */
	protected void widgetSelected(SelectionEvent e) {
		updateEnabledState();
		markDirty();
	}
	
	/**
	 * @return <code>true</code> if the dirty flag has been set otherwise
	 * <code>false</code>.
	 */
	boolean isDirty() {
		return dirty;
	}

	/**
	 * Marks the dialog as dirty.
	 */
	void markDirty() {
		dirty = true;
	}

	public void setFilter(MarkerFilter newFilter) {
		filter = newFilter;
		updateUIFromFilter();
	}
	
	/**
	 * @return the MarkerFilter associated with the dialog.
	 */
	public MarkerFilter getFilter() {
		return filter;
	}
	
	/**
	 * @return <code>true</code> if the filter's enablement button is checked 
	 * otherwise <code>false</code>.
	 */
	protected boolean isFilterEnabled() {
		return (filterEnabledButton == null) || filterEnabledButton.getSelection();
	}

}
