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


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

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.diagram.core.DiagramCoreResources;
import org.eclipse.epf.diagram.core.bridge.BridgeHelper;
import org.eclipse.epf.diagram.core.bridge.NodeAdapter;
import org.eclipse.epf.diagram.core.services.DiagramHelper;
import org.eclipse.epf.diagram.model.ActivityDetailDiagram;
import org.eclipse.epf.diagram.model.ActivityDiagram;
import org.eclipse.epf.diagram.model.Link;
import org.eclipse.epf.diagram.model.RoleNode;
import org.eclipse.epf.diagram.model.TaskNode;
import org.eclipse.epf.diagram.model.TypedNode;
import org.eclipse.epf.diagram.model.WorkBreakdownElementNode;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ControlNode;
import org.eclipse.uml2.uml.FinalNode;
import org.eclipse.uml2.uml.ForkNode;
import org.eclipse.uml2.uml.InitialNode;
import org.eclipse.uml2.uml.JoinNode;

/**
 * Validating routines for diagram editing
 * 
 * @author Phong Nguyen Le
 * @author Shashidhar Kannoori
 * @since 1.0
 */
public class DiagramCoreValidation {

	private static final String errMsg_CanNotConnect = DiagramCoreResources.DiagramValidation_err_cannot_connect_text; //$NON-NLS-1$

	private static final String errMsg_SamePredAndSucc = DiagramCoreResources.DiagramValidation_err_samepredandsuc_text; //$NON-NLS-1$

	private static final String errMsg_CanNotDelete = DiagramCoreResources.DiagramValidation_err_cannot_delete_text; //$NON-NLS-1$

	public static boolean isConnectionToReadOnlyTargetAllowed() {
//		return DiagramPreferences.getADAllowConnectionToReadOnlyElements();
		return true;
	}
	
	public static String isTargetReadonly(EditPart part){
		View view = (View)part.getModel();
		if(BridgeHelper.isReadOnly(view)) return errMsg_CanNotConnect;
		return null;
	}
	
	public static String canConnect(EditPart targetEditPart, EObject sourceElement, EObject targetElement){
		
		if(targetEditPart == null) return errMsg_CanNotConnect;
		
		EditPart part = targetEditPart.getParent();
		Diagram diagram = null;
		while(part != null && !(part instanceof DiagramEditPart)){
				part  = part.getParent();
		}
		if(part instanceof DiagramEditPart){
			diagram = (Diagram)((DiagramEditPart)part).getModel();
		}

		if(diagram == null) return errMsg_CanNotConnect;
		return checkConnect(diagram,  sourceElement, targetElement);
	}
	
	public static String checkConnect(Diagram diagram, EObject sourceElement, EObject targetElement){
		switch(DiagramHelper.getDiagramType(diagram)){
		case IDiagramManager.ACTIVITY_DIAGRAM:
			if(alwaysAllowed(sourceElement, targetElement)) {
				return null;
			}
			
			// If target Diagram is read-only - do not connect
			if(BridgeHelper.isReadOnly(diagram)) return errMsg_CanNotConnect;
				
			NodeAdapter sourceAdapter = BridgeHelper.getNodeAdapter(sourceElement);
			NodeAdapter targetAdapter = BridgeHelper.getNodeAdapter(targetElement);
			
			// if adapters of source and target is null - no connect.
			if(sourceAdapter == null || targetAdapter == null) return errMsg_CanNotConnect;
			
			Diagram sourceDiagram = sourceAdapter.getView().getDiagram();
			
			// If source and target diagrams not equal - do not connect.
			if (!diagram.equals(sourceDiagram))
								return errMsg_CanNotConnect;

			AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE
					.getWBS_ComposedAdapterFactory();
			Object adapter = adapterFactory.adapt(BridgeHelper.getMethodElement(sourceDiagram)
					, ITreeItemContentProvider.class);
			Object proc = null;
			if (adapter instanceof IBSItemProvider) {
				proc = ((IBSItemProvider) adapter).getTopItem();
			}
			// get all breakdown elements in this process
			//
			List<Object> allElements = new ArrayList<Object>();
			for (Iterator iter = new AdapterFactoryTreeIterator(adapterFactory,
					proc); iter.hasNext();) {
				Object obj = iter.next();
				allElements.add(TngUtil.unwrap(obj));
			}
			if(proc != null){
				EObject source = sourceAdapter.getElement();

				EObject target = null;
				if (targetAdapter != null) {
					target = targetAdapter.getElement();
				}
				if (source instanceof 
						WorkBreakdownElement) {
					if (target instanceof WorkBreakdownElement) {
						if (ProcessUtil.checkCircular(
								(WorkBreakdownElement) target,
								(WorkBreakdownElement) source, allElements))
							return errMsg_SamePredAndSucc;

						if (!isConnectionToReadOnlyTargetAllowed() && targetAdapter.isTargetReadOnly())
							return errMsg_CanNotConnect;
					} else {
						// target node might be control node
						Collection<ActivityNode> actNodes = new ArrayList<ActivityNode>();
						BridgeHelper.getSuccessorNodes(actNodes,
								(ActivityNode) targetElement);
						for (ActivityNode node : actNodes) {
							if (BridgeHelper.getNodeAdapter(node).isTargetReadOnly() && !isConnectionToReadOnlyTargetAllowed())
								return errMsg_CanNotConnect;
							if (ProcessUtil.checkCircular(
									(WorkBreakdownElement) BridgeHelper
											.getMethodElement(node),
									(WorkBreakdownElement) source, allElements)) {
								return errMsg_SamePredAndSucc;
							}
						}
					}
				} else {
					if (target instanceof WorkBreakdownElement) {
						Collection<ActivityNode> srcNodes = new ArrayList<ActivityNode>();
						BridgeHelper.getPredecessorNodes(srcNodes,
								(ActivityNode) sourceElement);
						if (!srcNodes.isEmpty()) {
							if (targetAdapter.isTargetReadOnly() && !isConnectionToReadOnlyTargetAllowed())
								return errMsg_CanNotConnect;
							for (ActivityNode predNode : srcNodes) {
								MethodElement pred = BridgeHelper
										.getMethodElement(predNode);
								if (ProcessUtil.checkCircular(
										(WorkBreakdownElement) target,
										(WorkBreakdownElement) pred,
										allElements)) {
									return errMsg_SamePredAndSucc;
								}
							}
						}
					} else {
						if (checkSyncBarCircularLooop((ActivityNode)sourceElement,
								(ActivityNode) targetElement) != null) {
							return errMsg_CanNotConnect;
						}

						// should not allow incoming connection to start node
						// and FreeText.
						if (targetElement instanceof InitialNode) {
							return errMsg_CanNotConnect;
						}

						Collection<ActivityNode> srcNodes = new ArrayList<ActivityNode>(); 
						BridgeHelper.getPredecessorNodes(srcNodes, (ActivityNode) sourceElement);
						if (!srcNodes.isEmpty()) {
							Collection<ActivityNode> targetNodes = new ArrayList<ActivityNode>();
							BridgeHelper.getSuccessorNodes(targetNodes,
									(ActivityNode) target);
							for (ActivityNode node : targetNodes) {
								NodeAdapter nodeAdapter = BridgeHelper
										.getNodeAdapter(node);
								if (nodeAdapter.isTargetReadOnly() && !isConnectionToReadOnlyTargetAllowed())
									return errMsg_CanNotConnect;
								WorkBreakdownElement succ = (WorkBreakdownElement) nodeAdapter
										.getElement();
								for (ActivityNode prednode : srcNodes) {
									NodeAdapter predAdapter = BridgeHelper
											.getNodeAdapter(prednode);
									WorkBreakdownElement pred = (WorkBreakdownElement) predAdapter
											.getElement();
									if (ProcessUtil.checkCircular(succ, pred,
											allElements)) {
										return errMsg_SamePredAndSucc;
									}
								}
							}
						}
					}
				}
				
			}
		}
			
		return null;
	}
	
	/*
	 * To avoid circular looping between synchronization bars. If SycnBar1 ->
	 * SyncBar2 (connected) then SyncBar2 -> SyncBar1 cannot connect. if
	 * syncbar1 -> syncbar2->syncbar3 then syncbar3 -> syncbar1 disallowed.
	 * 
	 */
	public static String checkSyncBarCircularLooop(ActivityNode sNode,
			ActivityNode tNode) {
		List list = tNode.getOutgoings();
		if (!list.isEmpty() && list.size() > 0) {
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				ActivityEdge link = (ActivityEdge) iterator.next();
				ActivityNode typednode = link.getTarget();
				if (sNode.equals(typednode))
					return errMsg_CanNotConnect;
				if (typednode instanceof ControlNode) {
					return checkSyncBarCircularLooop(sNode,
							(ControlNode)typednode);
				}
			}
		}
		return null;
	}
	
	/*
	 * Method to Check if SyncBar inComming connections have 
	 * any source is a readonly. 
	 * @return
	 */
	public static String checkSyncBarIncomingLinks(ActivityNode typedNode){
		for (Iterator iter = typedNode.getIncomings().iterator(); iter.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			ActivityNode source = link.getSource();
			NodeAdapter adapter = BridgeHelper.getNodeAdapter(source);
			if (adapter != null) {
				if(adapter.getElement() instanceof WorkBreakdownElement){
					if(adapter.isTargetReadOnly())
						return errMsg_CanNotDelete;
				}else if(source instanceof ControlNode){
					if(source instanceof ForkNode || source instanceof JoinNode)
						if(checkSyncBarIncomingLinks(source)!= null)
							return errMsg_CanNotDelete;
				}
			}
		}
		return null;
	}
	/*
	 *Method to check if synchronization bar outgoing connection
	 *has any target is readonly.  
	 */
	public static String checkSyncBarOutgoingLinks(ActivityNode typedNode){
		for (Iterator iter = typedNode.getOutgoings().iterator(); iter.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			ActivityNode target = link.getTarget();
			NodeAdapter adapter = BridgeHelper.getNodeAdapter(target);
			if (adapter != null) {
				if(adapter.getElement() instanceof WorkBreakdownElement){
					if(adapter.isTargetReadOnly())
						return errMsg_CanNotDelete;
				}else if(target instanceof ControlNode){
					if(target instanceof ForkNode || target instanceof JoinNode)
						if(checkSyncBarOutgoingLinks(target)!= null)
							return errMsg_CanNotDelete;
				}
			}
		}
		return null;
	}
	
	
	public static String checkDelete(Node node) {
		if (BridgeHelper.isReadOnly(node))
			return errMsg_CanNotDelete;
		Diagram diagram = node.getDiagram();
		if (diagram instanceof ActivityDiagram) {
			if (node.getElement() instanceof ControlNode) {
				
				Collection<ActivityNode> targetNodes = new ArrayList<ActivityNode>(); 
				BridgeHelper.getSuccessorNodes(targetNodes, (ActivityNode)node.getElement());
						
				for (ActivityNode targetNode : targetNodes) {
					NodeAdapter adapter = BridgeHelper.getNodeAdapter(targetNode);
					if(adapter != null && adapter.isTargetReadOnly()){
						return errMsg_CanNotDelete;
					}
				}
			}
		} else if (diagram instanceof ActivityDetailDiagram) {
			if (node.getElement() instanceof RoleNode) {
				return errMsg_CanNotDelete;
			}
		}
		return null;
	}
	
	public static String checkReconnect(Node source, Node target, Edge link) {
		if (source.getDiagram() instanceof ActivityDiagram) {
			if (link.getTarget() != null) {
				if (BridgeHelper.isReadOnly(link.getTarget())) {
					return errMsg_CanNotConnect;
				} else {
					if (link.getTarget() instanceof TypedNode) {
						Collection targetNodes = GraphicalDataHelper
								.getTargetNodes((TypedNode) link.getTarget(),
										WorkBreakdownElementNode.class);
						for (Iterator iter = targetNodes.iterator(); iter
								.hasNext();) {
							Node node = (Node) iter.next();
							if (BridgeHelper.isReadOnly(node)) {
								return errMsg_CanNotConnect;
							}
						}
					}
				}
			}
		}

		return checkConnect(source, target, link);
	}
	
	/*
	 * Method will not allow multiple link between two nodes. Needs to call
	 * CreakLinkCommand and ReconnectLinkCommand. Any action on a Link should
	 * call this checkConnect(Node source, Node target, Link link) before allow
	 * to connect.
	 */
	public static String checkConnect(Node source, Node target, Edge link) {

		if (source == target && !(BridgeHelper.getMethodElement(source) instanceof Activity)) {
			return errMsg_CanNotConnect;
		}

		List links = source.getTargetEdges();
		if (links != null) {
			// This is need for reconnect to same target node.
			if (links.contains(link)) {
				if (link.getTarget().equals(target)) {
					return null;
				}
			}
		// This is need for new connect and reconnect to different target node.
		for (Iterator iter = links.iterator(); iter.hasNext();) {
			Link linkx = (Link) iter.next();
			Object linkxtarget = linkx.getTarget();
			if (linkxtarget != null && linkxtarget.equals(target)) {
				return errMsg_CanNotConnect;
				}
			}
		}
		return checkConnect(source.getDiagram(), source.getElement(), target.getElement());
	}
	
	private static boolean alwaysAllowed(Object sourceElement, Object targetElement) {
		return sourceElement instanceof InitialNode 
		|| targetElement instanceof FinalNode
		|| (sourceElement instanceof ControlNode && !BridgeHelper.isSynchBar((ControlNode)sourceElement))
		|| (targetElement instanceof ControlNode && !BridgeHelper.isSynchBar((ControlNode)targetElement));
	}
	
	/*
	 * Checks if the given edge is a regular edge, means, it is not a special
	 * edge that is created in extended diagram with a inherited, read-only
	 * target.
	 */
	private static boolean isRegularEdge(Edge edge) {
		MethodElement workOrder = BridgeHelper.getMethodElement(edge);
		return workOrder == null || MethodElementPropertyHelper.getProperty(workOrder, MethodElementPropertyHelper.WORK_ORDER__SUCCESSOR) == null;
	}
	
	public static String checkDelete(Edge edge) {

		View source = edge.getSource();
		View target = edge.getTarget();

		if(target != null){
			Diagram diagram = target.getDiagram();
			switch(DiagramHelper.getDiagramType(diagram)){
			case IDiagramManager.ACTIVITY_DIAGRAM:				
				EObject sourceElement = source.getElement();
				EObject targetElement = target.getElement();
				if(alwaysAllowed(sourceElement, targetElement)) {
					return null;
				}
				if(BridgeHelper.isInherited(edge)) {
					return errMsg_CanNotDelete;
				}
				
				// Since making connection to a inherited, read-only target is
				// allowed now, the check logic below is no longer needed. We
				// only need to prevented inherited connections and nodes from
				// deletion.
				
//				// check if this edge is representing any work order
//				//
//				if (sourceElement instanceof ActivityNode
//						&& BridgeHelper.getMethodElement(sourceElement) == null) {
//					Collection<ActivityNode> actNodes = new ArrayList<ActivityNode>();
//					BridgeHelper.getSourceNodes(actNodes,
//							(ActivityNode) sourceElement,
//							WorkBreakdownElement.class);
//					if (actNodes.isEmpty()) {
//						return null;
//					}
//				}
//				
//				// the edge does represent a work order
//				
//				if(BridgeHelper.isReadOnly(target)) {
//					if(BridgeHelper.getMethodElement(sourceElement) instanceof WorkBreakdownElement)
//					return errMsg_CanNotDelete;
//				}
//				
//				if(targetElement instanceof ActivityNode) {
//					NodeAdapter adapter = BridgeHelper.getNodeAdapter(targetElement);
//					if(adapter != null && adapter.getElement() instanceof WorkBreakdownElement) {
//						return null;
//					}
////					// target does not represent a work breakdown element
////					// disallow deletion of the edge if one of the target nodes of the target is read-only or inherited
////					//
////					Collection<ActivityNode> actNodes = new ArrayList<ActivityNode>();
////					BridgeHelper.getSuccessorNodes(actNodes, (ActivityNode) targetElement);
////					for (ActivityNode activityNode : actNodes) {
////						View view = BridgeHelper.getView(diagram, activityNode);
////						if(view != null && BridgeHelper.isReadOnly(view)) {
////							return errMsg_CanNotDelete;
////						}
////					}
//					
//					if(BridgeHelper.isSynchBar((ActivityNode)targetElement)) {
//						return checkSyncBarOutgoingLinks((ActivityNode)targetElement);
//					}
//
//				}
				
				return null;
			case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
				return errMsg_CanNotDelete;
				
			case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
				if(BridgeHelper.isReadOnly(target))
					return errMsg_CanNotDelete;
				return null;
			}
		}
		return null;
	}
	
	/**
	 * Check to see link is readonly.
	 */
	public static boolean isReadOnly(Edge edge) {
		
		View target = edge.getTarget();
		View source = edge.getSource();
		if (target != null
				&& target.getDiagram().getElement() instanceof ActivityDetailDiagram) {
			if(source != null){
				Object sourceElement = source.getElement();
				if(sourceElement != null && sourceElement instanceof TaskNode
						&& ((TaskNode)sourceElement).isReadOnly()){
					return true;
				}
			}
			if(target != null){
				Object targetElement = target.getElement();
				if(targetElement != null && targetElement instanceof TaskNode
						&& ((TaskNode)targetElement).isReadOnly()){
					return true;
				}
			}
		} else {
			return checkDelete(edge) != null;
		}
		return false;
	}
	
	/**
	 * Check if any duplicate links between two ends already exists.
	 * 	 
	 * */
	public static boolean isDuplicateRelationship(EObject source, EObject target) {
		EObject container = source.eContainer();
		if (container instanceof org.eclipse.uml2.uml.Activity) {
			org.eclipse.uml2.uml.Activity activity = (org.eclipse.uml2.uml.Activity) container;
			List<ActivityEdge> list = activity.getEdges();
			for (Iterator<ActivityEdge> iter = list.iterator(); iter.hasNext();) {
				ActivityEdge element = (ActivityEdge) iter.next();
				if ((element.getSource() == source)
						&& element.getTarget() == target) {
					return true;
				}
			}
		}
		return false;
	}
}
