package org.eclipse.epf.authoring.ui.forms;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIImages;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.ConfigurationEditor;
import org.eclipse.epf.authoring.ui.editors.ConfigurationEditorInput;
import org.eclipse.epf.authoring.ui.providers.CategoryContentProvider;
import org.eclipse.epf.authoring.ui.providers.CategoryLabelProvider;
import org.eclipse.epf.authoring.ui.providers.ConfigPackageContentProvider;
import org.eclipse.epf.authoring.ui.providers.ConfigPackageLabelProvider;
import org.eclipse.epf.authoring.ui.providers.HideUncheckedViewerFilter;
import org.eclipse.epf.authoring.ui.util.AuthoringAccessibleListener;
import org.eclipse.epf.authoring.ui.util.ConfigurationMarkerHelper;
import org.eclipse.epf.authoring.ui.views.MethodContainerCheckedTreeViewer;
import org.eclipse.epf.authoring.ui.views.MethodContainerCheckedTreeViewer2;
import org.eclipse.epf.library.IConfigurationManager;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationData;
import org.eclipse.epf.library.configuration.ConfigurationProperties;
import org.eclipse.epf.library.configuration.closure.ClosureListener;
import org.eclipse.epf.library.configuration.closure.ConfigurationClosure;
import org.eclipse.epf.library.configuration.closure.IConfigurationError;
import org.eclipse.epf.library.edit.IPluginUIPackageContextChangedListener;
import org.eclipse.epf.library.edit.PluginUIPackageContext;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.MethodElementSetPropertyCommand;
import org.eclipse.epf.library.edit.navigator.ConfigPageCategoriesItemProvider;
import org.eclipse.epf.library.edit.navigator.ContentItemProvider;
import org.eclipse.epf.library.edit.navigator.MethodPackagesItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ConfigurationUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.MethodElementUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.ui.util.SWTUtil;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.ide.IGotoMarker;

public class ConfigurationPage extends FormPage implements IGotoMarker {
	
	public static final String TOUCHED_BY_CONFIG_EDITOR = "TouchedByConfigEditor";	//$NON-NLS-1$	
	
	private String formPrefix = AuthoringUIResources.ConfigurationPage_FormPrefix; 

	private MethodConfiguration config = null;
	private ConfigurationClosure closure = null;
	
	private MethodContainerCheckedTreeViewer configViewer;
	private ConfigPackageContentProvider contProvider;
	private ConfigPackageLabelProvider labelProvider;

	private MethodContainerCheckedTreeViewer2 addCategoryViewer;
	private MethodContainerCheckedTreeViewer2 subCategoryViewer;
	
	private HideUncheckedViewerFilter configViewerHideUncheckedFilter;
	private HideUncheckedViewerFilter addCategoryHideUncheckedFilter;
	private HideUncheckedViewerFilter subCategoryHideUncheckedFilter;
	

	private ComposedAdapterFactory adapterFactory = TngAdapterFactory.INSTANCE.createConfigPage_LibraryComposedAdapterFactory();

	private ILibraryChangeListener libListener = null;
	
	private static final ConfigurationMarkerHelper markerHelper = ConfigurationMarkerHelper.INSTANCE;
	boolean isDirty = false;
	protected ISelection currentSelection = StructuredSelection.EMPTY;

	private IActionManager actionMgr;
	ScrolledForm form = null;
	private Button updateOnClick;
	private Button noUpdateOnClick;
	private Button closureButton;
	private Button fixWarningButton;
	private Button refreshButton;
	private Button hideButton;
	private Text elemDespContentText;

	private ConfigurationProperties configProperties;
	private Button hideErrorButton;
	private Button hideWarnButton;
	private Button hideInfoButton;

	private ShowErrorJob showErrorJob = new ShowErrorJob(AuthoringUIResources.Configuration_Problem_Refresh); //$NON-NLS-1$

	protected ISelectionChangedListener treeSelectionListener = new ISelectionChangedListener() {
		/**
		 *	Handles the selection of an item in the tree viewer
		 *
		 *	@param event ISelection
		 */
		public void selectionChanged(final SelectionChangedEvent event) {
			BusyIndicator.showWhile(ConfigurationPage.this.getSite().getShell().getDisplay(), new Runnable() {
				public void run() {
					IStructuredSelection selection= (IStructuredSelection) event.getSelection();
					Object selectedElement= selection.getFirstElement();
					selectedElement = TngUtil.unwrap(selectedElement);
					if (selectedElement == null) {
						return;
					} else if (elemDespContentText != null && selectedElement instanceof MethodElement) {
						// display selected element's description
						String briefDesc = ((MethodElement) selectedElement).getBriefDescription();
						elemDespContentText.setText(briefDesc != null ? briefDesc : ""); //$NON-NLS-1$
					}
				}
			});
		}
	};

	private static final ClosureListener closureListener = new ClosureListener() {
		@Override
		public void errorAdded(MethodConfiguration config, IConfigurationError error) {
			IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config);
			if (configMgr.getConfigurationProperties().toHide(error)) {
				return;
			}
			markerHelper.createMarker(config, error);
		}

		@Override
		public void errorRemoved(MethodConfiguration config, IConfigurationError error) {
			markerHelper.deleteMarker(config, error);
		}

		@Override
		public void errorUpdated(MethodConfiguration config, IConfigurationError error) {
			markerHelper.adjustMarker(null, config, error);
		}
	};

	private IPluginUIPackageContextChangedListener layoutListener = new IPluginUIPackageContextChangedListener() {
		public void layoutChanged(boolean isFlat) {
			refreshViewers();
		}
	};

	/**
	 * Creates an instance
	 * @param editor
	 */
	public ConfigurationPage(FormEditor editor) {
		super(editor, AuthoringUIResources.ConfigurationPage_Description1, 
				AuthoringUIResources.ConfigurationPage_Description2); 
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
	 */
	protected void createFormContent(IManagedForm managedForm) {
		// create form toolkit
		form = managedForm.getForm();
		form.setText(formPrefix + config.getName());
		FormToolkit toolkit = managedForm.getToolkit();

		TableWrapLayout layout = new TableWrapLayout();
		form.getBody().setLayout(layout);

		Section treeSection = toolkit.createSection(form.getBody(),
				Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED
						| Section.TITLE_BAR);
		treeSection.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
		treeSection.setText(AuthoringUIResources.ConfigurationPage_ConfigContent); 
		treeSection.setDescription(AuthoringUIResources.ConfigurationPage_ConfigContentDescription); 
		treeSection.setLayout(new GridLayout());
		
		createContent(toolkit, treeSection);
		
		addListeners();

		// finally set the input.
		setInput(LibraryService.getInstance().getCurrentMethodLibrary());
		
		initializeViewersSelection();
	}

	
	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		setSite(site);
		setInput(input);

		ConfigurationEditorInput configInput = (ConfigurationEditorInput) input;
		config = configInput.getConfiguration();
		actionMgr = ((ConfigurationEditor) getEditor()).getActionManager();
		configProperties = LibraryService.getInstance()
		.getConfigurationManager(config).getConfigurationProperties();
	}

	/**
	 * Create tree content
	 * @param toolkit
	 * @param section
	 */
	public void createContent(FormToolkit toolkit, Section section) {
		Composite sectionClient = toolkit.createComposite(section);
		sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH));
		section.setClient(sectionClient);
		GridLayout layout = new GridLayout(2, true);
		sectionClient.setLayout(layout);

		PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sectionClient.getParent(),
				AuthoringUIHelpContexts.CONFIGURATION_EDITOR_ALL_CONTEXT);

		Composite buttonComposite = toolkit.createComposite(sectionClient);
		GridLayout gridLayout = new GridLayout(6, false);
		buttonComposite.setLayout(gridLayout);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		gridData.horizontalSpan = 2;
		buttonComposite.setLayoutData(gridData);
		
		Composite radioComposite = toolkit.createComposite(buttonComposite);
		gridLayout = new GridLayout();
		radioComposite.setLayout(gridLayout);
		gridData = new GridData(GridData.FILL_BOTH);
		gridData.horizontalSpan = 1;
		radioComposite.setLayoutData(gridData);
		
		
		updateOnClick = toolkit.createButton(radioComposite, AuthoringUIResources.ConfigurationPage_updateOnClick, SWT.RADIO);
		updateOnClick.setToolTipText(AuthoringUIResources.ConfigurationPage_updateOnClickToolTip); 
		updateOnClick.setLayoutData(new GridData(SWT.BEGINNING, SWT.DEFAULT, false, false));
		updateOnClick.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.ConfigurationPage_updateOnClickToolTip));
		
		noUpdateOnClick = toolkit.createButton(radioComposite, AuthoringUIResources.ConfigurationPage_noUpdateOnClick, SWT.RADIO);
		noUpdateOnClick.setToolTipText(AuthoringUIResources.ConfigurationPage_noUpdateOnClickToolTip); 
		noUpdateOnClick.setLayoutData(new GridData(SWT.BEGINNING, SWT.DEFAULT, false, false));
		noUpdateOnClick.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.ConfigurationPage_noUpdateOnClickToolTip));
		noUpdateOnClick.setSelection(true);

		Group group = new Group(buttonComposite, SWT.NONE);
		group.setLayout(new GridLayout(1, false));
		GridData data = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
		group.setLayoutData(data);
		group.setText(AuthoringUIResources.configProblemViewOptionsText);

		hideErrorButton = SWTUtil.createCheckbox(group, AuthoringUIResources.hideErrosText);
		hideWarnButton = SWTUtil.createCheckbox(group, AuthoringUIResources.hideWarningsText);
		hideInfoButton = SWTUtil.createCheckbox(group,AuthoringUIResources.hideInfosText);
		
		hideErrorButton.setSelection(configProperties.isHideErrors());
		hideWarnButton.setSelection(configProperties.isHideWarnings());
		hideInfoButton.setSelection(configProperties.isHideInfos());		

		
		
		hideButton = toolkit.createButton(buttonComposite, "", SWT.PUSH //$NON-NLS-1$
				| GridData.HORIZONTAL_ALIGN_END);
		hideButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"hideUncheckedElem.gif")); //$NON-NLS-1$
		hideButton.setToolTipText(AuthoringUIResources.ConfigurationPage_hideToolTip); 
		hideButton.setLayoutData(new GridData(GridData.END));
		hideButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.ConfigurationPage_hideToolTip));
		
		fixWarningButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		fixWarningButton.setImage(AuthoringUIPlugin.getDefault()
				.getSharedImage("addref_co.gif")); //$NON-NLS-1$
		fixWarningButton.setToolTipText(AuthoringUIResources.ConfigurationPage_AddMissingToolTip); 
		fixWarningButton.setLayoutData(new GridData(GridData.END));
		fixWarningButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.ConfigurationPage_AddMissingToolTip));

		// Add the closure button.
		closureButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		closureButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"closure_co.gif")); //$NON-NLS-1$
		closureButton.setToolTipText(AuthoringUIResources.ConfigurationPage_MakeClosureToolTip); 
		closureButton.setLayoutData(new GridData(GridData.END));
		closureButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.ConfigurationPage_MakeClosureToolTip));
		// closureButton.setText("");

		refreshButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$
		refreshButton.setImage(AuthoringUIImages.IMG_REFRESH);
		refreshButton.setToolTipText(AuthoringUIResources.refreshButton_text);
		{
			GridData gd = new GridData(GridData.END
					| GridData.HORIZONTAL_ALIGN_END);
			gd.horizontalAlignment = 3;
			gd.horizontalSpan = 1;
			refreshButton.setLayoutData(gd);
		}
		refreshButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.refreshButton_text));

		// Create Viewer and Handle Listener for the viewer.
		createViewers(toolkit, sectionClient);

		Label elemDespLabel = toolkit
				.createLabel(sectionClient, AuthoringUIResources.ConfigurationPage_Description); 
		GridData gd1 = new GridData();
		gd1.horizontalSpan = 6;
		elemDespLabel.setLayoutData(gd1);

		elemDespContentText = toolkit.createText(sectionClient, "", SWT.NONE //$NON-NLS-1$
				| SWT.MULTI | SWT.READ_ONLY | SWT.WRAP);
		GridData gd2 = new GridData(GridData.FILL_BOTH);
		gd2.grabExcessHorizontalSpace = true;
		gd2.horizontalSpan = 6;
		gd2.heightHint = 50;

		toolkit.paintBordersFor(sectionClient);
		toolkit.paintBordersFor(buttonComposite);
		elemDespContentText.setLayoutData(gd2);
		
		// set text widget to viewers so they can update description field
		configViewer.addSelectionChangedListener(treeSelectionListener);
		addCategoryViewer.addSelectionChangedListener(treeSelectionListener);
		subCategoryViewer.addSelectionChangedListener(treeSelectionListener);

		hideButton.setEnabled(true);
		hideButton.setVisible(true);
		refreshButton.setEnabled(true);
		refreshButton.setVisible(true);
		fixWarningButton.setEnabled(true);
		fixWarningButton.setVisible(true);
		closureButton.setEnabled(true);
		closureButton.setVisible(true);
	}


	private void initializeViewersSelection() {
		initializeConfigFactory();

    	initConfigViewer();
    	
		// read from config and check the appropriate items in the CC viewers
		List<ContentCategory> addCats = new ArrayList<ContentCategory>(config.getAddedCategory());
		initializeViewerSelection(addCategoryViewer, addCats);
    	List<ContentCategory> subCats = new ArrayList<ContentCategory>(config.getSubtractedCategory());
    	initializeViewerSelection(subCategoryViewer, subCats);
    	
	}

	private void initConfigViewer() {
		List<MethodPackage> packages = new ArrayList<MethodPackage>(config.getMethodPackageSelection());
    	List<MethodPlugin> plugins = new ArrayList<MethodPlugin>(config.getMethodPluginSelection());
    	initializeConfigViewerSelection(configViewer, packages, plugins);
    	setStateForCategoriesUIFolder(configViewer, plugins);
	}
	
	/** 
	 * This method is only meant for configuration viewer since there are lot
	 * of special cases taken care in this.
	 * 
	 * @param viewer
	 * @param packages
	 * @param plugins
	 */
	private void initializeConfigViewerSelection(ContainerCheckedTreeViewer viewer,
			List<MethodPackage> packages, List<MethodPlugin> plugins) {

		// We need to do following 2 lines because viewer.setChecked doesn't
		// work correctly
		// for content packages if viewer setCheckedElements is not run before
		// Somehow setCheckedElements initializes something...
		// for process package viwer.setChecked works fine.
		viewer.setCheckedElements(packages.toArray());
		viewer.setCheckedElements((new ArrayList()).toArray());

		if (!packages.isEmpty()) {
			for (MethodPackage element : packages) {
				try {
					if (!contProvider.hasChildren(element)) {
						viewer.setChecked(element, true);
					}
				} catch (Exception e) {
				}
			}
		}

		// special case for Method Content when plugin is selected but there are
		// no method content packages
		IContentProvider contProvider = viewer.getContentProvider();
		if (contProvider instanceof ConfigPackageContentProvider) {
			ConfigPackageContentProvider configContProvider = (ConfigPackageContentProvider) contProvider;
			for (MethodPlugin plugin : plugins) {
				Object[] children = configContProvider.getChildren(plugin);
				traverse(viewer, children, configContProvider);
			}
		}
	}
	
	
	/**
	 * This traverse is only called for plugins when they are included in the configuration.
	 * This method checks special method packages UI folder if there are no method content  packages and plugin is
	 * selected.
	 * 
	 * @param viewer
	 * @param items
	 * @param configContProvider
	 */
	private void traverse(ContainerCheckedTreeViewer viewer, Object[] items,
			ConfigPackageContentProvider configContProvider) {
		for (Object child: items) {
			Object[] children = configContProvider.getChildren(child);
			if (child instanceof MethodPackagesItemProvider) {
				// for MethodPackages if there are no content pacakges then select this UI folder too if plugin is
				// selected. We only call this traverse method for selected plugins, so you don't need to check again
				// if plugin is selected
				if (children.length == 0) {
					viewer.setChecked(child, true);
				}
				break;
			}
			if (child instanceof ContentItemProvider) {
				// No need to traverse other than contentItem provider
				traverse(viewer, children, configContProvider);
			}
		}
	}

	/**
	 * Set state for categories UI folder.
	 * If plugin is selected, categories UI folder should be selected. There are no methods to disable TreeItem.
	 * We achieve similar look and feel by changing background/foreground color.
	 * @param viewer
	 * @param plugins
	 */
	private void setStateForCategoriesUIFolder(ContainerCheckedTreeViewer viewer, List<MethodPlugin>plugins) {	 	
    	for (MethodPlugin plugin : plugins) {
    		// if plugin is selected then select categories folder as well
    		if (viewer.getGrayed(plugin)) {
    			try {
	    			Object[] children = contProvider.getChildren(plugin);
	    			for (Object child : children) {
	    				if (child instanceof ConfigPageCategoriesItemProvider){
	    					viewer.setChecked(child, true);
	    				}	
    				}
    			}
    			catch (Exception e) {			
    			}
    		}
    		
    		// make categories folder enabled/disbled.
			Tree t = viewer.getTree();
			TreeItem[] items = t.getItems();
			for (TreeItem parent : items) {
				if (parent.getData().equals(plugin)) {
					TreeItem[] childItems = parent.getItems();
					for (TreeItem child : childItems) {
						if (child.getData() instanceof ConfigPageCategoriesItemProvider) {
							if (viewer.getChecked(plugin))
								child.setForeground(ColorConstants.gray);
							else
								child.setForeground(ColorConstants.black);
						}
					}
				}
			}
    	}
	}
	
	private void initializeViewerSelection(ContainerCheckedTreeViewer viewer, List<? extends Object> elements) {
		if (!elements.isEmpty())
			viewer.setCheckedElements(elements.toArray());
	}

	private void createViewers(FormToolkit toolkit, Composite sectionClient) {
		Composite configViewerLabelComposite = toolkit.createComposite(sectionClient);
		GridData gd = new GridData(SWT.FILL, SWT.END, true, false);
		configViewerLabelComposite.setLayoutData(gd);
		gd.horizontalSpan = 1;
		configViewerLabelComposite.setLayout(new GridLayout(3, false));

		Composite addCatsViewerLabelComposite = toolkit.createComposite(sectionClient);
		gd = new GridData(SWT.FILL, SWT.END, true, false);
		addCatsViewerLabelComposite.setLayoutData(gd);
		gd.horizontalSpan = 1;
		addCatsViewerLabelComposite.setLayout(new GridLayout(3, false));
		
		// create the library tree viewer
		configViewer = new MethodContainerCheckedTreeViewer(sectionClient);
		gd = new GridData(GridData.FILL_BOTH
				| GridData.GRAB_HORIZONTAL);
		gd.heightHint = 200;
		gd.verticalSpan = 3;
		configViewer.getTree().setLayoutData(gd);

		contProvider = new ConfigPackageContentProvider(adapterFactory);
		configViewer.setContentProvider(contProvider);
		labelProvider = new ConfigPackageLabelProvider(contProvider);
		configViewer.setLabelProvider(labelProvider);
		createViewerLabelAndButtons(toolkit, configViewerLabelComposite,
				AuthoringUIResources.ConfigurationPage_TreeTitleLabel, configViewer);

		
		
		addCategoryViewer = new MethodContainerCheckedTreeViewer2(sectionClient);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
		gd.heightHint= 200;
		addCategoryViewer.getTree().setLayoutData(gd);
		addCategoryViewer.setContentProvider(new CategoryContentProvider(adapterFactory, config));
		addCategoryViewer.setLabelProvider(new CategoryLabelProvider(adapterFactory));

		createViewerLabelAndButtons(toolkit, addCatsViewerLabelComposite,
				AuthoringUIResources.ConfigurationPage_AddCategoriesTitleLabel, addCategoryViewer);
	
		Composite subCatsViewerLabelComposite = toolkit.createComposite(sectionClient);
		gd = new GridData(SWT.FILL, SWT.END, true, false);
		subCatsViewerLabelComposite.setLayoutData(gd);
		gd.horizontalSpan = 1;
		subCatsViewerLabelComposite.setLayout(new GridLayout(3, false));
		
		subCategoryViewer = new MethodContainerCheckedTreeViewer2(sectionClient);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
		gd.heightHint= 200;
		subCategoryViewer.getTree().setLayoutData(gd);
		subCategoryViewer.setContentProvider(new CategoryContentProvider(adapterFactory, config));
		subCategoryViewer.setLabelProvider(new CategoryLabelProvider(adapterFactory));
		createViewerLabelAndButtons(toolkit, subCatsViewerLabelComposite,
				AuthoringUIResources.ConfigurationPage_SubCategoriesTitleLabel, subCategoryViewer);
		
		// add listener so the 2 Category viewers are in sync
		// that is, when an item is checked in one, it is unchecked in the other
		addCategoryViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(final CheckStateChangedEvent event) {
				//Potentially long operation - show a busy cursor
				BusyIndicator.showWhile(subCategoryViewer.getTree().getDisplay(), new Runnable() {
					public void run() {
						if (event.getChecked())
							subCategoryViewer.setChecked(event.getElement(), false);
					}
				});
			}
		});

		subCategoryViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(final CheckStateChangedEvent event) {
				//Potentially long operation - show a busy cursor
				BusyIndicator.showWhile(addCategoryViewer.getTree().getDisplay(), new Runnable() {
					public void run() {
						if (event.getChecked())
							addCategoryViewer.setChecked(event.getElement(), false);
					}
				});
			}
		});
	}
	
	private void createViewerLabelAndButtons(FormToolkit toolkit, Composite parent, String text, final TreeViewer viewer) {
		Label label = toolkit.createLabel(parent, text);
		GridData gd = new GridData(SWT.FILL, SWT.END, true, false);
		label.setLayoutData(gd);
		
		Button expandButton = toolkit.createButton(parent, null, SWT.PUSH);
		gd = new GridData(SWT.RIGHT, SWT.END, false, false);
		expandButton.setLayoutData(gd);
		expandButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage("expandall.gif")); //$NON-NLS-1$
		expandButton.setToolTipText(AuthoringUIResources.FilterDialog_ExpandAll); 
		expandButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
						AuthoringUIResources.FilterDialog_ExpandAll));
		
		expandButton.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
			
			public void widgetSelected(SelectionEvent e) {
				viewer.expandAll();
			}
		});


		Button collapseButton = toolkit.createButton(parent, null, SWT.PUSH);
		gd = new GridData(SWT.RIGHT, SWT.END, false, false);
		collapseButton.setLayoutData(gd);
		collapseButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage("collapseall.gif")); //$NON-NLS-1$
		collapseButton.setToolTipText(AuthoringUIResources.FilterDialog_CollapseAll); 
		collapseButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.FilterDialog_CollapseAll));
		collapseButton.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
			
			public void widgetSelected(SelectionEvent e) {
				viewer.collapseAll();
			}
		});

	}

	
	private void reInitializeConfigFactory() {
		// the following may not be the most efficient way
		// need a fast way to update the closure
//		System.out.println("$$$ reInit closure for config add notification!");

		createConfigurationClosure();
	}
	
	private void createConfigurationClosure() {
		closure = new ConfigurationClosure(actionMgr, config);
		closure.addListener(closureListener);
		if (labelProvider != null) {
			labelProvider.setClosure(closure);
		}
	}


	/**
	 * Set input for connfiguration viewer
	 * @param input
	 */
	private void setInput(Object input) {
		configViewer.setInput(input);
		addCategoryViewer.setInput(input);
		subCategoryViewer.setInput(input);
		
		configViewer.expandAll();
		configViewer.collapseAll();
		addCategoryViewer.expandAll();
		addCategoryViewer.collapseAll();
		subCategoryViewer.expandAll();
		subCategoryViewer.collapseAll();

//		updateCheckStates();
	}

	private void refreshViewers() {
		configViewer.refresh();
		addCategoryViewer.refresh();
		subCategoryViewer.refresh();
	}
	
	
	protected void showHideElements() {
		configViewerHideUncheckedFilter.toggleHideUnchecked();
		addCategoryHideUncheckedFilter.toggleHideUnchecked();
		subCategoryHideUncheckedFilter.toggleHideUnchecked();
		refreshViewers();
//		updateCheckStates(); // neded to have this to update the check status
	}
	
	/**
	 * Initialize configuration factory
	 */
	public void initializeConfigFactory() {
		// loading the configuration closure might be slow,
		// display a progress bar
		org.eclipse.epf.library.edit.util.IRunnableWithProgress runnable = new org.eclipse.epf.library.edit.util.IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				createConfigurationClosure();
			}
		};

		UserInteractionHelper.runWithProgress(runnable, AuthoringUIResources.ConfigurationPage_LoadingMessage); 

		configViewerHideUncheckedFilter = new HideUncheckedViewerFilter(configViewer);
		configViewer.addFilter(configViewerHideUncheckedFilter);
		addCategoryHideUncheckedFilter = new HideUncheckedViewerFilter(addCategoryViewer);
		addCategoryViewer.addFilter(addCategoryHideUncheckedFilter);
		subCategoryHideUncheckedFilter = new HideUncheckedViewerFilter(subCategoryViewer);
		subCategoryViewer.addFilter(subCategoryHideUncheckedFilter);
		
	}

	
	private void addListeners() {
		hideErrorButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleHidesButtonWidgetSelected(e,
						MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_ERRORS);
			}
		});
		
		hideWarnButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleHidesButtonWidgetSelected(e,
						MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_WARNINGS);
			}
		});
		
		hideInfoButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleHidesButtonWidgetSelected(e,
						MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_INFOS);
			}
		});
		
		closureButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				
				BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
					public void run() {
						makeClosure();
					}
				});
			};
		});
		fixWarningButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
					public void run() {
						fixWarning();
					}
				});				
			};
		});
		refreshButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
					public void run() {
						saveConfiguration();
						showErrors();
					}
				});				
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		hideButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				showHideElements();
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		// add a check state change listener
		ICheckStateListener configCheckStateListener = new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent evt) {
				
				BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
					public void run() {
						// save configurtion
						saveConfiguration();
						if (updateOnClick.getSelection()) {
							// update the closure error
							showErrors();
						}
						actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString()));
					}
				});
				
			}
		};
		
		ICheckStateListener catsCheckStateListener = new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				
				BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
					public void run() {
						saveContentCategorySelectionsToConfiguration();
						// update the closure error
						showErrors();
					}
				});
			}
		};
		
		configViewer.addCheckStateListener(configCheckStateListener);
		addCategoryViewer.addCheckStateListener(catsCheckStateListener);
		subCategoryViewer.addCheckStateListener(catsCheckStateListener);

		// listen to the library changes and automatically update the
		// configuration view
		libListener = new ILibraryChangeListener() {
			public void libraryChanged(int option, Collection<Object> changedItems) {
				// for performance reason, we should not response to every
				// library change
				// only cover package and plugin changes
				if (option == ILibraryChangeListener.OPTION_DELETED
						|| option == ILibraryChangeListener.OPTION_NEWCHILD
						|| option == ILibraryChangeListener.OPTION_NEWCHILD) {
					if (changedItems != null && changedItems.size() > 0) {
						Object o = changedItems.toArray()[0];
						if (o instanceof MethodPlugin
								|| o instanceof ProcessComponent
								|| o instanceof MethodPackage
								|| o instanceof CustomCategory) {
							reInitializeConfigFactory();
							refreshViewers();
//							updateCheckStates();
							showErrors();
						}
					}
				}
			}
		};

		ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.addListener(libListener);
		}
		
		// listen to plugin presentation layout changes
		PluginUIPackageContext.INSTANCE.addListener(layoutListener);
	}
	
	class ShowErrorJob extends Job {
		
		public ShowErrorJob(String name) {
			super(name);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			// save the previous invalid elements
			final List<Object> invalid = closure.getInvalidElements();
			closure.checkError();
			if (closure.isAbortCheckError()) {
				return Status.OK_STATUS;
			}
			
			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (configViewerHideUncheckedFilter.isHideUnchecked()) {
						configViewer.refresh();
					} else {
						// get the new error elements, add to the previous error elements,
						// and update them to update the error/warning images
						invalid.addAll(closure.getInvalidElements());

						// also add the UI folders
						ConfigPackageContentProvider cp = (ConfigPackageContentProvider) configViewer
								.getContentProvider();
						invalid.addAll(cp.getUIElements());

						configViewer.update(invalid.toArray(), null);
					}
				}

			});
			return Status.OK_STATUS;
		}

	}
	
	protected void showErrors() {
		if (closure.isAbortCheckError()) {
			return;
		}
		
		if (showErrorJob.getState() == Job.RUNNING) {
			closure.setAbortCheckError(true);
		}

		if (! showErrorJob.cancel()) {
			try {
				showErrorJob.join();
			} catch (Exception e) {							
			}
		}
		
		closure.setAbortCheckError(false);
		showErrorJob.schedule();
	}
	
	//old code for showErrors method
	protected void showErrors_old() {
		// save the previous invalid elements
		List<Object> invalid = closure.getInvalidElements();

		closure.checkError();
		
		if (configViewerHideUncheckedFilter.isHideUnchecked()) {
			configViewer.refresh();
		} else {
			// get the new error elements, add to the previous error elements,
			// and update them to update the error/warning images
			invalid.addAll(closure.getInvalidElements());

			// also add the UI folders
			ConfigPackageContentProvider cp = (ConfigPackageContentProvider) configViewer
					.getContentProvider();
			invalid.addAll(cp.getUIElements());

			configViewer.update(invalid.toArray(), null);
		}

	}

	
	/**
	 * Make configuration closure
	 *
	 */
	protected void makeClosure() {
		closure.fixErrors();
		configViewer.refresh();
		initConfigViewer();
		//refreshViewers();
//		updateCheckStates();
		//saveConfiguration();

	}

	/**
	 * Fix all warnings 
	 */
	protected void fixWarning() {

		closure.fixProblems();
		configViewer.refresh();
		initConfigViewer();
		//refreshViewers();	
//		updateCheckStates();
		//saveConfiguration();

	}

	/**
	 * Save configuration
	 * @return
	 * 		True if configuration is save successfully, false otherwise
	 */
	public boolean saveConfiguration() {
		ConfigurationData configData = LibraryService.getInstance()
							.getConfigurationManager(config)
									.getConfigurationData();
		
		configData.setEnableUpdate(false);
		boolean ret = doSaveConfiguration();
		configData.setEnableUpdate(true);

		return ret;
	}
	
	private boolean doSaveConfiguration() {

		boolean oldNotify = config.eDeliver();
	    try
	    {    	
	    	List<MethodPackage> oldPackages = new ArrayList<MethodPackage>(config.getMethodPackageSelection());
	    	List<MethodPlugin> oldPlugins = new ArrayList<MethodPlugin>(config.getMethodPluginSelection());
	    	
	    	Set<MethodPackage> newPackages = getCheckedMethodPackages(configViewer.getCheckedElements());
	    	Set<MethodPlugin> newPlugins = getCheckedMethodPlugins(configViewer.getCheckedElements());
	    	
	    	// set categories checked for plugins selected
	    	List<MethodPlugin> plugins = new ArrayList<MethodPlugin>();
	    	plugins.addAll(newPlugins);
	    	plugins.addAll(oldPlugins);
	    	setStateForCategoriesUIFolder(configViewer, plugins);
	    	
	    	oldPackages.removeAll(newPackages);
	    	oldPlugins.removeAll(newPlugins);	
    	
	    	newPackages.removeAll(config.getMethodPackageSelection());
	    	newPlugins.removeAll(config.getMethodPluginSelection());
	
			if (ConfigurationUtil.removeCollFromMethodPluginList(actionMgr, config, oldPlugins) == false)
				return false;
			if (ConfigurationUtil.removeCollFromMethodPackageList(actionMgr, config, oldPackages) == false)
				return false;
			
			if (ConfigurationUtil.addCollToMethodPluginList(actionMgr, config, newPlugins) == false)
				return false;
			if (ConfigurationUtil.addCollToMethodPackageList(actionMgr, config, newPackages) == false)
				return false;
	
	    	// validate before save
			LibraryUtil.validateMethodConfiguration(actionMgr, config);

			actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString()));

			return true;
		
		} finally {
			config.eSetDeliver(oldNotify);
		}
	}
	
	/**
	 * Save configuration
	 * @return
	 * 		True if configuration is save successfully, false otherwise
	 */
	public boolean saveContentCategorySelectionsToConfiguration() {
		
    	List<ContentCategory> oldAddCats = new ArrayList<ContentCategory>(config.getAddedCategory());
    	List<ContentCategory> oldSubCats = new ArrayList<ContentCategory>(config.getSubtractedCategory());
    	
    	Set<ContentCategory> newAddCats = getCheckedContentCategories(addCategoryViewer.getCheckButNotGrayedElements());
    	Set<ContentCategory> newSubCats = getCheckedContentCategories(subCategoryViewer.getCheckButNotGrayedElements());
    	
    	oldAddCats.removeAll(newAddCats);
    	oldSubCats.removeAll(newSubCats);
    	
    	newAddCats.removeAll(config.getAddedCategory());
    	newSubCats.removeAll(config.getSubtractedCategory());
		
		if (ConfigurationUtil.removeCollFromAddedCategoryList(actionMgr, config, oldAddCats) == false)
			return false;
		
		if (!newAddCats.isEmpty()) {
			if (ConfigurationUtil.addCollToAddedCategoryList(actionMgr, config, newAddCats) == false)
				return false;
			
			Map<String, MethodElement> pluginMap = MethodElementUtil.buildMap(config.getMethodPluginSelection());
			HashSet<MethodPlugin> newAddedPlugins = new HashSet<MethodPlugin>();
			for (Iterator<ContentCategory> it = newAddCats.iterator(); it.hasNext(); ) {
				ContentCategory cat = it.next();
				MethodPlugin plugin = UmaUtil.getMethodPlugin(cat);
				if (! pluginMap.containsKey(plugin.getGuid())) {
					if (! newAddedPlugins.contains(plugin)) {
						newAddedPlugins.add(plugin);
					}
				}
			}
			if (! newAddedPlugins.isEmpty()) {
				if (ConfigurationUtil.addCollToMethodPluginList(actionMgr, config, newAddedPlugins) == false)
					return false;
				LibraryUtil.validateMethodConfiguration(actionMgr, config);
			}
			
		}
		if (ConfigurationUtil.removeCollFromSubtractedCategoryList(actionMgr, config, oldSubCats) == false)
			return false;
		
		if (ConfigurationUtil.addCollToSubtractedCategoryList(actionMgr, config, newSubCats) == false)
			return false;

		actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString()));

		return true;
	}
	
	protected Set<ContentCategory> getCheckedContentCategories(Object[] checkedItems) {
		Set<ContentCategory> result = new HashSet<ContentCategory>();
		for (int i = 0; i < checkedItems.length; i++) {
			Object item = TngUtil.unwrap(checkedItems[i]);
			if (item instanceof ContentCategory) {
//				if (config.getMethodPluginSelection().contains(LibraryUtil.getMethodPlugin((ContentCategory)item))) {
					result.add((ContentCategory)item);
//				}
			}
		}
		return result;
	}
	
	protected Set<MethodPackage> getCheckedMethodPackages(Object[] checkedItems) {
		Set<MethodPackage> result = new HashSet<MethodPackage>();
		for (int i = 0; i < checkedItems.length; i++) {
			Object item = TngUtil.unwrap(checkedItems[i]);
			if (item instanceof MethodPackage) {
				result.add((MethodPackage)item);
			}
		}
		return result;
	}
	
	protected Set<MethodPlugin> getCheckedMethodPlugins(Object[] checkedItems) {
		Set<MethodPlugin> result = new HashSet<MethodPlugin>();
		for (int i = 0; i < checkedItems.length; i++) {
			Object item = TngUtil.unwrap(checkedItems[i]);
			if (item instanceof MethodPlugin) {
				result.add((MethodPlugin)item);
			}
		}
		return result;
	}
	
	public void dispose() {
		super.dispose();

		if (libListener != null) {
			ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager();
			if (manager != null) {
				manager.removeListener(libListener);
			}
		}
		
		if (layoutListener != null) {
			PluginUIPackageContext.INSTANCE.removeListener(layoutListener);
		}

		if (closure != null) {
			closure.dispose();
			closure = null;
		}
		if (adapterFactory != null) {
			adapterFactory.dispose();
			adapterFactory = null;
		}
	}
	
	public void gotoMarker(IMarker marker) {
		// select problem in main viewer
		
		MethodElement e = ConfigurationMarkerHelper.INSTANCE.getErrorMethodElement(marker);

		if (e != null && configViewer != null) {
			configViewer.setSelection(new StructuredSelection(LibraryUtil.getSelectable(e)), true);
		}
	}
	
	public void doQuickFix(IMarker marker) {
		if ( marker == null ) {
			return;
		}
		MethodElement element = markerHelper.getCauseMethodElement(marker);	
		if ( element == null ) {
			return;
		}
		
		if ( closure.getConfigurationManager().getConfigurationData().isElementInSubtractedCategory(element)) {
			String message = AuthoringUIResources.bind(
					AuthoringUIResources.configurationPage_QuickfixError_reason1, 
					(new String[] {LibraryUtil.getTypeName(element)}));
			AuthoringUIPlugin.getDefault().getMsgDialog()
				.displayWarning(
						AuthoringUIResources.configurationPage_quickfixError_title, 
						message);
			return;
		}
		
		Object owner = LibraryUtil.getSelectable(element);
		configViewer.setChecked(owner, true);
		saveConfiguration();
		showErrors();					
   }

	private void handleHidesButtonWidgetSelected(SelectionEvent e, String key) {
		Object obj = e.getSource();
		if (obj instanceof Button) {
			Button button = (Button) obj;
			String value = button.getSelection() ? Boolean.TRUE.toString()
					: Boolean.FALSE.toString();
			actionMgr.execute(new MethodElementSetPropertyCommand(config, key, value));
		}
	}

}
