//------------------------------------------------------------------------------
// 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.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.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
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.Guidance;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
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.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.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.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;
	}

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

	/**
	 * Creates a new instance.
	 */
	public AssociationFormPage(FormEditor editor, String id, String name) {
		super(editor, id, name);
		this.editorTabName = name;
	}

	/**
	 * @see org.eclipse.ui.forms.editor.init(IEditorSite, 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);

		// form.setText(getFormPageTitlePrefix() + ": " +
		// contentElement.getName()); //$NON-NLS-1$
		form.setText(getFormPageTitlePrefix()
				+ ": " //$NON-NLS-1$
				+ TngUtil.getLabel((VariabilityElement) contentElement,
						"", true)); //$NON-NLS-1$

		// 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);
					// 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()) {
					form.setText(getFormPageTitlePrefix()
							+ ": " //$NON-NLS-1$
							+ TngUtil.getLabel(
									(VariabilityElement) contentElement,
									"", true)); //$NON-NLS-1$
				}
				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) {
									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) {
									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)) {
						ctrl_up1.setEnabled(true);
					} else
						ctrl_up1.setEnabled(false);
					if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
							.getTable().getItemCount() - 1
							&& !TngUtil.isLocked(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)) {
						ctrl_up1.setEnabled(true);
					} else
						ctrl_up1.setEnabled(false);
					if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
							.getTable().getItemCount() - 1
							&& !TngUtil.isLocked(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();
				}
			});
		}
	}

	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)) {
				ctrl_up1.setEnabled(true);
			} else
				ctrl_up1.setEnabled(false);

			if (viewer_selected.getTable().getSelectionIndex() < viewer_selected
					.getTable().getItemCount() - 1
					&& !TngUtil.isLocked(contentElement)) {
				ctrl_down1.setEnabled(true);
			} else
				ctrl_down1.setEnabled(false);
		} else if (isUpAndDownButtonsRequired1) {
			ctrl_up1.setEnabled(false);
			ctrl_down1.setEnabled(false);
			ctrl_ordering.setEnabled(true);
		}
	}

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

	/*
	 * (non-Javadoc)
	 * 
	 * @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 form page title prefix.
	 */
	private String getFormPageTitlePrefix() {
		String elementLabel = LibraryUIText.getUIText(methodElement);
		if (methodElement instanceof WorkProduct) {
			return LibraryUIText.TEXT_WORK_PRODUCT + " (" + elementLabel + ")"; //$NON-NLS-1$ //$NON-NLS-2$
		} else if (methodElement instanceof Guidance) {
			return LibraryUIText.TEXT_GUIDANCE + " (" + elementLabel + ")"; //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			return elementLabel;
		}
	}

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

	/**
	 * Returns the section description.
	 */
	protected String getSectionDescription() {
		// RATLC00478852 - 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));
	}

	public void setSectionDesc(String sectionDesc) {
		this.sectionDesc = sectionDesc;
	}

	public void setSelectedLabel(String selectedLabel1) {
		this.selectedLabel = selectedLabel1;
	}

	public void setSelectedLabel2(String selectedLabel2) {
		this.selectedLabel2 = selectedLabel2;
	}

	public void setSelectedLabel3(String selectedLabel3) {
		this.selectedLabel3 = selectedLabel3;
	}

	public void setCategoryIsSingleSelection1(boolean categoryIsSingleSelection1) {
		this.categoryIsSingleSelection1 = categoryIsSingleSelection1;
	}

	public void setCategoryIsSingleSelection2(boolean categoryIsSingleSelection2) {
		this.categoryIsSingleSelection2 = categoryIsSingleSelection2;
	}

	public void setCategoryIsSingleSelection3(boolean categoryIsSingleSelection3) {
		this.categoryIsSingleSelection3 = categoryIsSingleSelection3;
	}

	public void setUseCategory1(boolean useCategory1) {
		this.useCategory1 = useCategory1;
	}

	public void setUseCategory2(boolean useCategory2) {
		this.useCategory2 = useCategory2;
	}

	public void setUseCategory3(boolean useCategory3) {
		this.useCategory3 = useCategory3;
	}

	public void setAllowChange1(boolean allowChange1) {
		this.allowChange1 = allowChange1;
	}

	public void setAllowChange2(boolean allowChange2) {
		this.allowChange2 = allowChange2;
	}

	public void setAllowChange3(boolean allowChange3) {
		this.allowChange3 = allowChange3;
	}

	public void setIsUpAndDownButtonsRequired1(
			boolean isUpAndDownButtonsRequired1) {
		this.isUpAndDownButtonsRequired1 = isUpAndDownButtonsRequired1;
	}

	public void setIsUpAndDownButtonsRequired2(
			boolean isUpAndDownButtonsRequired2) {
		this.isUpAndDownButtonsRequired2 = isUpAndDownButtonsRequired2;
	}

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

	public void menuAboutToShow(IMenuManager menuManager) {
		menuManager.add(new Separator(org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS));
		menuManager.add(new ActionContributionItem(libraryViewFindElementAction));
	}
}
