/*******************************************************************************
 * Copyright (c) 2004, 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.preference;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

/**
 * The <code>BaseNodeFigure</code> class is the base class for all the figures
 * representing DiagramNodes, ie those that can have ports with maxConnections
 * to other nodes.
 * 
 * Assumes that all NodeFigures have some number of input and output ports
 * 
 * @author ddean
 * 
 */
public class BaseNodeFigure extends Figure implements IBaseFigure {
	protected IBaseFigure baseFigure;

	protected boolean anchorsVisible = true;

	protected Hashtable connectionAnchors = new Hashtable(7);

	protected Vector inputConnectionAnchors = new Vector(2, 2);

	protected Vector outputConnectionAnchors = new Vector(2, 2);

	protected Vector topConnectionAnchors = new Vector();

	protected Vector bottomConnectionAnchors = new Vector();

	protected Vector leftConnectionAnchors = new Vector();

	protected Vector rightConnectionAnchors = new Vector();

	public BaseNodeFigure(IBaseFigure figure) {
		setBaseFigure(figure);
		ObserveVisibleXYLayout layout = new ObserveVisibleXYLayout();
		layout.setObserveVisibility(true);
		setLayoutManager(layout);
	}

	public void setBaseFigure(IBaseFigure figure) {
		setBaseFigure(figure, new Rectangle(0, 0, -1, -1));
	}

	public void setHighlight(boolean flag) {
		if (baseFigure != null) {
			moveToTop(this, baseFigure);
			baseFigure.setHighlight(flag);
		}
	}

	public void setBaseFigure(IBaseFigure figure, Rectangle constraint) {
		if (!getChildren().contains(figure)) {
			if (getChildren().contains(baseFigure))
				remove(baseFigure);

			baseFigure = figure;
			if (!getChildren().contains(baseFigure)) {
				// CR389070: Figures are abbreviating rule figures names and
				// making them unreadable
				if (getParent() != null
						&& getParent().getLayoutManager() != null) {
					Rectangle r = getBounds().getCopy();
					r.width = -1;
					r.height = -1;
					getParent().getLayoutManager().setConstraint(this, r);
				}
				// CR389495: Working with nested complex activities causes in
				// the BP editor causes lockup
				// ensure that constraints are set on figure before add() - this
				// will cause a layout()
				this.add(baseFigure, constraint, 0);
			}
		}
	}

	public IBaseFigure getBaseFigure() {
		return baseFigure;
	}

	/***************************************************************************
	 * Input/Output Ports
	 **************************************************************************/

	/**
	 * Add an input port and its anchor
	 * 
	 * @param portName
	 *            unique name to refer to the port
	 */
	public void addInput(String portName) {
		InputPortFigure inputPort = new InputPortFigure();
		add(inputPort);
		inputPort.setToolTipText(portName);

		PortConnectionAnchor anchor = new PortConnectionAnchor(inputPort);
		getTargetConnectionAnchors().add(anchor);
		connectionAnchors.put(portName, anchor);
	}

	/**
	 * Add an output port and its anchor
	 * 
	 * @param portName
	 *            unique name to refer to the port
	 */
	public PortConnectionAnchor addOutput(String portName) {
		OutputPortFigure outputPort = new OutputPortFigure();
		add(outputPort);
		outputPort.setToolTipText(portName);

		PortConnectionAnchor anchor = new PortConnectionAnchor(outputPort);
		getSourceConnectionAnchors().add(anchor);
		connectionAnchors.put(portName, anchor);
		return anchor;
	}

	/**
	 * Searches for and returns the anchor on this figure that is closest to the
	 * reference point <code>p</code>
	 * 
	 * @param p
	 *            the reference point
	 * @return the anchor on this figure that is closest to <code>p</code>
	 */
	public ConnectionAnchor connectionAnchorAt(Point p) {
		ConnectionAnchor closest = null;
		long min = Long.MAX_VALUE;

		Enumeration e = getSourceConnectionAnchors().elements();
		while (e.hasMoreElements()) {
			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
			Point p2 = c.getLocation(null);
			long d = p.getDistance2(p2);
			if (d < min) {
				min = d;
				closest = c;
			}
		}
		e = getTargetConnectionAnchors().elements();
		while (e.hasMoreElements()) {
			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
			Point p2 = c.getLocation(null);
			long d = p.getDistance2(p2);
			if (d < min) {
				min = d;
				closest = c;
			}
		}
		return closest;
	}

	/**
	 * returns an anchor given its name
	 * 
	 * @param portName
	 *            name of the anchor
	 * @return the anchor with the name <code>portName</code>
	 */
	public ConnectionAnchor getConnectionAnchor(String portName) {
		return (ConnectionAnchor) connectionAnchors.get(portName);
	}

	/**
	 * returns the name of the specified anchor
	 * 
	 * @param c
	 *            the anchor whose name is requested
	 * @return the name of the specifed anchor
	 */
	public String getConnectionAnchorName(ConnectionAnchor c) {
		Enumeration enumer = connectionAnchors.keys();
		String key;
		while (enumer.hasMoreElements()) {
			key = (String) enumer.nextElement();
			if (connectionAnchors.get(key).equals(c))
				return key;
		}
		return null;
	}

	/**
	 * returns the source connection anchor that is closest to the reference
	 * point
	 * 
	 * @param p
	 *            the reference point
	 * @return the closest connection anchor to <code>p</code>
	 */
	public ConnectionAnchor getSourceConnectionAnchorAt(Point p) {
		ConnectionAnchor closest = null;
		long min = Long.MAX_VALUE;

		Enumeration e = getSourceConnectionAnchors().elements();
		while (e.hasMoreElements()) {
			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
			Point p2 = c.getLocation(null);
			long d = p.getDistance2(p2);
			if (d < min) {
				min = d;
				closest = c;
			}
		}
		return closest;
	}

	/**
	 * returns all the source connection anchors on this node figure
	 * 
	 * @return a vector of all the source connection anchors for this figure
	 */
	public Vector getSourceConnectionAnchors() {
		return outputConnectionAnchors;
	}

	/**
	 * returns the target connection anchor that is closest to the reference
	 * point
	 * 
	 * @param p
	 *            the reference point
	 * @return the closest target connection anchor to <code>p</code>
	 */
	public ConnectionAnchor getTargetConnectionAnchorAt(Point p) {
		ConnectionAnchor closest = null;
		long min = Long.MAX_VALUE;

		Enumeration e = getTargetConnectionAnchors().elements();
		while (e.hasMoreElements()) {
			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
			Point p2 = c.getLocation(null);
			long d = p.getDistance2(p2);
			if (d < min) {
				min = d;
				closest = c;
			}
		}
		return closest;
	}

	/**
	 * returns all the target connection anchors on this node figure
	 * 
	 * @return a vector of all the target connection anchors for this figure
	 */
	public Vector getTargetConnectionAnchors() {
		return inputConnectionAnchors;
	}

	/**
	 * Returns the name of the specified anchor
	 * 
	 * @param anchor
	 *            the connectio anchor whose name is requested
	 * @return the anchor's name
	 */
	public String getNameForAnchor(ConnectionAnchor anchor) {
		if (anchor != null) {
			Iterator it = connectionAnchors.keySet().iterator();
			String name;

			while (it.hasNext()) {
				name = (String) it.next();

				if (anchor.equals(connectionAnchors.get(name))) {
					return name;
				}
			}
		}
		return null;
	}

	public void setAnchorsVisible(boolean visible) {
		if (anchorsVisible != visible) {
			anchorsVisible = visible;
			ConnectionAnchor port;
			List all = new ArrayList();
			all.addAll(getTargetConnectionAnchors());
			all.addAll(getSourceConnectionAnchors());
			Iterator it = all.iterator();
			while (it.hasNext()) {
				IFigure fig = ((ConnectionAnchor) it.next()).getOwner();
				fig.setVisible(visible);
			}
			validate();
		}
	}

	/*
	 * Determine which side of the figure to place each anchor based on the
	 * relative position (north, south, east or west) of the connection line's
	 * opposite anchor. If the anchor is not connected to anything else, the
	 * default is to place target (input) anchors on the left and source
	 * (output) anchors on the right.
	 */
	protected void determineAnchorPositions() {
		Iterator it;
		topConnectionAnchors.clear();
		bottomConnectionAnchors.clear();
		leftConnectionAnchors.clear();
		rightConnectionAnchors.clear();

		if (anchorsVisible) {
			final Dimension size = baseFigure.getPreferredSize();
			PortConnectionAnchor port;

			// start with outputs
			it = getSourceConnectionAnchors().iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();
				// CR386077: SplitActivity True and False outputs switch
				// positions based on their targets
				int direction = port.getOrientation();
				if (direction == PositionConstants.NONE) {
					Point loc = port.getOwner().getParent().getBounds()
							.getLocation();
					// loc.x += size.width/2;
					// loc.y += size.height/2;
					Iterator itc = port.getConnections().iterator();
					if (itc.hasNext()) {
						while (itc.hasNext()) {
							PolylineConnection conn = (PolylineConnection) itc
									.next();
							ConnectionAnchor otherPort;
							if (port == conn.getSourceAnchor())
								otherPort = conn.getTargetAnchor();
							else
								otherPort = conn.getSourceAnchor();
							if (otherPort.getOwner() == null)
								continue;
							Point otherLoc = otherPort.getOwner().getParent()
									.getBounds().getLocation();
							// Dimension otherSize =
							// ((BaseNodeFigure)otherPort.getOwner().getParent()).getBaseFigure().getPreferredSize();
							// otherLoc.x += otherSize.width/2;
							// otherLoc.y += otherSize.height/2;
							direction = loc.getPosition(otherLoc);
							if (direction == PositionConstants.NORTH)
								topConnectionAnchors.add(port);
							else if (direction == PositionConstants.SOUTH)
								bottomConnectionAnchors.add(port);
							else if (direction == PositionConstants.WEST)
								leftConnectionAnchors.add(port);
							else
								rightConnectionAnchors.add(port);
							((PortFigure) port.getOwner())
									.setOrientation(direction);
							break; // currently, only the first connection is
									// considered
						}
					} else {
						rightConnectionAnchors.add(port);
						((PortFigure) port.getOwner())
								.setOrientation(PositionConstants.EAST);
					}
				} else {
					// CR386077: SplitActivity True and False outputs switch
					// positions based on their targets
					if (direction == PositionConstants.NORTH)
						topConnectionAnchors.add(port);
					else if (direction == PositionConstants.SOUTH)
						bottomConnectionAnchors.add(port);
					else if (direction == PositionConstants.WEST)
						leftConnectionAnchors.add(port);
					else
						rightConnectionAnchors.add(port);
				}
			}
			it = getTargetConnectionAnchors().iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();
				// CR386077: SplitActivity True and False outputs switch
				// positions based on their targets
				int direction = port.getOrientation();
				if (direction == PositionConstants.NONE) {
					Point loc = port.getOwner().getParent().getBounds()
							.getLocation();
					// loc.x += size.width/2;
					// loc.y += size.height/2;
					Iterator itc = port.getConnections().iterator();
					if (itc.hasNext()) {
						while (itc.hasNext()) {
							PolylineConnection conn = (PolylineConnection) itc
									.next();
							ConnectionAnchor otherPort;
							if (port == conn.getSourceAnchor())
								otherPort = conn.getTargetAnchor();
							else
								otherPort = conn.getSourceAnchor();
							if (otherPort.getOwner() == null)
								continue;
							Point otherLoc = otherPort.getOwner().getParent()
									.getBounds().getLocation();
							// Dimension otherSize =
							// ((BaseNodeFigure)otherPort.getOwner().getParent()).getBaseFigure().getPreferredSize();
							// otherLoc.x += otherSize.width/2;
							// otherLoc.y += otherSize.height/2;
							direction = loc.getPosition(otherLoc);
							if (direction == PositionConstants.NORTH)
								topConnectionAnchors.add(port);
							else if (direction == PositionConstants.SOUTH)
								bottomConnectionAnchors.add(port);
							else if (direction == PositionConstants.EAST)
								rightConnectionAnchors.add(port);
							else
								leftConnectionAnchors.add(port);
							((PortFigure) port.getOwner())
									.setOrientation(direction);
							break; // currently, only the first connection is
									// considered
						}
					} else {
						leftConnectionAnchors.add(port);
						((PortFigure) port.getOwner())
								.setOrientation(PositionConstants.WEST);
					}
				} else {
					// CR386077: SplitActivity True and False outputs switch
					// positions based on their targets
					if (direction == PositionConstants.NORTH)
						topConnectionAnchors.add(port);
					else if (direction == PositionConstants.SOUTH)
						bottomConnectionAnchors.add(port);
					else if (direction == PositionConstants.EAST)
						rightConnectionAnchors.add(port);
					else
						leftConnectionAnchors.add(port);
				}
			}

			Comparator comparePorts = new Comparator() {
				public int compare(Object arg0, Object arg1) {
					PortConnectionAnchor port0 = (PortConnectionAnchor) arg0;
					if (port0.getConnections().size() < 1)
						return 0;
					PortConnectionAnchor port1 = (PortConnectionAnchor) arg1;
					if (port1.getConnections().size() < 1)
						return 0;
					// CR386077: SplitActivity True and False outputs switch
					// positions based on their targets
					if (port0.getOrientation() != PositionConstants.NONE)
						return 0;
					if (port1.getOrientation() != PositionConstants.NONE)
						return 0;

					PolylineConnection conn0 = (PolylineConnection) port0
							.getConnections().get(0);
					ConnectionAnchor otherPort0;
					if (port0 == conn0.getSourceAnchor())
						otherPort0 = conn0.getTargetAnchor();
					else
						otherPort0 = conn0.getSourceAnchor();
					Point otherLoc0 = otherPort0.getOwner().getParent()
							.getBounds().getLocation();
					// Dimension otherSize0 =
					// ((BaseNodeFigure)otherPort0.getOwner().getParent()).getBaseFigure().getPreferredSize();
					// otherLoc0.x += otherSize0.width/2;
					// otherLoc0.y += otherSize0.height/2;

					PolylineConnection conn1 = (PolylineConnection) port1
							.getConnections().get(0);
					ConnectionAnchor otherPort1;
					if (port1 == conn1.getSourceAnchor())
						otherPort1 = conn1.getTargetAnchor();
					else
						otherPort1 = conn1.getSourceAnchor();
					Point otherLoc1 = otherPort1.getOwner().getParent()
							.getBounds().getLocation();
					Dimension otherSize1 = ((BaseNodeFigure) otherPort1
							.getOwner().getParent()).getBaseFigure()
							.getPreferredSize();
					// otherLoc1.x += otherSize1.width/2;
					// otherLoc1.y += otherSize1.height/2;

					switch (((PortFigure) port0.getOwner()).getOrientation()) {
					case PositionConstants.NORTH:
					case PositionConstants.SOUTH:
						return otherLoc0.x - otherLoc1.x;
					case PositionConstants.EAST:
					case PositionConstants.WEST:
						return otherLoc0.y - otherLoc1.y;
					}
					return 0;
				}
			};

			// order the anchors on each side so connection lines don't cross
			Collections.sort(topConnectionAnchors, comparePorts);
			Collections.sort(leftConnectionAnchors, comparePorts);
			Collections.sort(bottomConnectionAnchors, comparePorts);
			Collections.sort(rightConnectionAnchors, comparePorts);
		}
	}

	protected void placeAnchors() {
		determineAnchorPositions();
		if (anchorsVisible) {
			Iterator it;
			PortConnectionAnchor port;
			int y, x;

			Dimension sz = baseFigure.getPreferredSize();
			LayoutManager layout = getLayoutManager();
			// CR389070: Figures are abbreviating rule figures names and making
			// them unreadable
			Dimension d = getAnchorSize();

			// left ports
			x = 0;
			y = FigureConstants.PORT_SPACING / 2;
			// CR374981: Long activity labels do not get wrapped or truncated
			// keep a constant inset on all 4 sides of the icon
			// if ( topConnectionAnchors.size()>0 )
			y += d.height;
			y += (sz.height - (leftConnectionAnchors.size() * (d.height + FigureConstants.PORT_SPACING))) / 2;
			it = leftConnectionAnchors.iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();

				Rectangle r = new Rectangle(x, y, -1, -1);
				Rectangle oldrect = (Rectangle) layout.getConstraint(port
						.getOwner());
				if (!r.equals(oldrect))
					layout.setConstraint(port.getOwner(), new Rectangle(x, y,
							-1, -1));

				y += d.height + FigureConstants.PORT_SPACING;
			}

			// right ports
			x = sz.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			x += d.width;
			y = FigureConstants.PORT_SPACING / 2;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			y += d.height;
			y += (sz.height - (rightConnectionAnchors.size() * (d.height + FigureConstants.PORT_SPACING))) / 2;
			it = rightConnectionAnchors.iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();

				Rectangle r = new Rectangle(x, y, -1, -1);
				Rectangle oldrect = (Rectangle) layout.getConstraint(port
						.getOwner());
				if (!r.equals(oldrect))
					layout.setConstraint(port.getOwner(), new Rectangle(x, y,
							-1, -1));

				y += d.height + FigureConstants.PORT_SPACING;
			}

			// top ports
			y = 0;
			x = FigureConstants.PORT_SPACING / 2;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			x += d.width;
			x += (sz.width - (topConnectionAnchors.size() * (d.width + FigureConstants.PORT_SPACING))) / 2;
			it = topConnectionAnchors.iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();

				Rectangle r = new Rectangle(x, y, -1, -1);
				Rectangle oldrect = (Rectangle) layout.getConstraint(port
						.getOwner());
				if (!r.equals(oldrect))
					layout.setConstraint(port.getOwner(), new Rectangle(x, y,
							-1, -1));

				x += d.width + FigureConstants.PORT_SPACING;
			}

			// bottom ports
			y = sz.height;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			y += d.height;
			x = FigureConstants.PORT_SPACING / 2;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			x += d.width;
			x += (sz.width - (bottomConnectionAnchors.size() * (d.width + FigureConstants.PORT_SPACING))) / 2;
			it = bottomConnectionAnchors.iterator();
			while (it.hasNext()) {
				port = (PortConnectionAnchor) it.next();

				Rectangle r = new Rectangle(x, y, -1, -1);
				Rectangle oldrect = (Rectangle) layout.getConstraint(port
						.getOwner());
				if (!r.equals(oldrect))
					layout.setConstraint(port.getOwner(), new Rectangle(x, y,
							-1, -1));

				x += d.width + FigureConstants.PORT_SPACING;
			}
		}
	}

	/**
	 * CR389070: Figures are abbreviating rule figures names and making them
	 * unreadable Anchor size is now dependent on icon size, not constant. Asks
	 * the connection anchor for its size.
	 */
	public Dimension getAnchorSize() {
		Dimension d = new Dimension(FigureConstants.PORT_SIDE,
				FigureConstants.PORT_SIDE);
		if (!connectionAnchors.isEmpty()) {
			Iterator iter = connectionAnchors.values().iterator();
			PortConnectionAnchor a = (PortConnectionAnchor) iter.next();
			d = a.getOwner().getPreferredSize();
		}
		return d;
	}

	public Insets getAnchorInsets() {
		Insets in = new Insets(0, 0, 0, 0);
		// CR389070: Figures are abbreviating rule figures names and making them
		// unreadable
		Dimension d = getAnchorSize();
		// CR374981: Long activity labels do not get wrapped or truncated
		// if ( leftConnectionAnchors.size()>0 )
		in.left = d.width;
		// CR374981: Long activity labels do not get wrapped or truncated
		// if ( rightConnectionAnchors.size()>0 )
		in.right = d.width;
		// CR374981: Long activity labels do not get wrapped or truncated
		// if ( topConnectionAnchors.size()>0 )
		in.top = d.height;
		// CR374981: Long activity labels do not get wrapped or truncated
		// if ( bottomConnectionAnchors.size()>0 )
		in.bottom = d.height;
		return in;
	}

	public void invalidate() {
		super.invalidate();
	}

	/**
	 * validate method override to arrange the input and output ports around the
	 * links of the node figures
	 */
	public void validate() {
		placeAnchors();
		// CR389070: Figures are abbreviating rule figures names and making them
		// unreadable
		int x = 0;
		int y = 0;
		// if anchors are not visible (CompoundNodeFigure is maximized) always
		// set position at 0,0
		if (anchorsVisible) {
			Dimension d = getAnchorSize();
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			x = d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			y = d.height;
		}
		getLayoutManager().setConstraint(baseFigure,
				new Rectangle(x, y, -1, -1));
		layout();
		super.validate();
	}

	/***************************************************************************
	 * Miscellaneous
	 **************************************************************************/

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
	 */
	protected boolean useLocalCoordinates() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#setBounds(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void setBounds(Rectangle rect) {
		Rectangle r = rect.getCopy();
		r.x = 0;
		r.y = 0;
		if (anchorsVisible) {
			// CR389070: Figures are abbreviating rule figures names and making
			// them unreadable
			Dimension d = getAnchorSize();
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			{
				r.x += d.width;
				r.width -= d.width;
			}
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( rightConnectionAnchors.size()>0 )
			r.width -= d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			{
				r.y += d.height;
				r.height -= d.height;
			}
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( bottomConnectionAnchors.size()>0 )
			r.height -= d.height;
		}
		baseFigure.setBounds(r);
		r.setLocation(rect.getLocation());
		super.setBounds(r);
	}

	public Rectangle getBounds() {
		Dimension size = baseFigure.getBounds().getSize();
		if (anchorsVisible) {
			// CR389070: Figures are abbreviating rule figures names and making
			// them unreadable
			Dimension d = getAnchorSize();
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			size.width += d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( rightConnectionAnchors.size()>0 )
			size.width += d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			size.height += d.height;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( bottomConnectionAnchors.size()>0 )
			size.height += d.height;
		}
		Rectangle r = super.getBounds();
		r.setSize(size);
		return r;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int)
	 */
	public Dimension getPreferredSize(int wHint, int hHint) {
		Dimension size = baseFigure.getPreferredSize(wHint, hHint).getCopy();
		if (anchorsVisible) {
			// CR389070: Figures are abbreviating rule figures names and making
			// them unreadable
			Dimension d = getAnchorSize();
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( leftConnectionAnchors.size()>0 )
			size.width += d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( rightConnectionAnchors.size()>0 )
			size.width += d.width;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( topConnectionAnchors.size()>0 )
			size.height += d.height;
			// CR374981: Long activity labels do not get wrapped or truncated
			// if ( bottomConnectionAnchors.size()>0 )
			size.height += d.height;
		}
		return size;
	}

	public static void moveToTop(IFigure parent, IFigure child) {
		parent.getChildren().remove(child);
		parent.getChildren().add(child);
	}

	public void moveToTop() {
		IFigure parent = getParent();
		IFigure child = this;
		while (parent != null && !(parent instanceof Layer)) {
			child = parent;
			parent = parent.getParent();
		}
		if (parent instanceof Layer) {
			parent.getChildren().remove(child);
			parent.getChildren().add(child);
		}
	}

	/***************************************************************************
	 * IBaseFigure methods delegate to the baseFigure
	 **************************************************************************/

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#setText(java.lang.String)
	 */
	public void setText(String text) {
		baseFigure.setText(text);
	}

	public void setIcon(Image image) {
		baseFigure.setIcon(image);
	}

	/**
	 * The description property of a DiagramNode is displayed as a tool tip.
	 * This method is used to set it. Passing a null or zero-length string will
	 * remove the tool tip
	 * 
	 * @param description
	 *            the description to use for this node's tool tip
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#setToolTipText(java.lang.String)
	 */
	public void setToolTipText(String text) {
		baseFigure.setToolTipText(text);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#addDecorator(com.sybase.stf.gem.diagram.editor.figures.BaseFigureDecorator)
	 */
	public void addDecorator(BaseFigureDecorator decorator) {
		baseFigure.addDecorator(decorator);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#removeDecorator()
	 */
	public void removeDecorator() {
		baseFigure.removeDecorator();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#removeDecorator(int)
	 */
	public void removeDecorator(int position) {
		baseFigure.removeDecorator(position);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#getDecorators()
	 */
	public List getDecorators() {
		return baseFigure.getDecorators();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#getText()
	 */
	public String getText() {
		return baseFigure.getText();
	}

	/*
	 * CR374981: Long activity labels do not get wrapped or truncated This
	 * method was added to the IBaseFigure interface to support direct edit of
	 * figure labels on the canvas.
	 */
	public Rectangle getTextBounds() {
		Rectangle r = baseFigure.getTextBounds().getCopy();
		r.x += getBounds().x;
		r.y += getBounds().y;
		return r;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#getIcon()
	 */
	public Image getIcon() {
		return baseFigure.getIcon();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IBaseFigure#getToolTipText()
	 */
	public String getToolTipText() {
		return baseFigure.getToolTipText();
	}
}