//------------------------------------------------------------------------------
// 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.ControlNode;
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;
	}	
	
	protected 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);
					}
				}
			}
		}	
	}
	
	protected 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;
	}
}
