/******************************************************************************
 * Copyright (c) 2002, 2008 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 API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.diagram.ui.providers.internal;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.diagram.core.internal.commands.IPropertyValueDeferred;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.actions.internal.DiagramActionsDebugOptions;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.diagram.ui.internal.requests.ChangeBoundsDeferredRequest;
import org.eclipse.gmf.runtime.diagram.ui.internal.services.layout.LayoutNodesOperation;
import org.eclipse.gmf.runtime.diagram.ui.providers.internal.l10n.DiagramUIProvidersMessages;
import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.ChangePropertyValueRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.diagram.ui.requests.SetAllBendpointRequest;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.AbstractLayoutEditPartProvider;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.LayoutType;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.notation.FontStyle;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;

/**
 * @author sshaw
 * 
 * RadialProvider class that provides for LayoutType.RADIAL.
 */
public class RadialProvider
	extends AbstractLayoutEditPartProvider {

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
	 */
	public boolean provides(IOperation operation) {
		Assert.isNotNull(operation);

		View cview = getContainer(operation);
		if (cview == null)
			return false;
		
		IAdaptable layoutHint = ((LayoutNodesOperation) operation).getLayoutHint(); 
		String layoutType = (String) layoutHint.getAdapter(String.class);
		return LayoutType.RADIAL.equals(layoutType);		
	} 

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.services.layout.AbstractLayoutEditPartProvider#layoutEditParts(org.eclipse.gef.GraphicalEditPart, org.eclipse.core.runtime.IAdaptable)
	 */
	public Command layoutEditParts(
		GraphicalEditPart containerEP,
		IAdaptable layoutHint) {

		List children = containerEP.getChildren();
		return layout(containerEP, children, findRootView(children), layoutHint);
	}

	
	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.services.layout.AbstractLayoutEditPartProvider#layoutEditParts(java.util.List, org.eclipse.core.runtime.IAdaptable)
	 */
	public Command layoutEditParts(
		List selectedObjects,
		IAdaptable layoutHint) {

		if (selectedObjects.size()== 0){
			return null;
		}
		
		GraphicalEditPart editPart = (GraphicalEditPart) selectedObjects.get(0);		
		GraphicalEditPart containerEditPart = (GraphicalEditPart) editPart.getParent();
		
		return layout(containerEditPart, selectedObjects, findRootView(selectedObjects), layoutHint);
	}

	/**
	 * Method layout.
	 * 
	 * @param layoutType
	 * @param containerEP
	 * @param selectedObjects
	 * @param rootEP
	 * @return Command
	 * @throws InvalidParameterException
	 *             if either parameter is null.
	 */
	public Command layout(
		GraphicalEditPart containerEP,
		List selectedObjects,
		ShapeEditPart rootEditPart,
		IAdaptable layoutHint) {

		if (containerEP == null || selectedObjects == null) {
			InvalidParameterException ipe = new InvalidParameterException();
			Trace.throwing(DiagramProvidersPlugin.getInstance(), DiagramActionsDebugOptions.EXCEPTIONS_THROWING, getClass(), "layout()", //$NON-NLS-1$
			ipe);
			throw ipe;
		}

		if (rootEditPart == null)
			rootEditPart = findRootView(selectedObjects);

		List parts = new ArrayList(selectedObjects.size());

		// Only add IShapeView to the master list
		ListIterator li = selectedObjects.listIterator();
		while (li.hasNext()) {
			EditPart ep = (EditPart) li.next();
			if (!ep.equals(rootEditPart)
				&& (ep instanceof ShapeEditPart
					|| ep instanceof ConnectionNodeEditPart)) {
				parts.add(ep);
			}
		}

		Command cmd = null;
		CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
		RadialLayout radialLayout =
			new RadialLayout(rootEditPart, parts, 0, Math.PI * 2, false);

		cmd = radialLayout.getPrelayoutCommand();
		if (cmd != null)
			cc.add(cmd);
		
		try {
			cmd = radialLayout.getCommand();
			parts.add(rootEditPart);
		} catch (LayoutEstheticsException e) {
			// since the Layout esthetics have been violated, use the default layout
			// instead.
			parts.add(rootEditPart);
			
			ArrangeRequest request = new ArrangeRequest(
				RequestConstants.REQ_ARRANGE_DEFERRED);
			request.setViewAdaptersToArrange(parts);
			cmd = containerEP.getCommand(request);
		}
		
		if (cmd != null)
			cc.add(cmd);
		
		Request req = new Request(RequestConstants.REQ_REFRESH);
		cmd = rootEditPart.getParent().getCommand(req);
		if (cmd != null)
			cc.add(cmd);
		
		// position the entire radial circle
		OffsetRadialPartsCommand orpc = new OffsetRadialPartsCommand(
            rootEditPart.getEditingDomain(), parts);
        cmd = new ICommandProxy(orpc);
		if (cmd != null)
			cc.add(cmd);
		
		return cc;
	}

	/**
	 * @author sshaw
	 *
	 * Command to update the entire position of the Radial circle.
	 */
	static protected class OffsetRadialPartsCommand extends AbstractTransactionalCommand {
		private List editParts;
		private Rectangle origRect;
		
		/**
		 * @param editParts
		 * @param ptRoot
		 */
		public OffsetRadialPartsCommand(TransactionalEditingDomain editingDomain, List editParts) {
			super(editingDomain, "", null); //$NON-NLS-1$
			this.editParts = editParts;
			origRect = calcBoundBox();
		}
		
		protected CommandResult doExecuteWithResult(
                IProgressMonitor progressMonitor, IAdaptable info)
            throws ExecutionException {
            
			if (null == editParts)
				return CommandResult.newCancelledCommandResult();
			
			Rectangle radialRect = calcBoundBox();
			
			IGraphicalEditPart firstEP = (IGraphicalEditPart)editParts.get(0);
			IMapMode mm = MapModeUtil.getMapMode(firstEP.getFigure());
			
			// consider ideal location
			Rectangle newRadialRect = new Rectangle(radialRect);
			newRadialRect.translate( -radialRect.getTopLeft().x + mm.DPtoLP(50),
							 -radialRect.getTopLeft().y + mm.DPtoLP(50));
			
			if (origRect.x > newRadialRect.x && origRect.y > newRadialRect.y) {
				newRadialRect = new Rectangle( Math.max(newRadialRect.x, origRect.x - (radialRect.width / 2)), 
											   Math.max(newRadialRect.y, origRect.y - (radialRect.height / 2)), 
											radialRect.width, radialRect.height);
			}
			
			final Point translate = new Point(newRadialRect.getTopLeft().x - radialRect.getTopLeft().x,
										newRadialRect.getTopLeft().y - radialRect.getTopLeft().y);
			 
			ListIterator li = editParts.listIterator();
			while (li.hasNext()) {
				IGraphicalEditPart gep = (IGraphicalEditPart)li.next();
				View view = gep.getNotationView();
				if (view!=null){
					Integer pos = (Integer)ViewUtil.getStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_X());
					ViewUtil.setStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_X(), new Integer(pos.intValue() + translate.x));
					pos = (Integer)ViewUtil.getStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_Y());
					ViewUtil.setStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_Y(), new Integer(pos.intValue() + translate.y));
				}
			}
			
			// clear for garbage collection;
			editParts = null;
			return CommandResult.newOKCommandResult();
		}

		/**
		 * @return
		 */
		private Rectangle calcBoundBox() {
			Rectangle radialRect = null;
			ListIterator li = editParts.listIterator();
			while (li.hasNext()) {
				IGraphicalEditPart gep = (IGraphicalEditPart)li.next();
				if (null == radialRect) {
					radialRect = new Rectangle(gep.getFigure().getBounds());
				}
				else {
					radialRect.union(gep.getFigure().getBounds());
				}
			}
			return null == radialRect ?  new Rectangle() : radialRect;
		}
	}
	
	/**
	 * Method findRootView. Given a list of views, calculate the root view that
	 * all other views are ultimately related to.
	 * 
	 * @param views
	 *            List of editparts to determine the root view from.
	 * @return ShapeEditPart shape editpart object that represents the root
	 *         view.
	 */
	protected ShapeEditPart findRootView(List editparts) {
		if (editparts == null)
			throw new InvalidParameterException();

		// TodoKit: I am sure we must find better ways to dig up the root of a
		// tree, for now I assume it to be
		// the first in the collection as I know it was the first view created.
		int count = editparts.size(); 
		if (count > 0) {
			EditPart ep = (EditPart) editparts.get(0);
			if (ep instanceof ShapeEditPart) {
				return (ShapeEditPart) editparts.remove(0);
			}
		}

		return null;
	}

	/**
	 * @author sshaw
	 *
	 * Nested RuntimeException class thrown when the esthetics of the RadialLayout
	 * are violated.  i.e. when certain conditions are met that ensure that the RadialLayout
	 * will not look good.
	 */
	static protected class LayoutEstheticsException extends RuntimeException {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 3084395663087786098L;

		/**
		 * @param message
		 */
		public LayoutEstheticsException(String message) {
			super(message);
		}
	}
	
	/**
	 * @author sshaw
	 * 
	 * Helper class to build the radial layout based on a root editpart.
	 */
	static protected class RadialLayout {

		private ShapeEditPart rootEP;
		private List allEditparts = new ArrayList();
		private double startTheta;
		private double totalTheta;
		private boolean rootPositionLocked;

		public RadialLayout(
			ShapeEditPart rootEP,
			List shapeViews,
			double startTheta,
			double totalTheta,
			boolean rootPositionLocked) {
			this.rootEP = rootEP;
			this.allEditparts.addAll(shapeViews);
			this.startTheta = startTheta;
			this.totalTheta = totalTheta;
			this.rootPositionLocked = rootPositionLocked;
		}

		/**
		 * Method getRootEditPart.
		 * 
		 * @return ShapeEditPart
		 */
		public ShapeEditPart getRootEditPart() {
			return rootEP;
		}

		/**
		 * Method getCommand.
		 * 
		 * @return Command
		 */
		public Command getCommand() throws LayoutEstheticsException {
			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			Command cmd = null;
			List restViews = new ArrayList();
			
			List firstCircleParts = new ArrayList();
			
			int innerRingCount =
				findChildViews(rootEP, allEditparts, firstCircleParts, restViews);

			double theta = Math.PI;
			if (innerRingCount > 1) {
				theta = totalTheta / innerRingCount;
			} 
						
			// initialize the childAndSectionViewMap structure
			Map childAndSectionMap = new Hashtable(firstCircleParts.size());
			List circleSectionParts = null;
			List firstCircleShapes = new ArrayList(childAndSectionMap.keySet().size());
			
			for (int i = 0; i < firstCircleParts.size(); i++) {
				EditPart ep = (EditPart) firstCircleParts.get(i);
				if (ep instanceof ShapeEditPart) {
					ShapeEditPart shapeEP = (ShapeEditPart) ep;
					circleSectionParts =
						new ArrayList(firstCircleParts.size());

					List restRestViews = new ArrayList();
					findChildViews(
						shapeEP,
						restViews,
						circleSectionParts,
						restRestViews);

					firstCircleShapes.add(ep);
					childAndSectionMap.put(ep, circleSectionParts);
					childAndSectionMap.put(circleSectionParts, restRestViews);
				} 
			}
			
			CalculateRadialInfoCommand radialInfoCmd = 
				new CalculateRadialInfoCommand(rootEP, firstCircleShapes, theta);
			cc.add(radialInfoCmd);
			
			cmd = positionRings(firstCircleParts, childAndSectionMap, theta, radialInfoCmd);
			if (cmd != null)
				cc.add(cmd);
			
			// route any extra connection, restViews should only contain
			// connections by now, all other views has
			// better be placed already.
			cmd = routeConnection(firstCircleParts);
			if (cmd != null)
				cc.add(cmd);
			
			double increaseTheta = theta;
			cmd = positionNextRings(firstCircleParts, childAndSectionMap, increaseTheta );
			if (cmd != null)
				cc.add(cmd);
			
			return cc;
		}
		
		/**
		 * getPrelayoutCommand
		 * Initializes the set of shapes for the layout operation.
		 * @return Cpmmand that will initialize the shapes for the layout operation.
		 */
		private Command getPrelayoutCommand() {
			List restViews = new ArrayList();
			List firstCircleParts = new ArrayList();
			
			findChildViews(rootEP, allEditparts, firstCircleParts, restViews);
			Command cmd = diminishCircle(firstCircleParts);
				
			int size = getFontSize(rootEP);
			int fontAdjust = size / 8;

			size -= fontAdjust;

			Command c2 = diminishCircle(restViews, size);
			if (c2 != null) {
				if (cmd != null)
					cmd.chain(c2);
				else
					cmd = c2;
			}

			Request req = new Request(RequestConstants.REQ_REFRESH);
			Command c3 = rootEP.getParent().getCommand(req);
			if (c3 != null) {
				if (cmd != null)
					cmd.chain(c3);
				else
					cmd = c3;
			}
			
			return cmd;
		}

		/**
		 * positionNextRings
		 * Method to handle the recursion of the RadialLayout.  
		 * 
		 * @param firstCircleParts
		 * @param childAndSectionMap
		 * @param theta
		 * @return
		 */
		private Command positionNextRings(List firstCircleParts, Map childAndSectionMap, double theta ) {
			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			int n = 0;
			
			for (int i = 0; i < firstCircleParts.size(); i++) {
				double totalThetaPrim = theta;
				EditPart part = (EditPart) firstCircleParts.get(i);
				if (part instanceof ShapeEditPart) {
					List parts = (List)childAndSectionMap.get(part);
					
					if (parts != null
						&& !parts.isEmpty()) {
						int posViewCount = 0;
						
						n = i;
						// check next in list to see if we can increase theta
						while (i + 1 < firstCircleParts.size()) {
							Object key = firstCircleParts.get(i+1);
							List nextViews = (List)childAndSectionMap.get(key);
							if (null != nextViews && nextViews.size() == 0) {
								totalThetaPrim = Math.min(Math.PI, totalThetaPrim + theta);
								i++;
							}
							else
								break;
						}
						
						// count the ShapeEditParts
						ListIterator li = parts.listIterator();
						while (li.hasNext()) {
							if (li.next() instanceof ShapeEditPart)
								posViewCount++;
						}

						double dTheta = startTheta + (n * theta);
						double thetaPrim = totalThetaPrim / posViewCount;
						double startThetaPrim;
						if (posViewCount < 2) {
							startThetaPrim = dTheta;
						} else {
							startThetaPrim = dTheta - totalThetaPrim / 2 + thetaPrim / 2;
						}

						List restRestViews = (List)childAndSectionMap.get(parts);
						parts.addAll(restRestViews);
						
						RadialLayout radialLayout =
							new RadialLayout((ShapeEditPart)part, parts, startThetaPrim, totalThetaPrim, true);
						Command cmd = radialLayout.getCommand();
						if (cmd != null)
							cc.add(cmd);
					}
				}
			}
			
			if (!cc.isEmpty())
				return cc;
			
			return null;
		}

		/**
		 * @author sshaw
		 * 
		 * This class implements IAdaptable so that a deferred point can be
		 * calculated for an edit part.
		 */
		static protected class RadialPosition implements IAdaptable {

			private ShapeEditPart sep;
			private CalculateRadialInfoCommand radialInfo;
			private double theta;
			private boolean useDelta;
			private Point ptLocation = null;

			/**
			 * Method RadialPosition. Constructor for the inner ring elements.
			 * 
			 * @param sep
			 * @param innerIndex
			 */
			public RadialPosition(ShapeEditPart sep, double theta, CalculateRadialInfoCommand radialInfo, boolean useDelta) {
				this.sep = sep;
				this.theta = theta;
				this.radialInfo = radialInfo;
				this.useDelta = useDelta;
			}

			/**
			 * Method getAdapter.
			 * 
			 * @param adapterType
			 * @return Object
			 */
			public Object getAdapter(Class adapterType) {
				if (adapterType == IPropertyValueDeferred.class) {
					return getPosition();
				}

				return null;
			}

			/**
			 * Method getPosition. Calculates the point based on stored
			 * information about the radius and index of the edit part.
			 * 
			 * @return Point
			 */
			public Point getPosition() {
				if (null == ptLocation) {
					ptLocation = new Point(0, 0);
					
					if (null != radialInfo) {
						ptLocation.x =
							Math.round(
								radialInfo.getRadius() * ((float) Math.cos(theta)) ); 
						ptLocation.y =
							Math.round(
								radialInfo.getRadius() * ((float) Math.sin(theta)) );
						
						if (useDelta)
							ptLocation.translate(radialInfo.getDelta());
					}
					
					ptLocation.translate(
							-sep.getSize().width / 2,
							-sep.getSize().height / 2);
					
					sep = null;
					radialInfo = null;
				}
				
				return ptLocation;
			}
		}

		/**
		 * Method findChildViews. This method finds all of the child views
		 * relative to a given root view and a set of views.
		 * 
		 * @param rootEditPart
		 *            ShapeEditPart to be compared against. If a connection ends
		 *            on this root editpart the end must be related.
		 * @param editparts
		 *            List of a editparts that are used to compare against the
		 *            root editpart.
		 * @param childEPs
		 *            List that is passed in and populated by the method. It
		 *            will be populated the editparts that are related to the
		 *            rootView.
		 * @param restEPs
		 *            List that is passed in and populated by the method. It
		 *            will be populated with the editparts are not related to
		 *            the rootView.
		 * @return int number of related shape editparts in the childViews
		 *         list.
		 */
		protected int findChildViews(
			ShapeEditPart rootEditPart,
			List editparts,
			List childEPs,
			List restEPs) {
			if (rootEditPart == null)
				throw new InvalidParameterException();

			if (childEPs == null)
				throw new InvalidParameterException();

			if (restEPs == null)
				throw new InvalidParameterException();

			Set allSet = new HashSet(editparts.size());
			int posViewCount = 0;
			int count = editparts.size();
			for (int i = 0; i < count; i++) {
				EditPart ep = (EditPart) editparts.get(i);
				allSet.add(ep);
			}

			//get a list of the selected connections and the selected
			//shapes connections
			List connectionEPs = new ArrayList();
			for (int i = 0; i < count; i++) {
				EditPart ep = (EditPart) editparts.get(i);
				if (ep instanceof ShapeEditPart) {
					ShapeEditPart shapeEP = (ShapeEditPart) ep;
					connectionEPs.addAll(shapeEP.getSourceConnections());
					connectionEPs.addAll(shapeEP.getTargetConnections());
				} else if (ep instanceof ConnectionNodeEditPart) {
					connectionEPs.add(ep);
				}
			}

			for (int i = 0; i < connectionEPs.size(); i++) {
				EditPart ep = (EditPart) connectionEPs.get(i);
				if (ep instanceof ConnectionNodeEditPart) {
					ConnectionNodeEditPart connectionEP =
						(ConnectionNodeEditPart) ep;
					EditPart fromEP = connectionEP.getSource();
					EditPart toEP = connectionEP.getTarget();

					EditPart el = null;
					if (fromEP.equals(rootEditPart)) {
						el = toEP;
					} else if (toEP.equals(rootEditPart)) {
						el = fromEP;
					} 

					if (el != null && allSet.contains(el)) {
						childEPs.add(el);
						posViewCount++;
						childEPs.add(connectionEP);

						allSet.remove(el);
					}
				}

			}

			// If the rest collection was requested, pick out all views that
			// was not in the child collection.
			restEPs.addAll(allSet);

			return posViewCount;
		}

		/**
		 * Method getFontSize. Returns the size of the associated font with the
		 * viewEl,
		 * 
		 * @param sep
		 *            ShapeEditPart element to retrieve the fontdata from.
		 * @return int value of the font size (height).
		 */
		protected int getFontSize(ShapeEditPart sep) {
			if (sep == null)
				throw new InvalidParameterException();
			View view = sep.getNotationView();
			if (view!=null){
				FontStyle style = (FontStyle) view.getStyle(NotationPackage.eINSTANCE.getFontStyle());
				if (style != null)
					return style.getFontHeight();
			}
			return 9;
		}

		/**
		 * Method setFontSize. Sets the new font size for a given view element.
		 * This is a convenience wrapper. The same functionality can be
		 * achieved by using the setPropertyValue api.
		 * 
		 * @param viewEl
		 *            IView element to retrieve and set the fontdata from.
		 * @param size
		 *            value of the new font size (height).
		 * @return Command
		 */
		protected Command setFontSize(ShapeEditPart sep, int size) {
			if (sep == null)
				throw new InvalidParameterException();

			ChangePropertyValueRequest cpvr = new ChangePropertyValueRequest(
				DiagramUIProvidersMessages.RadialProvider_changeFontRequest_label,
				Properties.ID_FONTSIZE, new Integer(size));
		
			return getCommand(sep, cpvr, true);
		}

		/**
		 * Method diminishInnerCircle. Given a list of views this method will
		 * parse through them and diminish their size by setting the font.
		 * 
		 * @param editparts
		 *            List of editparts to diminish the size of.
		 * @param fontSize
		 *            int value of the new font size.
		 * @return Command
		 *  
		 */
		protected Command diminishCircle(List editparts) {
			if (editparts == null)
				throw new InvalidParameterException();

			int count = editparts.size();

			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			
			//diminish by collapsing all compartments and hiding
			// connection labels.
			for (int i = 0; i < count; i++) {
				EditPart editpart = (EditPart) editparts.get(i);
				ChangePropertyValueRequest request = null;

				if (editpart instanceof ShapeEditPart) {
					request = new ChangePropertyValueRequest(
						DiagramUIProvidersMessages.RadialProvider_changeVisibilityRequest_label,
						Properties.ID_ISVISIBLE, Boolean.FALSE);

					ShapeEditPart shapeEditPart = (ShapeEditPart) editpart;
					
					Iterator compartments = shapeEditPart
						.getResizableCompartments().iterator();
					while (compartments.hasNext()) {
						cc.add(((EditPart) compartments.next())
							.getCommand(request));
					}
					
					
				}
			}

			if (!cc.isEmpty())
				return cc;

			return null;
		}

		/**
		 * Method diminishCircle. Given a list of views this method will
		 * parse through them and diminish their size by setting the font and
		 * also by hiding all compartments.
		 * 
		 * @param editparts
		 *            List of editparts to diminish the size of.
		 * @param fontSize
		 *            int value of the new font size.
		 * @return Command
		 *  
		 */
		protected Command diminishCircle(List editparts, int fontSize) {
			if (editparts == null)
				throw new InvalidParameterException();

			long count = editparts.size();

			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$

			// diminish the same as the inner circle first.
			Command cmd = diminishCircle(editparts);
			if (cmd != null)
				cc.add(cmd);
			
			//diminish font for outer circle
			for (int i = 0; i < count; i++) {
				EditPart ep = (EditPart) editparts.get(i);
				if (ep instanceof ShapeEditPart) {
					cmd = setFontSize((ShapeEditPart) ep, fontSize);
					if (cmd != null)
						cc.add(cmd);
				}
			}

			if (!cc.isEmpty())
				return cc;

			return null;
		}

        /**
         * sortFirstCircleParts
         * Sort the circle views in a pattern such that the next iteration of radial 
         * views will be positioned evenly w.r.t. each other.
         * 
         * @param firstCircleViews List of circle views
         * @param childAndSectionViewMap Map of next level views.
         */
        protected void sortFirstCircleParts(List firstCircleParts, Map childAndSectionMap) {
        	List firstCircleShapeParts = new ArrayList(firstCircleParts.size());
        	List rest = new ArrayList(firstCircleParts.size());
        	ListIterator li = firstCircleParts.listIterator();
        	while (li.hasNext()) {
        		Object obj = li.next();
        		if (obj instanceof ShapeEditPart) {
        			firstCircleShapeParts.add(obj);
        		}
        		else
        			rest.add(obj);
        	}
        	
            // figure out how many empty 2nd line children there are
            List emptyNextCircleList = new ArrayList(firstCircleParts.size());
            List nextCircleList = new ArrayList(firstCircleParts.size());
            for (int i = 0; i < firstCircleShapeParts.size(); i++) {
            	List circleList = (List)childAndSectionMap.get(firstCircleShapeParts.get(i));
        		if (null != circleList && circleList.size() == 0)
        			emptyNextCircleList.add(firstCircleShapeParts.get(i));
        		else
        			nextCircleList.add(firstCircleShapeParts.get(i));
            }
            
            firstCircleParts.clear();
            if (nextCircleList.size() > 1) {
            	int addInc = firstCircleShapeParts.size() / nextCircleList.size();
	            int i = 0;
	            while (nextCircleList.size() > 0 || emptyNextCircleList.size() > 0) {
	            	if (i % addInc == 0 && nextCircleList.size() > 0) {
	            		firstCircleParts.add(nextCircleList.remove(0));
	            	}
	            	else {
	            		if (emptyNextCircleList.size() > 0)
	            			firstCircleParts.add(emptyNextCircleList.remove(0));
	            	}
	            	i++;
	            }
            }
            else
            	firstCircleParts.addAll(firstCircleShapeParts);
            
            firstCircleParts.addAll(rest);
        }
        
		/**
		 * Method positionRings. This method positions the view rings around
		 * the root view.
		 * 
		 * @return Command
		 */
		protected Command positionRings(List firstCircleParts, Map childAndSectionMap, 
										double theta, CalculateRadialInfoCommand radialInfo) {
			int n = 0;
 
			if (theta < Math.PI / 32 && isRootPositionLocked())
				throw new LayoutEstheticsException("Angle is too small to resulting in very large radius");//$NON-NLS-1$
			
			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			List editParts = new ArrayList();
			editParts.add(rootEP);
			
			sortFirstCircleParts(firstCircleParts, childAndSectionMap);
			
			ListIterator li = firstCircleParts.listIterator();
			while (li.hasNext()) {
				EditPart editpart = (EditPart) li.next();

				if (editpart instanceof ShapeEditPart) {
					ShapeEditPart sep = (ShapeEditPart) editpart;
					editParts.add(sep);
					
					IAdaptable deferredPos = new RadialPosition(sep, startTheta + n * theta, radialInfo, isRootPositionLocked());

					ChangeBoundsDeferredRequest request =
						new ChangeBoundsDeferredRequest(deferredPos);
					
					Command cmd = sep.getCommand(request);
					
					if (cmd != null)
						cc.add(cmd);

					n++;
				}
			}
			
			if (!isRootPositionLocked()) {
				IAdaptable deferredRootPos = new RadialPosition(getRootEditPart(), 0, null, isRootPositionLocked());
				ChangeBoundsDeferredRequest request = new ChangeBoundsDeferredRequest(deferredRootPos);
				Command cmd = rootEP.getCommand(request);
				if (cmd != null)
					cc.add(cmd);
			}
			
			if (!cc.isEmpty())
				return cc;

			return null;
		}

		/**
		 * Method routeConnections.
		 * 
		 * @param connections
		 *            List of connections that need to be routed.
		 * @return Command
		 */
		protected Command routeConnection(List connections) {

			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			ListIterator li = connections.listIterator();

			while (li.hasNext()) {
				EditPart editpart = (EditPart) li.next();
				if (editpart instanceof ConnectionNodeEditPart) {
					Command cmd =
						routeConnection((ConnectionNodeEditPart) editpart);
					if (cmd != null)
						cc.add(cmd);
				}
			}

			if (!cc.isEmpty())
				return cc;

			return null;
		}

		/**
		 * Method routeConnection. Route the given connection accordingly to the
		 * layout algorithm. TBD utilize the "avoid obstructions" routing.
		 * 
		 * @param connectionEP
		 *            ConnectionNodeEditPart connection to be routed.
		 * @return Command
		 */
		protected Command routeConnection(ConnectionNodeEditPart connectionEP) {
			if (connectionEP == null)
				throw new InvalidParameterException();

			// reset connections

			Connection connection = connectionEP.getConnectionFigure();
			PointList newPoints = new PointList(2);
			newPoints.addPoint(connection.getPoints().getFirstPoint());
			newPoints.addPoint(connection.getPoints().getLastPoint());
			SetAllBendpointRequest request =
				new SetAllBendpointRequest(
					RequestConstants.REQ_SET_ALL_BENDPOINT,
					newPoints);

			// recurse through the children to get the compound command
			return connectionEP.getCommand(request);
		}

		/**
		 * Method getCommand. Utility function to optionally recurse through
		 * all child edit parts to send the request to.
		 * 
		 * @param editpart
		 *            EditPart at the Top level to send the command request to.
		 * @param request
		 *            Request that is sent to the EditPart and it's children.
		 * @param bRecursive
		 *            boolean true if the method is to send the request to all
		 *            the children of the editpart as well, false otherwise.
		 * @return Command that is the result of the request to be executed.
		 */
		protected Command getCommand(
			EditPart editpart,
			Request request,
			boolean bRecursive) {
			List children = editpart.getChildren();
			ListIterator li = children.listIterator();

			CompoundCommand cc = new CompoundCommand(""); //$NON-NLS-1$
			Command cmd = editpart.getCommand(request);
			
			if (cmd != null)
				cc.add(cmd);

			if (bRecursive) {
				while (li.hasNext()) {
					IGraphicalEditPart childEP = (IGraphicalEditPart) li.next();
					cmd = getCommand(childEP, request, bRecursive);
					if (cmd != null)
						cc.add(cmd);
				}
			}

			if (!cc.isEmpty())
				return cc;

			return null;
		}
		
		/**
		 * @author sshaw
		 * 
		 * This will perform some interim calculation that depends on the
		 * previous command execution for setting the proper sizes for the view
		 * elements.
		 */
		static protected class CalculateRadialInfoCommand extends Command {

			//	deferred calculation values
			private int radius;
			private double theta;
			private ShapeEditPart rootEP;
			private List firstCircleViews;
			
			public CalculateRadialInfoCommand(ShapeEditPart rootEP, List firstCircleViews, double theta) {
				this.rootEP = rootEP;
				this.firstCircleViews = firstCircleViews;
				this.theta = theta;
			}
	        
			public void execute() {
				radius =
					calculateNeededRadius(firstCircleViews, firstCircleViews.size() * theta);

				// if innerradius is less than the 2 times the diagonal of the
				// RootView extend it some.
				double rootDiagonal = getViewWorstExtent(rootEP);
				if (2 * rootDiagonal > radius) {
					radius += rootDiagonal;
				}
				
				radius = Math.max(MapModeUtil.getMapMode(rootEP.getFigure()).DPtoLP(180), radius);
			}

			/**
			 * Method calculateNeededRadius. This method calculates the minimum
			 * radius needed to fully extent the given views away from a center
			 * point.
			 * 
			 * @param circleEPs
			 *            List of editparts that the radius will be calculated
			 *            from.
			 * @param sectionAngle
			 *            This is the angle in radians that the views will
			 *            extent around.
			 * @return int value of the calculated radius.
			 */
			protected int calculateNeededRadius(
				List circleEPs,
				double sectionAngle) {
				if (circleEPs == null)
					throw new InvalidParameterException();

				double neededDiameter = 0;
				int count = circleEPs.size();
				double maxDiagonal = 0;

				for (int i = 0; i < count; i++) {

					EditPart ep = (EditPart) circleEPs.get(i);
					if (ep instanceof ShapeEditPart) {
						ShapeEditPart sep = (ShapeEditPart) ep;

						double diagonal = getViewWorstExtent(sep);

						neededDiameter += diagonal;

						if (diagonal > maxDiagonal)
							maxDiagonal = diagonal;
					}

				}

				double rad;

				rad = neededDiameter / sectionAngle;

				return (int) Math.round(rad);
			}

			/**
			 * Method getViewWorstExtent. Determines the worst case extent of a
			 * given view to ensure no intersection occurs. The diagonal of the
			 * view extent is used to for this value.
			 * 
			 * @param sep
			 *            ShapeEditPart to calcualte to the worst case extent
			 *            from.
			 * @return double value of the biggest extent where no intersection
			 *         will occur with the view.
			 */
			protected double getViewWorstExtent(ShapeEditPart sep) {
				if (sep == null)
					throw new InvalidParameterException();

				Dimension ext = sep.getSize();				
				return Math.sqrt( 
					(ext.width * ext.width) + (ext.height * ext.height)) * 0.80;
			}

			/**
			 * @return Returns the radius.
			 */
			public int getRadius() {
				return radius;
			}

			/**
			 * @return Returns the delta.
			 */
			public Point getDelta() {
				View view = rootEP.getNotationView();
				if (view!=null){
					Integer posX = (Integer)ViewUtil.getStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_X());
					Integer posY = (Integer)ViewUtil.getStructuralFeatureValue(view,NotationPackage.eINSTANCE.getLocation_Y());
					return new Point(posX.intValue(), posY.intValue());
				}
				return new Point(0,0);
			}
		}
		
		/**
		 * @return Returns the rootPositionLocked.
		 */
		public boolean isRootPositionLocked() {
			return rootPositionLocked;
		}
	}
}
