//------------------------------------------------------------------------------
// 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.authoring.gef.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.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.diagram.model.ActivityDetailDiagram;
import org.eclipse.epf.diagram.model.ActivityDiagram;
import org.eclipse.epf.diagram.model.Diagram;
import org.eclipse.epf.diagram.model.Link;
import org.eclipse.epf.diagram.model.Node;
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.WorkProductDependencyDiagram;
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.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkProductDescriptor;


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

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

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

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

	/**
	 * Checks if user can connect the given nodes.
	 * 
	 * @param source
	 * @param target
	 * @return null if connection is allowed, error message otherwise.
	 */
	public static String checkConnect(Node source, Node target) {
		if (source.getDiagram() != target.getDiagram())
			return AuthoringUIResources.DiagramValidation_err_cannot_connect_text;

		if (source.getDiagram() instanceof ActivityDiagram) {
			AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE
					.getWBS_ComposedAdapterFactory();
			Object adapter = adapterFactory.adapt(source.getDiagram()
					.getObject(), ITreeItemContentProvider.class);
			Object proc = null;
			if (adapter instanceof IBSItemProvider) {
				proc = ((IBSItemProvider) adapter).getTopItem();
			}
			// get all breakdown elements in this process
			//
			List allElements = new ArrayList();
			for (Iterator iter = new AdapterFactoryTreeIterator(adapterFactory,
					proc); iter.hasNext();) {
				Object obj = iter.next();
				allElements.add(TngUtil.unwrap(obj));
			}
			if (proc != null) {
				// If target is ReadOnly (means extends) and allow the link if
				// its parent activity is a Contributor
				
				if (target.getDiagram().isReadOnly())
					return errMsg_CanNotConnect;
				if (source.getObject() instanceof WorkBreakdownElement) {
					if (target.getObject() instanceof WorkBreakdownElement) {
						if (ProcessUtil.checkCircular(
								(WorkBreakdownElement) target.getObject(),
								(WorkBreakdownElement) source.getObject(),
								allElements)) {
							return errMsg_SamePredAndSucc;
						}
						if(target.isReadOnly())
							return errMsg_CanNotConnect;
					} else if (target instanceof TypedNode) {
						// should not allow incoming connection to start node
						// and FreeText.
						if (((TypedNode) target).getType() == TypedNode.START
								|| ((TypedNode) target).getType() == TypedNode.FREE_TEXT) {
							return errMsg_CanNotConnect;
						}

						Collection targetNodes = GraphicalDataHelper
								.getTargetNodes((TypedNode) target,
										WorkBreakdownElementNode.class);
						WorkBreakdownElement pred = (WorkBreakdownElement) source
								.getObject();
						for (Iterator iter = targetNodes.iterator(); iter
								.hasNext();) {
							Node node = ((Node) iter.next());
							if (node.isReadOnly())
								return errMsg_CanNotConnect;
							if (ProcessUtil.checkCircular(
									(WorkBreakdownElement) node.getObject(),
									pred, allElements)) {
								return errMsg_SamePredAndSucc;
							}
						}
					}
				} else if (source instanceof TypedNode) {
					if (target == source) {
						return errMsg_CanNotConnect;
					}
					// should not allow outgoing connection from End Node and
					// Free Text
					if (((TypedNode) source).getType() == TypedNode.END
							|| ((TypedNode) source).getType() == TypedNode.FREE_TEXT) {
						return errMsg_CanNotConnect;
					}

					if (target instanceof TypedNode) {

						/*
						 * If source and target are TypedNodes, avoid circular
						 * loop connection.
						 */
						if (checkSyncBarCircularLooop((TypedNode) source,
								(TypedNode) target) != null) {
							return errMsg_CanNotConnect;
						}

						// should not allow incoming connection to start node
						// and FreeText.
						if (((TypedNode) target).getType() == TypedNode.START
								|| ((TypedNode) target).getType() == TypedNode.FREE_TEXT) {
							return errMsg_CanNotConnect;
						}

						Collection srcNodes = GraphicalDataHelper
								.getSourceNodes((TypedNode) source,
										WorkBreakdownElementNode.class);
						if (!srcNodes.isEmpty()) {
							Collection targetNodes = GraphicalDataHelper
									.getTargetNodes((TypedNode) target,
											WorkBreakdownElementNode.class);
							for (Iterator iter = targetNodes.iterator(); iter
									.hasNext();) {
								Node node = ((Node) iter.next());
								if (node.isReadOnly())
									return errMsg_CanNotConnect;
								WorkBreakdownElement succ = (WorkBreakdownElement) node
										.getObject();
								for (Iterator iterator = srcNodes.iterator(); iterator
										.hasNext();) {
									WorkBreakdownElement pred = (WorkBreakdownElement) ((Node) iterator
											.next()).getObject();
									if (ProcessUtil.checkCircular(succ, pred,
											allElements)) {
										return errMsg_SamePredAndSucc;
									}
								}
							}
						}
					} else if (target instanceof WorkBreakdownElementNode) {
						
						if(target.isReadOnly()) return errMsg_CanNotConnect;
						
						Collection srcNodes = GraphicalDataHelper
								.getSourceNodes((TypedNode) source,
										WorkBreakdownElementNode.class);
						WorkBreakdownElement succ = (WorkBreakdownElement) ((Node) target)
								.getObject();
						for (Iterator iterator = srcNodes.iterator(); iterator
								.hasNext();) {
							WorkBreakdownElement pred = (WorkBreakdownElement) ((Node) iterator
									.next()).getObject();
							if (ProcessUtil.checkCircular(succ, pred,
									allElements)) {
								return errMsg_SamePredAndSucc;
							}
						}

					}
				}
			}
		} else if (source.getDiagram() instanceof ActivityDetailDiagram) {
			if (source.isReadOnly() || target.isReadOnly()) {
				return errMsg_CanNotConnect;
			}

			if ((source.getObject() instanceof RoleDescriptor || target
					.getObject() instanceof RoleDescriptor)
					|| (source.getObject() instanceof TaskDescriptor && target
							.getObject() instanceof TaskDescriptor)
					|| (source.getObject() instanceof WorkProductDescriptor && target
							.getObject() instanceof WorkProductDescriptor)) {
				return errMsg_CanNotConnect;
			} else {
				// check for duplicate connection
				//
				for (Iterator iter = source.getOutgoingConnections().iterator(); iter
						.hasNext();) {
					Link link = (Link) iter.next();
					if (link.getTarget() == target) {
						return errMsg_CanNotConnect;
					}
				}

			}
		} else if (source.getDiagram() instanceof WorkProductDependencyDiagram) {
			if (source.isReadOnly() || target.isReadOnly()) {
				return errMsg_CanNotConnect;
			}
		}

		return null;
	}

	public static String checkDelete(Link link) {
		
//		if (link.getTarget() != null
//				&& link.getTarget().getDiagram() instanceof ActivityDiagram) {
//			if (link.getTarget().isReadOnly()){
//				if(link.getSource() instanceof TypedNode){
//					if(((TypedNode)link.getSource()).getType() == TypedNode.DECISION){
//						return null;
//					}
//				}
//				return errMsg_CanNotDelete;
//			}
//			if (link.getTarget() instanceof TypedNode) {
//				
//				TypedNode typednode = (TypedNode)link.getTarget();
//				if(typednode.getType() == TypedNode.DECISION){
//					return null;
//				}
//				if(link.getSource() instanceof TypedNode){
//					typednode = (TypedNode)link.getSource();
//					if(typednode.getType() == TypedNode.DECISION){
//						return null;
//					}
//				}
//				
//				if (link.getSource().isReadOnly())
//					return errMsg_CanNotDelete;
//				
//				if (link.getSource().getObject() instanceof WorkBreakdownElement
//						|| (link.getSource() instanceof TypedNode && !GraphicalDataHelper
//								.getSourceNodes((TypedNode) link.getSource(),
//										WorkBreakdownElementNode.class)
//								.isEmpty())) {
//					
//					Collection targetNodes = GraphicalDataHelper.getTargetNodes((TypedNode) link.getTarget(),
//												WorkBreakdownElementNode.class);
//					for (Iterator iter = targetNodes.iterator(); iter.hasNext();) {
//						Node node = (Node) iter.next();
//						if (node.isReadOnly()) {
//							return errMsg_CanNotDelete;
//						}
//					}
//				}
//
//			}
//			if (link.getSource() instanceof TypedNode) {
//				TypedNode typednode = (TypedNode)link.getSource();
//				if(typednode.getType() == TypedNode.DECISION){
//					return null;
//				}
//				if (link.getTarget().isReadOnly())
//					return errMsg_CanNotDelete;
//			}
//		} else if ((link.getTarget() != null && link.getTarget().isReadOnly())
//				|| (link.getSource() != null && link.getSource().isReadOnly())) {
//			return errMsg_CanNotDelete;
//		}
		//return null;
		
		
		Node source = link.getSource();
		Node target = link.getTarget();
		
		// Special handle for Activity Detail Diagram links cannot be deleted.
		if (target != null
				&& target.getDiagram() instanceof ActivityDetailDiagram) {
			return errMsg_CanNotDelete;
		}
		
		
		if (target != null
				&& target.getDiagram() instanceof ActivityDiagram) {
			
			// Target = breakdownelement
			if(target instanceof WorkBreakdownElementNode){
				// Source = Breakdown element
				if(source instanceof WorkBreakdownElementNode){
					if(link.getTarget().isReadOnly())
						return errMsg_CanNotDelete;
					else
						return null;
				}
				// Source = TypedNode
				if(source instanceof TypedNode){
					// Source = Decision Node
					TypedNode sourceNode = (TypedNode)source;
					if(!target.isReadOnly()){
						return null;
					}
					else if(sourceNode.getType() == TypedNode.DECISION){
						return null;
					}
					else if(sourceNode.getType() == TypedNode.SYNCH_BAR){
						return checkSyncBarIncomingLinks(sourceNode);
					}
					else if(sourceNode.isReadOnly()){
						return errMsg_CanNotDelete;
					}
				}
			}// Target is TypedNode
			else if(target instanceof TypedNode){
				
				TypedNode typedNode = (TypedNode)target;
				// if Target is TypedNode and its a DecisionPoint - should be black.
				if(typedNode.getType() == TypedNode.DECISION){
					return null;
				}
				// If Target is TypedNode and and Source is WorkBreakdownElement and readonly
				// Link should be green. 
				if(source instanceof WorkBreakdownElementNode){
					// Check Target - is having any indirect(outgoing connnection) contains decision points.
					if(checkSyncBarOutgoingLinks((TypedNode)target) == null)
						return null;
					if(source.isReadOnly())
						return errMsg_CanNotDelete;
				}
				if(source instanceof TypedNode){
					TypedNode sourceTypedNode = (TypedNode)source;
					// Source is Typed Node and its a decision point return null. 
					if(sourceTypedNode.getType() == TypedNode.DECISION){
						return null;
					}
					// if source is SyncBar and check all its incoming connections. 
					if(sourceTypedNode.getType() == TypedNode.SYNCH_BAR){
						return checkSyncBarIncomingLinks(sourceTypedNode);
					}
				}
			}
		}
		return null;
	}

	public static String checkDelete(Node node) {
		if (node.isReadOnly())
			return errMsg_CanNotDelete;
		Diagram diagram = node.getDiagram();
		if (diagram instanceof ActivityDiagram) {
			if (node instanceof TypedNode) {
				Collection targetNodes = GraphicalDataHelper.getTargetNodes(
						(TypedNode) node, WorkBreakdownElementNode.class);
				for (Iterator iter = targetNodes.iterator(); iter.hasNext();) {
					Node target = (Node) iter.next();
					if (target.isReadOnly()) {
						return errMsg_CanNotDelete;
					}
				}
			}
		} else if (diagram instanceof ActivityDetailDiagram) {
			if (node instanceof RoleNode) {
				return errMsg_CanNotDelete;
			}
		}
		return null;
	}

	public static String checkReconnect(Node source, Node target, Link link) {
		if (source.getDiagram() instanceof ActivityDiagram) {
			if (link.getTarget() != null) {
				if (link.getTarget().isReadOnly()) {
					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 (node.isReadOnly()) {
								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, Link link) {

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

		List links = source.getOutgoingConnections();
		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, target);
	}

	/*
	 * 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(TypedNode sNode,
			TypedNode tNode) {
		List list = tNode.getOutgoingConnections();
		if (!list.isEmpty() && list.size() > 0) {
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				Link link = (Link) iterator.next();
				Node typednode = link.getTarget();
				if (sNode.equals(typednode))
					return errMsg_CanNotConnect;
				if (typednode instanceof TypedNode) {
					return checkSyncBarCircularLooop(sNode,
							(TypedNode) typednode);
				}
			}
		}
		return null;
	}
	
	/*
	 * Method to Check if SyncBar inComming connections have 
	 * any source is a readonly. 
	 * @return
	 */
	public static String checkSyncBarIncomingLinks(TypedNode typedNode){
		for (Iterator iter = typedNode.getIncomingConnections().iterator(); iter.hasNext();) {
				Link link = (Link) iter.next();
				Node source = link.getSource();
				if(source instanceof WorkBreakdownElementNode){
					if(source.isReadOnly())
						return errMsg_CanNotDelete;
				}else if(source instanceof TypedNode){
					if(((TypedNode)source).getType() == TypedNode.SYNCH_BAR)
						if(checkSyncBarIncomingLinks((TypedNode)source)!= null)
							return errMsg_CanNotDelete;
				}
		}
		return null;
	}
	/*
	 *Method to check if synchronization bar outgoing connection
	 *has any target is readonly.  
	 */
	public static String checkSyncBarOutgoingLinks(TypedNode typedNode){
		for (Iterator iter = typedNode.getOutgoingConnections().iterator(); iter.hasNext();) {
				Link link = (Link) iter.next();
				Node target = link.getTarget();
				if(target instanceof WorkBreakdownElementNode){
					if(target.isReadOnly())
						return errMsg_CanNotDelete;
				}else if(target instanceof TypedNode){
					if(((TypedNode)target).getType() == TypedNode.SYNCH_BAR)
						if(checkSyncBarOutgoingLinks((TypedNode)target)!= null)
							return errMsg_CanNotDelete;
				}
		}
		return null;
	}
	
	/**
	 * Check to see link is readonly. 
	 */
	public static boolean isReadOnly(Link link) {
		Node target = link.getTarget();
		Node source = link.getSource();
		if (target != null && target.getDiagram() instanceof ActivityDiagram) {
			return checkDelete(link) != null;
		} else if (target != null
				&& target.getDiagram() instanceof ActivityDetailDiagram) {
			if ((source != null && source instanceof TaskNode && source
					.isReadOnly())
					|| (target instanceof TaskNode && target.isReadOnly()))
				return true;
		}
		return false;
	}
}
