//------------------------------------------------------------------------------
// 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.text.MessageFormat;
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.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.diagram.model.Diagram;
import org.eclipse.epf.diagram.model.DiagramResources;
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.NamedNode;
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.GraphicalDataManager;
import org.eclipse.epf.diagram.model.util.IDiagramChangeListener;
import org.eclipse.epf.library.edit.IFilter;
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.GraphNode;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.SemanticModelBridge;
import org.eclipse.epf.uma.SimpleSemanticModelElement;
import org.eclipse.epf.uma.UmaPackage;


/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Diagram</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * </p>
 *
 * @generated
 */
public class DiagramImpl extends NodeContainerImpl implements Diagram {

	private boolean newDiagram;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected DiagramImpl() {
		super();
	}

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

	// -------------------//
	// Start custom code //
	// -------------------//

	protected class ActivityAdapter extends TransactionalNodeLink implements
			IDiagramChangeListener {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.epf.diagram.model.util.IDiagramChangeListener#getDiagram()
		 */
		public Diagram getDiagram() {
			return DiagramImpl.this;
		}

		@Override
		protected void handleNotification(Notification msg) {
			switch (msg.getFeatureID(Activity.class)) {
			case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS:
				switch (msg.getEventType()) {
				case Notification.ADD:
					Node node = (Node) addNode(msg.getNewValue());
					if (node != null) {
					if (msg.getNotifier() == baseAct) {
						node.setReadOnly(true);
						}
					}
					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 = (NodeImpl) iter.next();
							node.setReadOnly(true);
						}
					}
					break;
				case Notification.REMOVE_MANY:
					removeNodes((Collection) msg.getOldValue());
					break;
				case Notification.MOVE:
					moveNode(msg.getNewValue());
					break;
				}
				break;
			}
		}

	}

	protected IDiagramChangeListener diagramChangeListener;

	private Activity baseAct;

	private Object diagramAdapter = new AdapterImpl() {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification msg) {
			if (!notificationEnabled)
				return;
			notificationEnabled = false;
			try {
				//Activity act = (Activity) getObject();
				switch (msg.getFeatureID(Diagram.class)) {
				case ModelPackage.DIAGRAM__NODES:
					// System.out.println(".notifyChanged(): index=" +
					// msg.getPosition());
					Collection collection;
					switch (msg.getEventType()) {
					case Notification.ADD:
						nodeAdded(msg.getPosition(), (Node) msg
								.getNewValue());
						return;
					case Notification.REMOVE:
						nodeRemoved((Node) msg.getOldValue());
						return;
					case Notification.ADD_MANY:
						collection = (Collection) msg.getNewValue();
						for (Iterator iter = collection.iterator(); iter
								.hasNext();) {
							Node node = (Node) iter.next();
							nodeAdded(msg.getPosition(), node);
						}

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

				}
			} finally {
				notificationEnabled = true;
			}
		}
	};

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

	protected Node addNode(Collection nodes, Object obj) {
		if (TngUtil.isInstanceOf(getBreakdownElementTypes(), obj)) {
			Node node = toNode((MethodElement) obj);
			if (node != null) {
				nodes.add(node);
				return node;
			}
		}
		return null;
	}

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

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

		Node node = GraphicalDataHelper.findNode(this, obj);
		if (node == null)
			return false;

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

		for (Iterator iter = node.getIncomingConnections().iterator(); iter
				.hasNext();) {
			Link link = (Link) iter.next();
			link.setSource(null);
		}
		node.getOutgoingConnections().clear();
		node.getIncomingConnections().clear();

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

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.Diagram#getUMADiagram()
	 */
	public org.eclipse.epf.uma.Diagram getUMADiagram() {
		return (org.eclipse.epf.uma.Diagram) getGraphNode();
	}

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

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

	protected int getType() {
		return -1;
	}

	protected void nodeAdded(int index, Node node) {
		addToUmaModel(index, node);
		node.addConsumer(this);
	}

	protected void nodeRemoved(Node node) {
		removeFromUmaModel(node);
		node.removeConsumer(this);
	}

	public boolean isNew() {
		return this.newDiagram;
	}

	public void setNew(boolean n) {
		this.newDiagram = n;
	}

	/**
	 * NOTE: this method is re-entrant, make sure to handle the data correctly to avoid memory leak and data corruption
	 * 
	 * @param newObject
	 *            must be an Activity
	 */
	public void setObject(Object newObject) {
		if (newObject instanceof BreakdownElementWrapperItemProvider
				&& ((BreakdownElementWrapperItemProvider) newObject)
						.isReadOnly()) {
			wrapper = (BreakdownElementWrapperItemProvider) newObject;
			setReadOnly(true);
		}
		newObject = TngUtil.unwrap(newObject);

		Object oldObject = object;
		object = newObject;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET,
					ModelPackage.LINKED_OBJECT__OBJECT, oldObject, object));

		// add diagram change listener to the linked object. Remove the old
		// listener if there is any.
		// But first keep the old listener to help find the UMA diagram of the
		// activity quickly.
		//
		Activity e = (Activity) newObject;		
		if(ProcessUtil.isExtendingOrLocallyContributing(e)) {
			baseAct = (Activity) e.getVariabilityBasedOnElement();
		}
		baseAct = null;
		
		if(newObject == null) {
			return;
		}

		// set the UMA diagram for this diagram
		//
		if(isGraphicalDataRequired()) {
			graphNode = GraphicalDataManager.getInstance().getUMADiagram(e,
					getType(), false);
			// set the flag to indicate this is a new diagram or not
			if (graphNode == null) {
				graphNode = GraphicalDataManager.getInstance().getUMADiagram(e,
						getType(), true);
				setNew(true);
			}
		}

		if(!e.eAdapters().contains(diagramChangeListener)) {
			e.eAdapters().add(diagramChangeListener);
		}
		if (baseAct != null) {
			baseAct.eAdapters().add(diagramChangeListener);
		}

		populateDiagram();

		if(!eAdapters().contains(diagramAdapter)) {
			this.eAdapters().add(diagramAdapter);
		}

	}

	/**
	 * Populates the diagram with the data from the UMA model. Subclass should
	 * override this method.
	 */
	protected void populateDiagram() {
		populateNodes();
		populateLinks();

		// add this diagram to the consumer list of all nodes so they will not
		// be disposed
		// before this diagram.
		//
		for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
			NodeImpl node = (NodeImpl) iter.next();
			node.addConsumer(this);
		}
	}

	/**
	 * Populates the incoming/outgoing links of the given node
	 * 
	 * @param node
	 */
	protected void populateLinks(Node 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]);
				}
			}
		}
	}

	protected void populateNodes() {		
		org.eclipse.epf.uma.Diagram diagram = getUMADiagram();
		if(diagram != null) {
			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);
		}
	}

	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 void populateLinks() {
		// fill outgoing/incoming connection lists of all nodes
		//
		int size = getNodes().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++) {
				Node node = ((Node) getNodes().get(i));
				notifies[i] = node.eDeliver();
				node.eSetDeliver(false);
			}
			for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
				Node node = (Node) iter.next();
				populateLinks(node, false);
			}
		} finally {
			// restore notification flag
			//
			for (int i = 0; i < size; i++) {
				((EObject) getNodes().get(i)).eSetDeliver(notifies[i]);
			}
		}

	}

	/**
	 * Removes the data for the removed node from the UMA model Subclass should
	 * override this method.
	 * 
	 * @param removedNode
	 */
	protected void removeFromUmaModel(Node removedNode) {
		Activity act = (Activity) getObject();
		if (removedNode.getObject() instanceof BreakdownElement) {
			act.getBreakdownElements().remove(removedNode.getObject());
		}
		
		if(getUMADiagram() != null) {
			getUMADiagram().getContained().remove(removedNode.getGraphNode());
		}
	}

	/**
	 * Adds the data for the newly added node to the UMA model Subclass should
	 * override this method.
	 * 
	 * @param position
	 * @param newValue
	 */
	protected void addToUmaModel(int position, Node addedNode) {

		if (addedNode.getGraphNode() == null) {
			// this node is readded after undo
			//
			((NodeImpl) addedNode).basicSetObject(addedNode.getObject());
		}
		
		if(getUMADiagram() != null) {
			getUMADiagram().getContained().add(addedNode.getGraphNode());
		}
	}

	/**
	 * Creates new node for this diagram for the given MethodElement.
	 * 
	 * @param e
	 * @return
	 */
	protected Node toNode(MethodElement e) {
		Node node = newNode();
		if (node == null)
			return null;
		node.setUMADiagram(getUMADiagram());
		node.setDiagram(this);
		node.setObject(e);
		return node;
	}

	protected Node newNode() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.Node#getMethodElementAdapterType()
	 */
	public Class getMethodElementAdapterType() {
		return getDiagramChangeListenerType();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.NodeImpl#dispose()
	 */
	protected void dispose() {
		// dispose all nodes
		//
		for (Iterator iter = nodes.iterator(); iter.hasNext();) {
			NodeImpl node = (NodeImpl) iter.next();
			node.dispose();
		}

		if (diagramChangeListener != null) {
			Activity e = (Activity) getObject();
			if (baseAct != null) {
				baseAct.eAdapters().remove(diagramChangeListener);
			}
			e.eAdapters().remove(diagramChangeListener);
		}

		super.dispose();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.Diagram#setDefaultName(org.eclipse.epf.diagram.model.NamedNode)
	 */
	public void setDefaultName(NamedNode newNode) {
		MethodElement obj = (MethodElement) newNode.getObject();
		int classID = obj.eClass().getClassifierID();
		Activity act = (Activity) getObject();
		ArrayList siblings = new ArrayList();
		for (Iterator iter = act.getBreakdownElements().iterator(); iter
				.hasNext();) {
			BreakdownElement e = (BreakdownElement) iter.next();
			if (e.eClass().getClassifierID() == classID) {
				siblings.add(e);
			}
		}
		String baseName = MessageFormat
				.format(
						DiagramResources.defaultBaseName, new Object[] { TngUtil.getTypeText(obj.eClass().getName()) }); 
		TngUtil.setDefaultName(siblings, obj, baseName);
		newNode.setName(obj.getName());
	}
	
	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;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.Diagram#setFilter(com.ibm.library.edit.IFilter)
	 */
	public void setFilter(IFilter filter) {
		this.filter = filter;
	}

	/**
	 * 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) {
	}
		
	public boolean isGraphicalDataRequired() {
		return graphicalDataRequired;
	}

	public void setGraphicalDataRequired(boolean graphicalDataRequired) {
		this.graphicalDataRequired = graphicalDataRequired;
	}
		
	public IFilter getFilter() {
		return filter;
	}
	
	public void setWrapper(BreakdownElementWrapperItemProvider wrapper) {
		this.wrapper = wrapper;
	}
	
	public Collection getChildren() {
		return Collections.EMPTY_LIST;
	}
	
	private Suppression suppression;

	protected BreakdownElementWrapperItemProvider wrapper;

	protected IFilter filter;
	
	private boolean graphicalDataRequired = true;

} // DiagramImpl
