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

	/**
	 * @return the MarkerFilter associated with the dialog.
	 */
	protected 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();
	}

}
