//------------------------------------------------------------------------------
// 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.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
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.util.CategorySortHelper;
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.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 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;

	private boolean isUpAndDownButtonsRequired1 = false;

	private boolean isUpAndDownButtonsRequired2 = false;

	private boolean isUpAndDownButtonsRequired3 = false;

	private boolean categoryIsSingleSelection1 = false;

	private boolean categoryIsSingleSelection2 = false;

	private 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) {
	}

	protected void moveDownItemsInSelectedItems1(ArrayList moveDownItems) {
	}
	
	// Viewer methods.
	protected void initContentProviderSelected() {
	}

	protected void initContentProviderSelected2() {
	}

	protected void initContentProviderSelected3() {
	}

	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) {
			Composite pane1 = createComposite(toolkit, aComposite, 1);
			label_Category = createLabel(toolkit, pane1, getSelectedLabel());

			if (categoryIsSingleSelection1)
				ctrl_selected = createTable(toolkit, pane1, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected = createTable(toolkit, pane1, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected = createTable(toolkit, pane1, MEDIUM_SIZE);
				else
					ctrl_selected = createTable(toolkit, pane1, 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(pane1);

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

				if (isUpAndDownButtonsRequired1) {
					ctrl_up1 = createButton(toolkit, pane2, UP_BUTTON);
					ctrl_down1 = createButton(toolkit, pane2, DOWN_BUTTON);
					ctrl_ordering = createButton(toolkit, pane2, ORDER_BUTTON);
					Combo ctrl_sort1 = createComboWithLabel(toolkit, pane2, 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(pane2);
		}

		if (useCategory2) {
			Composite pane3 = createComposite(toolkit, aComposite, 1);
			label_Category2 = createLabel(toolkit, pane3, getSelectedLabel2());
			if (categoryIsSingleSelection2)
				ctrl_selected2 = createTable(toolkit, pane3, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected2 = createTable(toolkit, pane3, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected2 = createTable(toolkit, pane3, MEDIUM_SIZE);
				else
					ctrl_selected2 = createTable(toolkit, pane3, 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(pane3);

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

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

		if (useCategory3) {
			Composite pane5 = createComposite(toolkit, aComposite, 1);
			label_Category3 = createLabel(toolkit, pane5, getSelectedLabel3());
			if (categoryIsSingleSelection3)
				ctrl_selected3 = createTable(toolkit, pane5, SINGLE_ROW);
			else {
				if (numTablesUsed == 1)
					ctrl_selected3 = createTable(toolkit, pane5, LARGE_SIZE);
				else if (numTablesUsed == 2)
					ctrl_selected3 = createTable(toolkit, pane5, MEDIUM_SIZE);
				else
					ctrl_selected3 = createTable(toolkit, pane5, 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(pane5);

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

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

		setEnabledAddButtons(true);

		setWidgetWidths();
		Composite pane7 = createComposite(toolkit, aComposite,
				GridData.FILL_BOTH, 1, 1, 1);
		ctrl_briefDesc = createTextEditWithLabelLarge(
				toolkit,
				pane7,
				AuthoringUIResources.AssociationFormPage_BriefDescriptionLabel); //$NON-NLS-1$
		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
	 * 
	 */
	private 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);
							}
							if (isUpAndDownButtonsRequired1
									&& selection.size() > 0
									&& !TngUtil.isLocked(contentElement)) {
								if (viewer_selected.getTable()
										.getSelectionIndex() > 0
										&& !TngUtil.isLocked(contentElement)
										&& selection.size() == 1 &&
										CategorySortHelper.isManualCategorySort(contentElement)) {
									ctrl_up1.setEnabled(true);
								} else
									ctrl_up1.setEnabled(false);

								if (viewer_selected.getTable()
										.getSelectionIndex() < viewer_selected
										.getTable().getItemCount() - 1
										&& !TngUtil.isLocked(contentElement)
										&& selection.size() == 1 &&
										CategorySortHelper.isManualCategorySort(contentElement)) {
									ctrl_down1.setEnabled(true);
								} else
									ctrl_down1.setEnabled(false);
							}

							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();
					if (viewer_selected.getTable().getSelectionIndex() > 0
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_up1.setEnabled(true);
					} else
						ctrl_up1.setEnabled(false);
					if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
							.getTable().getItemCount() - 1
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_down1.setEnabled(true);
					} else
						ctrl_down1.setEnabled(false);
				}
			});

			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();
					if (viewer_selected.getTable().getSelectionIndex() > 0
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_up1.setEnabled(true);
					} else
						ctrl_up1.setEnabled(false);
					if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
							.getTable().getItemCount() - 1
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_down1.setEnabled(true);
					} else
						ctrl_down1.setEnabled(false);
				}
			});

			ctrl_ordering.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					ContentElementsOrderDialog dlg = new ContentElementsOrderDialog(
							Display.getCurrent().getActiveShell(),
							contentElement, getActionManager());
					dlg.open();
					if (allowChange1 && isUpAndDownButtonsRequired1) {
						String sortType = CategorySortHelper.getCategorySortValue(contentElement);
						viewer_sort1.setSelection(new StructuredSelection(sortType), true);
						viewer_sort1.refresh();
					}
				}
			});
			
			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();
					}
					if (viewer_selected.getTable().getSelectionIndex() > 0
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_up1.setEnabled(true);
					} else
						ctrl_up1.setEnabled(false);
					if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
							.getTable().getItemCount() - 1
							&& !TngUtil.isLocked(contentElement) &&
							CategorySortHelper.isManualCategorySort(contentElement)) {
						ctrl_down1.setEnabled(true);
					} else
						ctrl_down1.setEnabled(false);
					refreshViewers();
				}
			});
		}
	}

	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);

				}
			}
		}
		IStructuredSelection selection = (IStructuredSelection) viewer_selected
				.getSelection();
		if (isUpAndDownButtonsRequired1 && selection.size() > 0
				&& !TngUtil.isLocked(contentElement)) {
			if (viewer_selected.getTable().getSelectionIndex() > 0
					&& !TngUtil.isLocked(contentElement) &&
					CategorySortHelper.isManualCategorySort(contentElement)) {
				ctrl_up1.setEnabled(true);
			} else
				ctrl_up1.setEnabled(false);

			if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
					.getTable().getItemCount() - 1
					&& !TngUtil.isLocked(contentElement) &&
					CategorySortHelper.isManualCategorySort(contentElement)) {
				ctrl_down1.setEnabled(true);
			} else
				ctrl_down1.setEnabled(false);
			viewer_sort1.getCombo().setEnabled(true);
		} else if (isUpAndDownButtonsRequired1 && selection.size() > 0) {
			// it's locked
			ctrl_up1.setEnabled(false);
			ctrl_down1.setEnabled(false);
			// if element is based on another, enable the Order button
			// so the user can view the realized order list
			if (contentElement.getVariabilityBasedOnElement() != null) {
				ctrl_ordering.setEnabled(true);
			} else {
				ctrl_ordering.setEnabled(false);
			}
			viewer_sort1.getCombo().setEnabled(false);
		} else if (isUpAndDownButtonsRequired1 && !TngUtil.isLocked(contentElement)) {
			// no selection
			ctrl_up1.setEnabled(false);
			ctrl_down1.setEnabled(false);
			ctrl_ordering.setEnabled(true);
			viewer_sort1.getCombo().setEnabled(true);
		} else if (isUpAndDownButtonsRequired1) {
			// it's locked and no selection
			viewer_sort1.getCombo().setEnabled(false);
			// if element is based on another, enable the Order button
			// so the user can view the realized order list
			if (contentElement.getVariabilityBasedOnElement() != null) {
				ctrl_ordering.setEnabled(true);
			} else {
				ctrl_ordering.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(PACKAGE_PREFIX + 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, PACKAGE_PREFIX + getId() + ".multipleSelectDescription");
	}

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

	/**
	 * 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));
	}
}
