//------------------------------------------------------------------------------
// 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.diagram.model.impl;

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.AdapterFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.diagram.model.ActivityDiagram;
import org.eclipse.epf.diagram.model.Link;
import org.eclipse.epf.diagram.model.ModelFactory;
import org.eclipse.epf.diagram.model.ModelPackage;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.diagram.model.TypedNode;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.IActivityDiagramChangeListener;
import org.eclipse.epf.diagram.model.util.IAdapterFactoryFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
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.process.WBSActivityItemProvider;
import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory;
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.GraphEdge;
import org.eclipse.epf.uma.GraphNode;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.SemanticModelBridge;
import org.eclipse.epf.uma.SimpleSemanticModelElement;
import org.eclipse.epf.uma.UMASemanticModelBridge;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Activity Diagram</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * </p>
 *
 * @generated
 */
public class ActivityDiagramImpl extends DiagramImpl implements ActivityDiagram {
	private class ActivityDiagramChangeListener extends ActivityAdapter
			implements IActivityDiagramChangeListener {

	};

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	protected ActivityDiagramImpl() {
		super();

		diagramChangeListener = new ActivityDiagramChangeListener();
	}

	protected Class getDiagramChangeListenerType() {
		return IActivityDiagramChangeListener.class;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return ModelPackage.Literals.ACTIVITY_DIAGRAM;
	}

	protected void populateNodes() {
		// Activity act = (Activity) getObject();
		org.eclipse.epf.uma.Diagram diagram = getUMADiagram();

		// add TypedNodes
		//
		List typedNodes = new ArrayList();
		for (Iterator iter = diagram.getContained().iterator(); iter.hasNext();) {
			Object element = iter.next();
			int type = getType(element);
			if (type > 0) {
				TypedNode node = ModelFactory.eINSTANCE.createTypedNode();
				node.setType(type);
				node.setObject(element);
				typedNodes.add(node);
			}
		}
		getNodes().addAll(typedNodes);

		// add WorkBreakdownElementNodes
		//
		addElementNodes();
	}

	private static boolean isValidWorkOrder(WorkOrder wo, Object pred) {
		if (wo.getPred() == pred) {
			return true;
		}

		if (pred instanceof Activity) {
			Activity act = (Activity) pred;
			// check if predecessor reference in the given work order is base of
			// pred
			//
			for (VariabilityElement ve = act.getVariabilityBasedOnElement(); ve != null; ve = ve
					.getVariabilityBasedOnElement()) {
				if (ve == wo.getPred()) {
					return true;
				}
			}
		}

		return false;
	}

	private boolean isValid(Link link) {
		if (link.getSource() == null || link.getTarget() == null
				|| !getNodes().contains(link.getSource())
				|| !getNodes().contains(link.getTarget())) {
			return false;
		}
		return true;
	}

	protected void populateLinks() {
		super.populateLinks();

		// remove the invalid links
		//
		for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
			Node node = ((Node) iter.next());
			WorkBreakdownElement wbe = null;
			if (node.getObject() instanceof WorkBreakdownElement) {
				wbe = (WorkBreakdownElement) node.getObject();
			}
			ArrayList linksToRemove = new ArrayList();
			linkListWalk: for (Iterator iterator = node
					.getIncomingConnections().iterator(); iterator.hasNext();) {
				Link link = (Link) iterator.next();
				if (!isValid(link)) {
					linksToRemove.add(link);
				}

				if (wbe != null) {
					// TODO: need revisit to check the valid connection from a
					// TypedNode
					//
					if (link.getSource() instanceof TypedNode)
						continue linkListWalk;

					Object pred = link.getSource().getObject();
					boolean workOrderFound = false;
					find_WorkOrder: for (Iterator iterator1 = wbe
							.getLinkToPredecessor().iterator(); iterator1
							.hasNext();) {
						WorkOrder wo = (WorkOrder) iterator1.next();
						if (isValidWorkOrder(wo, pred)) {
							workOrderFound = true;
							break find_WorkOrder;
						}
					}
					if (!workOrderFound) {
						// invalid link, remove it
						//
						linksToRemove.add(link);
					}
				}
			}

			for (Iterator iterator = linksToRemove.iterator(); iterator
					.hasNext();) {
				Link link = (Link) iterator.next();
				GraphicalDataHelper.removeLink(link);
			}
			linksToRemove.clear();

			for (Iterator iterator = node.getOutgoingConnections().iterator(); iterator
					.hasNext();) {
				Link link = (Link) iterator.next();
				if (!isValid(link)) {
					linksToRemove.add(link);
				}
			}

			for (Iterator iterator = linksToRemove.iterator(); iterator
					.hasNext();) {
				Link link = (Link) iterator.next();
				GraphicalDataHelper.removeLink(link);
			}
			linksToRemove.clear();
			linksToRemove = null;
		}

		// Check the links of each ActivityNode
		// set the WorkOrder to the link if needed
		// add new link for those WorkOrders that still don't have the
		// corresponding link
		//
		AdapterFactory adapterFactory = getAdapterFactory();
		
		for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
			Node node = ((Node) iter.next());
			if (node.getObject() instanceof WorkBreakdownElement) {
				List list = new ArrayList(); 
				// Get the raw data of workorders for object.
				WorkBreakdownElement local = (WorkBreakdownElement) node.getObject();
				list.addAll(local.getLinkToPredecessor());
				
				// Get the Predecessor List on top of raw data, this is need for in case of extend.
				ITreeItemContentProvider adapter = null;
				adapter = (ITreeItemContentProvider)adapterFactory
									.adapt(local, ITreeItemContentProvider.class);
				if(adapter instanceof IBSItemProvider){
					list.addAll(((IBSItemProvider)adapter).getPredecessors());
				}
				
				// Iterate work orders and create links.
				for (Iterator iterator = list.iterator(); iterator
						.hasNext();) {
					Object next = iterator.next();
					WorkOrder workOrder = null;
					BreakdownElement pred = null;
					if(next instanceof WorkOrder){
						workOrder = (WorkOrder)next;
						pred = workOrder.getPred();
					}
					if(next instanceof WBSActivityItemProvider){
						pred = (BreakdownElement)((WBSActivityItemProvider)next).getTarget(); 
					}
					
					if (pred != null && pred instanceof WorkBreakdownElement) {
						Node predNode = GraphicalDataHelper.findNode(this,
								pred, true);
						if (predNode != null) {
							// check if there is a link for this work order
							// already
							//
							boolean linkFound = false;
							find_link: for (Iterator iterator1 = node
									.getIncomingConnections().iterator(); iterator1
									.hasNext();) {
								Link link = (Link) iterator1.next();
								if (link.getSource() == predNode) {
									// link already exists
									// check if work order is set to this link
									//
									linkFound = true;
									GraphEdge edge = (GraphEdge) link
											.getObject();
									if (edge.getSemanticModel() == null) {
										GraphicalDataHelper.setSemanticModel(
												link, workOrder);
									}
									break find_link;
								}
							}
							if (!linkFound) {
								// check if this WorkOrder can be represented
								// via links of TypedNodes
								//
								if (!canReachAsFirstActivityNode(predNode, node)) {
									// add new link for this work order
									//
									NamedNodeImpl nodeImpl = ((NamedNodeImpl) node);
									NamedNodeImpl predNodeImpl = (NamedNodeImpl) predNode;
									boolean oldNotify = nodeImpl.notificationEnabled;
									boolean predNodeNotify = predNodeImpl.notificationEnabled;
									try {
										nodeImpl.notificationEnabled = false;
										predNodeImpl.notificationEnabled = false;
										nodeImpl.addIncomingConnection(pred); 
									} finally {
										nodeImpl.notificationEnabled = oldNotify;
										predNodeImpl.notificationEnabled = predNodeNotify;
									}
								}
							}
						}
					}
				}
			}
		}
		cleanDuplicateLinks();
	}

	private void cleanDuplicateLinks() {
		List duplicateLinks = new ArrayList();
		for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
			Object node = iter.next();
			if (node instanceof Node) {
				Node wbNode = (Node) node;
				if(wbNode.getIncomingConnections() != null){
					findDuplicateLinks(duplicateLinks, wbNode.getIncomingConnections());
				}
				if(wbNode.getOutgoingConnections() !=null){
					findDuplicateLinks(duplicateLinks, wbNode.getOutgoingConnections());
				}
			}
			
		}
		for (Iterator iterator = duplicateLinks.iterator(); iterator.hasNext();) {
			Link link = (Link) iterator.next();
			GraphicalDataHelper.removeLink(link);
		}
		duplicateLinks.clear();
		duplicateLinks = null;
	}

	private void findDuplicateLinks(List duplicateLinks, List links) {
		for (int i = 0; i < links.size(); i++) {
			Link link = (Link) links.get(i);
			if(!duplicateLinks.contains(link)){
				for (int j = i + 1; j < links.size(); j++) {
					Link link1 = (Link) links.get(j);
					if (link1.getSource() == link.getSource()
							&& link1.getTarget() == link.getTarget()) {
						duplicateLinks.add(link1);
					}
				}
			}
		}
	}

	/**
	 * Checks if Node src can reach Node target as the first ActivityNode in the
	 * diagram
	 * 
	 * @param src
	 * @param target
	 * @return
	 */
	private static boolean canReachAsFirstActivityNode(Node src, Node target) {
		for (Iterator iter = src.getOutgoingConnections().iterator(); iter
				.hasNext();) {
			Link link = (Link) iter.next();
			if (link.getTarget() == target) {
				return true;
			}
			if (link.getTarget() instanceof TypedNode
					&& canReachAsFirstActivityNode(link.getTarget(), target)) {
				return true;
			}
		}
		return false;
	}

	// private List toNodes(List activities) {
	// List list = new ArrayList();
	// for (Iterator iter = activities.iterator(); iter.hasNext();) {
	// list.add(toNode((MethodElement) iter.next()));
	// }
	// return list;
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#newNode()
	 */
	protected Node newNode() {
		return ModelFactory.eINSTANCE.createWorkBreakdownElementNode();
	}

	public Collection getChildren() {
		ITreeItemContentProvider adapter = getAdapter();
		if (adapter != null) {
			
			//Turn off the VariabilityInfo for the activity diagram.
			Object obj = null;
			boolean enableVariabilityInfo = false;
			if(adapter instanceof ActivityWrapperItemProvider){
				obj = ((ActivityWrapperItemProvider)adapter).getDelegatingItemProvider();
			}
			if(adapter instanceof BSActivityItemProvider){
				obj = adapter;
			}
			
			if(obj instanceof BSActivityItemProvider){
				enableVariabilityInfo = ((BSActivityItemProvider)obj).isEnableVariabilityInfo();
				((BSActivityItemProvider)obj).setEnableVariabilityInfo(false);
			}
			// end of variability info 
			
			
			// return adapter.getChildren(getObject());
			// commented above line, For diagrams - rollup should be false, for
			// handling rollup state below code.
			List children = new ArrayList();
			extractChildren(adapter, getObject(), children);
			
			// reset variabilityinfo status back
			if(obj instanceof BSActivityItemProvider){
				((BSActivityItemProvider)obj).setEnableVariabilityInfo(enableVariabilityInfo);
			}
			
			return children;
		} else {
			return Collections.EMPTY_LIST;
		}
	}

	private void addElementNodes() {

		ArrayList nodes = new ArrayList();
		for (Iterator iter = getChildren().iterator(); iter.hasNext();) {
			Object e = iter.next();
			Object child = TngUtil.unwrap(e);
			if (child instanceof WorkBreakdownElement) {
				NamedNodeImpl node = (NamedNodeImpl) toNode((MethodElement) child);
				if (e instanceof BreakdownElementWrapperItemProvider) {
					BreakdownElementWrapperItemProvider wrapper = ((BreakdownElementWrapperItemProvider) e);
					if (wrapper.isReadOnly()) {
						node.itemProvider = wrapper;
						// TODO: check if readOnly attribute is still needed
						// after introduction of itemProvider
						//
						node.readOnly = true;
					}
				}
				nodes.add(node);
			}
		}

		getNodes().addAll(nodes);
	}

	private static int getType(Object obj) {
		if (obj instanceof GraphNode) {
			GraphNode node = (GraphNode) obj;
			SemanticModelBridge modelBridge = node.getSemanticModel();
			if (modelBridge instanceof SimpleSemanticModelElement) {
				String type = ((SimpleSemanticModelElement) modelBridge)
						.getTypeInfo();
				if (GraphicalDataHelper.GRAPH_NODE_SYNCH_BAR.equals(type)) {
					return TypedNode.SYNCH_BAR;
				} else if (GraphicalDataHelper.GRAPH_NODE_DECISION.equals(type)) {
					return TypedNode.DECISION;
				} else if (GraphicalDataHelper.GRAPH_NODE_END.equals(type)) {
					return TypedNode.END;
				} else if (GraphicalDataHelper.GRAPH_NODE_START.equals(type)) {
					return TypedNode.START;
				} else if (GraphicalDataHelper.GRAPH_NODE_FREE_TEXT
						.equals(type)) {
					return TypedNode.FREE_TEXT;
				}
			}
		}
		return -1;
	}

	protected int getType() {
		return GraphicalDataHelper.ACTIVITY_DIAGRAM;
	}

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

	private int toActivityIndex(int index) {
		if (index == -1)
			return index;
		int size = getNodes().size();
		int i = index + 1;
		if (i == size)
			return -1;
		Node node = (Node) getNodes().get(i);
		if (node == null)
			return -1;

		for (; !(node.getObject() instanceof BreakdownElement) && i < size; i++) {
			node = (Node) getNodes().get(i);
		}
		if (i == size)
			return -1;
		Activity act = (Activity) getObject();
		return act.getBreakdownElements().indexOf(node.getObject());

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#addToUmaModel(int,
	 *      org.eclipse.epf.diagram.model.Node)
	 */
	protected void addToUmaModel(int position, Node addedNode) {
		if (addedNode.getObject() instanceof BreakdownElement) {
			Activity act = (Activity) getObject();

			// translate ActivityNode index to Activity index
			//
			int i = toActivityIndex(position);
			// System.out.println("DiagramImpl.addToUmaModel():
			// WorkBreakdownElement index: " + i);
			if (i == -1) {
				act.getBreakdownElements().add(addedNode.getObject());
			} else {
				act.getBreakdownElements().add(i, addedNode.getObject());
			}
		}

		super.addToUmaModel(position, addedNode);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#addNode(java.util.Collection,
	 *      java.lang.Object)
	 */
	protected Node addNode(Collection nodes, Object obj) {
		if (obj instanceof Activity) {
			Activity act = (Activity) obj;
			VariabilityElement base = act.getVariabilityBasedOnElement();
			if (base != null) {
				// find existing node for base and link it to the activity
				//
				NodeImpl baseNode = (NodeImpl) GraphicalDataHelper.findNode(
						this, base);
				if (baseNode != null) {
					GraphNode graphNode = baseNode.getGraphNode();
					UMASemanticModelBridge bridge = (UMASemanticModelBridge) graphNode
							.getSemanticModel();
					if (bridge.getElement() != act) {
						bridge.setElement(act);
					}
				} else {
					baseNode = (NodeImpl) GraphicalDataHelper.findNode(this,
							act);
				}
				if (baseNode != null) {
					// disassociate with the base
					//
					if (baseNode.methodElementAdapter != null) {
						base.eAdapters().remove(baseNode.methodElementAdapter);
					}

					baseNode.basicSetObject(act);
					baseNode.setReadOnly(false);

					return null;
				}
			}
		}
		return super.addNode(nodes, obj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#removeNode(java.lang.Object)
	 */
	protected boolean removeNode(Object obj) {
		if (obj instanceof Activity) {
			Activity act = (Activity) obj;
			VariabilityElement base = act.getVariabilityBasedOnElement();
			if (base != null) {
				// find existing node for the old activity and relink it to its
				// base
				//
				NodeImpl node = (NodeImpl) GraphicalDataHelper.findNode(this,
						act);
				if (node != null) {
					GraphNode graphNode = node.getGraphNode();
					UMASemanticModelBridge bridge = (UMASemanticModelBridge) graphNode
							.getSemanticModel();
					if (bridge.getElement() != base) {
						bridge.setElement(base);
					}
				} else {
					node = (NodeImpl) GraphicalDataHelper.findNode(this, base);
				}
				if (node != null) {
					// disassociate with the old activity
					//
					if (node.methodElementAdapter != null) {
						act.eAdapters().remove(node.methodElementAdapter);
					}

					node.basicSetObject(base);
					node.setReadOnly(true);

					return false;
				}
			}
		}
		return super.removeNode(obj);
	}
	/**
	 * Moved code from getChildren. getAdapter() will return Adapter,
	 * which will allow us to find itemprovider for the children. 
	 * 
	 * @return
	 */
	private ITreeItemContentProvider getAdapter(){
		ITreeItemContentProvider adapter = null;
		if (wrapper != null) {
			adapter = wrapper;
		} else {
			
			adapter =(ITreeItemContentProvider)getAdapterFactory().adapt(
					getObject(), ITreeItemContentProvider.class);
		}
		return adapter;
	}
	
	private AdapterFactory getAdapterFactory(){
		AdapterFactory adapterFactory = null;
		if (filter == null) {
			adapterFactory = TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
		} else if (filter instanceof IAdapterFactoryFilter) {
			adapterFactory = (ConfigurableComposedAdapterFactory) ((IAdapterFactoryFilter) filter)
					.getWBSAdapterFactory();
		}
		return adapterFactory;
	}
} // ActivityDiagramImpl
