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

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.ColumnDescriptor;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.command.ActivityDropCommand;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.jface.util.IOpenEventListener;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;


/**
 * Displays the Process elements in a tree table viewer.
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @since 1.0
 */
public class ProcessTreeViewer extends TreeViewer implements
		IActionTypeProvider {
	private static final String COPY_TXT = AuthoringUIResources.copy_text; 
	private static final String EXTEND_TXT = AuthoringUIResources.extend_text; 
	private static final String DEEP_COPY_TXT = AuthoringUIResources.deepCopy_text; 

	private int actionType = IActionTypeProvider.COPY;

	private Menu actionTypePopup;

	private Point actionTypePopupLocation;

	/**
	 * Creates a new instance.
	 */
	public ProcessTreeViewer(Composite parent, int style) {
		super(parent, style);

		Tree tree = getTree();
		tree.setHeaderVisible(true);
		tree.setLinesVisible(true);

		addTreeListener(new ITreeViewerListener() {

			public void treeCollapsed(TreeExpansionEvent event) {
				setItemProviderExpanded(event.getElement(), false);
			}

			public void treeExpanded(TreeExpansionEvent event) {
				setItemProviderExpanded(event.getElement(), true);
			}

		});
	}

	/**
	 * Set up colunms according to the given array of descriptors
	 * @param columnDescriptors
	 */
	public void setupColumns(ColumnDescriptor[] columnDescriptors) {
		// Remove all old TreeColumns.
		TreeColumn[] cols = getTree().getColumns();
		int size = cols.length;
		for (int i = 0; i < size; i++) {
			cols[i].dispose();
		}

		String[] colProps = new String[columnDescriptors.length];
		for (int i = 0; i < columnDescriptors.length; i++) {
			colProps[i] = columnDescriptors[i].id;
			TreeColumn column = new TreeColumn(getTree(),
					columnDescriptors[i].alignment);
			column.setText(columnDescriptors[i].label);
			column.setResizable(columnDescriptors[i].resizable);
			column.setWidth(columnDescriptors[i].width);
		}

		setColumnProperties(colProps);

	}

	private void setItemProviderExpanded(Object element, boolean expand) {
		Object adapter = getAdapterFactory().adapt(element,
				ITreeItemContentProvider.class);
		if (adapter instanceof IBSItemProvider) {
			((IBSItemProvider) adapter).setExpanded(Boolean.valueOf(expand));
		}
	}

	/**
	 * @return the AdapterFactory
	 */
	public AdapterFactory getAdapterFactory() {
		return getContentProvider() == null ? null
				: ((AdapterFactoryContentProvider) getContentProvider())
						.getAdapterFactory();
	}

	/**
	 * @see org.eclipse.jface.viewers.TableTreeViewer#setExpanded(Item, boolean)
	 */
	protected void setExpanded(Item node, boolean expand) {
		super.setExpanded(node, expand);
		Object adapter = getAdapterFactory().adapt(node.getData(),
				ITreeItemContentProvider.class);
		if (adapter instanceof IBSItemProvider) {
			IBSItemProvider bsItemProvider = ((IBSItemProvider) adapter);
			if (bsItemProvider.isExpanded() == null) {
				bsItemProvider.setExpanded((Boolean.valueOf(expand)));
			}
		}
	}

	/**
	 * @see org.eclipse.jface.viewers.AbstractTreeViewer#createTreeItem(Widget,
	 *      Object, int)
	 */
	protected void createTreeItem(Widget parent, Object element, int index) {
		super.createTreeItem(parent, element, index);
		Object adapter = getAdapterFactory().adapt(element,
				ITreeItemContentProvider.class);
		if (adapter instanceof IBSItemProvider) {
			Boolean expand = ((IBSItemProvider) adapter).isExpanded();
			if (expand != null) {
				setExpandedState(element, expand.booleanValue());
			}
		}
	}

	/**
	 * @see org.eclipse.jface.viewers.TableTreeViewer#doUpdateItem(Item, Object)
	 */
	protected void doUpdateItem(Item item, Object element) {
		super.doUpdateItem(item, element);
		setExpanded(item, element);
	}

	private void setExpanded(Item item, Object element) {
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) getAdapterFactory().adapt(element,
				ITreeItemContentProvider.class);
		if(adapter.hasChildren(element)) {
			if (adapter instanceof IBSItemProvider) {
				Boolean expand = ((IBSItemProvider) adapter).isExpanded();
				if (expand != null) {
					setExpandedState(item, expand.booleanValue());
				}
			}
		}
	}

	/**
	 * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalRefresh(Widget,
	 *      Object, boolean, boolean)
	 */
	protected void internalRefresh(Widget widget, Object element,
			boolean doStruct, boolean updateLabels) {
		super.internalRefresh(widget, element, doStruct, updateLabels);

		if (doStruct) {
			if (widget instanceof Item) {
				setExpanded((Item) widget, element);
			} else {
				Item[] children = getChildren(widget);
				for (int i = 0; i < children.length; i++) {
					Item child = children[i];
					if (child instanceof Item) {
						Item item = (Item) child;
						setExpanded(item, item.getData());
					}
				}
			}
		}
	}

	private Command command;

	private IActionManager actionManager;

	/**
	 * @see org.eclipse.epf.library.edit.ui.IActionTypeProvider#getActionType()
	 */
//	public int getActionType() {
//		if (actionTypePopup == null) {
//			createActionTypePopup();
//		}
//
//		Display.getCurrent().syncExec(new Runnable() {
//
//			public void run() {
//				actionType = 0;
//				actionTypePopup.setLocation(actionTypePopupLocation);
//				actionTypePopup.setVisible(true);
//			}
//
//		});
//
//		return actionType;
//	}

	private void createActionTypePopup(boolean canExtend) {
		actionTypePopup = new Menu(getControl());
		SelectionListener selectionListener = new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				MenuItem item = ((MenuItem) e.getSource());
				String text = item.getText();
				if (text == COPY_TXT) {
					ProcessTreeViewer.this.actionType = IActionTypeProvider.COPY;
				} else if (text == EXTEND_TXT) {
					ProcessTreeViewer.this.actionType = IActionTypeProvider.EXTEND;
				} else if (text == DEEP_COPY_TXT) {
					ProcessTreeViewer.this.actionType = DEEP_COPY;
				}

				if (command instanceof ActivityDropCommand) {
					ActivityDropCommand cmd = ((ActivityDropCommand) command);
					cmd.setType(ProcessTreeViewer.this.actionType);
					cmd.setLabel(text);
				}

				if (actionManager != null
						&& command instanceof IResourceAwareCommand) {
					actionManager.execute((IResourceAwareCommand) command);
				} else {
					command.execute();
				}

				actionTypePopup.setVisible(false);
			}

		};
		MenuItem menuItem;
		if (canExtend)	{
			menuItem = new MenuItem(actionTypePopup, SWT.CASCADE);
			menuItem.setText(COPY_TXT);
			menuItem.addSelectionListener(selectionListener);
			menuItem = new MenuItem(actionTypePopup, SWT.CASCADE);
			menuItem.setText(EXTEND_TXT);
			menuItem.addSelectionListener(selectionListener);
		}
		menuItem = new MenuItem(actionTypePopup, SWT.CASCADE);
		menuItem.setText(DEEP_COPY_TXT);
		menuItem.addSelectionListener(selectionListener);
	}

	/**
	 * @see org.eclipse.epf.library.edit.ui.IActionTypeProvider#setInputData(Object)
	 */
	public void setInputData(Object object) {
		actionTypePopupLocation = (Point) object;
	}

	/**
	 * @see org.eclipse.epf.library.edit.ui.IActionTypeProvider#execute(org.eclipse.emf.common.command.Command, boolean)
	 */
	public void execute(Command cmd, boolean canExtend) {
//		if (actionTypePopup == null) {
			createActionTypePopup(canExtend);
//		}

		this.command = cmd;
		actionTypePopup.setLocation(actionTypePopupLocation);
		actionTypePopup.setVisible(true);
	}

	/**
	 * @see org.eclipse.jface.viewers.TreeViewer#hookControl(Control)
	 */
	protected void hookControl(Control control) {
		// From ContentViewer.
		control.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				handleDispose(event);
			}
		});

		// From StructuredViewer.
		OpenStrategy handler = new OpenStrategy(control);
		handler.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				handleSelect(e);
			}

			public void widgetDefaultSelected(SelectionEvent e) {
				handleDoubleSelect(e);
			}
		});
		handler.addPostSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handlePostSelect(e);
			}
		});
		handler.addOpenListener(new IOpenEventListener() {
			public void handleOpen(SelectionEvent e) {
				ProcessTreeViewer.this.handleOpen(e);
			}
		});

		// From AbstractTreeViewer.
		addTreeListener(control, new TreeListener() {
			public void treeExpanded(TreeEvent event) {
				handleTreeExpand(event);
			}

			public void treeCollapsed(TreeEvent event) {
				handleTreeCollapse(event);
			}
		});

		getTree().addListener(SWT.MouseDoubleClick, new Listener() {

			public void handleEvent(Event event) {
				TreeItem[] treeItems = getTree().getSelection();

				// Don't edit if more than one items are selected.
				if (treeItems == null || treeItems.length != 1)
					return;

				// Find the edit column.
				TreeItem treeItem = treeItems[0];
				if (treeItem == null || treeItem.isDisposed()) {
					// Item no longer exists.
					return;
				}
				int columnToEdit;
				int columns = getTree().getColumnCount();
				if (columns == 0) {
					// If no TableColumn, Table acts as if it has a single
					// column which takes the whole width.
					columnToEdit = 0;
				} else {
					columnToEdit = -1;
					for (int i = 0; i < columns; i++) {
						Rectangle bounds = treeItem.getBounds(i);
						if (bounds.contains(event.x, event.y)) {
							columnToEdit = i;
							break;
						}
					}
					if (columnToEdit == -1) {
						return;
					}
				}

				editElement(treeItem.getData(), columnToEdit);
			}

		});
	}

	/**
	 * @see org.eclipse.epf.library.edit.ui.IActionTypeProvider#setActionManager(IActionManager)
	 */
	public void setActionManager(IActionManager actionMgr) {
		actionManager = actionMgr;
	}

}