/*******************************************************************************
 * Copyright (c) 2001, 2009 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.wst.validation.ui.internal.preferences;

import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
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.custom.ScrolledComposite;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
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.TableItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.wst.validation.Validator;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.GlobalConfiguration;
import org.eclipse.wst.validation.internal.ProjectConfiguration;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValPrefManagerProject;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.ValidatorMutable;
import org.eclipse.wst.validation.internal.ValManager.UseProjectPreferences;
import org.eclipse.wst.validation.internal.model.ProjectPreferences;
import org.eclipse.wst.validation.internal.operations.ValidatorManager;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.ui.DelegatingValidatorPreferencesDialog;
import org.eclipse.wst.validation.internal.ui.plugin.ValidationUIPlugin;
import org.eclipse.wst.validation.ui.internal.HelpContextIds;
import org.eclipse.wst.validation.ui.internal.ImageNames;
import org.eclipse.wst.validation.ui.internal.ValUIMessages;
import org.eclipse.wst.validation.ui.internal.dialog.FilterDialog;

/**
 * From this page the user can configure individual validators on individual projects.
 * 
 * @author karasiuk
 */
public class ValidationPropertyPage extends PropertyPage  {

	private IValidationPage _pageImpl;
	private Shell 			_shell;

	public interface IValidationPage {
		
		Composite createPage(Composite parent) throws InvocationTargetException;
		boolean performOk() throws InvocationTargetException;
		boolean performDefaults() throws InvocationTargetException;
		Composite getControl();
		void dispose();
		void loseFocus();
		void gainFocus();
	}

	public class InvalidPage implements IValidationPage {
		
		private Composite page = null;
		private Composite composite = null;
		private GridLayout layout = null;
		private Label messageLabel = null;

		public InvalidPage(Composite parent) {
			page = createPage(parent);
		}

		/**
		 * This page is added to the Properties guide if some internal problem
		 * occurred; for example, the highlighted item in the workbench is not
		 * an IProject (according to this page's plugin.xml, this page is only
		 * valid when an IProject is selected).
		 */
		public Composite createPage(Composite parent) {
			noDefaultAndApplyButton();

			final ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
			sc1.setLayoutData(new GridData(GridData.FILL_BOTH));
			composite = new Composite(sc1, SWT.NONE);
			sc1.setContent(composite);
			layout = new GridLayout();
			composite.setLayout(layout);

			messageLabel = new Label(composite, SWT.NONE);
			messageLabel.setText(ValUIMessages.VBF_EXC_INVALID_REGISTER);

			composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

			return composite;
		}

		public boolean performDefaults() {
			return true;
		}

		/**
		 * Since this page occurs under invalid circumstances, there is nothing
		 * to save.
		 */
		public boolean performOk() {
			return true;
		}

		public Composite getControl() {
			return page;
		}

		public void dispose() {
			messageLabel.dispose();
			// layout.dispose();
			composite.dispose();
		}

		public void loseFocus() {
		}

		public void gainFocus() {
		}
	}

	private final class ValidatorListPage implements IValidationPage {
		private Composite 		_page;

		private TableViewer 	_validatorList;
		private Button 			_enableAllButton;
		private Button 			_disableAllButton;
		private Button 			_override;
		private Button 			_suspend;
		private Link			_configLink;
		private Button			_addValidationBuilder;
		private Table 			_validatorsTable;
		private ValidatorMutable[]		_validators;
		
		/** Number of things that may have changed. */
		private int				_changes;

		/**
		 * This class is provided for the CheckboxTableViewer in the
		 * ValidationPropertiesPage$ValidatorListPage class.
		 */
		public class ValidationContentProvider implements IStructuredContentProvider {
			public void dispose() {
			}

			public Object[] getElements(Object inputElement) {
				if (inputElement instanceof ValidatorMutable[]) {
					return (ValidatorMutable[]) inputElement;
				}
				return new Object[0];
			}

			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			}
		}

		/**
		 * This class is provided for
		 * ValidationPropertiesPage$ValidatorListPage's checkboxTableViewer
		 * element.
		 */
		public class ValidationLabelProvider extends LabelProvider implements ITableLabelProvider {
			public String getText(Object element) {
				if (element == null)return ""; //$NON-NLS-1$
				else if (element instanceof Validator)
					return ((ValidatorMutable) element).getName();
				else
					return super.getText(element);
			}

			private Image getImage(String imageName) {
				boolean isDisabled = !_validatorsTable.isEnabled();
				if (isDisabled)
					imageName = imageName + ImageNames.disabled;

				return ValidationUIPlugin.getPlugin().getImage(imageName);
			}

			public Image getColumnImage(Object element, int columnIndex) {
				ValidatorMutable v = (ValidatorMutable) element;
				if (columnIndex == 1) {
					return getImage(v.isManualValidation() ? ImageNames.okTable
							: ImageNames.failTable);
				} else if (columnIndex == 2) {
					return getImage(v.isBuildValidation() ? ImageNames.okTable
							: ImageNames.failTable);
				} else if (columnIndex == 3) {
					if (hasSettings(v))return getImage(ImageNames.settings);
					return  null;
				}
				return null;
			}

			public String getColumnText(Object element, int columnIndex) {
				if (columnIndex == 0)return ((ValidatorMutable) element).getName();
				return null;
			}
		}

		public ValidatorListPage(Composite parent) throws InvocationTargetException {
			_page = createPage(parent);
		}

		private void setupTableColumns(Table table) {
			TableColumn validatorColumn = new TableColumn(table, SWT.NONE);
			validatorColumn.setText(ValUIMessages.VALIDATOR);
			validatorColumn.setWidth(245);
			TableColumn manualColumn = new TableColumn(table, SWT.CENTER);
			manualColumn.setText(ValUIMessages.MANUAL);
			manualColumn.pack();
			TableColumn buildColumn = new TableColumn(table, SWT.CENTER);
			buildColumn.setText(ValUIMessages.BUILD);
			buildColumn.pack();
			TableColumn settingsColumn = new TableColumn(table, SWT.CENTER);
			settingsColumn.setText(ValUIMessages.SETTINGS);
			settingsColumn.pack();
		}

		public Composite createPage(Composite parent) throws InvocationTargetException {
			Validator[] vals = ValManager.getDefault()
				.getValidatorsConfiguredForProject(getProject(), UseProjectPreferences.MustUse);
			_validators = new ValidatorMutable[vals.length];
			for (int i=0; i<vals.length; i++)_validators[i] = new ValidatorMutable(vals[i]);

			Composite validatorGroup = new Composite(parent, SWT.NONE);

			GridLayout validatorGroupLayout = new GridLayout();
			validatorGroupLayout.numColumns = 2;
			validatorGroup.setLayout(validatorGroupLayout);
			GridDataFactory.fillDefaults().grab(true, true).applyTo(validatorGroup);

			addOverride(validatorGroup);
			addConfigLink(validatorGroup);
			addSuspend(validatorGroup);
			addValidationBuilder(validatorGroup);
			new Label(validatorGroup, SWT.NONE).setLayoutData(new GridData());

			Label listLabel = new Label(validatorGroup, SWT.NONE);
			GridData listLabelData = new GridData(GridData.FILL_HORIZONTAL);
			listLabelData.horizontalSpan = 2;
			listLabel.setLayoutData(listLabelData);
			listLabel.setText(ValUIMessages.PREF_VALLIST_TITLE);
			
			_validatorsTable = new Table(validatorGroup, SWT.BORDER | SWT.FULL_SELECTION);
			Point preferredSize = _validatorsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			GridDataFactory.fillDefaults().grab(true, true).hint(preferredSize)
				.span(2,1).applyTo(_validatorsTable);

			_validatorsTable.setHeaderVisible(true);
			_validatorsTable.setLinesVisible(true);

			_validatorList = new TableViewer(_validatorsTable);
			_validatorList.setLabelProvider(new ValidationLabelProvider());
			_validatorList.setContentProvider(new ValidationContentProvider());
			_validatorList.setSorter(new ViewerSorter());
			setupTableColumns(_validatorsTable);

			_validatorList.setInput(_validators);
			_validatorsTable.addMouseListener(new MouseAdapter() {

				public void mouseDown(MouseEvent e) {
					if (e.button != 1)return;

					TableItem tableItem = _validatorsTable.getItem(new Point(e.x, e.y));
					if (tableItem == null || tableItem.isDisposed()) {
						// item no longer exists
						return;
					}
					int columnNumber;
					int columnsCount = _validatorsTable.getColumnCount();
					if (columnsCount == 0) {
						// If no TableColumn, Table acts as if it has a single column
						// which takes the whole width.
						columnNumber = 0;
					} else {
						columnNumber = -1;
						for (int i = 0; i < columnsCount; i++) {
							Rectangle bounds = tableItem.getBounds(i);
							if (bounds.contains(e.x, e.y)) {
								columnNumber = i;
								break;
							}
						}
						if (columnNumber == -1)return;
					}

					columnClicked(columnNumber);
				}
			});

			_validatorsTable.setMenu(createContextMenu());
			_validatorsTable.addFocusListener(new FocusAdapter() {

				public void focusGained(FocusEvent e) {
					super.focusGained(e);
					if (_validatorsTable.getSelectionCount() == 0) {
						_validatorsTable.select(0);
					}
				}
			});
			
			addButtons(validatorGroup);

			updateWidgets();

			applyDialogFont(validatorGroup);
			validatorGroup.setSize(validatorGroup.computeSize(SWT.DEFAULT, SWT.DEFAULT));

			return validatorGroup;
		}

		private void addButtons(Composite validatorGroup) {
			
			Composite buttons = new Composite(validatorGroup, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			buttons.setLayout(new RowLayout());
			
			_enableAllButton = new Button(buttons, SWT.PUSH);
			_enableAllButton.setText(ValUIMessages.PREF_BUTTON_ENABLEALL);
			_enableAllButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					try {
						performEnableAll();
					} catch (InvocationTargetException exc) {
						displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE,ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
					}
				}
			});

			_disableAllButton = new Button(buttons, SWT.PUSH);
			_disableAllButton.setText(ValUIMessages.PREF_BUTTON_DISABLEALL);
			_disableAllButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					try {
						performDisableAll();
					} catch (InvocationTargetException exc) {
						displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE, ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
					}
				}
			});
		}

		private void addSuspend(Composite validatorGroup) {
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			_suspend = new Button(validatorGroup, SWT.CHECK);
			_suspend.setLayoutData(gd);
			_suspend.setText(ValUIMessages.DISABLE_VALIDATION);
			_suspend.setSelection(getProjectPreferences().getSuspend());
			_suspend.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					_suspend.setFocus();
					_changes++;
					enableDisableWidgets();
					_validatorList.refresh();
				}
			});
		}
		
		private void addConfigLink(Composite validatorGroup){
			_configLink = new Link(validatorGroup,SWT.None);
			GridData layout = new GridData(GridData.HORIZONTAL_ALIGN_END);
			_configLink.setLayoutData(layout);
			_configLink.setText("<A>"+ //$NON-NLS-1$
				ValUIMessages.ConfigWsSettings+"</A>"); //$NON-NLS-1$
			_configLink.addSelectionListener(new SelectionListener() {
				public static final String DATA_NO_LINK = "PropertyAndPreferencePage.nolink"; //$NON-NLS-1$

				public void doLinkActivated(Link e) {
					String id = getPreferencePageID();
					PreferencesUtil.createPreferenceDialogOn(getShell(), id, new String[]{id}, DATA_NO_LINK).open();
					try {
						updateWidgets();
					} catch (InvocationTargetException ie) {

					}
				}

				private String getPreferencePageID() {
					return "ValidationPreferencePage"; //$NON-NLS-1$
				}

				public void widgetDefaultSelected(SelectionEvent e) {
					doLinkActivated((Link) e.widget);					
				}

				public void widgetSelected(SelectionEvent e) {
					doLinkActivated((Link) e.widget);					
				}
			});
			
		}
		
		/**
		 * If the current project doesn't have the validation builder configured on it, 
		 * and the user has asked us to add a builder, add the builder. 
		 * Otherwise return without doing anything.
		 */
		private void addBuilder() {
			if (_addValidationBuilder != null && _addValidationBuilder.getSelection())
				ValidatorManager.addProjectBuildValidationSupport(getProject());
		}

		
		private void addValidationBuilder(Composite validatorGroup) {
			if (hasValidationBuilder())return;
			
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			_addValidationBuilder = new Button(validatorGroup, SWT.CHECK);
			_addValidationBuilder.setLayoutData(gd);
			_addValidationBuilder.setText(ValUIMessages.ADD_VALIDATION_BUILDER);
			_addValidationBuilder.setSelection(false);
		}
				
		/**
		 * Does this validator have extra settings that can be configured?
		 * @param v
		 * @return true if it does
		 */
		boolean hasSettings(ValidatorMutable v){
			if (v.isV2Validator())return true;
			if (v.getDelegatingId() != null)return true;
			return false;
		}

		/**
		 * Answer if this project has a validator builder assigned to it.
		 */
		private boolean hasValidationBuilder(){
			try {
				IProjectDescription description = getProject().getDescription();
				ICommand[] commands = description.getBuildSpec();
				for (int i = 0; i < commands.length; i++) {
					if (commands[i].getBuilderName().equals(ValidationPlugin.VALIDATION_BUILDER_ID))
						return true;
				}
				return false;
			}
			catch (CoreException e){
				ValidationPlugin.getPlugin().handleException(e);
			}
			return false;
		}


		private void addOverride(Composite validatorGroup) {
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
//			gd.horizontalSpan = 2;
			_override = new Button(validatorGroup, SWT.CHECK);
			_override.setLayoutData(gd);
			_override.setText(ValUIMessages.LabelEnableProjectSpecific);
			_override.setSelection(getProjectPreferences().getOverride());
			_override.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					_override.setFocus();
					_changes++;
					ValManager vm = ValManager.getDefault();
					if (vm.getGlobalPreferences().getOverride()){
//						IProject project = getProject();
//						UseProjectPreferences useProject = UseProjectPreferences.Normal;
//						if (_override.getSelection())useProject = UseProjectPreferences.MustUse;
//						_validators = copyValidators(vm.getValidatorsConfiguredForProject(project, useProject));
//						_validatorList.setInput(_validators);
						enableDisableWidgets();
						_validatorList.refresh();
					}
					else {
						MessageDialog.openWarning(_shell, ValUIMessages.Validation, 
							ValUIMessages.ProjectOverridesNotAllowed);						
					}
				}

			});
		}

		protected Menu createContextMenu() {
			final Menu menu = new Menu(_validatorsTable.getShell(), SWT.POP_UP);
			final MenuItem manualItem = new MenuItem(menu, SWT.CHECK);
			manualItem.setText(ValUIMessages.PREF_MNU_MANUAL);
			final MenuItem buildItem = new MenuItem(menu, SWT.CHECK);
			buildItem.setText(ValUIMessages.PREF_MNU_BUILD);
			final MenuItem settingsItem = new MenuItem(menu, SWT.PUSH);
			settingsItem.setText(ValUIMessages.PREF_MNU_SETTINGS);

			class MenuItemListener extends SelectionAdapter {
				public void widgetSelected(SelectionEvent e) {
					MenuItem menuItem = (MenuItem) e.getSource();
					int index = menu.indexOf(menuItem) + 1;
					columnClicked(index);
				}
			}
			MenuItemListener listener = new MenuItemListener();
			manualItem.addSelectionListener(listener);
			buildItem.addSelectionListener(listener);
			settingsItem.addSelectionListener(listener);

			menu.addMenuListener(new MenuAdapter() {
				public void menuShown(MenuEvent e) {
					IStructuredSelection selection = (IStructuredSelection) _validatorList.getSelection();
					ValidatorMutable val = (ValidatorMutable) selection.getFirstElement();
					manualItem.setSelection(val.isManualValidation());
					buildItem.setSelection(val.isBuildValidation());
					settingsItem.setEnabled(hasSettings(val));
				}
			});

			return menu;
		}

		protected void columnClicked(int columnToEdit) {
			IStructuredSelection selection = (IStructuredSelection) _validatorList.getSelection();
			ValidatorMutable val = (ValidatorMutable) selection.getFirstElement();

			switch (columnToEdit) {
			case 1:
				val.setManualValidation(!val.isManualValidation());
				break;
			case 2:
				val.setBuildValidation(!val.isBuildValidation());
				break;
			case 3:
				if (val.isV2Validator()){
					ValidatorMutable newVal = new ValidatorMutable(val);
					FilterDialog fd = new FilterDialog(_shell, newVal, getProject());
					if (Window.OK == fd.open()){
						_changes++;
						newVal = fd.getValidator();
						int i = findit(val);
						if (i != -1)_validators[i] = newVal;
					}
				}
				else {
					handleOldDelegate(val);
				}

				break;
			default:
				break;
			}
			_validatorList.refresh();
		}

		private int findit(ValidatorMutable val) {
			for (int i=0; i<_validators.length; i++)if (_validators[i] == val)return i;
			return -1;
		}
		
		private void handleOldDelegate(ValidatorMutable val) {
			try {
				if (!val.isV1Validator())return;
				
				ValidatorMetaData vmd = val.getVmd();
			    if (!vmd.isDelegating())return;
			    
			    GlobalConfiguration gc = ConfigurationManager.getManager().getGlobalConfiguration();
			    String delegateID = gc.getDelegateUniqueName(vmd);
			    Shell shell = Display.getCurrent().getActiveShell();
			    DelegatingValidatorPreferencesDialog dialog = 
			    	new DelegatingValidatorPreferencesDialog(shell, vmd, delegateID);
			
			    dialog.setBlockOnOpen(true);
			    dialog.create();
			
			    int result = dialog.open();
		        if (result == Window.OK){
		        	_changes++;
		        	gc.setDelegateUniqueName(vmd, dialog.getDelegateID());
		        }
			}
			catch (InvocationTargetException e){
				
			}
		}

		protected void updateWidgets() throws InvocationTargetException {
			// Need to update even the widgets that do not change based on another
			// widgets because of performDefaults(). If performDefaults() is selected,
			// then the pagePreferences values are reset, and these widgets
			// might also need to be updated.
			updateAllWidgets();
			updateHelp();
		}

		protected void updateWidgetsForDefaults() throws InvocationTargetException {
			_suspend.setSelection(false);
			_override.setSelection(false);
			enableDisableWidgets();
			_validatorList.setInput(_validators);
			_validatorList.refresh();
		}

		private void updateAllWidgets() throws InvocationTargetException {
			_suspend.setSelection(getProjectPreferences().getSuspend());
			_override.setSelection(getProjectPreferences().getOverride());
			enableDisableWidgets();
			_validatorList.setInput(_validators);
			_validatorList.refresh();
		}

		public boolean performOk() throws InvocationTargetException {
			
			addBuilder();
			for (ValidatorMutable vm : _validators)if (vm.isChanged())_changes++;
			if (_changes == 0)return true;
			// [213631] this warning should only be shown if the user actually tried to override
			// the validators
			if (!ValManager.getDefault().getGlobalPreferences().getOverride() && _override.getSelection()){
				MessageDialog.openWarning(_shell, ValUIMessages.Validation, ValUIMessages.ProjectOverridesNotAllowed);
				return false;
			}
			updateV1ProjectSettings();
			IProject project = getProject();
			ProjectPreferences pp = new ProjectPreferences(project, _override.getSelection(), _suspend.getSelection(), null);
			ValPrefManagerProject vpm = new ValPrefManagerProject(project);
			vpm.savePreferences(pp, _validators);
			return true;
		}
		
		/**
		 * Update the version 1 project settings.
		 */
		private void updateV1ProjectSettings() {
			try {
				ProjectConfiguration pc = ConfigurationManager.getManager().getProjectConfiguration(getProject());
				pc.setDoesProjectOverride(_override.getSelection());
				pc.setDisableAllValidation(_suspend.getSelection());
			}
			catch (InvocationTargetException e){
				ValidationPlugin.getPlugin().handleException(e);
			}			
		}

		/**
		 * Answer the specific project preferences. If the project didn't have any specific project
		 * preferences, then create a default set.
		 * @return
		 */
		private ProjectPreferences getProjectPreferences(){
			return ValManager.getDefault().getProjectPreferences(getProject());
		}

		public boolean performDefaults() throws InvocationTargetException {
			Validator[] vals = ValManager.getDefault()
				.getValidatorsConfiguredForProject(getProject(), UseProjectPreferences.MustNotUse);
			_validators = new ValidatorMutable[vals.length];
			for (int i=0; i<vals.length; i++)_validators[i] = new ValidatorMutable(vals[i]);

			_changes++;
			updateWidgetsForDefaults();
			getDefaultsButton().setFocus();
			return true;
		}

		public boolean performEnableAll() throws InvocationTargetException {
			setAllValidators(true);
			_enableAllButton.setFocus();
			_validatorList.refresh();
			return true;
		}

		private void setAllValidators(boolean bool) {
			for (TableItem item : _validatorsTable.getItems()) {
				ValidatorMutable val = (ValidatorMutable) item.getData();
				val.setManualValidation(bool);
				val.setBuildValidation(bool);
			}
		}

		public boolean performDisableAll() throws InvocationTargetException {
			setAllValidators(false);
			_disableAllButton.setFocus();
			_validatorList.refresh();
			return true;
		}

		protected void updateHelp() {
//			PlatformUI.getWorkbench().getHelpSystem().setHelp(_suspend, ContextIds.VALIDATION_PREFERENCE_PAGE_DISABLE_ALL_ENABLED);
		}

		/*
		 * Store the current values of the controls into the preference store.
		 */

		public Composite getControl() {
			return _page;
		}

		public void dispose() {
			_override.dispose();
			_suspend.dispose();
			_configLink.dispose();
			_disableAllButton.dispose();
			_enableAllButton.dispose();
			_validatorList.getTable().dispose();
		}
		
		/**
		 * Enable or disable the widgets based on some top level preferences. 
		 */
		private void enableDisableWidgets() {
			boolean globalOverride = ValManager.getDefault().getGlobalPreferences().getOverride();
			boolean enable = !_suspend.getSelection() & _override.getSelection() & globalOverride;
			_suspend.setEnabled(_override.getSelection() & globalOverride);
			_validatorsTable.setEnabled(enable);
			_enableAllButton.setEnabled(enable);
			_disableAllButton.setEnabled(enable);
			_configLink.setEnabled(!globalOverride || !_override.getSelection());
		}

		public void loseFocus() {
			// This page does not need to cache anything before it loses focus.
		}

		public void gainFocus() {
		}
	}

	protected Control createContents(Composite parent) {
		try {
			PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, HelpContextIds.ProjectPage);
			_shell = parent.getShell();
			_pageImpl = new ValidatorListPage(parent);
		} catch (Exception exc) {
			_pageImpl = new InvalidPage(parent);
			displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE, ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
		}

		return _pageImpl.getControl();
	}

	protected void performDefaults() {
		super.performDefaults();

		try {
			_pageImpl.performDefaults();
		} catch (Exception exc) {
			displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE, ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
		}
	}

	public boolean performOk() {
		try {
			return _pageImpl.performOk();
		} catch (Exception exc) {
			displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE, ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
			return false;
		}
	}

	/**
	 * Since the pages are inner classes of a child PreferencePage, not a
	 * PreferencePage itself, DialogPage's automatic disposal of its children's
	 * widgets cannot be used. Instead, dispose of each inner class' widgets
	 * explicitly.
	 */
	public void dispose() {
		super.dispose();
		try {
			if (_pageImpl != null) {
				_pageImpl.dispose();
				_pageImpl = null;
			}
		} catch (Exception exc) {
			displayAndLogError(ValUIMessages.VBF_EXC_INTERNAL_TITLE, ValUIMessages.VBF_EXC_INTERNAL_PAGE, exc);
		}
	}

	private void logError(Throwable exc) {
		ValidationUIPlugin.getPlugin().handleException(exc);
	}

	/*
	 * package visibility because if this method is private, then the compiler
	 * needs to create a synthetic accessor method for the internal classes, and
	 * that can have performance implications.
	 */
	void displayAndLogError(String title, String message, Throwable exc) {
		logError(exc);
		displayMessage(title, message, org.eclipse.swt.SWT.ICON_ERROR);
	}

	private void displayMessage(String title, String message, int iIconType) {
		MessageBox messageBox = new MessageBox(getShell(),
			org.eclipse.swt.SWT.OK | iIconType | org.eclipse.swt.SWT.APPLICATION_MODAL);
		messageBox.setMessage(message);
		messageBox.setText(title);
		messageBox.open();
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
	 */
	public void setVisible(boolean visible) {
		super.setVisible(visible);

		if (_pageImpl == null)return;
		if (visible)_pageImpl.gainFocus();
		else _pageImpl.loseFocus();
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#getDefaultsButton()
	 */
	protected Button getDefaultsButton() {
		return super.getDefaultsButton();
	}
	
	/**
	 * Returns the selected project.
	 */
	public IProject getProject() {
		IAdaptable selectedElement = getElement();
		if (selectedElement == null)return null;
		if (selectedElement instanceof IProject)return (IProject) selectedElement;

		Object adaptedObject = selectedElement.getAdapter(IProject.class);
		if (adaptedObject instanceof IProject)return (IProject) adaptedObject;
		return null;

	}
}
