//------------------------------------------------------------------------------
// 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.forms;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.EStructuralFeature;
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.actions.LibraryViewFindElementAction;
import org.eclipse.epf.authoring.ui.dialogs.ContentElementsOrderDialog;
import org.eclipse.epf.authoring.ui.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor;
import org.eclipse.epf.authoring.ui.util.EditorsContextHelper;
import org.eclipse.epf.authoring.ui.util.UIHelper;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.MoveInListCommand;
import org.eclipse.epf.library.edit.util.CategorySortHelper;
import org.eclipse.epf.library.edit.util.ContentElementOrderList;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.library.util.LibraryManager;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ComboViewer;
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.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;


/**
 * The base class for all Association type form pages in the Method editors.
 * 
 * @author Jeff Hardy
 * @author Shashidhar Kannoori
 * @author Kelvin Low
 * @since 1.0
 */
public class AssociationFormPage extends BaseFormPage implements IMenuListener {

	protected static final String PACKAGE_PREFIX = "AuthoringUI_"; //$NON-NLS-1$	

	protected IStructuredContentProvider contentProviderSelected;

	protected ILabelProvider labelProviderSelected = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getColumnText(Object object, int columnIndex) {
			return TngUtil.getLabelWithPath(object);
		}
	};

	protected IStructuredContentProvider contentProviderSelected2;

	protected ILabelProvider labelProviderSelected2 = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getColumnText(Object object, int columnIndex) {
			return TngUtil.getLabelWithPath(object);
		}
	};

	protected IStructuredContentProvider contentProviderSelected3;

	protected ILabelProvider labelProviderSelected3 = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getColumnText(Object object, int columnIndex) {
			return TngUtil.getLabelWithPath(object);
		}
	};

	protected Section aSection;

	protected Composite aComposite;
	
	protected Composite category1pane1;
	protected Composite category1pane2;
	protected Composite category2pane1;
	protected Composite category2pane2;
	protected Composite category3pane1;
	protected Composite category3pane2;

	protected TableViewer viewer_selected, viewer_selected2, viewer_selected3;

	protected Table ctrl_selected, ctrl_selected2, ctrl_selected3;

	protected Button ctrl_add, ctrl_remove, ctrl_add2, ctrl_remove2, ctrl_add3,
			ctrl_remove3;

	protected Button ctrl_up1, ctrl_down1, ctrl_up2, ctrl_down2, ctrl_up3,
			ctrl_down3;

	protected Text ctrl_briefDesc;

	protected Button ctrl_select, ctrl_clear;

	protected ArrayList usedCategories = new ArrayList();

	protected Label label_Category, label_Category2, label_Category3;

	private boolean useCategory1 = true;

	private boolean useCategory2 = true;

	private boolean useCategory3 = true;

	private boolean allowChange1 = true;

	private boolean allowChange2 = true;

	private boolean allowChange3 = true;

	protected boolean isUpAndDownButtonsRequired1 = false;

	protected boolean isUpAndDownButtonsRequired2 = false;

	protected boolean isUpAndDownButtonsRequired3 = false;

	protected boolean categoryIsSingleSelection1 = false;

	protected boolean categoryIsSingleSelection2 = false;

	protected boolean categoryIsSingleSelection3 = false;

	private LibraryViewFindElementAction libraryViewFindElementAction;
	// strings used in the form
	protected String formNamePrefix = "Form prefix"; //$NON-NLS-1$

	protected String sectionName = "Section name"; //$NON-NLS-1$

	protected String sectionDesc = "Section description"; //$NON-NLS-1$

	protected String selectedLabel = "Selected Label 1"; //$NON-NLS-1$

	protected String selectedLabel2 = "Selected Label 2"; //$NON-NLS-1$

	protected String selectedLabel3 = "Selected Label 3"; //$NON-NLS-1$

	// Data model methods.
	protected void addItemsToModel1(ArrayList newItems) {
	}

	protected void addItemsToModel2(ArrayList newItems) {
	}

	protected void addItemsToModel3(ArrayList newItems) {
	}

	protected void removeItemsFromModel1(ArrayList rmItems) {
	}

	protected void removeItemsFromModel2(ArrayList rmItems) {
	}

	protected void removeItemsFromModel3(ArrayList rmItems) {
	}

	protected void moveUpItemsInSelectedItems1(ArrayList moveUpItems) {
		if (!moveUpItems.isEmpty()) {
			EStructuralFeature feature = getOrderFeature();
			ContentElementOrderList orderList = getContentElementOrderList();
			if (feature != null && orderList != null) {
				MoveInListCommand cmd = new MoveInListCommand(
						contentElement, moveUpItems, orderList,
						feature, MoveInListCommand.UP);
				getActionManager().execute(cmd);
			}
		}
	}

	protected void moveDownItemsInSelectedItems1(ArrayList moveDownItems) {
		if (!moveDownItems.isEmpty()) {
			EStructuralFeature feature = getOrderFeature();
			ContentElementOrderList orderList = getContentElementOrderList();
			if (feature != null && orderList != null) {
				MoveInListCommand cmd = new MoveInListCommand(
						contentElement, moveDownItems, orderList,
						feature, MoveInListCommand.DOWN);
				getActionManager().execute(cmd);
			}
		}
	}
	
	// Viewer methods.
	protected void initContentProviderSelected() {
	}

	protected void initContentProviderSelected2() {
	}

	protected void initContentProviderSelected3() {
	}

	protected ContentElementOrderList getContentElementOrderList() {
		return null;
	}
	
	protected String[] getModelStructurePath() {
		return null;
	}
	
	protected Object getContentElement() {
		return null;
	}

	protected String getTabString() {
		return "contentelement";} //$NON-NLS-1$

	protected String getTabString2() {
		return getTabString();
	}

	protected String getTabString3() {
		return getTabString();
	}

	/*
	 * getFilterTypes should be override to pass types.
	 */
	protected String[] getFilterTypes(){
		return null;
	}
	/*
	 * getFilterTypes should be override to pass types.
	 */
	protected String[] getFilterTypes2(){
		return null;
	}
	/*
	 * getFilterTypes should be override to pass types.
	 */
	protected String[] getFilterTypes3(){
		return null;
	}

	protected MethodElementEditor editor = (MethodElementEditor) getEditor();

	// Filter info.
	protected IFilter filter, filter2, filter3;

	protected IFilter getFilter() {
		return filter;
	}

	protected IFilter getFilter2() {
		return filter;
	}

	protected IFilter getFilter3() {
		return filter;
	}

	// Ordering of contributed categorized elements in custom
	// categories
	protected Button ctrl_ordering;

	protected ComboViewer viewer_sort1;
	
	protected IStructuredContentProvider contentProviderSort = new AdapterFactoryContentProvider(
			TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory()) {
		public Object[] getElements(Object object) {
			List<String> sortTypesList = CategorySortHelper.getCategorySortTypes();
			return sortTypesList.toArray();
		}
	};

	protected ILabelProvider labelProviderSort = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getText(Object object) {
			if (object instanceof String) {
				String str = ((String)object);
				return CategorySortHelper.getSortTypeDisplayName(str);
			}
			return null;
		}
	};
	
	/**
	 * Creates a new instance.
	 */
	public AssociationFormPage(FormEditor editor, String id, String name) {
		super(editor, id, name);
		this.editorTabName = name;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.BaseFormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
	}

	/**
	 * @see org.eclipse.ui.forms.editor.createFormContent(IManagedForm)
	 */
	protected void createFormContent(IManagedForm managedForm) {
		super.createFormContent(managedForm);

		UIHelper.setFormText(form, contentElement);
		
		// Create a section.
		aSection = toolkit.createSection(form.getBody(), Section.TITLE_BAR
				| Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED);
		TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB);
		aSection.setLayoutData(td);
		aSection.setText(getSectionName());
		aSection.setDescription(getSectionDescription());
		aSection.setLayout(new GridLayout());

		aComposite = toolkit.createComposite(aSection);
		aComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		aComposite.setLayout(new GridLayout(2, false));
		aSection.setClient(aComposite);

		int numTablesUsed = 0;

		if (useCategory1)
			numTablesUsed++;
		if (useCategory2)
			numTablesUsed++;
		if (useCategory3)
			numTablesUsed++;

		if (useCategory1) {
			category1pane1 = createComposite(toolkit, aComposite, 1);
			label_Category = createLabel(toolkit, category1pane1, getSelectedLabel());

			if (categoryIsSingleSelection1)
				ctrl_selected = createTable(toolkit, category1pane1, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected = createTable(toolkit, category1pane1, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected = createTable(toolkit, category1pane1, MEDIUM_SIZE);
				else
					ctrl_selected = createTable(toolkit, category1pane1, SMALL_SIZE);
			}

			libraryViewFindElementAction = new LibraryViewFindElementAction(AuthoringUIResources.actionLabel_findElementInLibNav); 
			viewer_selected = new TableViewer(ctrl_selected);
			viewer_selected.setLabelProvider(labelProviderSelected);
			initContentProviderSelected();
			viewer_selected.setInput(contentElement);
			if (!isUpAndDownButtonsRequired1)
				viewer_selected.setSorter(new ViewerSorter());

			createContextMenuFor(viewer_selected);
			toolkit.paintBordersFor(category1pane1);

			category1pane2 = createCompositeForButtons(toolkit, aComposite);
			if (allowChange1) {
				ctrl_add = createButton(toolkit, category1pane2,
						(categoryIsSingleSelection1) ? SELECT_BUTTON
								: ADD_BUTTON);
				ctrl_remove = createButton(toolkit, category1pane2,
						(categoryIsSingleSelection1) ? CLEAR_BUTTON
								: REMOVE_BUTTON);

				if (isUpAndDownButtonsRequired1) {
					ctrl_up1 = createButton(toolkit, category1pane2, UP_BUTTON);
					ctrl_down1 = createButton(toolkit, category1pane2, DOWN_BUTTON);
					if (contentElement instanceof ContentCategory) {
						ctrl_ordering = createButton(toolkit, category1pane2, ORDER_BUTTON);
						ctrl_ordering.setEnabled(true);
						Combo ctrl_sort1 = createComboWithLabel(toolkit, category1pane2, LibraryEditResources.SortType_Label);
						viewer_sort1 = new ComboViewer(ctrl_sort1);
						viewer_sort1.setContentProvider(contentProviderSort);
						viewer_sort1.setLabelProvider(labelProviderSort);
						viewer_sort1.setInput(contentElement);
						// set initial selection
						String sortType = CategorySortHelper.getCategorySortValue(contentElement);
						viewer_sort1.setSelection(new StructuredSelection(sortType), true);
					}

					// ctrl_ordering.setLayoutData(new
					// GridData(GridData.FILL_HORIZONTAL));

				}
			}
			toolkit.paintBordersFor(category1pane2);
		}

		if (useCategory2) {
			category2pane1 = createComposite(toolkit, aComposite, 1);
			label_Category2 = createLabel(toolkit, category2pane1, getSelectedLabel2());
			if (categoryIsSingleSelection2)
				ctrl_selected2 = createTable(toolkit, category2pane1, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected2 = createTable(toolkit, category2pane1, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected2 = createTable(toolkit, category2pane1, MEDIUM_SIZE);
				else
					ctrl_selected2 = createTable(toolkit, category2pane1, SMALL_SIZE);
			}
			viewer_selected2 = new TableViewer(ctrl_selected2);
			viewer_selected2.setLabelProvider(labelProviderSelected2);
			initContentProviderSelected2();
			viewer_selected2.setInput(contentElement);
			viewer_selected2.setSorter(new ViewerSorter());
			createContextMenuFor(viewer_selected2);

			toolkit.paintBordersFor(category2pane1);

			category2pane2 = createCompositeForButtons(toolkit, aComposite);
			if (allowChange2) {
				ctrl_add2 = createButton(toolkit, category2pane2, ADD_BUTTON);
				ctrl_remove2 = createButton(toolkit, category2pane2, REMOVE_BUTTON);

				if (isUpAndDownButtonsRequired2) {
					ctrl_up2 = createButton(toolkit, category2pane2, UP_BUTTON);
					ctrl_down2 = createButton(toolkit, category2pane2, DOWN_BUTTON);
				}
			}
			toolkit.paintBordersFor(category2pane2);
		}

		if (useCategory3) {
			category3pane1 = createComposite(toolkit, aComposite, 1);
			label_Category3 = createLabel(toolkit, category3pane1, getSelectedLabel3());
			if (categoryIsSingleSelection3)
				ctrl_selected3 = createTable(toolkit, category3pane1, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected3 = createTable(toolkit, category3pane1, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected3 = createTable(toolkit, category3pane1, MEDIUM_SIZE);
				else
					ctrl_selected3 = createTable(toolkit, category3pane1, SMALL_SIZE);
			}
			viewer_selected3 = new TableViewer(ctrl_selected3);
			viewer_selected3.setLabelProvider(labelProviderSelected3);
			initContentProviderSelected3();
			viewer_selected3.setInput(contentElement);
			viewer_selected3.setSorter(new ViewerSorter());
			createContextMenuFor(viewer_selected3);

			toolkit.paintBordersFor(category3pane1);

			category3pane2 = createCompositeForButtons(toolkit, aComposite);
			if (allowChange3) {
				ctrl_add3 = createButton(toolkit, category3pane2, ADD_BUTTON);
				ctrl_remove3 = createButton(toolkit, category3pane2, REMOVE_BUTTON);

				if (isUpAndDownButtonsRequired3) {
					ctrl_up3 = createButton(toolkit, category3pane2, UP_BUTTON);
					ctrl_down3 = createButton(toolkit, category3pane2, DOWN_BUTTON);
				}
			}
			toolkit.paintBordersFor(category3pane2);
		}

		setEnabledAddButtons(true);

		setWidgetWidths();
		Composite pane7 = createComposite(toolkit, aComposite,
				GridData.FILL_BOTH, 1, 1, 1);
		ctrl_briefDesc = createTextEditWithLabelLarge(
				toolkit,
				pane7,
				AuthoringUIResources.AssociationFormPage_BriefDescriptionLabel); 
		ctrl_briefDesc.setEditable(false);
		toolkit.paintBordersFor(pane7);
		toolkit.paintBordersFor(aComposite);

		addListeners();

		setContextHelp();

	}

	protected void setEnabledAddButtons(boolean value) {
		if (allowChange1)
			ctrl_add.setEnabled(value);
		if (useCategory2 && allowChange2)
			ctrl_add2.setEnabled(value);
		if (useCategory3 && allowChange3)
			ctrl_add3.setEnabled(value);
	}

	protected void setEnabledRemoveButtons(boolean value) {
		if (allowChange1)
			ctrl_remove.setEnabled(value);
		if (useCategory2 && allowChange2)
			ctrl_remove2.setEnabled(value);
		if (useCategory3 && allowChange3)
			ctrl_remove3.setEnabled(value);
	}

	protected void disableButtonsAndDeselectTables() {
		// setEnabledAddButtons(false);
		setEnabledRemoveButtons(false);
		viewer_selected.setSelection(null, true);
		if (useCategory2)
			viewer_selected2.setSelection(null, true);
		if (useCategory3)
			viewer_selected3.setSelection(null, true);
		ctrl_briefDesc.setText(""); //$NON-NLS-1$
	}

	protected void refreshViewers() {

		viewer_selected.refresh();
		// Check if existing element is contributor/contributes for standard
		// categories
		// should not shown in the tableviewer.
		// Commented below to allow contributors to display in the list box
		// if(contentElement instanceof ContentCategory){
		// if(!(contentElement instanceof CustomCategory)){
		// Object[] elements =
		// contentProviderSelected.getElements(contentElement);
		// for(int i=0; i<elements.length; i++){
		// Object element = elements[i];
		// if(element instanceof ContentElement){
		// if(UIHelper.isContributor((ContentElement)element)){
		// viewer_selected.remove(element);
		// }
		// }
		// }
		// }
		// }

		if (useCategory2) {
			viewer_selected2.refresh();
			// if(contentElement instanceof ContentCategory){
			// Object[] elements =
			// contentProviderSelected2.getElements(contentElement);
			// for(int i=0; i<elements.length; i++){
			// Object element = elements[i];
			// if(element instanceof ContentElement){
			// if(UIHelper.isContributor((ContentElement)element)){
			// viewer_selected2.remove(element);
			// }
			// }
			// }
			// }

		}
		if (useCategory3) {
			viewer_selected3.refresh();
			// if(contentElement instanceof ContentCategory){
			// Object[] elements =
			// contentProviderSelected3.getElements(contentElement);
			// for(int i=0; i<elements.length; i++){
			// Object element = elements[i];
			// if(element instanceof ContentElement){
			// if(UIHelper.isContributor((ContentElement)element)){
			// viewer_selected3.remove(element);
			// }
			// }
			// }
			// }
		}
		ctrl_briefDesc.setText(""); //$NON-NLS-1$

	}

	/**
	 * Add listeners
	 * 
	 */
	protected void addListeners() {
		form.addListener(SWT.Activate, new Listener() {
			public void handleEvent(Event e) {
				if (form != null && !form.isDisposed()) {
					UIHelper.setFormText(form, contentElement);
				}
				refreshViewers();
				if (TngUtil.isLocked(contentElement)) {
					enableControls(false);
				} else {
					enableControls(true);
				}
			}
		});
		
		form.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				if (form != null && !form.isDisposed()) {
					UIHelper.setFormText(form, contentElement);
				}
				refreshViewers();
				if (TngUtil.isLocked(contentElement)) {
					enableControls(false);
				} else {
					enableControls(true);
				}
			}
		});

		if (useCategory1) {
			// Add focus listener on primary tasks list
			ctrl_selected.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					disableButtonsAndDeselectTables();

					IStructuredSelection selection = (IStructuredSelection) viewer_selected
							.getSelection();
					if (allowChange1 && selection.size() > 0
							&& !TngUtil.isLocked(contentElement)) {
						ctrl_remove.setEnabled(true);
					}
				}
			});

			viewer_selected
					.addSelectionChangedListener(new ISelectionChangedListener() {

						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_selected
									.getSelection();
							libraryViewFindElementAction.selectionChanged(event);
							if (allowChange1 && selection.size() > 0
									&& !TngUtil.isLocked(contentElement)) {
								ctrl_remove.setEnabled(true);
							}
							enableUpDownButtons1();

							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_briefDesc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_briefDesc
										.setText(getMultipleSelectDescription(selection
												.size()));
							}
						}

					});

			if (allowChange1) {
				ctrl_add.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						TableItem[] items = viewer_selected.getTable()
								.getItems();
						List selectedList = new ArrayList();
						for (int i = 0; i < items.length; i++) {
							selectedList.add(items[i].getData());
						}

						if (getFilter() != null) {
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(), getFilter(),
									getContentElement(), getTabString());
							fd.setBlockOnOpen(true);
							fd.setTitle(getTabString());
							if(categoryIsSingleSelection1){
								fd.setViewerSelectionSingle(true);
							}
							fd.setExistingElements(selectedList);
							if(getFilterTypes() != null){
								fd.setTypes(getFilterTypes());
							}
							fd.open();
							addItemsToModel1(fd.getSelectedItems());
						}
						// viewer_selected.refresh();
						refreshViewers();

					}
				});

				ctrl_remove.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						IStructuredSelection selection = (IStructuredSelection) viewer_selected
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItemsFromModel1(rmItems);
							// viewer_selected.refresh();
							refreshViewers();
							// clear the selection
							viewer_selected.setSelection(null, true);
							ctrl_briefDesc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove.setEnabled(false);
					}
				});
			}
		}

		if (useCategory2) {
			// Add focus listener on primary tasks list
			ctrl_selected2.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					disableButtonsAndDeselectTables();

					IStructuredSelection selection = (IStructuredSelection) viewer_selected2
							.getSelection();
					if (allowChange2 && selection.size() > 0
							&& !TngUtil.isLocked(contentElement)) {
						ctrl_remove2.setEnabled(true);
					}
				}
			});

			viewer_selected2
					.addSelectionChangedListener(new ISelectionChangedListener() {

						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_selected2
									.getSelection();
							libraryViewFindElementAction.selectionChanged(event);
							if (allowChange2 && selection.size() > 0
									&& !TngUtil.isLocked(contentElement)) {
								ctrl_remove2.setEnabled(true);
							}
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_briefDesc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_briefDesc
										.setText(getMultipleSelectDescription(selection
												.size()));
							}
						}

					});

			if (allowChange2) {
				ctrl_add2.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						TableItem[] items = viewer_selected2.getTable()
								.getItems();
						List selectedList = new ArrayList();
						for (int i = 0; i < items.length; i++) {
							selectedList.add(items[i].getData());
						}
						if (getFilter2() != null) {
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(), getFilter2(),
									getContentElement(), getTabString2());
							fd.setBlockOnOpen(true);
							fd.setTitle(getTabString2());
							fd.setExistingElements(selectedList);
							fd.open();
							addItemsToModel2(fd.getSelectedItems());
						}
						viewer_selected2.refresh();
					}
				});

				ctrl_remove2.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						IStructuredSelection selection = (IStructuredSelection) viewer_selected2
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItemsFromModel2(rmItems);
							viewer_selected2.refresh();

							// clear the selection
							viewer_selected2.setSelection(null, true);
							ctrl_briefDesc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove2.setEnabled(false);
					}
				});
			}
		}
		if (useCategory3) {
			// Add focus listener on primary tasks list
			ctrl_selected3.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					disableButtonsAndDeselectTables();

					IStructuredSelection selection = (IStructuredSelection) viewer_selected3
							.getSelection();
					if (allowChange3 && selection.size() > 0
							&& !TngUtil.isLocked(contentElement)) {
						ctrl_remove3.setEnabled(true);
					}
				}
			});

			viewer_selected3
					.addSelectionChangedListener(new ISelectionChangedListener() {

						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_selected3
									.getSelection();
							libraryViewFindElementAction.selectionChanged(event);
							if (allowChange3 && selection.size() > 0
									&& !TngUtil.isLocked(contentElement)) {
								ctrl_remove3.setEnabled(true);
							}
							if (selection.size() == 1) {
								String desc = ((MethodElement) selection
										.getFirstElement())
										.getBriefDescription();
								if (desc == null) {
									desc = ""; //$NON-NLS-1$
								}
								ctrl_briefDesc.setText(desc);
							} else if (selection.size() > 1) {
								ctrl_briefDesc
										.setText(getMultipleSelectDescription(selection
												.size()));
							}
						}

					});

			if (allowChange3) {
				ctrl_add3.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						TableItem[] items = viewer_selected3.getTable()
								.getItems();
						List selectedList = new ArrayList();
						for (int i = 0; i < items.length; i++) {
							selectedList.add(items[i].getData());
						}
						if (getFilter3() != null) {
							ItemsFilterDialog fd = new ItemsFilterDialog(
									PlatformUI.getWorkbench()
											.getActiveWorkbenchWindow()
											.getShell(), getFilter3(),
									getContentElement(), getTabString3());
							fd.setBlockOnOpen(true);
							fd.setTitle(getTabString3());
							fd.setExistingElements(selectedList);
							fd.open();
							addItemsToModel3(fd.getSelectedItems());
						}
						viewer_selected3.refresh();

					}
				});

				ctrl_remove3.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						IStructuredSelection selection = (IStructuredSelection) viewer_selected3
								.getSelection();
						if (selection.size() > 0) {
							// update the model
							ArrayList rmItems = new ArrayList();
							rmItems.addAll(selection.toList());
							removeItemsFromModel3(rmItems);
							viewer_selected3.refresh();

							// clear the selection
							viewer_selected3.setSelection(null, true);
							ctrl_briefDesc.setText(""); //$NON-NLS-1$
						}
						ctrl_remove3.setEnabled(false);
					}
				});
			}
		}

		if (allowChange1 && isUpAndDownButtonsRequired1) {
			ctrl_up1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_selected
							.getSelection();
					if (selection.size() > 0) {
						ArrayList moveUpItems = new ArrayList();
						moveUpItems.addAll(selection.toList());
						moveUpItemsInSelectedItems1(moveUpItems);
					}
					// viewer_selected.refresh();
					refreshViewers();
					enableUpDownButtons1();
				}
			});

			ctrl_down1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_selected
							.getSelection();
					if (selection.size() > 0) {
						ArrayList moveDownItems = new ArrayList();
						moveDownItems.addAll(selection.toList());
						moveDownItemsInSelectedItems1(moveDownItems);
					}
					// viewer_selected.refresh();
					refreshViewers();
					enableUpDownButtons1();
				}
			});

			if (ctrl_ordering != null) {
				ctrl_ordering.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						ContentElementsOrderDialog dlg = new ContentElementsOrderDialog(
								Display.getCurrent().getActiveShell(),
								contentElement, getActionManager());
						dlg.setFeature(getOrderFeature());
						dlg.open();
						if (allowChange1 && isUpAndDownButtonsRequired1) {
							String sortType = CategorySortHelper.getCategorySortValue(contentElement);
							viewer_sort1.setSelection(new StructuredSelection(sortType), true);
							viewer_sort1.refresh();
						}
					}
				});
			}
			
			if (viewer_sort1 != null) {
				viewer_sort1.addSelectionChangedListener(new ISelectionChangedListener() {
					public void selectionChanged(SelectionChangedEvent event) {
						IStructuredSelection selection = (IStructuredSelection) viewer_sort1
								.getSelection();
						String sortType = (String)selection.getFirstElement();
						if (!CategorySortHelper.getCategorySortValue(contentElement).equals(sortType)) {
							MethodElementProperty prop = CategorySortHelper.getCategorySortProperty(contentElement);
							
							if (prop == null) {			
								prop = CategorySortHelper.createNewSortProperty(sortType);
								getActionManager()
								.doAction(
										IActionManager.ADD,
										contentElement,
										UmaPackage.eINSTANCE
												.getMethodElement_MethodElementProperty(),
										prop, -1);
							}
							else {
								getActionManager().doAction(IActionManager.SET,
									prop,
									UmaPackage.eINSTANCE
											.getMethodElementProperty_Value(),
											sortType, -1);
							}
							LibraryView.getView().refreshViews();
						}
						refreshViewers();
						enableUpDownButtons1();
					}
				});
			}
		}
	}

	protected EStructuralFeature getOrderFeature() {
		// TODO Auto-generated method stub
		return null;
	}

	protected void enableControls(boolean editable) {
		if (useCategory1) {
			if (allowChange1) {
				ctrl_add.setEnabled(editable);
				IStructuredSelection selection = (IStructuredSelection) viewer_selected
						.getSelection();
				if (allowChange1 && selection.size() > 0
						&& !TngUtil.isLocked(contentElement)) {
					ctrl_remove.setEnabled(true);
				} else {
					ctrl_remove.setEnabled(false);

				}
			}
		}

		if (useCategory2) {
			if (allowChange2) {
				ctrl_add2.setEnabled(editable);
				IStructuredSelection selection = (IStructuredSelection) viewer_selected2
						.getSelection();
				if (allowChange2 && selection.size() > 0
						&& !TngUtil.isLocked(contentElement)) {
					ctrl_remove2.setEnabled(true);
				} else {
					ctrl_remove2.setEnabled(false);

				}
			}
		}
		if (useCategory3) {
			if (allowChange3) {
				ctrl_add3.setEnabled(editable);
				IStructuredSelection selection = (IStructuredSelection) viewer_selected3
						.getSelection();
				if (allowChange3 && selection.size() > 0
						&& !TngUtil.isLocked(contentElement)) {
					ctrl_remove3.setEnabled(true);
				} else {
					ctrl_remove3.setEnabled(false);

				}
			}
		}
		enableUpDownButtons1();
		if (isUpAndDownButtonsRequired1 && viewer_sort1 != null) {
			if (!TngUtil.isLocked(contentElement)) {
				viewer_sort1.getCombo().setEnabled(true);
			} else {
				viewer_sort1.getCombo().setEnabled(false);
			}
		}
	}

	void setDirty(boolean b) {
		// Phong (03/07/2005): the dirty state of the editor is already taken
		// care in MethodElementEditor, transparent from user
		// interaction. No firePropertyChange(PROP_DIRTY) should be called
		// somewhere else.
		// NOTE: unnecessary calls to firePropertyChange(PROP_DIRTY) will cause
		// performance problem.
		// firePropertyChange(PROP_DIRTY);
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#dispose()
	 */
	public void dispose() {
		if (usedCategories.size() > 0)
			LibraryManager.getInstance().releaseCategories(contentElement,
					usedCategories);

		if (labelProviderSelected != null) {
			labelProviderSelected.dispose();
		}
		if (labelProviderSelected2 != null) {
			labelProviderSelected2.dispose();
		}
		if (labelProviderSelected3 != null) {
			labelProviderSelected3.dispose();
		}
		super.dispose();
	}

	/**
	 * Returns the section name.
	 */
	protected String getSectionName() {
		return null;
	}

	/**
	 * Returns the section description.
	 */
	protected String getSectionDescription() {
		// TVT issue single quote 
		// Format should be done only for CategoryGuidancePage, AuthoringUI.categoryGuidancesPage.sectionDescription key 
		// have has replacement variable in its value. For more information check NLS_MESSAGEFORMAT_VAR
	   /* 
	    * NLS_MESSAGEFORMAT_VAR
	    Strings which contain replacement variables are processed by the  
	    MessageFormat class (single quote must be coded as 2 consecutive single  
	    quotes ''). Strings which do NOT contain replacement variables are NOT   
	    processed by the MessageFormat class (single quote must be coded as 1
		single quote ').*/
		
		if (methodElement instanceof ContentElement
				&& "categoryGuidancesPage".equalsIgnoreCase(getId())) { //$NON-NLS-1$
			return NLS.bind(getId() + "_sectionDescription", LibraryUIText.getUITextLower(methodElement)); //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * Returns the first selected lable.
	 */
	protected String getSelectedLabel() {
		// if (methodElement instanceof ContentCategory) {
		// return AuthoringUIResources.formatString(PACKAGE_PREFIX + getId() +
		// ".selectedLabel", LibraryUIText.getUIText(methodElement));
		// //$NON-NLS-1$
		// }
		return null;
	}

	/**
	 * Returns the second selected lable.
	 */
	protected String getSelectedLabel2() {
		return null;
	}

	/**
	 * Returns the third selected lable.
	 */
	protected String getSelectedLabel3() {
		return null;
	}

	/**
	 * Returns the multiple section description.
	 */
	protected String getMultipleSelectDescription(int count) {
		return getMultipleSelectDescription(count, getMultipleSelectDescriptionString()); //$NON-NLS-1$
	}

	/**
	 * Returns the multiple section description.
	 */
	protected String getMultipleSelectDescription(int count, String message) {
		return AuthoringUIResources.bind(message, new Integer(count));
	}
	
	protected String getMultipleSelectDescriptionString() {
		return AuthoringUIResources.roleCategoriesPage_multipleSelectDescription;
	}

	/**
	 * Set description for section
	 * @param sectionDesc
	 * 			Description
	 */
	public void setSectionDesc(String sectionDesc) {
		this.sectionDesc = sectionDesc;
	}

	/**
	 * Set first label
	 * @param selectedLabel1
	 */
	public void setSelectedLabel(String selectedLabel1) {
		this.selectedLabel = selectedLabel1;
	}

	/**
	 * Set second label
	 * @param selectedLabel2
	 */
	public void setSelectedLabel2(String selectedLabel2) {
		this.selectedLabel2 = selectedLabel2;
	}

	/**
	 * Set third label
	 * @param selectedLabel3
	 */
	public void setSelectedLabel3(String selectedLabel3) {
		this.selectedLabel3 = selectedLabel3;
	}

	/**
	 * Set an option for the first category to be either single selection or multiple selection
	 * @param categoryIsSingleSelection1
	 */
	public void setCategoryIsSingleSelection1(boolean categoryIsSingleSelection1) {
		this.categoryIsSingleSelection1 = categoryIsSingleSelection1;
	}

	/**
	 * Set an option for the second category to be either single selection or multiple selection
	 * @param categoryIsSingleSelection2
	 */
	public void setCategoryIsSingleSelection2(boolean categoryIsSingleSelection2) {
		this.categoryIsSingleSelection2 = categoryIsSingleSelection2;
	}

	/**
	 * Set an option for the third category to be either single selection or multiple selection
	 * @param categoryIsSingleSelection3
	 */
	public void setCategoryIsSingleSelection3(boolean categoryIsSingleSelection3) {
		this.categoryIsSingleSelection3 = categoryIsSingleSelection3;
	}

	/**
	 * Set an option to use first category
	 * @param useCategory1
	 */
	public void setUseCategory1(boolean useCategory1) {
		this.useCategory1 = useCategory1;
	}

	/**
	 * Set an option to use second category
	 * @param useCategory2
	 */
	public void setUseCategory2(boolean useCategory2) {
		this.useCategory2 = useCategory2;
	}

	
	/**
	 * Set an option to use third category
	 * @param useCategory3
	 */
	public void setUseCategory3(boolean useCategory3) {
		this.useCategory3 = useCategory3;
	}

	/**
	 * Set an option to allow changes for first table in UI
	 * @param allowChange1
	 */
	public void setAllowChange1(boolean allowChange1) {
		this.allowChange1 = allowChange1;
	}

	/**
	 * Set an option to allow changes for the second table in UI
	 * @param allowChange2
	 */
	public void setAllowChange2(boolean allowChange2) {
		this.allowChange2 = allowChange2;
	}

	/**
	 * Set an option to allow changes for third table.
	 * @param allowChange3
	 */
	public void setAllowChange3(boolean allowChange3) {
		this.allowChange3 = allowChange3;
	}

	/**
	 * Set an option to show first set of up/down buttons
	 * @param isUpAndDownButtonsRequired1
	 */
	public void setIsUpAndDownButtonsRequired1(
			boolean isUpAndDownButtonsRequired1) {
		this.isUpAndDownButtonsRequired1 = isUpAndDownButtonsRequired1;
	}

	/**
	 * Set an option to show second set of up/down buttons
	 * @param isUpAndDownButtonsRequired2
	 */
	public void setIsUpAndDownButtonsRequired2(
			boolean isUpAndDownButtonsRequired2) {
		this.isUpAndDownButtonsRequired2 = isUpAndDownButtonsRequired2;
	}

	/**
	 * Set an option to show third set of up/down buttons.
	 * @param isUpAndDownButtonsRequired3
	 */
	public void setIsUpAndDownButtonsRequired3(
			boolean isUpAndDownButtonsRequired3) {
		this.isUpAndDownButtonsRequired3 = isUpAndDownButtonsRequired3;
	}

	// calculate widths for labels and tables, based on width of labels
	protected void setWidgetWidths() {
		int allCategoriesWidth = 0, categoryWidth = 0, category2Width = 0, category3Width = 0;
		int largestWidth = 0;
		// if (useCategory1) allCategoriesWidth =
		// label_allCategories.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
		if (useCategory1)
			categoryWidth = label_Category
					.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
		if (useCategory2)
			category2Width = label_Category2.computeSize(SWT.DEFAULT,
					SWT.DEFAULT).x;
		if (useCategory3)
			category3Width = label_Category3.computeSize(SWT.DEFAULT,
					SWT.DEFAULT).x;

		if (useCategory1)
			largestWidth = Math.max(allCategoriesWidth, categoryWidth);
		if (useCategory2)
			largestWidth = Math.max(largestWidth, category2Width);
		if (useCategory3)
			largestWidth = Math.max(largestWidth, category3Width);

		if (useCategory1) {
			// ((GridData)label_allCategories.getLayoutData()).widthHint =
			// largestWidth;
			// ((GridData)ctrl_allAvailable.getLayoutData()).widthHint =
			// largestWidth;
			((GridData) label_Category.getLayoutData()).widthHint = largestWidth;
			((GridData) ctrl_selected.getLayoutData()).widthHint = largestWidth;
		}
		if (useCategory2) {
			((GridData) label_Category2.getLayoutData()).widthHint = largestWidth;
			((GridData) ctrl_selected2.getLayoutData()).widthHint = largestWidth;
		}
		if (useCategory3) {
			((GridData) label_Category3.getLayoutData()).widthHint = largestWidth;
			((GridData) ctrl_selected3.getLayoutData()).widthHint = largestWidth;
		}
	}

	protected IActionManager getActionManager() {
		FormEditor editor = getEditor();
		if (editor instanceof MethodElementEditor) {
			return ((MethodElementEditor) editor).getActionManager();
		}
		return null;
	}

	private void setContextHelp() {
		// in the future, we should check the subclass type to set up a
		// different
		// context page for ech type of associations
		EditorsContextHelper.setHelp(getPartControl(), getContentElement());
	}
	
	/**
	 * Create context menu for the given viewer
	 * @param viewer
	 */
	public void createContextMenuFor(final StructuredViewer viewer) {
		MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
		contextMenu.add(new Separator(org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS));
		contextMenu.setRemoveAllWhenShown(true);
		contextMenu.addMenuListener(this);
		Menu menu = contextMenu.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(contextMenu, viewer);
	}

	/**
	 * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	public void menuAboutToShow(IMenuManager menuManager) {
		menuManager.add(new Separator(org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS));
		menuManager.add(new ActionContributionItem(libraryViewFindElementAction));
	}
	
	protected void enableUpDownButtons1() {
		if (ctrl_up1 != null) {
			if (isShouldEnableUp1()) {
				ctrl_up1.setEnabled(true);
			} else {
				ctrl_up1.setEnabled(false);
			}
		}
		if (ctrl_down1 != null) {
			if (isShouldEnableDown1()) {
				ctrl_down1.setEnabled(true);
			} else {
				ctrl_down1.setEnabled(false);
			}
		}
	}
	
	protected boolean isShouldEnableUp1() {
		if (viewer_selected != null && contentElement != null) {
			IStructuredSelection selection = (IStructuredSelection) viewer_selected
				.getSelection();
			if (isUpAndDownButtonsRequired1 &&
					selection.size() == 1 &&
					viewer_selected.getTable().getSelectionIndex() > 0 &&
					!TngUtil.isLocked(contentElement) && 
					CategorySortHelper.isManualCategorySort(contentElement)) {
				return true;
			}
		} 
		return false;
	}
	
	protected boolean isShouldEnableDown1() {
		IStructuredSelection selection = (IStructuredSelection) viewer_selected
			.getSelection();
		if (isUpAndDownButtonsRequired1 &&
				selection.size() == 1 &&
				(viewer_selected.getTable().getSelectionIndex() < viewer_selected
					.getTable().getItemCount() - 1) &&
				!TngUtil.isLocked(contentElement) &&
				CategorySortHelper.isManualCategorySort(contentElement)) {
			return true;
		} else {
			return false;
		}
	}

}
