/*******************************************************************************
 * Copyright (c) 2000, 2005 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.markers.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
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.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
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 abstract class DialogMarkerFilter extends TrayDialog {
	/**
	 * 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) {
			return ((AbstractNode) element).getName();
		}
	}

	/**
	 * 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,
					MarkerMessages.filtersDialog_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);
			selectButton = createButton(composite, SELECT_WORKING_SET_ID,
					MarkerMessages.filtersDialog_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) {
				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(NLS.bind(
						MarkerMessages.filtersDialog_workingSet, workingSet
								.getLabel()));
			} else {
				button.setText(MarkerMessages.filtersDialog_noWorkingSet);
			}
		}

		void setEnabled(boolean enabled) {
			button.setEnabled(enabled);
			selectButton.setEnabled(enabled);
		}
	}

	/**
	 * AbstractNode is the abstract superclass of the node elements for
	 * MarkerTypes.
	 * 
	 */
	private abstract class AbstractNode {

		/**
		 * Get the parent element of the receiver.
		 * 
		 * @return Object
		 */
		public abstract Object getParent();

		/**
		 * Get the name of the receiver.
		 * 
		 * @return String
		 */
		public abstract String getName();

		/**
		 * Return whether or not the receiver has children.
		 * 
		 * @return boolean
		 */
		public abstract boolean hasChildren();

		/**
		 * Get the children of the receiver.
		 * 
		 * @return Object[]
		 */
		public abstract Object[] getChildren();

		/**
		 * Return whether or not this is a category node.
		 * 
		 * @return boolean
		 */
		public abstract boolean isCategory();

	}

	/**
	 * MarkerTypeNode is the wrapper for marker types.
	 * 
	 */
	private class MarkerTypeNode extends AbstractNode {

		MarkerType type;

		MarkerCategory category;

		/**
		 * Create an instance of the receiver wrapping markerType.
		 * 
		 * @param markerType
		 */
		public MarkerTypeNode(MarkerType markerType) {
			type = markerType;
			nodeToTypeMapping.put(markerType.getId(), this);
		}

		/**
		 * Set the category of the receiver.
		 * 
		 * @param category
		 */
		public void setCategory(MarkerCategory category) {
			this.category = category;
		}

		/**
		 * Get the category for the receiver.
		 * 
		 * @return MarkerCategory
		 */
		public MarkerCategory getCategory() {
			return category;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getChildren()
		 */
		public Object[] getChildren() {
			return new Object[0];
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getParent()
		 */
		public Object getParent() {
			return category;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#hasChildren()
		 */
		public boolean hasChildren() {
			return false;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getName()
		 */
		public String getName() {
			return type.getLabel();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#isCategory()
		 */
		public boolean isCategory() {
			return false;
		}

		/**
		 * Return the marker type this is wrapping
		 * @return Object
		 */
		public Object getMarkerType() {
			return type;
		}
	}

	/**
	 * The MarkerCategory is a data type to represent the categories in the tree
	 * view.
	 * 
	 */
	private class MarkerCategory extends AbstractNode {

		String name;

		Collection types = new ArrayList();

		/**
		 * Create a new instance of the receiver with name categoryName.
		 * 
		 * @param categoryName
		 */
		public MarkerCategory(String categoryName) {
			name = categoryName;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getName()
		 */
		public String getName() {
			return name;
		}

		/**
		 * Add markerType to the list of types.
		 * 
		 * @param markerType
		 */
		public void add(MarkerTypeNode markerType) {
			types.add(markerType);
			markerType.setCategory(this);
		}

		/**
		 * Return the marker types contained in the receiver.
		 * 
		 * @return Object[]
		 */
		public Object[] getMarkerTypes() {
			return types.toArray();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getChildren()
		 */
		public Object[] getChildren() {
			return getMarkerTypes();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getParent()
		 */
		public Object getParent() {
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#hasChildren()
		 */
		public boolean hasChildren() {
			return true;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#isCategory()
		 */
		public boolean isCategory() {
			return true;
		}

	}

	private MarkerFilter[] filters;

	private CheckboxTreeViewer typesViewer;

	private Button anyResourceButton;

	private Button anyResourceInSameProjectButton;

	private Button selectedResourceButton;

	private Button selectedResourceAndChildrenButton;

	private Button selectAllButton;

	private Button deselectAllButton;

	private WorkingSetGroup workingSetGroup;

	private boolean dirty = false;

	private CheckboxTableViewer filtersList;

	private MarkerFilter[] selectedFilters;

	private HashMap nodeToTypeMapping = new HashMap();

	private ITreeContentProvider typesContentProvider;

	/**
	 * Create a new instance of the receiver.
	 * 
	 * @param parentShell
	 * @param filtersList
	 */
	DialogMarkerFilter(Shell parentShell, MarkerFilter[] filtersList) {
		super(parentShell);
		setFilters(filtersList);
		setShellStyle(getShellStyle() | SWT.RESIZE);
	}

	/**
	 * Set the filters in the filtersList by copying them.
	 * 
	 * @param initialFilters
	 */
	private void setFilters(MarkerFilter[] initialFilters) {
		MarkerFilter[] newMarkers = new MarkerFilter[initialFilters.length];
		for (int i = 0; i < initialFilters.length; i++) {
			MarkerFilter newFilter;
			try {
				newFilter = initialFilters[i].makeClone();
			} catch (CloneNotSupportedException exception) {
				ErrorDialog.openError(getShell(),
						MarkerMessages.MarkerFilterDialog_errorTitle,
						MarkerMessages.MarkerFilterDialog_failedFilterMessage,
						Util.errorStatus(exception));
				return;
			}

			newMarkers[i] = newFilter;

		}
		filters = newMarkers;

	}

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

	/**
	 * Method declared on Window.
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(MarkerMessages.filtersDialog_title);
	}

	protected void createResetArea(Composite parent) {

		Button reset = new Button(parent, SWT.PUSH);
		reset.setText(MarkerMessages.restoreDefaults_text);
		reset.setData(new Integer(RESET_ID));

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

		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		Point minSize = reset.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
		data.widthHint = Math.max(widthHint, minSize.x);
		data.horizontalSpan = 2;
		reset.setLayoutData(data);
	}

	/**
	 * 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(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateForSelection();
			}
		});
		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(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateForSelection();
			}
		});
		return combo;
	}

	/**
	 * Method declared on Dialog.
	 */
	protected Control createDialogArea(Composite parent) {
		Composite dialogArea = (Composite) super.createDialogArea(parent);

		dialogArea.setLayout(new GridLayout(2, false));

		createFiltersArea(dialogArea);

		Composite selectedComposite = createSelectedFilterArea(dialogArea);
		selectedComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true));
		updateUIFromFilter();

		filtersList.setSelection(new StructuredSelection(filters[0]));

		applyDialogFont(dialogArea);
		return dialogArea;
	}

	/**
	 * Create the list in the receiver.
	 * 
	 * @param dialogArea
	 */
	/**
	 * @param dialogArea
	 */
	void createFiltersArea(Composite dialogArea) {

		Composite listArea = new Composite(dialogArea, SWT.NONE);
		listArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
		listArea.setLayout(new GridLayout());

		Label title = new Label(listArea, SWT.NONE);
		title.setText(MarkerMessages.MarkerFilter_filtersTitle);
		filtersList = CheckboxTableViewer.newCheckList(listArea, SWT.BORDER);
		filtersList.setContentProvider(new IStructuredContentProvider() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
			 */
			public Object[] getElements(Object inputElement) {
				return filters;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
			 */
			public void dispose() {
				// Do nothing
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
			 *      java.lang.Object, java.lang.Object)
			 */
			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
				// Do nothing
			}
		});

		filtersList.setLabelProvider(new LabelProvider() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
			 */
			public String getText(Object element) {
				return ((MarkerFilter) element).getName();
			}
		});

		filtersList.addCheckStateListener(new ICheckStateListener() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
			 */
			public void checkStateChanged(CheckStateChangedEvent event) {
				((MarkerFilter) event.getElement()).setEnabled(event
						.getChecked());

			}
		});

		selectedFilters = new MarkerFilter[] { filters[0] };
		filtersList.setSelection(new StructuredSelection(selectedFilters));

		filtersList
				.addSelectionChangedListener(new ISelectionChangedListener() {

					/*
					 * (non-Javadoc)
					 * 
					 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
					 */
					public void selectionChanged(SelectionChangedEvent event) {
						updateFilterFromUI();
						setSelectedFilter(event);

					}
				});

		filtersList.setInput(this);
		for (int i = 0; i < filters.length; i++) {
			filtersList.setChecked(filters[i], filters[i].isEnabled());
		}

		filtersList.getControl().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, false, true));

		Composite buttons = new Composite(listArea, SWT.NONE);
		buttons.setLayout(new GridLayout(2, false));

		Button addNew = new Button(buttons, SWT.PUSH);
		addNew.setText(MarkerMessages.MarkerFilter_addFilterName);
		addNew.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				InputDialog newDialog = new InputDialog(getShell(),
						MarkerMessages.MarkerFilterDialog_title,
						MarkerMessages.MarkerFilterDialog_message,
						MarkerMessages.MarkerFilter_newFilterName,
						new IInputValidator() {
							/*
							 * (non-Javadoc)
							 * 
							 * @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
							 */
							public String isValid(String newText) {
								if (newText.length() == 0)
									return MarkerMessages.MarkerFilterDialog_emptyMessage;
								return null;
							}
						});
				newDialog.open();
				String newName = newDialog.getValue();
				if (newName != null) {
					createNewFilter(newName);
				}
			}
		});

		Button remove = new Button(buttons, SWT.PUSH);
		remove.setText(MarkerMessages.MarkerFilter_deleteSelectedName);
		remove.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				removeFilters(filtersList.getSelection());
			}
		});
	}

	/**
	 * Set the selected filter from event.
	 * 
	 * @param event
	 */
	protected void setSelectedFilter(SelectionChangedEvent event) {

		ISelection selection = event.getSelection();
		if (selection instanceof IStructuredSelection) {
			Collection list = ((IStructuredSelection) selection).toList();
			MarkerFilter[] selected = new MarkerFilter[list.size()];
			list.toArray(selected);
			selectedFilters = selected;

		} else
			selectedFilters = new MarkerFilter[0];
		updateUIFromFilter();

	}

	/**
	 * Remove the filters in selection.
	 * 
	 * @param selection
	 */
	protected void removeFilters(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			List toRemove = ((IStructuredSelection) selection).toList();
			MarkerFilter[] newFilters = new MarkerFilter[filters.length
					- toRemove.size()];
			int index = 0;
			for (int i = 0; i < filters.length; i++) {
				if (toRemove.contains(filters[i]))
					continue;
				newFilters[index] = filters[i];
				index++;
			}

			filters = newFilters;
			filtersList.refresh();
			updateUIFromFilter();
		}
	}

	/**
	 * Create a new filter called newName.
	 * 
	 * @param newName
	 */
	private void createNewFilter(String newName) {
		MarkerFilter[] newFilters = new MarkerFilter[filters.length + 1];
		System.arraycopy(filters, 0, newFilters, 0, filters.length);
		MarkerFilter filter = newFilter(newName);
		newFilters[filters.length] = filter;
		filters = newFilters;
		filtersList.refresh();
		filtersList.setSelection(new StructuredSelection(filter), true);
		filtersList.getControl().setFocus();
	}

	/**
	 * Crate a newFilter called newName
	 * 
	 * @param newName
	 * @return MarkerFilter
	 */
	protected abstract MarkerFilter newFilter(String newName);

	/**
	 * Create the area for the selected filter.
	 * 
	 * @param composite
	 */
	Composite createSelectedFilterArea(Composite composite) {

		Composite selectedComposite = new Composite(composite, SWT.NONE);
		selectedComposite.setLayout(new GridLayout(2, false));

		Composite leftComposite = new Composite(selectedComposite, SWT.NONE);
		leftComposite.setLayout(new GridLayout());
		leftComposite
				.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		createResourceArea(leftComposite);
		createAttributesArea(leftComposite);

		Composite rightComposite = new Composite(selectedComposite, SWT.NONE);
		createTypesArea(rightComposite);
		rightComposite.setLayout(new GridLayout());
		rightComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true));

		createSeparatorLine(selectedComposite);
		createResetArea(selectedComposite);

		return selectedComposite;
	}

	/**
	 * 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 = 2;
		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(new SelectionAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
			 */
			public void widgetSelected(SelectionEvent e) {
				updateForSelection();
			}
		});
		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,
				MarkerMessages.filtersDialog_anyResource);
		anyResourceInSameProjectButton = createRadioButton(group,
				MarkerMessages.filtersDialog_anyResourceInSameProject); // added
		// by
		// cagatayk@acm.org
		selectedResourceButton = createRadioButton(group,
				MarkerMessages.filtersDialog_selectedResource);
		selectedResourceAndChildrenButton = createRadioButton(group,
				MarkerMessages.filtersDialog_selectedAndChildren);
		workingSetGroup = new WorkingSetGroup(group);
	}

	/**
	 * Creates the area showing which marker types should be included.
	 * 
	 * @param parent
	 *            the parent composite
	 */
	protected void createTypesArea(Composite parent) {

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		GridLayout layout = new GridLayout();
		composite.setLayout(layout);

		Label label = new Label(composite, SWT.NONE);
		label.setText(MarkerMessages.filtersDialog_showItemsOfType);

		Tree tree = new Tree(composite, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL
				| SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
		tree.setLinesVisible(true);
		tree.setHeaderVisible(false);
		TableLayout tableLayout = new TableLayout();
		tree.setLayout(tableLayout);
		tableLayout.addColumnData(new ColumnWeightData(100, true));
		new TreeColumn(tree, SWT.NONE, 0);

		typesViewer = new CheckboxTreeViewer(tree);
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
		gridData.widthHint = convertVerticalDLUsToPixels(100);
		gridData.heightHint = convertVerticalDLUsToPixels(200);

		typesContentProvider = getTypesContentProvider();
		typesViewer.getControl().setLayoutData(gridData);
		typesViewer.setContentProvider(typesContentProvider);
		typesViewer.setLabelProvider(getLabelProvider());
		typesViewer.setSorter(getSorter());
		typesViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				markDirty();
				Object element = event.getElement();
				boolean checked = event.getChecked();
				setChildrenChecked(element, checked);
				setParentCheckState(element, checked);
			}
		});
		typesViewer.setInput(getSelectedFilter().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,
				MarkerMessages.filtersDialog_selectAll, false);
		deselectAllButton = createButton(buttonComposite, DESELECT_ALL_ID,
				MarkerMessages.filtersDialog_deselectAll, false);
	}

	/**
	 * Get the currently selected marker filter if there is only one selection.
	 * 
	 * @return MarkerFilter or <code>null</code>.
	 */
	protected MarkerFilter getSelectedFilter() {

		if (selectedFilters.length == 1)
			return selectedFilters[0];
		return null;
	}

	/**
	 * Get the content provider for the receiver.
	 * 
	 * @return ITreeContentProvider
	 */
	private ITreeContentProvider getTypesContentProvider() {
		return new ITreeContentProvider() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
			 */
			public Object[] getElements(Object inputElement) {
				MarkerFilter selected = getSelectedFilter();
				if (selected == null)
					return new Object[0];

				return getRootEntries(selected);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
			 */
			public void dispose() {
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
			 *      java.lang.Object, java.lang.Object)
			 */
			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
			 */
			public Object[] getChildren(Object parentElement) {
				return ((AbstractNode) parentElement).getChildren();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
			 */
			public Object getParent(Object element) {
				return ((AbstractNode) element).getParent();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
			 */
			public boolean hasChildren(Object element) {
				return ((AbstractNode) element).hasChildren();
			}
		};
	}

	/**
	 * 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
	 */
	abstract void createAttributesArea(Composite parent);

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

	/**
	 * Returns the selected marker types.
	 * 
	 * @return List the selected marker types
	 */
	protected List getSelectedTypes() {
		Object[] checkElements = typesViewer.getCheckedElements();
		List selected = new ArrayList();
		for (int i = 0; i < checkElements.length; i++) {
			AbstractNode node = (AbstractNode) checkElements[i];
			if (!node.isCategory())
				selected.add(((MarkerTypeNode)node).getMarkerType());

		}
		return selected;
	}

	/**
	 * Return the sorter for the receiver.
	 * 
	 * @return ViewerSorter
	 */
	protected ViewerSorter getSorter() {
		return new ViewerSorter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer,
			 *      java.lang.Object, java.lang.Object)
			 */
			public int compare(Viewer viewer, Object e1, Object e2) {
				return collator.compare(((AbstractNode) e1).getName(),
						((AbstractNode) e2).getName());
			}
		};
	}

	/**
	 * 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() {
		updateFilterFromUI();
		super.okPressed();
	}

	/**
	 * 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() {
		typesViewer.setAllChecked(true);
		int onResource = MarkerFilter.DEFAULT_ON_RESOURCE;
		anyResourceButton.setSelection(onResource == MarkerFilter.ON_ANY);
		anyResourceInSameProjectButton
				.setSelection(onResource == MarkerFilter.ON_ANY_IN_SAME_CONTAINER);
		selectedResourceButton
				.setSelection(onResource == MarkerFilter.ON_SELECTED_ONLY);
		selectedResourceAndChildrenButton
				.setSelection(onResource == MarkerFilter.ON_SELECTED_AND_CHILDREN);
		workingSetGroup.setSelection(onResource == MarkerFilter.ON_WORKING_SET);
		updateEnabledState(true);
	}

	/**
	 * 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) {

				Object mapping = nodeToTypeMapping.get(((MarkerType) obj).getId());
				if (mapping != null){
					typesViewer.setChecked(mapping, true);
					setParentCheckState(mapping, true);
				}
			}
		}
	}

	/**
	 * Updates the enabled state of the widgetry based on whether or not it is
	 * enabled.
	 */
	protected void updateEnabledState(boolean enabled) {

		typesViewer.getTree().setEnabled(enabled);
		selectAllButton.setEnabled(enabled
				&& typesViewer.getTree().getItemCount() > 0);
		deselectAllButton.setEnabled(enabled
				&& typesViewer.getTree().getItemCount() > 0);

		anyResourceButton.setEnabled(enabled);
		anyResourceInSameProjectButton.setEnabled(enabled);
		selectedResourceButton.setEnabled(enabled);
		selectedResourceAndChildrenButton.setEnabled(enabled);
		workingSetGroup.setEnabled(enabled);
	}

	/**
	 * Updates the given filter from the UI state.
	 */
	protected final void updateFilterFromUI() {

		MarkerFilter filter = getSelectedFilter();

		if (filter == null) {
			updateEnabledState(false);
			return;
		}

		updateFilterFromUI(filter);
	}

	/**
	 * Update the selected filter from the UI.
	 * 
	 * @param filter
	 */
	protected void updateFilterFromUI(MarkerFilter filter) {

		filter.setSelectedTypes(getSelectedTypes());

		if (selectedResourceButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_SELECTED_ONLY);
		else if (selectedResourceAndChildrenButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_SELECTED_AND_CHILDREN);
		else if (anyResourceInSameProjectButton.getSelection())
			filter.setOnResource(MarkerFilter.ON_ANY_IN_SAME_CONTAINER);
		else if (workingSetGroup.getSelection())
			filter.setOnResource(MarkerFilter.ON_WORKING_SET);
		else
			filter.setOnResource(MarkerFilter.ON_ANY);

		filter.setWorkingSet(workingSetGroup.getWorkingSet());
	}

	/**
	 * Updates the UI state from the given filter.
	 */
	protected final void updateUIFromFilter() {

		MarkerFilter filter = getSelectedFilter();

		if (filter == null) {
			updateEnabledState(false);
			return;
		}

		updateUIWithFilter(filter);
	}

	/**
	 * Update the UI with the contents of filter.
	 * 
	 * @param filter
	 */
	protected void updateUIWithFilter(MarkerFilter filter) {
		setSelectedTypes(filter.getSelectedTypes());

		int on = filter.getOnResource();
		anyResourceButton.setSelection(on == MarkerFilter.ON_ANY);
		anyResourceInSameProjectButton
				.setSelection(on == MarkerFilter.ON_ANY_IN_SAME_CONTAINER);
		selectedResourceButton
				.setSelection(on == MarkerFilter.ON_SELECTED_ONLY);
		selectedResourceAndChildrenButton
				.setSelection(on == MarkerFilter.ON_SELECTED_AND_CHILDREN);
		workingSetGroup.setSelection(on == MarkerFilter.ON_WORKING_SET);
		workingSetGroup.setWorkingSet(filter.getWorkingSet());

		updateEnabledState(true);
	}

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

	/**
	 * Set the marker filter.
	 * 
	 * @param newFilter
	 */
	public void setFilter(MarkerFilter newFilter) {
		setFilters(new MarkerFilter[] { newFilter });
		updateUIFromFilter();
	}

	/**
	 * @return the MarkerFilter associated with the dialog.
	 */
	public MarkerFilter[] getFilters() {
		return filters;
	}

	/**
	 * A selection has occured on one of the checkboxes or combos. Update.
	 * 
	 */
	protected void updateForSelection() {
		updateEnabledState(true);
		markDirty();
	}

	/**
	 * Get all of the marker types avilable for the filter
	 * 
	 * @param selected
	 * @return Object[]
	 */
	Object[] getRootEntries(MarkerFilter selected) {

		List roots = selected.getRootTypes();
		List markerNodes = new ArrayList();
		HashMap categories = new HashMap();
		for (int i = 0; i < roots.size(); i++) {
			Object obj = roots.get(i);
			buildTypeTree(markerNodes, obj, categories);
		}
		return markerNodes.toArray();
	}

	/**
	 * Build the list of types and categories from the supplied object
	 * 
	 * @param elements
	 * @param obj
	 * @param categories
	 */
	private void buildTypeTree(List elements, Object obj, HashMap categories) {
		if (obj instanceof MarkerType) {

			MarkerType markerType = (MarkerType) obj;

			String categoryName = MarkerSupportRegistry.getInstance()
					.getCategory(markerType.getId());

			if (categoryName == null) {
				elements.add(new MarkerTypeNode(markerType));
			} else {
				MarkerCategory category;
				if (categories.containsKey(categoryName))
					category = (MarkerCategory) categories.get(categoryName);
				else {
					category = new MarkerCategory(categoryName);
					categories.put(categoryName, category);
					elements.add(category);
				}
				MarkerTypeNode node = new MarkerTypeNode(markerType);
				category.add(node);
			}

			MarkerType[] subTypes = ((MarkerType) obj).getAllSubTypes();
			for (int j = 0; j < subTypes.length; j++) {
				buildTypeTree(elements, subTypes[j], categories);
			}
		}
	}

	/**
	 * Grey check the parent if required
	 * 
	 * @param element
	 * @param checked
	 */
	private void setParentCheckState(Object element, boolean checked) {
		Object parent = typesContentProvider.getParent(element);
		if (parent == null)
			return;
		Object[] children = typesContentProvider.getChildren(parent);
		if (children.length == 0)
			return;
		if (checked) {// at least one is checked
			for (int i = 0; i < children.length; i++) {
				Object object = children[i];
				if (!typesViewer.getChecked(object)) {
					typesViewer.setGrayChecked(parent, true);
					return;
				}
			}
			// All checked - check the parent
			typesViewer.setChecked(parent, true);
		} else {
			for (int i = 0; i < children.length; i++) {
				Object object = children[i];
				if (typesViewer.getChecked(object)) {
					typesViewer.setGrayChecked(parent, true);
					return;
				}
			}
			// All checked - check the parent
			typesViewer.setChecked(parent, false);
		}
	
	}

	/**
	 * Set the check state of the children of element to checked.
	 * 
	 * @param element
	 * @param checked
	 */
	private void setChildrenChecked(Object element, boolean checked) {
		Object[] children = typesContentProvider.getChildren(element);
		if (children.length > 0) {
			for (int i = 0; i < children.length; i++) {
				typesViewer.setChecked(children[i], checked);
			}
		}
	}

}
