//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.properties;

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

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.providers.VariabilityElementLabelProvider;
import org.eclipse.epf.library.edit.IConfigurationApplicator;
import org.eclipse.epf.library.edit.Providers;
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.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
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.TableViewer;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;


/**
 * The task descriptor - step section
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class TaskDescriptorStepSection extends AbstractSection {

	protected ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory());

	private TaskDescriptor element;

	private IActionManager actionMgr;

	private FormToolkit toolkit;

	private Button ctrl_add, ctrl_remove, ctrl_up, ctrl_down;

	private Table ctrl_selected;

	private TableViewer viewer;

	// private Text ctrl_brief_desc;
	private Image titleImage;


	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {

		super.createControls(parent, tabbedPropertySheetPage);
		init();

		parent.setLayout(new GridLayout());
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));

		// create steps section
		createStepSection(parent);

		addListeners();

	}

	/**
	 * Initialize
	 *
	 */
	private void init() {
		// get activity object
		element = (TaskDescriptor) getElement();

		// get toolkit
		toolkit = getWidgetFactory();

		// get action manager
		actionMgr = EPFPropertySheetPage.getActionManager();
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof TaskDescriptor) {
				element = (TaskDescriptor) getElement();
				viewer.refresh();

				// hide/refresh controls
				updateControls();
			}
		} catch (Exception ex) {
			logger.logError("Error refreshing TaskDescriptor step section" + element, ex);  //$NON-NLS-1$
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#dispose()
	 */
	public void dispose() {
		super.dispose();

		if (labelProvider != null) {
			labelProvider.dispose();
		}
	}

	/**
	 * Update controls based on editable flag. Controls will be either editable 
	 * or read-only after updating this.
	 */
	public void updateControls() {
		ctrl_add.setEnabled(editable);
		if (element.getTask() == null)
			ctrl_add.setEnabled(false);
		else {
			List steps = getSteps();
			if (steps != null && steps.size() > 0) 
				ctrl_add.setEnabled(true);
			else 
				ctrl_add.setEnabled(false);
		}
		
		IStructuredSelection selection = (IStructuredSelection) viewer
				.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove.setEnabled(editable);
			ctrl_up.setEnabled(editable);
			ctrl_down.setEnabled(editable);
		} else {
			ctrl_remove.setEnabled(false);
			ctrl_up.setEnabled(false);
			ctrl_down.setEnabled(false);

		}
	}

	/**
	 * Create Step section on the given composite
	 * @param composite
	 */
	private void createStepSection(Composite composite) {
		// create step section
		Section stepSection = FormUI
				.createSection(
						toolkit,
						composite,
						PropertiesResources.TaskDescriptor_stepInformationTitle, 
						PropertiesResources.TaskDescriptor_stepInformationDescription); 

		// create step composite
		Composite stepComposite = FormUI.createComposite(toolkit, stepSection,
				2, false);

		// create table composite
		Composite pane1 = FormUI.createComposite(toolkit, stepComposite,
				GridData.FILL_BOTH);
		FormUI.createLabel(toolkit, pane1, PropertiesResources.TaskDescriptor_Selected_Steps); 

		ctrl_selected = FormUI.createTable(toolkit, pane1);
		viewer = new TableViewer(ctrl_selected);

		IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				return element.getSelectedSteps().toArray();
			}
		};

		viewer.setContentProvider(contentProvider);
		viewer.setLabelProvider(labelProvider);
		viewer.setInput(element);

		// create button composite
		Composite pane2 = FormUI.createComposite(toolkit, stepComposite,
				GridData.VERTICAL_ALIGN_CENTER
						| GridData.HORIZONTAL_ALIGN_CENTER);

		// create buttons
		ctrl_add = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Add);
		ctrl_add.setEnabled(false);
		ctrl_remove = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Remove); 
		ctrl_remove.setEnabled(false);
		ctrl_up = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Up); 
		ctrl_down = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Down); 

		if (element.getTask() != null) {
			List steps = getSteps();
			if (steps != null && steps.size() > 0) {
				ctrl_add.setEnabled(true);
			}
		}
		// create brief description
		// int heightHint = 40;
		// int horizontalSpan = 2;
		// Label label = FormUI.createLabel(toolkit, stepComposite,
		// PropertiesResources.getString("Process.briefDescription"),
		// heightHint);
		// ctrl_brief_desc = FormUI.createText(toolkit, stepComposite,
		// heightHint, heightHint);
		// ctrl_brief_desc.setEditable(false);
		//		
		toolkit.paintBordersFor(stepComposite);
		toolkit.paintBordersFor(pane1);

	}

	/**
	 * Add listeners
	 */
	private void addListeners() {
		// Add focus listener on primary tasks list
		ctrl_selected.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if ((selection.size() > 0) && editable) {
					ctrl_remove.setEnabled(editable);
					ctrl_up.setEnabled(editable);
					ctrl_down.setEnabled(editable);
				}
			}
		});

		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if ((selection.size() > 0) && editable) {
					ctrl_remove.setEnabled(true);

					if (viewer.getTable().getSelectionIndex() > 0
							&& selection.size() == 1) {
						ctrl_up.setEnabled(true);
					} else
						ctrl_up.setEnabled(false);

					if (viewer.getTable().getSelectionIndex() < viewer
							.getTable().getItemCount() - 1
							&& selection.size() == 1) {
						ctrl_down.setEnabled(true);
					} else
						ctrl_down.setEnabled(false);

				}

				if (selection.size() == 1) {
					String desc = ((MethodElement) selection.getFirstElement())
							.getBriefDescription();
					if (desc == null) {
						desc = ""; //$NON-NLS-1$
					}
					// ctrl_brief_desc.setText(desc);
				} else if (selection.size() > 1) {
					// ctrl_brief_desc.setText(PropertiesResources.getString("Process.MultipleSelection")
					// + " - " + selection.size());
				}
			}
		});

		ctrl_add.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredContentProvider stepContentProvider = new AdapterFactoryContentProvider(
						TngAdapterFactory.INSTANCE
								.getNavigatorView_ComposedAdapterFactory()) {
					public Object[] getElements(Object object) {

						return getSteps().toArray();
//						// get all steps
//						IConfigurationApplicator configApplicator = Providers
//								.getConfigurationApplicator();
//						MethodConfiguration config = TngUtil.getOwningProcess(
//								element).getDefaultContext();
//						List steps = (List) configApplicator.getReference(
//								element.getTask(), UmaPackage.eINSTANCE
//										.getTask_Steps(), config);
//
//						// remove already existing steps
//						steps.removeAll(element.getSelectedSteps());
//						return steps.toArray();
					}
				};

				ILabelProvider stepLabelProvider = new VariabilityElementLabelProvider(
						TngAdapterFactory.INSTANCE
								.getNavigatorView_ComposedAdapterFactory()) {

					public boolean isExternal(Object obj) {

						boolean flag = !element.getTask().getPresentation()
								.getSections().contains(obj);
						return flag;
					}
				};

				ListSelectionDialog dlg = new ListSelectionDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						element.getTask(), stepContentProvider,
						stepLabelProvider, PropertiesResources.TaskDescriptor_StepDialogMessage); 
				titleImage = Display.getCurrent().getActiveShell().getImage();
				ListSelectionDialog.setDefaultImage(titleImage);
				dlg.setTitle(PropertiesResources.TaskDescriptor_StepDialogTitle);
				dlg.setBlockOnOpen(true);
				dlg.open();

				addSteps(dlg.getResult());
				
				// enable/disable add button
				List steps = getSteps();
				if (steps != null && steps.size() > 0) 
					ctrl_add.setEnabled(true);
				else 
					ctrl_add.setEnabled(false);
				
				viewer.refresh();
			}
		});

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

					// clear the selection
					viewer.setSelection(null, true);
					// ctrl_brief_desc.setText("");
				}
				// ctrl_remove.setEnabled(false);
				
				// enable/disable add button
				List steps = getSteps();
				if (steps != null && steps.size() > 0) 
					ctrl_add.setEnabled(true);
				else 
					ctrl_add.setEnabled(false);
			}
		});

		ctrl_up.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ArrayList steps = new ArrayList();
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					ArrayList items = new ArrayList();
					items.addAll(selection.toList());
					BasicEList stepList = (BasicEList) element
							.getSelectedSteps();

					for (Iterator it = items.iterator(); it.hasNext();) {
						Object object = it.next();
						int index = stepList.indexOf(object);
						if (index > 0)
							stepList.move(index - 1, object);

					}
					steps.addAll(stepList);
					// TODO - write a command. 
					// activate dirty flag
					actionMgr.doAction(IActionManager.REMOVE_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(),
							stepList, -1);
					actionMgr.doAction(IActionManager.ADD_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(), steps,
							-1);

					viewer.refresh();
				}

				if (viewer.getTable().getSelectionIndex() > 0 && editable)
					ctrl_up.setEnabled(true);
				else
					ctrl_up.setEnabled(false);

				if (viewer.getTable().getSelectionIndex() < viewer.getTable()
						.getItemCount() - 1
						&& editable)
					ctrl_down.setEnabled(true);
				else
					ctrl_down.setEnabled(false);
			}

		});

		ctrl_down.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ArrayList steps = new ArrayList();
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					ArrayList items = new ArrayList();
					items.addAll(selection.toList());
					BasicEList stepList = (BasicEList) element
							.getSelectedSteps();

					for (Iterator it = items.iterator(); it.hasNext();) {
						Object object = it.next();
						int index = stepList.indexOf(object);

						if (index < stepList.size() - 1)
							stepList.move(index + items.size(), object);

					}
					steps.addAll(stepList);

					// TODO - write a cmmand. Hacking it for now to activate
					// dirty flag
					actionMgr.doAction(IActionManager.REMOVE_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(),
							stepList, -1);
					actionMgr.doAction(IActionManager.ADD_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(), steps,
							-1);

					viewer.refresh();
				}

				if (viewer.getTable().getSelectionIndex() > 0 && editable)
					ctrl_up.setEnabled(true);
				else
					ctrl_up.setEnabled(false);

				if (viewer.getTable().getSelectionIndex() < viewer.getTable()
						.getItemCount() - 1
						&& editable)
					ctrl_down.setEnabled(true);
				else
					ctrl_down.setEnabled(false);

			}

		});
	}

	/**
	 * Assign Steps to task descriptor
	 * @param addItems
	 * 			List of steps
	 */
	private void addSteps(Object[] addItems) {
		// update the model
		if (addItems != null) {
			for (int i = 0; i < addItems.length; i++) {
				org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) addItems[i];

				actionMgr.doAction(IActionManager.ADD, element,
						UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
						item, -1);
			}
		}
	}

	/**
	 * Remove assigned steps for the task descriptor
	 * @param rmItems
	 * 			List of steps 
	 */
	private void removeSteps(List rmItems) {
		// update the model
		if (!rmItems.isEmpty()) {
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) it.next();

				actionMgr.doAction(IActionManager.REMOVE, element,
						UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
						item, -1);
			}
		}
	}
	
	/**
	 * Get steps that could be assigned to this task descriptor
	 * @return
	 */
	private List getSteps(){
		//	get all steps
		IConfigurationApplicator configApplicator = Providers
				.getConfigurationApplicator();
		MethodConfiguration config = TngUtil.getOwningProcess(
				element).getDefaultContext();
		List steps = (List) configApplicator.getReference(
				element.getTask(), UmaPackage.eINSTANCE
						.getTask_Steps(), config);

		// remove already existing steps
		steps.removeAll(element.getSelectedSteps());
		return steps;
	}
}