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