//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.dialogs;

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

import 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.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.authoring.ui.providers.VariabilityElementLabelProvider;
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.MoveInCategoryCommand;
import org.eclipse.epf.library.edit.util.CategorySortHelper;
import org.eclipse.epf.library.edit.util.ContentElementOrderList;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
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.TableViewer;
import org.eclipse.swt.SWT;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;

/**
 * Open an dialog to order content elements
 * 
 * @author Shashidhar Kannoori
 * @since 1.0
 *
 */
public class ContentElementsOrderDialog extends Dialog {

	private Composite baseComposite;

	private Button ctrl_up, ctrl_down;

	private Table ctrl_steps;

	private TableViewer stepsTableViewer;

	private ContentElementOrderList allSteps;

	private IStructuredContentProvider stepsViewerContentProvider;

	private ILabelProvider stepsViewerLabelProvider;

	// private Task contentElement;
	private ContentElement contentElement;

	// the Element to use for sorting
	private MethodElement sortElement;

	private IActionManager actionManager;

	private ArrayList commands = new ArrayList();
	
	protected ComboViewer viewer_sort;
	
	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 <code>AdvancedSearchDialog</code> giveb the parent control.
	 * 
	 * @param parent
	 *            The parent control.
	 */
	public ContentElementsOrderDialog(Shell parent,
			ContentElement contentElement, IActionManager actionManager) {
		super(parent);
		this.contentElement = contentElement;
		if (TngUtil.isContributor(contentElement)) {
			this.sortElement = contentElement.getVariabilityBasedOnElement();
		} else {
			this.sortElement = contentElement;
		}
		this.actionManager = actionManager;
		allSteps = null;
	}

	/**
	 * @see Dialog#createDialogArea(Composite parent)
	 */
	protected Control createDialogArea(Composite parent) {
		baseComposite = (Composite) super.createDialogArea(parent);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 4;
		baseComposite.setLayout(gridLayout);
		baseComposite.setLayoutData(new GridData());

		// Empty line
		createLabel(baseComposite, " ", 4); //$NON-NLS-1$

		createLabel(baseComposite, " ", 1); //$NON-NLS-1$
		createLabel(
				baseComposite,
				AuthoringUIResources.ContentElementsOrderDialog_ContentElement_text, 3); //$NON-NLS-1$

		createLabel(baseComposite, " ", 1); //$NON-NLS-1$
		ctrl_steps = new Table(baseComposite, SWT.MULTI | SWT.BORDER);
		{
			GridData gridData = new GridData(GridData.FILL_BOTH);
			gridData.horizontalSpan = 2;
			gridData.widthHint = 300;
			gridData.heightHint = 400;
			ctrl_steps.setLayoutData(gridData);
		}

		initProviders();

		stepsTableViewer = new TableViewer(ctrl_steps);
		stepsTableViewer.setContentProvider(stepsViewerContentProvider);
		stepsTableViewer.setLabelProvider(stepsViewerLabelProvider);

		Composite orderButtonPane = new Composite(baseComposite, SWT.NULL);
		{
			GridData gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER
					| GridData.HORIZONTAL_ALIGN_CENTER);
			gridData.horizontalSpan = 1;
			orderButtonPane.setLayoutData(gridData);
			orderButtonPane.setLayout(new GridLayout());
		}

		ctrl_up = createButton(orderButtonPane, AuthoringUIText.UP_BUTTON_TEXT);
		ctrl_up.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		ctrl_down = createButton(orderButtonPane,
				AuthoringUIText.DOWN_BUTTON_TEXT);
		ctrl_down.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		ctrl_up.setEnabled(false);
		ctrl_down.setEnabled(false);

		createLabel(orderButtonPane, LibraryEditResources.SortType_Label, 1);
		Combo ctrl_sort = new Combo(orderButtonPane, SWT.SINGLE | SWT.FLAT | SWT.READ_ONLY);
		viewer_sort = new ComboViewer(ctrl_sort);
		viewer_sort.setContentProvider(contentProviderSort);
		viewer_sort.setLabelProvider(labelProviderSort);
		viewer_sort.setInput(contentElement);
		// set initial selection
		String sortType = CategorySortHelper.getCategorySortValue(sortElement);
		viewer_sort.setSelection(new StructuredSelection(sortType), true);

		// Empty line
		createLabel(baseComposite, " ", 4); //$NON-NLS-1$

		createLine(baseComposite, 4);

		super
				.getShell()
				.setText(
						AuthoringUIResources.ContentElementsOrderDialog_description_text); //$NON-NLS-1$

		addListeners();
		loadData();

		// contributors cannot change the sort type - the base element's sort is used
		if (TngUtil.isContributor(contentElement)) {
			viewer_sort.getCombo().setEnabled(false);
		}
		if (TngUtil.isLocked(contentElement)) {
			viewer_sort.getCombo().setEnabled(false);
		} else {
			viewer_sort.getCombo().setEnabled(true);
		}

		return baseComposite;
	}

	private void createLine(Composite parent, int ncol) {
		Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
				| SWT.BOLD);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = ncol;
		line.setLayoutData(gridData);
	}

	private Label createLabel(Composite parent, String text, int nCol) {
		Label label = new Label(parent, SWT.NONE);
		label.setText(text);
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan = nCol;
			label.setLayoutData(gridData);
		}

		return label;
	}

	private Button createButton(Composite parent, String label) {
		Button button = new Button(parent, SWT.NONE);
		button.setText(label);
		return button;
	}

	/**
	 * Creates the dialog buttons.
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		// Create the OK button.
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);

		// Create the Cancel button.
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	private void initProviders() {
		stepsViewerContentProvider = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				if (allSteps == null) {
					allSteps = new ContentElementOrderList(
							contentElement,
							ContentElementOrderList.CONTENT_ELEMENTS__FOR_ELEMENT_AND_PARENTS);
				}
				List returnList = CategorySortHelper.sortCategoryElements(sortElement, allSteps.toArray());
				return returnList.toArray();
			}
		};

		stepsViewerLabelProvider = new VariabilityElementLabelProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {

			public boolean isExternal(Object element) {
				return !((CustomCategory) contentElement)
						.getCategorizedElements().contains(element);
			}

		};
	}

	public void addListeners() {

		stepsTableViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {

					public void selectionChanged(SelectionChangedEvent event) {
						IStructuredSelection selection = (IStructuredSelection) stepsTableViewer
								.getSelection();
						if (selection.size() > 0
								&& !TngUtil.isLocked(contentElement)) {
							if (stepsTableViewer.getTable().getSelectionIndex() > 0
									&& !TngUtil.isLocked(contentElement)
									&& selection.size() == 1 &&
									CategorySortHelper.isManualCategorySort(sortElement)) {
								ctrl_up.setEnabled(true);
							} else
								ctrl_up.setEnabled(false);

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

				});

		ctrl_up.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) stepsTableViewer
						.getSelection();

				ArrayList moveUpItems = new ArrayList();
				moveUpItems.addAll(selection.toList());
				EStructuralFeature feature = UmaPackage.eINSTANCE
						.getCustomCategory_CategorizedElements();
				MoveInCategoryCommand cmd = new MoveInCategoryCommand(
						(CustomCategory) contentElement, moveUpItems, allSteps,
						feature, ModelStructure.DEFAULT.customCategoryPath, 1);
				actionManager.execute(cmd);
				commands.add(cmd);

				refreshViewers();

				if (stepsTableViewer.getTable().getSelectionIndex() > 0
						&& !TngUtil.isLocked(contentElement) &&
						CategorySortHelper.isManualCategorySort(sortElement)) {
					ctrl_up.setEnabled(true);
				} else
					ctrl_up.setEnabled(false);
				if (stepsTableViewer.getTable().getSelectionIndex() < stepsTableViewer
						.getTable().getItemCount() - 1
						&& !TngUtil.isLocked(contentElement) &&
						CategorySortHelper.isManualCategorySort(sortElement)) {
					ctrl_down.setEnabled(true);
				} else
					ctrl_down.setEnabled(false);
			}
		});

		ctrl_down.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) stepsTableViewer
						.getSelection();
				ArrayList moveDownItems = new ArrayList();
				moveDownItems.addAll(selection.toList());
				EStructuralFeature feature = UmaPackage.eINSTANCE
						.getCustomCategory_CategorizedElements();
				MoveInCategoryCommand cmd = new MoveInCategoryCommand(
						(CustomCategory) contentElement, moveDownItems, allSteps,
						feature, ModelStructure.DEFAULT.customCategoryPath,	0);
				actionManager.execute(cmd);
				commands.add(cmd);

				refreshViewers();

				if (stepsTableViewer.getTable().getSelectionIndex() > 0
						&& !TngUtil.isLocked(contentElement) &&
						CategorySortHelper.isManualCategorySort(sortElement)) {
					ctrl_up.setEnabled(true);
				} else
					ctrl_up.setEnabled(false);
				if (stepsTableViewer.getTable().getSelectionIndex() < stepsTableViewer
						.getTable().getItemCount() - 1
						&& !TngUtil.isLocked(contentElement) &&
						CategorySortHelper.isManualCategorySort(sortElement)) {
					ctrl_down.setEnabled(true);
				} else
					ctrl_down.setEnabled(false);
			}
		});
		
		viewer_sort.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection selection = (IStructuredSelection) viewer_sort
						.getSelection();
				String sortType = (String)selection.getFirstElement();
				MethodElementProperty prop = CategorySortHelper.getCategorySortProperty(contentElement);
				
				if (prop == null) {
					prop = CategorySortHelper.createNewSortProperty(sortType);
					actionManager
					.doAction(
							IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE
									.getMethodElement_MethodElementProperty(),
							prop, -1);
				}
				else {
					actionManager.doAction(IActionManager.SET,
						prop,
						UmaPackage.eINSTANCE
								.getMethodElementProperty_Value(),
								sortType, -1);
				}
				refreshViewers();
			}
		});

	}
	
	private void refreshViewers() {
		stepsTableViewer.refresh();
	}

	/**
	 * Load initial data from model
	 */
	private void loadData() {
		stepsTableViewer.setInput(contentElement);
	}

	/**
	 * Called when the OK button is selected.
	 */
	protected void okPressed() {
		allSteps.apply();
		super.okPressed();
	}

	protected void cancelPressed() {
		if (!commands.isEmpty()) {
			for (int i = commands.size() - 1; i > -1; i--) {
				Object cmd = commands.get(i);
				if (cmd instanceof MoveInCategoryCommand) {
					((MoveInCategoryCommand) cmd).undo();
				}
			}
		}
		super.cancelPressed();
	}

}