//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010 huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE----------------------------
package org.huihoo.god4j.jgraph;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.huihoo.god4j.util.UUID;
import org.huihoo.workflow.impl.xpdl.WorkflowActivityImpl;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.PortView;

/**
 * @author zosatapo
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class XPDLJGraphUtils
{
	public static Map cloneMap(Map map)
	{
		Map newMap = new Hashtable(map);
		// Clone Bounds
		Rectangle2D bounds = GraphConstants.getBounds(newMap);
		if (bounds != null)
		{
			GraphConstants.setBounds(newMap, (Rectangle2D)bounds.clone());
		}	
		
		// Clone List Of Points
		java.util.List points = GraphConstants.getPoints(newMap);
		if (points != null)
		{	
			GraphConstants.setPoints(newMap, clonePoints(points));
		}
		
		// Clone Edge Label
		Point label = GraphConstants.getLabelPosition(newMap);
		if (label != null)
		{	
			GraphConstants.setLabelPosition(newMap, new Point(label));
		}
		return newMap;
	}

	public static java.util.List clonePoints(java.util.List points)
	{
		ArrayList newList = new ArrayList();
		Iterator it = points.iterator();
		while (it.hasNext())
		{
			// Clone Point
			Object point = it.next();
			if (point instanceof PortView)
				point = ((PortView) point).getLocation(null);
			else if (point instanceof Point)
				point = new Point((Point) point);
			newList.add(point);
		}
		return newList;
	}

	public final static Point convertToPoint(Point2D point2D)
	{
		if (point2D != null)
		{
			if (point2D instanceof Point)
			{
				return (Point) point2D;
			}
			else
			{
				return new Point((int) point2D.getX(), (int) point2D.getY());
			}
		}

		return null;
	}

	public final static List parsePointList(String pointsInfo)
	{
		//(x1,y1)-(x2,y2)-(x3,y3)
		if (pointsInfo == null)
		{
			return null;
		}
		pointsInfo = pointsInfo.trim();

		StringTokenizer pointsToken = new StringTokenizer(pointsInfo, "-");
		int countTokens = pointsToken.countTokens();
		Point points[] = new Point[countTokens];
		int pointCount = 0;

		while (pointsToken.hasMoreTokens())
		{
			Point point = parsePoint(pointsToken.nextToken());
			if (point != null)
			{
				points[pointCount++] = point;
			}

			if (pointCount >= countTokens)
			{
				break;
			}
		}

		if (pointCount > 0)
		{
			List pointsList = new ArrayList();
			for (int i = 0; i < pointCount; ++i)
			{
				pointsList.add(points[i]);
			}

			return pointsList;
		}
		return null;
	}

	public final static String savePointList(List pointList)
	{
		if (pointList != null)
		{
			StringBuffer buffer = new StringBuffer();
			int sizePoint = pointList.size();
			for (int i = 0; i < sizePoint; ++i)
			{
				Object obj = pointList.get(i);
				if (obj instanceof Point2D)
				{
					buffer.append(savePoint(convertToPoint((Point2D) obj)) + "-");
				}
			}

			String result = buffer.toString();
			if (result.length() > 1)
			{
				return result.substring(0, result.length() - 1);
			}
		}

		return null;
	}

	public final static Point parsePoint(String pointInfo)
	{
		//(x,y)
		if (pointInfo == null)
		{
			return null;
		}
		pointInfo = pointInfo.trim();
		int lbPos = pointInfo.indexOf("(");
		int rbPos = pointInfo.indexOf(")");
		if (lbPos == -1 || rbPos == -1)
		{
			return null;
		}

		pointInfo = pointInfo.substring(lbPos + 1, rbPos);
		StringTokenizer token = new StringTokenizer(pointInfo, ",");
		int countTokens = token.countTokens();
		if (countTokens != 2)
		{
			return null;
		}

		String pos[] = new String[countTokens];
		int posCount = 0;
		while (token.hasMoreTokens())
		{
			pos[posCount++] = token.nextToken();
			if (posCount >= countTokens)
			{
				break;
			}
		}
		try
		{
			return new Point(Integer.parseInt(pos[0]), Integer.parseInt(pos[1]));
		}
		catch (Throwable throwable)
		{
			;
		}

		return null;
	}

	public final static String savePoint(Point point)
	{
		if (point != null)
		{
			return "(" + point.x + "," + point.y + ")";
		}

		return null;
	}

	public final static Rectangle parseBounds(String rectInfo)
	{
		//(x,y,width,height)
		if (rectInfo == null)
		{
			return null;
		}
		rectInfo = rectInfo.trim();
		int lbPos = rectInfo.indexOf("(");
		int rbPos = rectInfo.indexOf(")");
		if (lbPos == -1 || rbPos == -1)
		{
			return null;
		}

		rectInfo = rectInfo.substring(lbPos + 1, rbPos);
		StringTokenizer token = new StringTokenizer(rectInfo, ",");
		int countTokens = token.countTokens();
		if (countTokens != 4)
		{
			return null;
		}

		String pos[] = new String[countTokens];
		int posCount = 0;
		while (token.hasMoreTokens())
		{
			pos[posCount++] = token.nextToken();
			if (posCount >= countTokens)
			{
				break;
			}
		}
		try
		{
			return new Rectangle(
				Integer.parseInt(pos[0]),
				Integer.parseInt(pos[1]),
				Integer.parseInt(pos[2]),
				Integer.parseInt(pos[3]));
		}
		catch (Throwable throwable)
		{
			;
		}

		return null;
	}
	public static final String saveRect(Rectangle rect)
	{
		if (rect != null)
		{
			return "(" + rect.x + "," + rect.y + "," + rect.width + "," + rect.height + ")";
		}

		return null;
	}

	public static final WorkflowActivity cloneActivity(WorkflowActivity activity)
	{
		int size = activity.getWorkflowProcess().getWorkflowActivities().size() + 1;
		WorkflowActivity clone = new WorkflowActivityImpl(UUID.generate(), activity.getName() + "_" + size);
		clone.setWorkflowProcess(activity.getWorkflowProcess());
		clone.setActivityType(activity.getActivityType());
		clone.setDescription(activity.getDescription());
		clone.setDuration(activity.getDuration());
		clone.setJoinType(activity.getJoinType());
		clone.setSplitType(activity.getSplitType());
		clone.setPerformerType(activity.getPerformerType());
		//clone.getPerformers().addAll(activity.getPerformers());
		return clone;
	}
}
