//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.dialogs;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

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.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.filters.DescriptorConfigurationFilter;
import org.eclipse.epf.authoring.ui.filters.ExProcessAuthoringConfigurator;
import org.eclipse.epf.authoring.ui.util.AuthoringAccessibleListener;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationFilter;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.itemsfilter.FilterHelper;
import org.eclipse.epf.library.edit.itemsfilter.ICategoryFilter;
import org.eclipse.epf.library.edit.itemsfilter.IProcessFilter;
import org.eclipse.epf.library.edit.navigator.MethodPluginItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.util.MethodElementUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.search.internal.core.text.PatternConstructor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;

/**
 * Filter Dialog - allow the user to filter the content element, content
 * categories, custom categories, All types of contentelements based on location of the use of the filter
 * dialog.
 * 
 * @author Lokanath Jagga
 * @author Shashidhar Kannoori
 */
public class ItemsFilterDialog extends Dialog implements
		ISelectionChangedListener, IDoubleClickListener {

	protected Button okButton, cancelButton;

	protected Text ctrl_pattern, ctrl_brief_desc;

	private String pattern, filterTypeStr;

	protected Combo filterType;

	private String dialogTitle, tabStr;

	private Object contentElement;

	private ArrayList selectedList = new ArrayList();

	private boolean viewerSelectionSingle = false;
	private String viewerLabel = null;
	
	/*
	 * Treeviewer for ContentElements to display.
	 */
	private TreeViewer treeViewer;

	protected IStructuredContentProvider contentProvider;

	protected ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getText(Object object) {
			// return super.getText(object);
			if (object instanceof VariabilityElement) {
				return TngUtil.getLabel((VariabilityElement) object, "", true); //$NON-NLS-1$
			} else if (object instanceof MethodPlugin) {
				MethodPluginItemProvider methodPluginItemProvider = (MethodPluginItemProvider)TngUtil.getAdapter((MethodPlugin)object, MethodPluginItemProvider.class);
				if (methodPluginItemProvider != null) {
					return methodPluginItemProvider.getFullName(object);
				}
			} 
			return super.getText(object);
		}
		
		
		public String getColumnText(Object object, int index) {
			return getText(object);
		}
		
		public Image getColumnImage(Object object, int index) {
			return super.getImage(object);
		}
	};

	private AdapterFactory adapterFactory;
	private ComposedAdapterFactory composedAdapterFactory;

	/*
	 * Dialog Attributes
	 */
	// private boolean anyChilds = true;
	private List alreadySelectedList = new ArrayList();

	private IFilter filter;

	Pattern regexPattern;

	// private MethodConfiguration methodConfiguration;
	protected FilterHelper helper;

	private String STORE_EXPANDED_LEVEL_ID = ".LEVEL_ID"; //$NON-NLS-1$
	private String PATTERN_ID = ".Pattern"; //$NON-NLS-1$
	private String TYPE_ID = ".Type"; //$NON-NLS-1$

	private String DIALOG_NAME;

	private Button expandButton;

	private Button collapseButton;

	private Object input;

	private String[] types;

	/**
	 * Constructs a new FilterDialog. This constructor will use filter based on
	 * tabStr, filters out the list of elements based on already existing
	 * selected element in the selected table. Initializes the ContentProvider
	 * for the treeviewer.
	 * 
	 */
	public ItemsFilterDialog(Shell parentShell, Object contentElement,
			String tabStr, List alreadyExists) {
		super(parentShell);
		this.contentElement = contentElement;
		this.tabStr = tabStr;
		this.filter = null;
		this.alreadySelectedList = alreadyExists;
		helper = new FilterHelper(contentElement, tabStr, null, null,
				this.alreadySelectedList);
		initProviderForTabs();
	}

	public ItemsFilterDialog(Shell parentShell, IFilter filter, String tabStr,
			List alreadyExists, Object input) {
		this(parentShell, filter, null, tabStr, alreadyExists);
		this.input = input;
	}

	/**
	 * Constructs a new FilterDialog. This constructor will use passed filter.
	 * tabStr is used for the searchtype only. Initializes the ContentProvider
	 * for the treeviewer.
	 * 
	 */
	public ItemsFilterDialog(Shell parentShell, IFilter filter,
			Object contentElement, String tabStr) {
		super(parentShell);
		this.filter = filter;
		this.tabStr = tabStr;

		helper = new FilterHelper(contentElement, tabStr, null, null, null);
		initProviderForTabs();
	}

	/**
	 * Constructs a new FilterDialog. This constructor will use passed filter.
	 * tabStr is used for the searchtype only. Initializes the ContentProvider
	 * for the treeviewer.
	 * 
	 */
	public ItemsFilterDialog(Shell parentShell, IFilter filter,
			Object contentElement, String tabStr, List alreadyExists) {
		super(parentShell);
		this.filter = filter;
		this.tabStr = tabStr;
		this.alreadySelectedList = alreadyExists;
		helper = new FilterHelper(contentElement, tabStr, null, null,
				alreadyExists);
		this.contentElement = contentElement;
		initProviderForTabs();
	}

	/**
	 * Constructs a new FilterDialog. Only for methodconfiguration. This
	 * constructor will use passed filter. Initializes the ContentProvider for
	 * the treeviewer.
	 * 
	 */
	// public ItemsFilterDialog(Shell parentShell, Object contentElement,
	// MethodConfiguration methodConfiguration, String tabStr) {
	// super(parentShell);
	// this.contentElement = contentElement;
	// this.tabStr = tabStr;
	// this.filter = null;
	// this.methodConfiguration = methodConfiguration;
	// helper = new FilterHelper(contentElement, tabStr, null, null, null);
	// initProviderForTabs();
	// }
	/**
	 * This constructor is very generic, in order to initialize filter, input
	 * and contentprovider should be handled explicitly by calling below method.
	 * setFilter(IFilter) setInput(Object)
	 * setContentProvider(IStructuredProvider)
	 * 
	 */
	public ItemsFilterDialog(Shell parentShell) {
		super(parentShell);
		helper = new FilterHelper(null, null, null, null, null);
	}

	/**
	 * This method is called if a button has been pressed.
	 */
	protected void buttonPressed(int buttonId) {
		if (buttonId == IDialogConstants.OK_ID)
			saveValues();
		super.buttonPressed(buttonId);
		if(composedAdapterFactory != null){
			composedAdapterFactory.dispose();
		}

	}

	/**
	 * Notifies that the cancel button of this dialog has been pressed.
	 */
	protected void cancelPressed() {
	    if (treeJob != null) {
	    	treeJob.cancel();
	    }
		super.cancelPressed();
		if(composedAdapterFactory != null){
			composedAdapterFactory.dispose();
		}
	}
	
	@Override
	protected void okPressed() {
	    if (treeJob != null) {
	    	treeJob.cancel();
	    }
		super.okPressed();
	}

	/**
	 * Set title for dialog box eg: Select Dialog For Role, dialogTitle needs to
	 * "Role"
	 */
	public void setTitle(String dialogTitle) {
		this.dialogTitle = dialogTitle;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		if (dialogTitle == null)
			dialogTitle = tabStr;
		shell.setText(AuthoringUIResources.FilterDialog_title + dialogTitle); 
	}

	/**
	 * (non-Javadoc) Adds buttons to this dialog's button bar.
	 * 
	 * @param parent
	 *            the button bar composite
	 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);
	}

	/**
	 * Creates dialog area and controls and viewer.
	 * 
	 * @param the
	 *            parent composite to contain the dialog area
	 * @return the dialog area control
	 */
	protected Control createDialogArea(Composite parent) {

		Composite composite = (Composite) super.createDialogArea(parent);
		composite.setFont(parent.getFont());

		GridLayout layout = (GridLayout) composite.getLayout();
		layout.marginWidth = 10;
		layout.marginHeight = 10;
		layout.numColumns = 3;

		Label typeLabel = new Label(composite, SWT.NONE);
		{
			typeLabel.setText(AuthoringUIResources.FilterDialog_Type_text); 
			GridData gD1 = new GridData(GridData.BEGINNING);
			typeLabel.setLayoutData(gD1);

		}
		filterType = new Combo(composite, SWT.SINGLE | SWT.READ_ONLY);
		{
			GridData gD1 = new GridData(GridData.BEGINNING);
			gD1.horizontalSpan = 2;
			gD1.widthHint = 390;
			filterType.setLayoutData(gD1);
		}

		if (types == null) {
			fillFilterTypeCombo();
		} else {
			filterType.setItems(types);
			if (helper != null) {
				filterTypeStr = filterType.getItem(0);
				helper.setFilterTypeStr(filterType.getItem(0));
				if (tabStr == null) {
					tabStr = filterTypeStr;
					helper.setTabStr(tabStr);
				}
			}
		}
		filterType.select(0);

		Label ctrl_patternLabel = new Label(composite, SWT.NONE);
		{
			ctrl_patternLabel.setText(AuthoringUIResources.FilterDialog_Pattern_text); 
			GridData gD = new GridData();
			gD.horizontalSpan = 3;
			ctrl_patternLabel.setLayoutData(gD);
		}

		ctrl_pattern = new Text(composite, SWT.BORDER);
		{
			GridData gD1 = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
			gD1.horizontalSpan = 3;
			ctrl_pattern.setLayoutData(gD1);
			ctrl_pattern.getAccessible().addAccessibleListener(
					new AuthoringAccessibleListener(
							AuthoringUIResources.FilterDialog_Pattern_text +  
							AuthoringUIResources.FilterDialog_Pattern_description));
		}
		Label ctrl_patternLabel1 = new Label(composite, SWT.WRAP);
		{
			ctrl_patternLabel1.setText(AuthoringUIResources.FilterDialog_Pattern_description); 
			GridData gD = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false, 3, 1);
			gD.widthHint = 550;
			ctrl_patternLabel1.setLayoutData(gD);
		}
		
		Composite buttonsComposite = new Composite(composite, SWT.NONE);		
		
		GridData gd2 = new GridData(GridData.FILL_HORIZONTAL
			| GridData.HORIZONTAL_ALIGN_END);
		gd2.horizontalSpan = 2;
		buttonsComposite.setLayoutData(gd2);
		GridLayout buttonsLayout = new GridLayout();
		buttonsLayout.numColumns = 2;
		buttonsLayout.marginRight = 0;
		buttonsComposite.setLayout(buttonsLayout);
		
		expandButton = new Button(buttonsComposite, SWT.BUTTON1);

		expandButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"expandall.gif")); //$NON-NLS-1$
		expandButton.setToolTipText(AuthoringUIResources.FilterDialog_ExpandAll); 
		
		expandButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
						AuthoringUIResources.FilterDialog_ExpandAll));		

		gd2 = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
				| GridData.GRAB_HORIZONTAL);

		expandButton.setLayoutData(gd2);

		collapseButton = new Button(buttonsComposite, SWT.PUSH);
		collapseButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage(
				"collapseall.gif")); //$NON-NLS-1$

		collapseButton.setToolTipText(AuthoringUIResources.FilterDialog_CollapseAll); 
		collapseButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener(
				AuthoringUIResources.FilterDialog_CollapseAll));
		
		gd2 = new GridData(GridData.HORIZONTAL_ALIGN_END);

		collapseButton.setLayoutData(gd2);
		
		createLine(composite, 3);
		createViewerLabel(composite);
		// create a treeviewer area.
		createViewer(composite);

		restoreLastSettings();

		new Label(composite, SWT.NONE).setText(AuthoringUIResources.FilterDialog_BriefDescription); 
		ctrl_brief_desc = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL | SWT.READ_ONLY);
		{
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 3;
			gd.heightHint = 60;
			ctrl_brief_desc.setLayoutData(gd);
		}
		// Restore the last state
		createLine(composite, 3);

		// Return results.
		addListener();
		return composite;
	}

	/**
	 * Create a new viewer in the parent.
	 * 
	 * @param parent
	 *            the parent <code>Composite</code>.
	 */
	private void createViewer(Composite parent) {
		if (viewerSelectionSingle) {
			treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL
					| SWT.V_SCROLL | SWT.BORDER);
		} else {
			treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
					| SWT.V_SCROLL | SWT.BORDER);
		}
		treeViewer.setLabelProvider(labelProvider);
		treeViewer.setContentProvider(contentProvider);
		treeViewer.setUseHashlookup(true);

		// Set the input to treeViewer
		treeViewer.setInput(getInput());

		treeViewer.addSelectionChangedListener(this);
		treeViewer.addDoubleClickListener(this);
		treeViewer.getTree().setFont(parent.getFont());

		if (tabStr.equalsIgnoreCase(FilterConstants.ALL_ELEMENTS)) { 
			treeViewer.setSorter(new FilterSorterForAll());
		} else {
			treeViewer.setSorter(new FilterSorter());
		}

		GridData spec = new GridData(GridData.FILL_BOTH);
		{
			spec.widthHint = 300;
			spec.heightHint = 300;
			spec.horizontalSpan = 3;
			treeViewer.getControl().setLayoutData(spec);
		}
	}

	/**
	 * Returns input if externally set by setInput invoker.
	 * Else, calculates the input based on the Object set to the dialog.
	 */
	private Object getInput(){
		if(input != null){
			return input;
		}else{
			if (contentElement != null) {
				if (contentElement instanceof Process) {
						Process process = (Process)contentElement;
						if (process.eContainer() instanceof ProcessComponent) {
							if (!(tabStr.equals(FilterConstants.GUIDANCE)
									|| tabStr.equals(FilterConstants.ROADMAP) 
									|| tabStr.equals(FilterConstants.SUPPORTING_MATERIALS))) {
							return process.eContainer();
						} else
							return process;
						}
				} 
				return UmaUtil.getMethodLibrary((EObject) contentElement);
			} 
			return LibraryService.getInstance().getCurrentMethodLibrary();
		}
	}
	
	private void createLine(Composite parent, int ncol) {
		Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
				| SWT.BOLD);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = ncol;
		line.setLayoutData(gridData);
	}

	private void createViewerLabel(Composite parent) {
   		if (viewerLabel != null) {
   			Label label = new Label(parent, SWT.NONE);
			label.setText(viewerLabel);
   		}
   	}
	
	public void setViewerSelectionSingle(boolean single) {
		viewerSelectionSingle = single;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
	 */
	public void doubleClick(DoubleClickEvent event) {
		IStructuredSelection s = (IStructuredSelection) event.getSelection();
		Object element = s.getFirstElement();
		element = LibraryUtil.unwrap(element);
		if (element instanceof ContentElement || element instanceof Process
				|| element instanceof ProcessComponent
				|| element instanceof BreakdownElement
				|| element instanceof ProcessPackage) {
			selectedList.add(element);
		} 
		saveLastSettings();
		close();
		if(composedAdapterFactory != null){
			composedAdapterFactory.dispose();
		}
	}

	/**
	 * Return the dialog store to cache values into
	 */
	protected IDialogSettings getDialogSettings() {
		DialogSettings dialogSettings = (DialogSettings) AuthoringUIPlugin
				.getDefault().getDialogSettings();
		DialogSettings section = (DialogSettings) dialogSettings
				.getSection(DIALOG_NAME + STORE_EXPANDED_LEVEL_ID);
		if (section == null)
			section = (DialogSettings) dialogSettings.addNewSection(DIALOG_NAME
					+ STORE_EXPANDED_LEVEL_ID);
		return section;
	}

	/**
	 * Use the dialog settings to restore widget values to the values that they
	 * held last time this dialog was used to completion.
	 */
	protected void restoreLastSettings() {
		DIALOG_NAME = tabStr;
		DialogSettings dialogSettings = (DialogSettings) getDialogSettings();
		String temp = dialogSettings.get(DIALOG_NAME + PATTERN_ID); 
		if (temp != null && temp.length() > 0) { 
			pattern = dialogSettings.get(DIALOG_NAME + PATTERN_ID); 
			filterTypeStr = dialogSettings.get(DIALOG_NAME + TYPE_ID); 
			filterType.setText(filterTypeStr);
			regexPattern = getRegEx(pattern);
			
			//Trim "*" from pattern string before display. This action is just for display.
//			if(pattern != null){
//				if(pattern.lastIndexOf(FilterConstants.ANY_STRING) 
//						== pattern.length()-1){
//					pattern = pattern.substring(0, pattern.length()-1);
//				}
//			}
			ctrl_pattern.setText(pattern);
			
			if (helper != null) {
				helper.setPattern(pattern);
				helper.setRegexPattern(regexPattern);
				helper.setFilterTypeStr(filterTypeStr);
			}
			initProviderForTabs();

		}
		List elements = (List) FilterConstants.hashMap.get(DIALOG_NAME
				+ STORE_EXPANDED_LEVEL_ID);
		if (elements == null || elements.isEmpty()) {
			treeViewer.expandAll();
			return;
		}

		if (elements != null && !elements.isEmpty()) {
			try {
				treeViewer.setExpandedElements(elements.toArray());
				treeViewer.refresh();
			} catch (Exception e) {
				treeViewer.expandAll();
			}
		}

	}

	public void traverseTree(TreeItem[] items, List list) {
		for (int i = 0; i < items.length; i++) {
			TreeItem[] itemsx = items[i].getItems();
			if (itemsx.length > 1) {
				list.add(items[i].getData());
				traverseTree(itemsx, list);
			} else {
				list.add(items[i].getData());
			}
		}
	}

	/**
	 * Since OK was pressed, write widget values to the dialog store so that
	 * they will persist into the next invocation of this dialog
	 */
	protected void saveValues() {
		IStructuredSelection selection = (IStructuredSelection) treeViewer
				.getSelection();
		if (selection.size() > 0) {
			Object[] objectArr = selection.toArray();
			for (int i = 0; i < objectArr.length; i++) {
				Object obj = LibraryUtil.unwrap(objectArr[i]);
				if (obj instanceof ContentElement 
						|| obj instanceof Process 
						|| obj instanceof ProcessComponent
						|| obj instanceof BreakdownElement
						|| obj instanceof ProcessPackage) {
					selectedList.add(obj);
				} 
			}
		}
		saveLastSettings();
	}

	/**
	 * Saves the last settings of dialog.
	 */
	public void saveLastSettings() {

		// eclipse docs forIDialogSettings for understanding.
		IDialogSettings settings = getDialogSettings();
		DIALOG_NAME = tabStr;
		Object[] expandedElements = treeViewer.getExpandedElements();
		List expandList = new ArrayList();
		// String[] expandedCategoryIds = new String[expandedElements.length];
		for (int i = 0; i < expandedElements.length; i++) {
			Object obj = expandedElements[i];
			if (obj instanceof NamedElement) {
				expandList.add(expandedElements[i]);
			}
		}
		settings.put(DIALOG_NAME + PATTERN_ID, pattern);
		settings.put(DIALOG_NAME + TYPE_ID, filterTypeStr);
		FilterConstants.hashMap.put(DIALOG_NAME + STORE_EXPANDED_LEVEL_ID,
				expandList);
	}

	/**
	 * Notifies that the selection has changed.
	 * 
	 * @param event
	 *            event object describing the change
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		updateSelection(event);
		updateButtons();
	}

	/**
	 * Update the button enablement state.
	 */
	protected void updateButtons() {
		// okButton.setEnabled(getSelection().length > 0);
	}

	public Object getParentObject(Object contentElement) {
		return MethodElementUtil.getMethodModel(contentElement);
	}

	/**
	 * Update the selection object.
	 */
	protected void updateSelection(SelectionChangedEvent event) {
		// ArrayList descs = new ArrayList();
		IStructuredSelection sel = (IStructuredSelection) event.getSelection();
		Object selected = sel.getFirstElement();
		if (selected instanceof BreakdownElementWrapperItemProvider ||
				selected instanceof BreakdownElementItemProvider){
			Object unwrap =  TngUtil.unwrap(selected);
			setBriefDescription(unwrap);
		}else {
			setBriefDescription(selected);
		}
	}
	/**
	 * Set the brief description to control
	 */
	private void setBriefDescription(Object element) {
		if (element instanceof MethodElement) {
			String desc = ((MethodElement) element).getBriefDescription();
			if (desc != null) {
				ctrl_brief_desc.setText(desc);
			}
		}
	}

	public void fillFilterTypeCombo() {
		if (filter instanceof ConfigurationFilter) {
			String[] str = new String[1];
			str[0] = (String) tabStr;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.categoryStrs.contains(tabStr)) {
			String[] str = new String[2];
			str[0] = (String) tabStr;
			str[1] = FilterConstants.METHO_PLUGINS;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.CUSTOM_CATEGORIES.equalsIgnoreCase(tabStr)) {
			String[] str = new String[2];
			str[0] = (String) tabStr;
			str[1] = FilterConstants.METHO_PLUGINS;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.breakdownElements.contains(tabStr)) {
			String[] str = new String[1];
			str[0] = (String) tabStr;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.contentElementStrs.contains(tabStr)) {
			String[] str = new String[3];
			str[0] = tabStr;
			str[1] = FilterConstants.CONTENT_PACKAGES;
			str[2] = FilterConstants.METHO_PLUGINS;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.ALL_ELEMENTS.equals(tabStr)) { // 172956
			String space = "-"; //$NON-NLS-1$
			String[] str = new String[26];
			int i = 0;
			str[i++] = FilterConstants.ALL_ELEMENTS;
			str[i++] = FilterConstants.CONTENT_PACKAGES;
			str[i++] = space + FilterConstants.ROLES;
			str[i++] = space + FilterConstants.TASKS;
			str[i++] = space + FilterConstants.WORKPRODUCTS;
			str[i++] = space + FilterConstants.GUIDANCE;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.CHECKLISTS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.CONCEPTS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.EXAMPLES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.GUIDELINES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REUSABLE_ASSETS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.SUPPORTING_MATERIALS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.ESTIMATE_CONSIDERATIONS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REPORTS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TEMPLATES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.ESTIMATE_CONSIDERATIONS;
			str[i++] = FilterConstants.DISCIPLINES;
			str[i++] = FilterConstants.ROLESETS;
			str[i++] = FilterConstants.WORKPRODUCTTYPES;
			str[i++] = FilterConstants.DOMAINS;
			str[i++] = FilterConstants.TOOLS;
			str[i++] = FilterConstants.CUSTOM_CATEGORIES;
			str[i++] = FilterConstants.PROCESSES;
			str[i++] = FilterConstants.METHO_PLUGINS;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else if (FilterConstants.CONFIG_CONTENT_ELEMENT.equals(tabStr)) {
			String[] str = new String[1];
			str[0] = (String) tabStr;
			filterType.setItems(str);
			filterTypeStr = str[0];
		} else {
			String[] str = new String[1];
			str[0] = (String) tabStr;
			filterType.setItems(str);
			filterTypeStr = str[0];
		}
	}

	public long delay = 800;
	
	private class UpdateTreeJob extends Job {

		public UpdateTreeJob(String name) {
			super(name);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {

			// need to run this in UI thread
			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

				public void run() {
					if (treeViewer == null || 
							treeViewer.getControl() == null ||
							treeViewer.getControl().isDisposed()) {
						return;
					}
					treeViewer.getTree().clearAll(true);
					if (ctrl_pattern.getText() != null
							&& ctrl_pattern.getText().trim().length() > 0) {
						pattern = ctrl_pattern.getText().trim();
						// if(pattern.indexOf(FilterConstants.ANY_STRING)> -1
						// || pattern.indexOf(FilterConstants.ANY_CHARACTER) >
						// -1){
						//              
						// }else{
						// pattern = pattern+FilterConstants.ANY_STRING;
						// }
					} else {
						pattern = FilterConstants.ANY_STRING;
						// return;
					}
					regexPattern = getRegEx(pattern);
					if (helper != null) {
						helper.setPattern(pattern);
						helper.setRegexPattern(regexPattern);
						helper.setFilterTypeStr(filterTypeStr);
						helper.setTabStr(filterTypeStr);
					}
					refreshTreeViewer();
				}

			});
			return Status.OK_STATUS;
		}

	}
	
	private UpdateTreeJob treeJob = new UpdateTreeJob(AuthoringUIResources.ItemsFilterDialog_UpdateTreeJob_name);
	
	public void addListener() {
		ctrl_pattern.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				
			  if (treeJob.getState() == Job.NONE) {
			    // We should schedule the job to run
			    treeJob.schedule(delay);
			  } else if (treeJob.getState() == Job.WAITING ||
					  treeJob.getState() == Job.SLEEPING){
			    // Cancel the previous job, and reschedule
			    treeJob.cancel();
			    treeJob.schedule(delay);
			  }
			}
		});

		filterType.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				// updateFontList();
				if (filterType.getSelectionIndex() > -1) {
					filterTypeStr = filterType.getItem(filterType
							.getSelectionIndex());
				}
				filterTypeStr.trim();
				if (helper != null) {
					helper.setPattern(pattern);
					helper.setRegexPattern(regexPattern);
					helper.setFilterTypeStr(filterTypeStr);
					helper.setTabStr(filterTypeStr);
				}
				// initProviderForTabs();
				refreshTreeViewer();
			}

			public void widgetDefaultSelected(SelectionEvent selectionevent) {
			}
		});
		expandButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {				
				expandOrCollapse(true);
			}
		});
		collapseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				expandOrCollapse(false);
			}
		});

	}

	public ArrayList getSelectedItems() {
		return selectedList;
	}

	private void initProviderForTabs() {

		if (filter != null) {
			if (filter instanceof org.eclipse.epf.library.edit.itemsfilter.IFilter) {
				if(filter instanceof ICategoryFilter){
					// special handling for contentcategory.
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=157452
					helper.setContentCategoryTabStr(tabStr);
				}
				((org.eclipse.epf.library.edit.itemsfilter.IFilter) filter)
						.setHelper(helper);
			} else if (filter instanceof DescriptorConfigurationFilter) {
				((DescriptorConfigurationFilter) filter).setHelper(helper);
			}else if (filter instanceof ExProcessAuthoringConfigurator) {
				((ExProcessAuthoringConfigurator) filter).setHelper(helper);
			}
		}
		if (filter instanceof IProcessFilter) {
			if (tabStr
					.equalsIgnoreCase(FilterConstants.WORK_PRODUCT_DESCRIPTORS)) {
				adapterFactory =TngAdapterFactory.INSTANCE.getPBSFilter_AdapterFactory(filter);
				contentProvider = new AdapterFactoryContentProvider(
						adapterFactory);
				composedAdapterFactory = TngAdapterFactory.INSTANCE.getPBSFilter_ComposedAdapterFactory();
				labelProvider = new AdapterFactoryLabelProvider(
						TngAdapterFactory.INSTANCE
								.getPBS_ComposedAdapterFactory()) {
					public String getColumnText(Object object, int index) {
						return super.getText(object);
					}
					
					public Image getColumnImage(Object object, int index) {
						return super.getImage(object);
					}
				};
			} else if (tabStr
					.equalsIgnoreCase(FilterConstants.ROLE_DESCRIPTORS)) {
				adapterFactory = TngAdapterFactory.INSTANCE
				.getOBSFilter_AdapterFactory(filter); 
				contentProvider = new AdapterFactoryContentProvider(adapterFactory);
				composedAdapterFactory = TngAdapterFactory.INSTANCE.getOBSFilter_ComposedAdapterFactory();
				labelProvider = new AdapterFactoryLabelProvider(
						TngAdapterFactory.INSTANCE
								.getOBS_ComposedAdapterFactory()){
					public String getColumnText(Object object, int index) {
						return super.getText(object);
					}
					
					public Image getColumnImage(Object object, int index) {
						return super.getImage(object);
					}
				};
			}
		} else {
			adapterFactory = TngAdapterFactory.INSTANCE
						.getItemsFilter_AdapterFactory(filter); 
			contentProvider = new AdapterFactoryContentProvider(adapterFactory);
			composedAdapterFactory = TngAdapterFactory.INSTANCE.getItemsFilter_ComposedAdapterFactory();
		}
	}

	public void setExistingElements(List list) {
		this.alreadySelectedList = list;
		if (helper != null) {
			helper.setAlreadySelectedList(list);
		}
	}

	public FilterHelper getHelper() {
		return this.helper;
	}

	public String[] getFilterTypeArray() {
		return null;
	}

	/*
	 * sets the ContentProvider used by TreeViewer.
	 */
	public void setContentProvider(IStructuredContentProvider contentProvider,
			ComposedAdapterFactory composedAdapterFactory) {
		this.contentProvider = contentProvider;
		this.composedAdapterFactory = composedAdapterFactory;
	}

	/*
	 * Passing String[] array fills the FilterType list in dropdown combo box.
	 */
	public void setTypes(String[] str) {
		this.types = str;
	}

	/*
	 * set the Filter.
	 */
	public void setFilter(IFilter filter) {
		this.filter = filter;
		if (helper != null) {
			if (this.filter instanceof org.eclipse.epf.library.edit.itemsfilter.IFilter) {
				((org.eclipse.epf.library.edit.itemsfilter.IFilter) this.filter)
						.setHelper(helper);
			} else if (this.filter instanceof DescriptorConfigurationFilter) {
				((DescriptorConfigurationFilter) this.filter).setHelper(helper);
			}
		}
	}

	public void setInput(Object input) {
		if (input != null) {
			this.input = input;
		}
	}

	public void setViewerLabel(String viewerLabel) {
		this.viewerLabel = viewerLabel;
	}
	/*
	 * 
	 */
	public void refreshTreeViewer(){
		try {
			// To improve performance of filter, filter first and reset visible to
			// true.This will avoid the flickering in UI at time of filtering
			// elements in the tree structure
			
			treeViewer.getTree().clearAll(true);
			treeViewer.getTree().setVisible(false);
			treeViewer.refresh();
			treeViewer.expandAll();
			treeViewer.getTree().setVisible(true);
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
	}
	/*
	 * 
	 */
	public void expandOrCollapse(boolean expand){
		treeViewer.getTree().setVisible(false);
		if(expand){
			treeViewer.expandAll();
		}else{
			treeViewer.collapseAll();
		}
		treeViewer.getTree().setVisible(true);
	}
	
	private Pattern getRegEx(String pattern){
		try{
			return PatternConstructor.createPattern(pattern, false, false);
		}catch(Exception e){
			return PatternConstructor.createPattern(FilterConstants.ANY_STRING, false, false); 
		}
	}
}