//------------------------------------------------------------------------------
// 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.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
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.properties.AbstractSection;
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.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodElementUtil;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
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.MethodLibrary;
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.Scope;
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 BaseItemsFilterDialog 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;
	
	private ProcessScopeUtil processUtil = ProcessScopeUtil.getInstance();
	
	private Combo selectCombo;
	
	private final String[] selectComboItems = {
			AuthoringUIResources.FilterDialog_Process_Scope_Grp_referencedPluginsBtn,
			AuthoringUIResources.FilterDialog_Process_Scope_Grp_selectedPluginsBtn,
			AuthoringUIResources.FilterDialog_Process_Scope_Grp_libBtn,
			AuthoringUIResources.FilterDialog_Process_Scope_Grp_configBtn
			};

	private Button viewBtn;
	
	private boolean enableProcessScope = false;
	
	private AbstractSection section;
	
	private Process configFreeProcess;
	
	private List selectedMethodPlugins = new ArrayList();
	
	private String PLUGIN_LIST_SECTION = ".Plugin_List_Section"; //$NON-NLS-1$
	
	private String PLUGIN_LIST_KEY = "Plugin_List_Key"; //$NON-NLS-1$
	
	/*
	 * 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.FILL_HORIZONTAL);
			gD1.horizontalSpan = 2;
			filterType.setLayoutData(gD1);
		}

		if (types == null) {
			fillFilterTypeCombo();
			if(helper != null) {
				helper.setFilterTypeStr(filterTypeStr);
			}
		} else {
			filterType.setItems(types);
			if (helper != null) {
				filterTypeStr = filterType.getItem(0);
				helper.setFilterTypeStr(filterTypeStr);
				if (tabStr == null) {
					tabStr = filterTypeStr;
					helper.setTabStr(tabStr);
				}
			}
		}
		filterType.select(0);
		
		//for config free process
		if (supportProcessScope(contentElement)) {
			createSelectionScope(composite);
		}
		
		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 = 500;
			ctrl_patternLabel1.setLayoutData(gD);
		}
		
		Composite buttonsComposite = new Composite(composite, SWT.NONE);		
		
		GridData gd2 = new GridData(GridData.FILL_HORIZONTAL
			| GridData.HORIZONTAL_ALIGN_END);
		gd2.horizontalSpan = 3;
		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();
		
		//initialize for process scope
		if (supportProcessScope(contentElement)) {
			selectCombo.select(0);
			updateBtnStatus();
			updateFilterDialog();
		}
		
		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.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.ONLY_CONTENT_ELEMENTS.equals(tabStr)) {
			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.ESTIMATE_CONSIDERATIONS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.EXAMPLES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.GUIDELINES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.PRACTICES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REPORTS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REUSABLE_ASSETS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.ROADMAP;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.SUPPORTING_MATERIALS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TEMPLATES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TERM_DEFINITIONS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.WHITE_PAPERS;
			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;
			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[28];
			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.ESTIMATE_CONSIDERATIONS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.EXAMPLES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.GUIDELINES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.PRACTICES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REPORTS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.REUSABLE_ASSETS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.ROADMAP;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.SUPPORTING_MATERIALS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TEMPLATES;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TERM_DEFINITIONS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.space
					+ FilterConstants.WHITE_PAPERS;
			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);
			}
		});
		
		if (supportProcessScope(contentElement)) {			
			selectCombo.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					updateBtnStatus();
					updateFilterDialog();
				}
			});
						
			viewBtn.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					int index = selectCombo.getSelectionIndex();
					
					if (index == 0) {					
						showPluginListDialog(true);
					} 
					
					if (index == 1) {
						showPluginListDialog(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); 
		}
	}
	
	private void createSelectionScope(Composite parent) {
		Label selectLabel = new Label(parent, SWT.NONE);
		selectLabel.setText(AuthoringUIResources.FilterDialog_Process_Scope_Grp);
		
		selectCombo = new Combo(parent, SWT.READ_ONLY);		
		selectCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		selectCombo.setItems(selectComboItems);
		
		viewBtn = new Button(parent, SWT.PUSH);
		viewBtn.setText(AuthoringUIResources.FilterDialog_Process_Scope_Grp_viewBtn);
		viewBtn.setEnabled(false);
	}
		
	private boolean supportProcessScope(Object inputElement) {
		boolean result = false;
		
		if (enableProcessScope) {
			if (inputElement instanceof BreakdownElement) {
				Process process = getProcess((BreakdownElement)inputElement);
				result = processUtil.isConfigFree(process);
				if (result) {
					configFreeProcess = process;
				}
			}	
		}

		return result;
	}
	
	private Process getProcess(BreakdownElement element) {
		AdapterFactory aFactory = TngAdapterFactory.INSTANCE
				.getWBS_ComposedAdapterFactory();
		ItemProviderAdapter adapter = (ItemProviderAdapter) aFactory.adapt(
				element, ITreeItemContentProvider.class);
		Object obj = ProcessUtil.getRootProcess(aFactory, adapter, element);
		
		return (Process) obj;
	}
	
	private void updateBtnStatus() {
		int index = selectCombo.getSelectionIndex();
		
		if ((index == 0) || (index == 1)) {
			viewBtn.setEnabled(true);
		} else {
			viewBtn.setEnabled(false);
		}
	}
	
	private void updateFilterDialog() {
		int index = selectCombo.getSelectionIndex();
		
		if (index == 0) {
			processUtil.setElemementSelectionScopeType(ProcessScopeUtil.ScopeType_Process);				
		}
		
		if (index == 1) {
			processUtil.setElemementSelectionScopeType(ProcessScopeUtil.ScopeType_Plugins);
			restoreDialogSettingsForPluginList();
			Scope pluginScope = processUtil.getPluginScope();
			pluginScope.clearAll();
			for (Object plugin : selectedMethodPlugins) {
				pluginScope.addPlugin((MethodPlugin)plugin);
			}			
		}
		
		if (index == 2) {
			processUtil.setElemementSelectionScopeType(ProcessScopeUtil.ScopeType_Library);
		}
		
		if (index == 3) {
			processUtil.setElemementSelectionScopeType(ProcessScopeUtil.ScopeType_Config);
		}
		
		updateFilter();
		
		initProviderForTabs();
		refreshTreeViewer();
	}
	
	/**
	 * Methods setEnableProcessScope() and setSection() must be used together, client should
	 * call those two methods together when want to support process scope selection under
	 * config-free process situation.
	 * 
	 * Example: please see /org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/properties/RelationSection.java
	 * 
	 */	
	public void setEnableProcessScope(boolean enableProcessScope) {
		this.enableProcessScope = enableProcessScope;
	}
	
	public void setSection(AbstractSection section) {
		this.section = section;
	}
	
	private void updateFilter() {
		if (section != null) {
			if (filter instanceof DescriptorConfigurationFilter) {
				((DescriptorConfigurationFilter)filter).setMethodConfiguration(section.getConfiguration());
			}
		}	
	}
	
	private void showPluginListDialog(boolean readOnly) {
		List referencedMethodPlugins = processUtil.getScope(configFreeProcess).getMethodPluginSelection();
		PluginListDialog dialog = null;
		
		if (readOnly) {
			dialog = new PluginListDialog(this.getShell(), true, referencedMethodPlugins);
			dialog.open();
		} else {
			dialog = new PluginListDialog(this.getShell(), false, selectedMethodPlugins);
			if (dialog.open() == Dialog.OK) {
				List plugins = dialog.getResults();
				Scope pluginScope = processUtil.getPluginScope();
				pluginScope.clearAll();
				selectedMethodPlugins.clear();
				for (Object obj : plugins) {
					if (obj instanceof MethodPlugin) {
						pluginScope.addPlugin((MethodPlugin)obj);
						selectedMethodPlugins.add(obj);
					}
				}				
				refreshTreeViewer();
				saveDialogSettingsForPluginList();
			}
		}
	}
	
	private IDialogSettings getDialogSettingsForPluginList() {
		IDialogSettings dialogSettings = AuthoringUIPlugin.getDefault().getDialogSettings();
		String processId = configFreeProcess.getGuid();
		IDialogSettings section = dialogSettings.getSection(processId + PLUGIN_LIST_SECTION);
		if (section == null) {
			section = dialogSettings.addNewSection(processId + PLUGIN_LIST_SECTION);
		}
		
		return section;
	}
	
	private void saveDialogSettingsForPluginList() {
		IDialogSettings settings = getDialogSettingsForPluginList();
		String[] pluginId = new String[selectedMethodPlugins.size()];
		
		for (int i = 0; i < selectedMethodPlugins.size(); i++) {
			pluginId[i] = ((MethodPlugin)selectedMethodPlugins.get(i)).getGuid();			
		}
		
		settings.put(PLUGIN_LIST_KEY, pluginId);
	}
	
	private void restoreDialogSettingsForPluginList() {
		IDialogSettings settings = getDialogSettingsForPluginList();
		String[] pluginId = settings.getArray(PLUGIN_LIST_KEY);
		MethodLibrary lib = LibraryEditUtil.getInstance().getCurrentMethodLibrary();
		if (lib != null) {
			List allMethodPluginsInLibrary = lib.getMethodPlugins();		
			if (pluginId != null) {
				selectedMethodPlugins.clear();
				for (Object plugin : allMethodPluginsInLibrary) {
					String tempId = ((MethodPlugin)plugin).getGuid();
					for (String id : pluginId) {
						if (tempId.equals(id)) {
							selectedMethodPlugins.add(plugin);
							break;
						}
					}
				}		
			}
		}
	}
	
}
