//------------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// 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.diagram.core.bridge;

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

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.model.util.TxUtil;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.command.ActionManager;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.process.BSActivityItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityPartition;
import org.eclipse.uml2.uml.UMLPackage;

/**
 * @author Phong Nguyen Le
 * 
 * @since 1.2
 */
public class DiagramAdapter extends NodeAdapter {

	private Activity baseAct;

	protected IFilter filter;

	private Suppression suppression;

	protected long umaLastModified;


	public DiagramAdapter(BreakdownElementWrapperItemProvider wrapper) {
		this((Activity) TngUtil.unwrap(wrapper));
		this.wrapper = wrapper;
		basicSetTargetReadOnly(wrapper.isReadOnly());
	}

	public DiagramAdapter(Activity e) {
		super(e);

		// listens to change in the base activity if there is any
		//
		if (ProcessUtil.isExtendingOrLocallyContributing(e)) {
			baseAct = (Activity) e.getVariabilityBasedOnElement();
			baseAct.eAdapters().add(methodElementAdapter);
		}
	}

	public void dispose() {
		// dispose all node adapters of the child nodes
		//
		for (Iterator<?> iter = getNodes().iterator(); iter.hasNext();) {
			ActivityNode node = (ActivityNode) iter.next();
			NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
			if (nodeAdapter != null) {
				nodeAdapter.dispose();
			}
		}

		super.dispose();
		
		if (baseAct != null) {
			baseAct.eAdapters().remove(methodElementAdapter);
		}

	}

	protected class ActivityAdapter extends MethodElementAdapter {
		protected Collection handleNotification(Notification msg) {
			Collection newNodesToRefresh = new ArrayList();
			switch (msg.getFeatureID(Activity.class)) {
			case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS:
				switch (msg.getEventType()) {
				case Notification.ADD:
					ActivityNode node = (ActivityNode) addNode(msg
							.getNewValue());
					if (node != null) {
						if (msg.getNotifier() == baseAct) {
							BridgeHelper.getNodeAdapter(node)
									.basicSetTargetReadOnly(true);
							newNodesToRefresh.add(node);
						}
					}
					break;
				case Notification.REMOVE:
					removeNode(msg.getOldValue());
					break;
				case Notification.ADD_MANY:
					Collection nodes = addNodes((Collection) msg.getNewValue());
					if (msg.getNotifier() == baseAct) {
						for (Iterator iter = nodes.iterator(); iter.hasNext();) {
							node = (ActivityNode) iter.next();
							BridgeHelper.getNodeAdapter(node)
									.basicSetTargetReadOnly(true);
							newNodesToRefresh.add(node);
						}
					}
					break;
				case Notification.REMOVE_MANY:
					removeNodes((Collection) msg.getOldValue());
					break;
				case Notification.MOVE:
					moveNode(msg.getNewValue());
					break;
				case Notification.SET:
					replaceNode(msg.getOldValue(), msg.getNewValue());
					break;
				}
				break;
			default:
				return super.handleNotification(msg);
			}
			return newNodesToRefresh;
		}
	}
	
	protected void handleNotification(Notification msg) {
		switch(msg.getFeatureID(org.eclipse.uml2.uml.Activity.class)) {
		case UMLPackage.ACTIVITY__NODE:
			Collection collection;
			switch (msg.getEventType()) {
			case Notification.ADD:
				nodeAdded(msg.getPosition(), (ActivityNode) msg
						.getNewValue());
				return;
			case Notification.REMOVE:
				nodeRemoved((ActivityNode) msg.getOldValue());
				return;
			case Notification.ADD_MANY:
				collection = (Collection) msg.getNewValue();
				for (Iterator iter = collection.iterator(); iter
				.hasNext();) {
					ActivityNode node = (ActivityNode) iter.next();
					nodeAdded(msg.getPosition(), node);
				}

				return;
			case Notification.REMOVE_MANY:
				collection = (Collection) msg.getOldValue();
				for (Iterator iter = collection.iterator(); iter
				.hasNext();) {
					nodeRemoved((ActivityNode) iter.next());
				}
				return;
			}
		}
		
		super.handleNotification(msg);
	}

	protected void replaceNode(Object oldElement, Object newElement) {
		
	}

	protected MethodElementAdapter createMethodElementAdapter() {
		return new ActivityAdapter();
	}

	protected final void populateLinks() {
		populateLinks(getNodes());
	}
	
	protected void populateLinks(List<ActivityNode> selectedNodes) {
		// fill outgoing/incoming connection lists of all nodes
		//
		int size = selectedNodes.size();
		boolean[] notifies = new boolean[size];
		try {
			// disable notification for all nodes in this diagram to avoid
			// unwanted concurrent modification of their connection list
			//
			for (int i = 0; i < size; i++) {
				ActivityNode node = selectedNodes.get(i);
				notifies[i] = node.eDeliver();
				node.eSetDeliver(false);
			}
			for (ActivityNode node : selectedNodes) {
				populateLinks(node, false);
			}
		} finally {
			// restore notification flag
			//
			for (int i = 0; i < size; i++) {
				selectedNodes.get(i).eSetDeliver(notifies[i]);
			}
		}
	}

	protected List getNodes() {
		org.eclipse.uml2.uml.Activity diagram = getDiagram();
		return diagram != null ? getDiagram().getNodes() : Collections.emptyList();
	}
	
	protected org.eclipse.uml2.uml.Activity getDiagram() {
		return (org.eclipse.uml2.uml.Activity) getTarget();
	}

	protected boolean removeNode(Object obj) {
		if (!TngUtil.isInstanceOf(getBreakdownElementTypes(), obj))
			return false;

		ActivityNode node = BridgeHelper.findNode(getDiagram(), obj);
		if (node == null)
			return false;

		for (Iterator iter = node.getOutgoings().iterator(); iter.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			link.setTarget(null);
		}

		for (Iterator iter = node.getIncomings().iterator(); iter.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			link.setSource(null);
		}
		node.getOutgoings().clear();
		node.getIncomings().clear();

		getNodes().remove(node);
		return true;
	}

	protected void removeNodes(Collection collection) {
		for (Iterator iter = collection.iterator(); iter.hasNext();) {
			removeNode(iter.next());
		}
	}

	protected ActivityNode addNode(Object obj) {
		ActivityNode node = addNode(getNodes(), obj);
		if (node == null)
			return node;
		populateLinks(node, true);
		return node;
	}

	protected Collection addNodes(Collection collection) {
		List nodes = new ArrayList();
		for (Iterator iter = collection.iterator(); iter.hasNext();) {
			addNode(nodes, iter.next());
		}

		// use addAll() to avoid unnecessary notifications
		//
		getNodes().addAll(nodes);
		return nodes;
	}

	/**
	 * In Process WBS, if breakdownelement is moved up or down, diagram should
	 * be updated accordingly. Sub-class should override this method if diagram
	 * needs update on move.
	 * 
	 * @param newValue
	 */
	public void moveNode(Object oldValue) {
	}

	/**
	 * Populates the incoming/outgoing links of the given node
	 * 
	 * @param node
	 */
	protected void populateLinks(ActivityNode node, boolean disableNotification) {
		// int size = 0;
		// boolean[] notifies = null;
		// try {
		// if (disableNotification) {
		// size = getNodes().size();
		// notifies = new boolean[size];
		// // disable notification for all nodes in this diagram to avoid
		// // unwanted concurrent modification of their connection list
		// //
		// for (int i = 0; i < size; i++) {
		// Node child = ((Node) getNodes().get(i));
		// notifies[i] = child.eDeliver();
		// child.eSetDeliver(false);
		// }
		// }
		//
		// GraphNode graphNode = node.getGraphNode();
		// if (graphNode != null) {
		// GraphicalDataHelper.fillConnections(node, graphNode);
		// }
		// } finally {
		// if (disableNotification) {
		// // restore notification flag
		// //
		// for (int i = 0; i < size; i++) {
		// ((EObject) getNodes().get(i)).eSetDeliver(notifies[i]);
		// }
		// }
		// }
	}

	/**
	 * Creates new node for this diagram for the given MethodElement.
	 * 
	 * @param e
	 * @return
	 */
	protected ActivityNode toNode(MethodElement e) {
		ActivityNode node = newNode(e);
		if (node == null)
			return null;
		initializeNode(node, e);
		return node;
	}
	
	protected void initializeNodeAdapter(NodeAdapter nodeAdapter) {
		nodeAdapter.setEditingDomain(domain);
		nodeAdapter.actionManager = actionManager;
	}
	
	private void initializeNode(ActivityNode node, MethodElement e) {
		String name = BridgeHelper.getNodeName(e);
		node.setName(name);		

		NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
		if (nodeAdapter != null && nodeAdapter.getElement() != e) {
			nodeAdapter.dispose();
			nodeAdapter = null;
		}
		if (nodeAdapter == null) {
			nodeAdapter = createNodeAdapter(e);
			initializeNodeAdapter(nodeAdapter);
			node.eAdapters().add(nodeAdapter);
		}
	}

	protected NodeAdapter createNodeAdapter(MethodElement e) {
		return null;
	}

	protected ActivityNode newNode(MethodElement e) {
		return null;
	}

	/**
	 * Creates a new node for the given method element <code>obj</code> and
	 * add it to the given collection of nodes
	 * 
	 * @param nodes
	 * @param obj
	 *            method element
	 * @return
	 */
	protected ActivityNode addNode(Collection nodes, Object obj) {
		if (TngUtil.isInstanceOf(getBreakdownElementTypes(), obj)) {
			ActivityNode node = toNode((MethodElement) obj);
			if (node != null) {
				nodes.add(node);
				return node;
			}
		}
		return null;
	}

	protected List getBreakdownElementTypes() {
		return Collections.singletonList(BreakdownElement.class);
	}

	public Activity getActivity() {
		return (Activity) element;
	}

	protected void removeFromUmaModel(ActivityNode removedNode) {
		Object e;
		if ((e = BridgeHelper.getMethodElement(removedNode)) instanceof BreakdownElement) {
			getActionManager().doAction(IActionManager.REMOVE, getActivity(), 
					UmaPackage.Literals.ACTIVITY__BREAKDOWN_ELEMENTS, e, -1);
		}

		super.removeFromUmaModel(removedNode);
	}

	protected void extractChildren(ITreeItemContentProvider adapter, Object object, Collection children) {
		// disable rollup before getting the children
		//
		boolean oldRolledUp = false;
		if(adapter instanceof BSActivityItemProvider) {
			BSActivityItemProvider itemProvider = (BSActivityItemProvider)adapter;
			oldRolledUp = itemProvider.isRolledUp();
			itemProvider.basicSetRolledUp(false);
		}
		else if(adapter instanceof IBSItemProvider){
			IBSItemProvider itemProvider = (IBSItemProvider)adapter;
			oldRolledUp = itemProvider.isRolledUp();
			itemProvider.setRolledUp(false);
		}
		
		try {
			// filter out the suppressed elements
			//
			for (Iterator iter = adapter.getChildren(object).iterator(); iter.hasNext();) {
				Object child = iter.next();
				if(!getSuppression().isSuppressed(child)) {
					children.add(child);
				}
			}
			
			// don't filter suppressed elements
			//
			//children.addAll(adapter.getChildren(object));
		}
		finally {
			// restore the rolled-up flag
			//
			if(adapter instanceof IBSItemProvider) {
				((IBSItemProvider)adapter).setRolledUp(oldRolledUp);
			}
		}
	}
	
	public Suppression getSuppression() {
		return suppression;
	}

	public void setSuppression(Suppression suppression) {
		this.suppression = suppression;
	}	
	
	private void updateView(Collection<?> selectedNodes) throws InterruptedException, RollbackException {
		updateView(getView(), selectedNodes);
	}
	
	private static boolean isWorkBreakdownElementType(View node) {
		// hack by using the visual IDs defined in AD model
		//  StructuredActivityNodeEditPart 1007 Activity
		//  StructuredActivityNode2EditPart 1010 Phase
		//  StructuredActivityNode3EditPart 1011 Iteration
		//  ActivityParameterNodeEditPart 1009 TaskDescriptor
		//  ActivityParameterNode2EditPart 1012 Milestone
		//
		
		String type = node.getType();
		return type != null && ("1007".equals(type) //$NON-NLS-1$
				|| "1010".equals(type) //$NON-NLS-1$
				|| "1011".equals(type) //$NON-NLS-1$
				|| "1009".equals(type) //$NON-NLS-1$
				|| "1012".equals(type)); //$NON-NLS-1$
	}
	
	private static void updateView(View view, Collection<?> selectedNodes) {
		// show the selected nodes and hide all the other
		//	
		for (Iterator<?> iter = view.getChildren().iterator(); iter.hasNext();) {
			View node = (View) iter.next();
			if(selectedNodes.contains(node.getElement())) {
				NodeAdapter adapter = BridgeHelper.getNodeAdapter(node.getElement());
				if(adapter != null) {
					adapter.updateView();
				}
//				if(!node.isVisible()) {
					node.setVisible(true);
//				}
			}
			else {
				if(node.getElement() instanceof ActivityNode) {
					if(node.isVisible()) {
						node.setVisible(false);
					}
				}
				else if(node.getElement() instanceof ActivityPartition) {
					updateView(node, selectedNodes);
				}
				// this is a work around to not show any work breakdown element
				// node that does not have any model reference (View.element)
				// GMF returns the container view's element if the child node's element
				// is not set. Therefore, if the child node is shown, it will be displayed
				// as a node of parent activity. Deleting this node in editor will delete
				// the parent activity as result.
				//
				else if(isWorkBreakdownElementType(node) && (!node.isSetElement() || node.getElement() == view.getElement())) {
					if(node.isVisible()) {
						node.setVisible(false);
					}
				}
				else {
					if(!node.isVisible()) {
						node.setVisible(true);
					}
				}
			}
		}	
	}
	
	private void updateEdges(Collection selectedNodes) throws InterruptedException, RollbackException {
		for (Iterator iter = getView().getChildren().iterator(); iter.hasNext();) {
			View node = (View) iter.next();
			if(selectedNodes.contains(node.getElement())) {
				NodeAdapter adapter = BridgeHelper.getNodeAdapter(node.getElement());
				adapter.updateView();
//				if(!node.isVisible()) {
					node.setVisible(true);
					setEdgeVisibility(node, true);
//				}
			}
			else {
				if(node.getElement() instanceof ActivityNode) {
					if(node.isVisible()) {
						setEdgeVisibility(node, false);
					}
				}
				else {
					if(!node.isVisible()) {
						node.setVisible(true);
						setEdgeVisibility(node, true);
					}
				}
			}
		}	
	}
	
	private void setEdgeVisibility(View view, boolean visibility){
		Diagram diagram = view.getDiagram();
		for (Iterator iterator = diagram.getEdges().iterator(); iterator
				.hasNext();) {
			Edge edge = (Edge) iterator.next();
			if(edge.getSource() == view || edge.getTarget() == view){
				if(visibility){
					view.setVisible(true);
				}
				edge.setVisible(visibility);
			}
		}
	}
	/**
	 * Populates the diagram with the data from the UMA model. Subclass should
	 * override this method.
	 */
	public void populateDiagram() {
		boolean notify = notificationEnabled;
		try {
			notificationEnabled = false;
			final List<ActivityNode> selectedNodes = new ArrayList<ActivityNode>();
			org.eclipse.uml2.uml.Activity diagram = getDiagram();			
			TxUtil.runInTransaction(diagram, new Runnable() {

				public void run() {
					selectedNodes.addAll(populateNodes());
					populateLinks(selectedNodes);
				}
				
			});
			
			// add this diagram to the consumer list of all nodes so they will not
			// be disposed
			// before this diagram.
			//
			for (ActivityNode node : selectedNodes) {
				NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
				if(nodeAdapter != null) {
					nodeAdapter.addConsumer(this);
				}
			}
			
			TxUtil.runInTransaction(diagram, new Runnable() {

				public void run() {
					try {
						updateEdges(selectedNodes);
						updateView(selectedNodes);
					} catch(Exception e) {
						DiagramCorePlugin.getDefault().getLogger().logError(e);
					}
				}
				
			});
		}
		catch(Exception e) {
			DiagramCorePlugin.getDefault().getLogger().logError(e);
		}
		finally {
			notificationEnabled = notify;
		}
	}
	
	protected Collection populateNodes() {
		return Collections.EMPTY_LIST;
	}

	public void setFilter(IFilter filter) {
		this.filter = filter;
	}
	
	public IActionManager getActionManager() {
		if(actionManager == null) {
			actionManager = new ActionManager() {
				public boolean doAction(int actionType, EObject object, EStructuralFeature feature, Object value, int index) {
					boolean ret = super.doAction(actionType, object, feature, value, index);
					if(ret) {
						umaLastModified = System.currentTimeMillis();
					}
					return ret;
				}
			};
		}
		return actionManager;
	}
	
	public long getUmaLastModified() {
		return umaLastModified;
	}

	public IFilter getFilter() {
		return filter;
	}
}
