/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxVertexHandler
 * 
 * Event handler for resizing cells. This handler is automatically created in
 * <mxGraph.createHandler>.
 * 
 * Constructor: mxVertexHandler
 * 
 * Constructs an event handler that allows to resize vertices
 * and groups.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be resized.
 */
function mxVertexHandler(state)
{
	if (state != null)
	{
		this.state = state;
		this.init();
		
		// Handles escape keystrokes
		this.escapeHandler = mxUtils.bind(this, function(sender, evt)
		{
			if (this.livePreview && this.index != null)
			{
				// Redraws the live preview
				this.state.view.graph.cellRenderer.redraw(this.state, true);
				
				// Redraws connected edges
				this.state.view.invalidate(this.state.cell);
				this.state.invalid = false;
				this.state.view.validate();
			}
			
			this.reset();
		});
		
		this.state.view.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
	}
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxVertexHandler.prototype.graph = null;

/**
 * Variable: state
 * 
 * Reference to the <mxCellState> being modified.
 */
mxVertexHandler.prototype.state = null;

/**
 * Variable: singleSizer
 * 
 * Specifies if only one sizer handle at the bottom, right corner should be
 * used. Default is false.
 */
mxVertexHandler.prototype.singleSizer = false;

/**
 * Variable: index
 * 
 * Holds the index of the current handle.
 */
mxVertexHandler.prototype.index = null;

/**
 * Variable: allowHandleBoundsCheck
 * 
 * Specifies if the bounds of handles should be used for hit-detection in IE or
 * if <tolerance> > 0. Default is true.
 */
mxVertexHandler.prototype.allowHandleBoundsCheck = true;

/**
 * Variable: handleImage
 * 
 * Optional <mxImage> to be used as handles. Default is null.
 */
mxVertexHandler.prototype.handleImage = null;

/**
 * Variable: tolerance
 * 
 * Optional tolerance for hit-detection in <getHandleForEvent>. Default is 0.
 */
mxVertexHandler.prototype.tolerance = 0;

/**
 * Variable: rotationEnabled
 * 
 * Specifies if a rotation handle should be visible. Default is false.
 */
mxVertexHandler.prototype.rotationEnabled = false;

/**
 * Variable: parentHighlightEnabled
 * 
 * Specifies if the parent should be highlighted if a child cell is selected.
 * Default is false.
 */
mxVertexHandler.prototype.parentHighlightEnabled = false;

/**
 * Variable: rotationRaster
 * 
 * Specifies if rotation steps should be "rasterized" depening on the distance
 * to the handle. Default is true.
 */
mxVertexHandler.prototype.rotationRaster = true;

/**
 * Variable: rotationCursor
 * 
 * Specifies the cursor for the rotation handle. Default is 'crosshair'.
 */
mxVertexHandler.prototype.rotationCursor = 'crosshair';

/**
 * Variable: livePreview
 * 
 * Specifies if resize should change the cell in-place. This is an experimental
 * feature for non-touch devices. Default is false.
 */
mxVertexHandler.prototype.livePreview = false;

/**
 * Variable: manageSizers
 * 
 * Specifies if sizers should be hidden and spaced if the vertex is small.
 * Default is false.
 */
mxVertexHandler.prototype.manageSizers = false;

/**
 * Variable: constrainGroupByChildren
 * 
 * Specifies if the size of groups should be constrained by the children.
 * Default is false.
 */
mxVertexHandler.prototype.constrainGroupByChildren = false;

/**
 * Variable: rotationHandleVSpacing
 * 
 * Vertical spacing for rotation icon. Default is -16.
 */
mxVertexHandler.prototype.rotationHandleVSpacing = -16;

/**
 * Variable: horizontalOffset
 * 
 * The horizontal offset for the handles. This is updated in <redrawHandles>
 * if <manageSizers> is true and the sizers are offset horizontally.
 */
mxVertexHandler.prototype.horizontalOffset = 0;

/**
 * Variable: verticalOffset
 * 
 * The horizontal offset for the handles. This is updated in <redrawHandles>
 * if <manageSizers> is true and the sizers are offset vertically.
 */
mxVertexHandler.prototype.verticalOffset = 0;

/**
 * Function: init
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxVertexHandler.prototype.init = function()
{
	this.graph = this.state.view.graph;
	this.selectionBounds = this.getSelectionBounds(this.state);
	this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
	this.selectionBorder = this.createSelectionShape(this.bounds);
	// VML dialect required here for event transparency in IE
	this.selectionBorder.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
	this.selectionBorder.pointerEvents = false;
	this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	this.selectionBorder.init(this.graph.getView().getOverlayPane());
	mxEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
	
	if (this.graph.isCellMovable(this.state.cell))
	{
		this.selectionBorder.setCursor(mxConstants.CURSOR_MOVABLE_VERTEX);
	}

	// Adds the sizer handles
	if (mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells)
	{
		var resizable = this.graph.isCellResizable(this.state.cell);
		this.sizers = [];

		if (resizable || (this.graph.isLabelMovable(this.state.cell) &&
			this.state.width >= 2 && this.state.height >= 2))
		{
			var i = 0;

			if (resizable)
			{
				if (!this.singleSizer)
				{
					this.sizers.push(this.createSizer('nw-resize', i++));
					this.sizers.push(this.createSizer('n-resize', i++));
					this.sizers.push(this.createSizer('ne-resize', i++));
					this.sizers.push(this.createSizer('w-resize', i++));
					this.sizers.push(this.createSizer('e-resize', i++));
					this.sizers.push(this.createSizer('sw-resize', i++));
					this.sizers.push(this.createSizer('s-resize', i++));
				}
				
				this.sizers.push(this.createSizer('se-resize', i++));
			}
			
			var geo = this.graph.model.getGeometry(this.state.cell);
			
			if (geo != null && !geo.relative && !this.graph.isSwimlane(this.state.cell) &&
				this.graph.isLabelMovable(this.state.cell))
			{
				// Marks this as the label handle for getHandleForEvent
				this.labelShape = this.createSizer(mxConstants.CURSOR_LABEL_HANDLE, mxEvent.LABEL_HANDLE, mxConstants.LABEL_HANDLE_SIZE, mxConstants.LABEL_HANDLE_FILLCOLOR);
				this.sizers.push(this.labelShape);
			}
		}
		else if (this.graph.isCellMovable(this.state.cell) && !this.graph.isCellResizable(this.state.cell) &&
			this.state.width < 2 && this.state.height < 2)
		{
			this.labelShape = this.createSizer(mxConstants.CURSOR_MOVABLE_VERTEX,
				mxEvent.LABEL_HANDLE, null, mxConstants.LABEL_HANDLE_FILLCOLOR);
			this.sizers.push(this.labelShape);
		}
	}
	
	// Adds the rotation handler
	if (this.isRotationHandleVisible())
	{
		this.rotationShape = this.createSizer(this.rotationCursor, mxEvent.ROTATION_HANDLE,
			mxConstants.HANDLE_SIZE + 3, mxConstants.HANDLE_FILLCOLOR);
		this.sizers.push(this.rotationShape);
	}

	this.customHandles = this.createCustomHandles();
	this.redraw();
	
	if (this.constrainGroupByChildren)
	{
		this.updateMinBounds();
	}
};

/**
 * Function: isRotationHandleVisible
 * 
 * Returns true if the rotation handle should be showing.
 */
mxVertexHandler.prototype.isRotationHandleVisible = function()
{
	return this.graph.isEnabled() && this.rotationEnabled && this.graph.isCellRotatable(this.state.cell) &&
		(mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells) &&
		this.state.width >= 2 && this.state.height >= 2;
};

/**
 * Function: isConstrainedEvent
 * 
 * Returns true if the aspect ratio if the cell should be maintained.
 */
mxVertexHandler.prototype.isConstrainedEvent = function(me)
{
	return mxEvent.isShiftDown(me.getEvent()) || this.state.style[mxConstants.STYLE_ASPECT] == 'fixed';
};

/**
 * Function: isCenteredEvent
 * 
 * Returns true if the center of the vertex should be maintained during the resize.
 */
mxVertexHandler.prototype.isCenteredEvent = function(state, me)
{
	return false;
};

/**
 * Function: createCustomHandles
 * 
 * Returns an array of custom handles. This implementation returns null.
 */
mxVertexHandler.prototype.createCustomHandles = function()
{
	return null;
};

/**
 * Function: updateMinBounds
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxVertexHandler.prototype.updateMinBounds = function()
{
	var children = this.graph.getChildCells(this.state.cell);
	
	if (children.length > 0)
	{
		this.minBounds = this.graph.view.getBounds(children);
		
		if (this.minBounds != null)
		{
			var s = this.state.view.scale;
			var t = this.state.view.translate;

			this.minBounds.x -= this.state.x;
			this.minBounds.y -= this.state.y;
			this.minBounds.x /= s;
			this.minBounds.y /= s;
			this.minBounds.width /= s;
			this.minBounds.height /= s;
			this.x0 = this.state.x / s - t.x;
			this.y0 = this.state.y / s - t.y;
		}
	}
};

/**
 * Function: getSelectionBounds
 * 
 * Returns the mxRectangle that defines the bounds of the selection
 * border.
 */
mxVertexHandler.prototype.getSelectionBounds = function(state)
{
	return new mxRectangle(Math.round(state.x), Math.round(state.y), Math.round(state.width), Math.round(state.height));
};

/**
 * Function: createParentHighlightShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxVertexHandler.prototype.createParentHighlightShape = function(bounds)
{
	return this.createSelectionShape(bounds);
};

/**
 * Function: createSelectionShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxVertexHandler.prototype.createSelectionShape = function(bounds)
{
	var shape = new mxRectangleShape(bounds, null, this.getSelectionColor());
	shape.strokewidth = this.getSelectionStrokeWidth();
	shape.isDashed = this.isSelectionDashed();
	
	return shape;
};

/**
 * Function: getSelectionColor
 * 
 * Returns <mxConstants.VERTEX_SELECTION_COLOR>.
 */
mxVertexHandler.prototype.getSelectionColor = function()
{
	return mxConstants.VERTEX_SELECTION_COLOR;
};

/**
 * Function: getSelectionStrokeWidth
 * 
 * Returns <mxConstants.VERTEX_SELECTION_STROKEWIDTH>.
 */
mxVertexHandler.prototype.getSelectionStrokeWidth = function()
{
	return mxConstants.VERTEX_SELECTION_STROKEWIDTH;
};

/**
 * Function: isSelectionDashed
 * 
 * Returns <mxConstants.VERTEX_SELECTION_DASHED>.
 */
mxVertexHandler.prototype.isSelectionDashed = function()
{
	return mxConstants.VERTEX_SELECTION_DASHED;
};

/**
 * Function: createSizer
 * 
 * Creates a sizer handle for the specified cursor and index and returns
 * the new <mxRectangleShape> that represents the handle.
 */
mxVertexHandler.prototype.createSizer = function(cursor, index, size, fillColor)
{
	size = size || mxConstants.HANDLE_SIZE;
	
	var bounds = new mxRectangle(0, 0, size, size);
	var sizer = this.createSizerShape(bounds, index, fillColor);

	if (sizer.isHtmlAllowed() && this.state.text != null && this.state.text.node.parentNode == this.graph.container)
	{
		sizer.bounds.height -= 1;
		sizer.bounds.width -= 1;
		sizer.dialect = mxConstants.DIALECT_STRICTHTML;
		sizer.init(this.graph.container);
	}
	else
	{
		sizer.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
				mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
		sizer.init(this.graph.getView().getOverlayPane());
	}

	mxEvent.redirectMouseEvents(sizer.node, this.graph, this.state);
	
	if (this.graph.isEnabled())
	{
		sizer.setCursor(cursor);
	}
	
	if (!this.isSizerVisible(index))
	{
		sizer.visible = false;
	}
	
	return sizer;
};

/**
 * Function: isSizerVisible
 * 
 * Returns true if the sizer for the given index is visible.
 * This returns true for all given indices.
 */
mxVertexHandler.prototype.isSizerVisible = function(index)
{
	return true;
};

/**
 * Function: createSizerShape
 * 
 * Creates the shape used for the sizer handle for the specified bounds an
 * index. Only images and rectangles should be returned if support for HTML
 * labels with not foreign objects is required.
 */
mxVertexHandler.prototype.createSizerShape = function(bounds, index, fillColor)
{
	if (this.handleImage != null)
	{
		bounds = new mxRectangle(bounds.x, bounds.y, this.handleImage.width, this.handleImage.height);
		var shape = new mxImageShape(bounds, this.handleImage.src);
		
		// Allows HTML rendering of the images
		shape.preserveImageAspect = false;

		return shape;
	}
	else if (index == mxEvent.ROTATION_HANDLE)
	{
		return new mxEllipse(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
	else
	{
		return new mxRectangleShape(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
};

/**
 * Function: createBounds
 * 
 * Helper method to create an <mxRectangle> around the given centerpoint
 * with a width and height of 2*s or 6, if no s is given.
 */
mxVertexHandler.prototype.moveSizerTo = function(shape, x, y)
{
	if (shape != null)
	{
		shape.bounds.x = Math.floor(x - shape.bounds.width / 2);
		shape.bounds.y = Math.floor(y - shape.bounds.height / 2);
		
		// Fixes visible inactive handles in VML
		if (shape.node != null && shape.node.style.display != 'none')
		{
			shape.redraw();
		}
	}
};

/**
 * Function: getHandleForEvent
 * 
 * Returns the index of the handle for the given event. This returns the index
 * of the sizer from where the event originated or <mxEvent.LABEL_INDEX>.
 */
mxVertexHandler.prototype.getHandleForEvent = function(me)
{
	// Connection highlight may consume events before they reach sizer handle
	var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 1;
	var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
		new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
	
	function checkShape(shape)
	{
		return shape != null && (me.isSource(shape) || (hit != null && mxUtils.intersects(shape.bounds, hit) &&
			shape.node.style.display != 'none' && shape.node.style.visibility != 'hidden'));
	}

	if (this.customHandles != null && this.isCustomHandleEvent(me))
	{
		// Inverse loop order to match display order
		for (var i = this.customHandles.length - 1; i >= 0; i--)
		{
			if (checkShape(this.customHandles[i].shape))
			{
				// LATER: Return reference to active shape
				return mxEvent.CUSTOM_HANDLE - i;
			}
		}
	}

	if (checkShape(this.rotationShape))
	{
		return mxEvent.ROTATION_HANDLE;
	}
	else if (checkShape(this.labelShape))
	{
		return mxEvent.LABEL_HANDLE;
	}
	
	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			if (checkShape(this.sizers[i]))
			{
				return i;
			}
		}
	}

	return null;
};

/**
 * Function: isCustomHandleEvent
 * 
 * Returns true if the given event allows custom handles to be changed. This
 * implementation returns true.
 */
mxVertexHandler.prototype.isCustomHandleEvent = function(me)
{
	return true;
};

/**
 * Function: mouseDown
 * 
 * Handles the event if a handle has been clicked. By consuming the
 * event all subsequent events of the gesture are redirected to this
 * handler.
 */
mxVertexHandler.prototype.mouseDown = function(sender, me)
{
	var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 0;
	
	if (!me.isConsumed() && this.graph.isEnabled() && (tol > 0 || me.getState() == this.state))
	{
		var handle = this.getHandleForEvent(me);

		if (handle != null)
		{
			this.start(me.getGraphX(), me.getGraphY(), handle);
			me.consume();
		}
	}
};

/**
 * Function: isLivePreviewBorder
 * 
 * Called if <livePreview> is enabled to check if a border should be painted.
 * This implementation returns true if the shape is transparent.
 */
mxVertexHandler.prototype.isLivePreviewBorder = function()
{
	return this.state.shape != null && this.state.shape.fill == null && this.state.shape.stroke == null;
};

/**
 * Function: start
 * 
 * Starts the handling of the mouse gesture.
 */
mxVertexHandler.prototype.start = function(x, y, index)
{
	this.inTolerance = true;
	this.childOffsetX = 0;
	this.childOffsetY = 0;
	this.index = index;
	this.startX = x;
	this.startY = y;
	
	// Saves reference to parent state
	var model = this.state.view.graph.model;
	var parent = model.getParent(this.state.cell);
	
	if (this.state.view.currentRoot != parent && (model.isVertex(parent) || model.isEdge(parent)))
	{
		this.parentState = this.state.view.graph.view.getState(parent);
	}
	
	// Creates a preview that can be on top of any HTML label
	this.selectionBorder.node.style.display = (index == mxEvent.ROTATION_HANDLE) ? 'inline' : 'none';
	
	// Creates the border that represents the new bounds
	if (!this.livePreview || this.isLivePreviewBorder())
	{
		this.preview = this.createSelectionShape(this.bounds);
		
		if (!(mxClient.IS_SVG && Number(this.state.style[mxConstants.STYLE_ROTATION] || '0') != 0) &&
			this.state.text != null && this.state.text.node.parentNode == this.graph.container)
		{
			this.preview.dialect = mxConstants.DIALECT_STRICTHTML;
			this.preview.init(this.graph.container);
		}
		else
		{
			this.preview.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
					mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
			this.preview.init(this.graph.view.getOverlayPane());
		}
	}
	
	// Prepares the handles for live preview
	if (this.livePreview)
	{
		this.hideSizers();
		
		if (index == mxEvent.ROTATION_HANDLE)
		{
			this.rotationShape.node.style.display = '';
		}
		else if (index == mxEvent.LABEL_HANDLE)
		{
			this.labelShape.node.style.display = '';
		}
		else if (this.sizers != null && this.sizers[index] != null)
		{
			this.sizers[index].node.style.display = '';
		}
		else if (index <= mxEvent.CUSTOM_HANDLE && this.customHandles != null)
		{
			this.customHandles[mxEvent.CUSTOM_HANDLE - index].setVisible(true);
		}
		
		// Gets the array of connected edge handlers for redrawing
		var edges = this.graph.getEdges(this.state.cell);
		this.edgeHandlers = [];
		
		for (var i = 0; i < edges.length; i++)
		{
			var handler = this.graph.selectionCellsHandler.getHandler(edges[i]);
			
			if (handler != null)
			{
				this.edgeHandlers.push(handler);
			}
		}
	}
};

/**
 * Function: hideHandles
 * 
 * Shortcut to <hideSizers>.
 */
mxVertexHandler.prototype.setHandlesVisible = function(visible)
{
	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			this.sizers[i].node.style.display = (visible) ? '' : 'none';
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].setVisible(visible);
		}
	}
};

/**
 * Function: hideSizers
 * 
 * Hides all sizers except.
 * 
 * Starts the handling of the mouse gesture.
 */
mxVertexHandler.prototype.hideSizers = function()
{
	this.setHandlesVisible(false);
};

/**
 * Function: checkTolerance
 * 
 * Checks if the coordinates for the given event are within the
 * <mxGraph.tolerance>. If the event is a mouse event then the tolerance is
 * ignored.
 */
mxVertexHandler.prototype.checkTolerance = function(me)
{
	if (this.inTolerance && this.startX != null && this.startY != null)
	{
		if (mxEvent.isMouseEvent(me.getEvent()) ||
			Math.abs(me.getGraphX() - this.startX) > this.graph.tolerance ||
			Math.abs(me.getGraphY() - this.startY) > this.graph.tolerance)
		{
			this.inTolerance = false;
		}
	}
};

/**
 * Function: updateHint
 * 
 * Hook for subclassers do show details while the handler is active.
 */
mxVertexHandler.prototype.updateHint = function(me) { };

/**
 * Function: removeHint
 * 
 * Hooks for subclassers to hide details when the handler gets inactive.
 */
mxVertexHandler.prototype.removeHint = function() { };

/**
 * Function: roundAngle
 * 
 * Hook for rounding the angle. This uses Math.round.
 */
mxVertexHandler.prototype.roundAngle = function(angle)
{
	return Math.round(angle * 10) / 10;
};

/**
 * Function: roundLength
 * 
 * Hook for rounding the unscaled width or height. This uses Math.round.
 */
mxVertexHandler.prototype.roundLength = function(length)
{
	return Math.round(length);
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the preview.
 */
mxVertexHandler.prototype.mouseMove = function(sender, me)
{
	if (!me.isConsumed() && this.index != null)
	{
		// Checks tolerance for ignoring single clicks
		this.checkTolerance(me);

		if (!this.inTolerance)
		{
			if (this.index <= mxEvent.CUSTOM_HANDLE)
			{
				if (this.customHandles != null)
				{
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].processEvent(me);
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].active = true;
				}
			}
			else if (this.index == mxEvent.LABEL_HANDLE)
			{
				this.moveLabel(me);
			}
			else if (this.index == mxEvent.ROTATION_HANDLE)
			{
				this.rotateVertex(me);
			}
			else
			{
				this.resizeVertex(me);
			}

			this.updateHint(me);
		}
		
		me.consume();
	}
	// Workaround for disabling the connect highlight when over handle
	else if (!this.graph.isMouseDown && this.getHandleForEvent(me) != null)
	{
		me.consume(false);
	}
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.moveLabel = function(me)
{
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var tr = this.graph.view.translate;
	var scale = this.graph.view.scale;
	
	if (this.graph.isGridEnabledEvent(me.getEvent()))
	{
		point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale;
		point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale;
	}

	var index = (this.rotationShape != null) ? this.sizers.length - 2 : this.sizers.length - 1;
	this.moveSizerTo(this.sizers[index], point.x, point.y);
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.rotateVertex = function(me)
{
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var dx = this.state.x + this.state.width / 2 - point.x;
	var dy = this.state.y + this.state.height / 2 - point.y;
	this.currentAlpha = (dx != 0) ? Math.atan(dy / dx) * 180 / Math.PI + 90 : ((dy < 0) ? 180 : 0);
	
	if (dx > 0)
	{
		this.currentAlpha -= 180;
	}

	// Rotation raster
	if (this.rotationRaster && this.graph.isGridEnabledEvent(me.getEvent()))
	{
		var dx = point.x - this.state.getCenterX();
		var dy = point.y - this.state.getCenterY();
		var dist = Math.abs(Math.sqrt(dx * dx + dy * dy) - 20) * 3;
		var raster = Math.max(1, 5 * Math.min(3, Math.max(0, Math.round(80 / Math.abs(dist)))));
		
		this.currentAlpha = Math.round(this.currentAlpha / raster) * raster;
	}
	else
	{
		this.currentAlpha = this.roundAngle(this.currentAlpha);
	}

	this.selectionBorder.rotation = this.currentAlpha;
	this.selectionBorder.redraw();
					
	if (this.livePreview)
	{
		this.redrawHandles();
	}
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.resizeVertex = function(me)
{
	var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
	var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var tr = this.graph.view.translate;
	var scale = this.graph.view.scale;
	var cos = Math.cos(-alpha);
	var sin = Math.sin(-alpha);
	
	var dx = point.x - this.startX;
	var dy = point.y - this.startY;

	// Rotates vector for mouse gesture
	var tx = cos * dx - sin * dy;
	var ty = sin * dx + cos * dy;
	
	dx = tx;
	dy = ty;

	var geo = this.graph.getCellGeometry(this.state.cell);
	this.unscaledBounds = this.union(geo, dx / scale, dy / scale, this.index,
		this.graph.isGridEnabledEvent(me.getEvent()), 1,
		new mxPoint(0, 0), this.isConstrainedEvent(me),
		this.isCenteredEvent(this.state, me));
	
	// Keeps vertex within maximum graph or parent bounds
	if (!geo.relative)
	{
		var max = this.graph.getMaximumGraphBounds();
		
		// Handles child cells
		if (max != null && this.parentState != null)
		{
			max = mxRectangle.fromRectangle(max);
			
			max.x -= (this.parentState.x - tr.x * scale) / scale;
			max.y -= (this.parentState.y - tr.y * scale) / scale;
		}
		
		if (this.graph.isConstrainChild(this.state.cell))
		{
			var tmp = this.graph.getCellContainmentArea(this.state.cell);
			
			if (tmp != null)
			{
				var overlap = this.graph.getOverlap(this.state.cell);
				
				if (overlap > 0)
				{
					tmp = mxRectangle.fromRectangle(tmp);
					
					tmp.x -= tmp.width * overlap;
					tmp.y -= tmp.height * overlap;
					tmp.width += 2 * tmp.width * overlap;
					tmp.height += 2 * tmp.height * overlap;
				}
				
				if (max == null)
				{
					max = tmp;
				}
				else
				{
					max = mxRectangle.fromRectangle(max);
					max.intersect(tmp);
				}
			}
		}
	
		if (max != null)
		{
			if (this.unscaledBounds.x < max.x)
			{
				this.unscaledBounds.width -= max.x - this.unscaledBounds.x;
				this.unscaledBounds.x = max.x;
			}
			
			if (this.unscaledBounds.y < max.y)
			{
				this.unscaledBounds.height -= max.y - this.unscaledBounds.y;
				this.unscaledBounds.y = max.y;
			}
			
			if (this.unscaledBounds.x + this.unscaledBounds.width > max.x + max.width)
			{
				this.unscaledBounds.width -= this.unscaledBounds.x +
					this.unscaledBounds.width - max.x - max.width;
			}
			
			if (this.unscaledBounds.y + this.unscaledBounds.height > max.y + max.height)
			{
				this.unscaledBounds.height -= this.unscaledBounds.y +
					this.unscaledBounds.height - max.y - max.height;
			}
		}
	}
	
	this.bounds = new mxRectangle(((this.parentState != null) ? this.parentState.x : tr.x * scale) +
		(this.unscaledBounds.x) * scale, ((this.parentState != null) ? this.parentState.y : tr.y * scale) +
		(this.unscaledBounds.y) * scale, this.unscaledBounds.width * scale, this.unscaledBounds.height * scale);

	if (geo.relative && this.parentState != null)
	{
		this.bounds.x += this.state.x - this.parentState.x;
		this.bounds.y += this.state.y - this.parentState.y;
	}

	cos = Math.cos(alpha);
	sin = Math.sin(alpha);
	
	var c2 = new mxPoint(this.bounds.getCenterX(), this.bounds.getCenterY());

	var dx = c2.x - ct.x;
	var dy = c2.y - ct.y;
	
	var dx2 = cos * dx - sin * dy;
	var dy2 = sin * dx + cos * dy;
	
	var dx3 = dx2 - dx;
	var dy3 = dy2 - dy;
	
	var dx4 = this.bounds.x - this.state.x;
	var dy4 = this.bounds.y - this.state.y;
	
	var dx5 = cos * dx4 - sin * dy4;
	var dy5 = sin * dx4 + cos * dy4;
	
	this.bounds.x += dx3;
	this.bounds.y += dy3;
	
	// Rounds unscaled bounds to int
	this.unscaledBounds.x = this.roundLength(this.unscaledBounds.x + dx3 / scale);
	this.unscaledBounds.y = this.roundLength(this.unscaledBounds.y + dy3 / scale);
	this.unscaledBounds.width = this.roundLength(this.unscaledBounds.width);
	this.unscaledBounds.height = this.roundLength(this.unscaledBounds.height);
	
	// Shifts the children according to parent offset
	if (!this.graph.isCellCollapsed(this.state.cell) && (dx3 != 0 || dy3 != 0))
	{
		this.childOffsetX = this.state.x - this.bounds.x + dx5;
		this.childOffsetY = this.state.y - this.bounds.y + dy5;
	}
	else
	{
		this.childOffsetX = 0;
		this.childOffsetY = 0;
	}
	
	if (this.livePreview)
	{
		this.updateLivePreview(me);
	}
	
	if (this.preview != null)
	{
		this.drawPreview();
	}
};

/**
 * Function: updateLivePreview
 * 
 * Repaints the live preview.
 */
mxVertexHandler.prototype.updateLivePreview = function(me)
{
	// TODO: Apply child offset to children in live preview
	var scale = this.graph.view.scale;
	var tr = this.graph.view.translate;
	
	// Saves current state
	var tempState = this.state.clone();

	// Temporarily changes size and origin
	this.state.x = this.bounds.x;
	this.state.y = this.bounds.y;
	this.state.origin = new mxPoint(this.state.x / scale - tr.x, this.state.y / scale - tr.y);
	this.state.width = this.bounds.width;
	this.state.height = this.bounds.height;
	
	// Needed to force update of text bounds
	this.state.unscaledWidth = null;
	
	// Redraws cell and handles
	var off = this.state.absoluteOffset;
	off = new mxPoint(off.x, off.y);

	// Required to store and reset absolute offset for updating label position
	this.state.absoluteOffset.x = 0;
	this.state.absoluteOffset.y = 0;
	var geo = this.graph.getCellGeometry(this.state.cell);				

	if (geo != null)
	{
		var offset = geo.offset || this.EMPTY_POINT;

		if (offset != null && !geo.relative)
		{
			this.state.absoluteOffset.x = this.state.view.scale * offset.x;
			this.state.absoluteOffset.y = this.state.view.scale * offset.y;
		}
		
		this.state.view.updateVertexLabelOffset(this.state);
	}
	
	// Draws the live preview
	this.state.view.graph.cellRenderer.redraw(this.state, true);
	
	// Redraws connected edges TODO: Include child edges
	this.state.view.invalidate(this.state.cell);
	this.state.invalid = false;
	this.state.view.validate();
	this.redrawHandles();
	
	// Restores current state
	this.state.setState(tempState);
};

/**
 * Function: mouseUp
 * 
 * Handles the event by applying the changes to the geometry.
 */
mxVertexHandler.prototype.mouseUp = function(sender, me)
{
	if (this.index != null && this.state != null)
	{
		var point = new mxPoint(me.getGraphX(), me.getGraphY());

		this.graph.getModel().beginUpdate();
		try
		{
			if (this.index <= mxEvent.CUSTOM_HANDLE)
			{
				if (this.customHandles != null)
				{
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].active = false;
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].execute();
				}
			}
			else if (this.index == mxEvent.ROTATION_HANDLE)
			{
				if (this.currentAlpha != null)
				{
					var delta = this.currentAlpha - (this.state.style[mxConstants.STYLE_ROTATION] || 0);
					
					if (delta != 0)
					{
						this.rotateCell(this.state.cell, delta);
					}
				}
				else
				{
					this.rotateClick();
				}
			}
			else
			{
				var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
				var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				
				var dx = point.x - this.startX;
				var dy = point.y - this.startY;
				
				// Rotates vector for mouse gesture
				var tx = cos * dx - sin * dy;
				var ty = sin * dx + cos * dy;
				
				dx = tx;
				dy = ty;
				
				var s = this.graph.view.scale;
				var recurse = this.isRecursiveResize(this.state, me);
				this.resizeCell(this.state.cell, this.roundLength(dx / s), this.roundLength(dy / s),
					this.index, gridEnabled, this.isConstrainedEvent(me), recurse);
			}
		}
		finally
		{
			this.graph.getModel().endUpdate();
		}

		me.consume();
		this.reset();
	}
};

/**
 * Function: rotateCell
 * 
 * Rotates the given cell to the given rotation.
 */
mxVertexHandler.prototype.isRecursiveResize = function(state, me)
{
	return this.graph.isRecursiveResize(this.state);
};

/**
 * Function: rotateClick
 * 
 * Hook for subclassers to implement a single click on the rotation handle.
 * This code is executed as part of the model transaction. This implementation
 * is empty.
 */
mxVertexHandler.prototype.rotateClick = function() { };

/**
 * Function: rotateCell
 * 
 * Rotates the given cell and its children by the given angle in degrees.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be rotated.
 * angle - Angle in degrees.
 */
mxVertexHandler.prototype.rotateCell = function(cell, angle, parent)
{
	if (angle != 0)
	{
		var model = this.graph.getModel();

		if (model.isVertex(cell) || model.isEdge(cell))
		{
			if (!model.isEdge(cell))
			{
				var state = this.graph.view.getState(cell);
				var style = (state != null) ? state.style : this.graph.getCellStyle(cell);
		
				if (style != null)
				{
					var total = (style[mxConstants.STYLE_ROTATION] || 0) + angle;
					this.graph.setCellStyles(mxConstants.STYLE_ROTATION, total, [cell]);
				}
			}
			
			var geo = this.graph.getCellGeometry(cell);
			
			if (geo != null)
			{
				var pgeo = this.graph.getCellGeometry(parent);
				
				if (pgeo != null && !model.isEdge(parent))
				{
					geo = geo.clone();
					geo.rotate(angle, new mxPoint(pgeo.width / 2, pgeo.height / 2));
					model.setGeometry(cell, geo);
				}
				
				if ((model.isVertex(cell) && !geo.relative) || model.isEdge(cell))
				{
					// Recursive rotation
					var childCount = model.getChildCount(cell);
					
					for (var i = 0; i < childCount; i++)
					{
						this.rotateCell(model.getChildAt(cell, i), angle, cell);
					}
				}
			}
		}
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxVertexHandler.prototype.reset = function()
{
	if (this.sizers != null && this.index != null && this.sizers[this.index] != null &&
		this.sizers[this.index].node.style.display == 'none')
	{
		this.sizers[this.index].node.style.display = '';
	}

	this.currentAlpha = null;
	this.inTolerance = null;
	this.index = null;

	// TODO: Reset and redraw cell states for live preview
	if (this.preview != null)
	{
		this.preview.destroy();
		this.preview = null;
	}

	if (this.livePreview && this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			if (this.sizers[i] != null)
			{
				this.sizers[i].node.style.display = '';
			}
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			if (this.customHandles[i].active)
			{
				this.customHandles[i].active = false;
				this.customHandles[i].reset();
			}
			else
			{
				this.customHandles[i].setVisible(true);
			}
		}
	}
	
	// Checks if handler has been destroyed
	if (this.selectionBorder != null)
	{
		this.selectionBorder.node.style.display = 'inline';
		this.selectionBounds = this.getSelectionBounds(this.state);
		this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y,
			this.selectionBounds.width, this.selectionBounds.height);
		this.drawPreview();
	}

	this.removeHint();
	this.redrawHandles();
	this.edgeHandlers = null;
	this.unscaledBounds = null;
};

/**
 * Function: resizeCell
 * 
 * Uses the given vector to change the bounds of the given cell
 * in the graph using <mxGraph.resizeCell>.
 */
mxVertexHandler.prototype.resizeCell = function(cell, dx, dy, index, gridEnabled, constrained, recurse)
{
	var geo = this.graph.model.getGeometry(cell);
	
	if (geo != null)
	{
		if (index == mxEvent.LABEL_HANDLE)
		{
			var scale = this.graph.view.scale;
			dx = Math.round((this.labelShape.bounds.getCenterX() - this.startX) / scale);
			dy = Math.round((this.labelShape.bounds.getCenterY() - this.startY) / scale);
			
			geo = geo.clone();
			
			if (geo.offset == null)
			{
				geo.offset = new mxPoint(dx, dy);
			}
			else
			{
				geo.offset.x += dx;
				geo.offset.y += dy;
			}
			
			this.graph.model.setGeometry(cell, geo);
		}
		else if (this.unscaledBounds != null)
		{
			var scale = this.graph.view.scale;

			if (this.childOffsetX != 0 || this.childOffsetY != 0)
			{
				this.moveChildren(cell, Math.round(this.childOffsetX / scale), Math.round(this.childOffsetY / scale));
			}

			this.graph.resizeCell(cell, this.unscaledBounds, recurse);
		}
	}
};

/**
 * Function: moveChildren
 * 
 * Moves the children of the given cell by the given vector.
 */
mxVertexHandler.prototype.moveChildren = function(cell, dx, dy)
{
	var model = this.graph.getModel();
	var childCount = model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(cell, i);
		var geo = this.graph.getCellGeometry(child);
		
		if (geo != null)
		{
			geo = geo.clone();
			geo.translate(dx, dy);
			model.setGeometry(child, geo);
		}
	}
};
/**
 * Function: union
 * 
 * Returns the union of the given bounds and location for the specified
 * handle index.
 * 
 * To override this to limit the size of vertex via a minWidth/-Height style,
 * the following code can be used.
 * 
 * (code)
 * var vertexHandlerUnion = mxVertexHandler.prototype.union;
 * mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained)
 * {
 *   var result = vertexHandlerUnion.apply(this, arguments);
 *   
 *   result.width = Math.max(result.width, mxUtils.getNumber(this.state.style, 'minWidth', 0));
 *   result.height = Math.max(result.height, mxUtils.getNumber(this.state.style, 'minHeight', 0));
 *   
 *   return result;
 * };
 * (end)
 * 
 * The minWidth/-Height style can then be used as follows:
 * 
 * (code)
 * graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30, 'minWidth=100;minHeight=100;');
 * (end)
 * 
 * To override this to update the height for a wrapped text if the width of a vertex is
 * changed, the following can be used.
 * 
 * (code)
 * var mxVertexHandlerUnion = mxVertexHandler.prototype.union;
 * mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained)
 * {
 *   var result = mxVertexHandlerUnion.apply(this, arguments);
 *   var s = this.state;
 *   
 *   if (this.graph.isHtmlLabel(s.cell) && (index == 3 || index == 4) &&
 *       s.text != null && s.style[mxConstants.STYLE_WHITE_SPACE] == 'wrap')
 *   {
 *     var label = this.graph.getLabel(s.cell);
 *     var fontSize = mxUtils.getNumber(s.style, mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE);
 *     var ww = result.width / s.view.scale - s.text.spacingRight - s.text.spacingLeft
 *     
 *     result.height = mxUtils.getSizeForString(label, fontSize, s.style[mxConstants.STYLE_FONTFAMILY], ww).height;
 *   }
 *   
 *   return result;
 * };
 * (end)
 */
mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained, centered)
{
	if (this.singleSizer)
	{
		var x = bounds.x + bounds.width + dx;
		var y = bounds.y + bounds.height + dy;
		
		if (gridEnabled)
		{
			x = this.graph.snap(x / scale) * scale;
			y = this.graph.snap(y / scale) * scale;
		}
		
		var rect = new mxRectangle(bounds.x, bounds.y, 0, 0);
		rect.add(new mxRectangle(x, y, 0, 0));
		
		return rect;
	}
	else
	{
		var w0 = bounds.width;
		var h0 = bounds.height;
		var left = bounds.x - tr.x * scale;
		var right = left + w0;
		var top = bounds.y - tr.y * scale;
		var bottom = top + h0;
		
		var cx = left + w0 / 2;
		var cy = top + h0 / 2;
		
		if (index > 4 /* Bottom Row */)
		{
			bottom = bottom + dy;
			
			if (gridEnabled)
			{
				bottom = this.graph.snap(bottom / scale) * scale;
			}
		}
		else if (index < 3 /* Top Row */)
		{
			top = top + dy;
			
			if (gridEnabled)
			{
				top = this.graph.snap(top / scale) * scale;
			}
		}
		
		if (index == 0 || index == 3 || index == 5 /* Left */)
		{
			left += dx;
			
			if (gridEnabled)
			{
				left = this.graph.snap(left / scale) * scale;
			}
		}
		else if (index == 2 || index == 4 || index == 7 /* Right */)
		{
			right += dx;
			
			if (gridEnabled)
			{
				right = this.graph.snap(right / scale) * scale;
			}
		}
		
		var width = right - left;
		var height = bottom - top;

		if (constrained)
		{
			var geo = this.graph.getCellGeometry(this.state.cell);

			if (geo != null)
			{
				var aspect = geo.width / geo.height;
				
				if (index== 1 || index== 2 || index == 7 || index == 6)
				{
					width = height * aspect;
				}
				else
				{
					height = width / aspect;
				}
				
				if (index == 0)
				{
					left = right - width;
					top = bottom - height;
				}
			}
		}

		if (centered)
		{
			width += (width - w0);
			height += (height - h0);
			
			var cdx = cx - (left + width / 2);
			var cdy = cy - (top + height / 2);

			left += cdx;
			top += cdy;
			right += cdx;
			bottom += cdy;
		}

		// Flips over left side
		if (width < 0)
		{
			left += width;
			width = Math.abs(width);
		}
		
		// Flips over top side
		if (height < 0)
		{
			top += height;
			height = Math.abs(height);
		}

		var result = new mxRectangle(left + tr.x * scale, top + tr.y * scale, width, height);
		
		if (this.minBounds != null)
		{
			result.width = Math.max(result.width, this.minBounds.x * scale + this.minBounds.width * scale +
				Math.max(0, this.x0 * scale - result.x));
			result.height = Math.max(result.height, this.minBounds.y * scale + this.minBounds.height * scale +
				Math.max(0, this.y0 * scale - result.y));
		}
		
		return result;
	}
};

/**
 * Function: redraw
 * 
 * Redraws the handles and the preview.
 */
mxVertexHandler.prototype.redraw = function()
{
	this.selectionBounds = this.getSelectionBounds(this.state);
	this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
	
	this.redrawHandles();
	this.drawPreview();
};

/**
 * Returns the padding to be used for drawing handles for the current <bounds>.
 */
mxVertexHandler.prototype.getHandlePadding = function()
{
	// KNOWN: Tolerance depends on event type (eg. 0 for mouse events)
	var result = new mxPoint(0, 0);
	var tol = this.tolerance;

	if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null &&
		(this.bounds.width < 2 * this.sizers[0].bounds.width + 2 * tol ||
		this.bounds.height < 2 * this.sizers[0].bounds.height + 2 * tol))
	{
		tol /= 2;
		
		result.x = this.sizers[0].bounds.width + tol;
		result.y = this.sizers[0].bounds.height + tol;
	}
	
	return result;
};

/**
 * Function: redrawHandles
 * 
 * Redraws the handles. To hide certain handles the following code can be used.
 * 
 * (code)
 * mxVertexHandler.prototype.redrawHandles = function()
 * {
 *   mxVertexHandlerRedrawHandles.apply(this, arguments);
 *   
 *   if (this.sizers != null && this.sizers.length > 7)
 *   {
 *     this.sizers[1].node.style.display = 'none';
 *     this.sizers[6].node.style.display = 'none';
 *   }
 * };
 * (end)
 */
mxVertexHandler.prototype.redrawHandles = function()
{
	var tol = this.tolerance;
	this.horizontalOffset = 0;
	this.verticalOffset = 0;
	var s = this.bounds;

	if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null)
	{
		if (this.index == null && this.manageSizers && this.sizers.length >= 8)
		{
			// KNOWN: Tolerance depends on event type (eg. 0 for mouse events)
			var padding = this.getHandlePadding();
			this.horizontalOffset = padding.x;
			this.verticalOffset = padding.y;
			
			if (this.horizontalOffset != 0 || this.verticalOffset != 0)
			{
				s = new mxRectangle(s.x, s.y, s.width, s.height);

				s.x -= this.horizontalOffset / 2;
				s.width += this.horizontalOffset;
				s.y -= this.verticalOffset / 2;
				s.height += this.verticalOffset;
			}
			
			if (this.sizers.length >= 8)
			{
				if ((s.width < 2 * this.sizers[0].bounds.width + 2 * tol) ||
					(s.height < 2 * this.sizers[0].bounds.height + 2 * tol))
				{
					this.sizers[0].node.style.display = 'none';
					this.sizers[2].node.style.display = 'none';
					this.sizers[5].node.style.display = 'none';
					this.sizers[7].node.style.display = 'none';
				}
				else
				{
					this.sizers[0].node.style.display = '';
					this.sizers[2].node.style.display = '';
					this.sizers[5].node.style.display = '';
					this.sizers[7].node.style.display = '';
				}
			}
		}

		var r = s.x + s.width;
		var b = s.y + s.height;
		
		if (this.singleSizer)
		{
			this.moveSizerTo(this.sizers[0], r, b);
		}
		else
		{
			var cx = s.x + s.width / 2;
			var cy = s.y + s.height / 2;
			
			if (this.sizers.length >= 8)
			{
				var crs = ['nw-resize', 'n-resize', 'ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize'];
				
				var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
				var cos = Math.cos(alpha);
				var sin = Math.sin(alpha);
				
				var da = Math.round(alpha * 4 / Math.PI);
				
				var ct = new mxPoint(s.getCenterX(), s.getCenterY());
				var pt = mxUtils.getRotatedPoint(new mxPoint(s.x, s.y), cos, sin, ct);
				
				this.moveSizerTo(this.sizers[0], pt.x, pt.y);
				this.sizers[0].setCursor(crs[mxUtils.mod(0 + da, crs.length)]);
				
				pt.x = cx;
				pt.y = s.y;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[1], pt.x, pt.y);
				this.sizers[1].setCursor(crs[mxUtils.mod(1 + da, crs.length)]);
				
				pt.x = r;
				pt.y = s.y;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[2], pt.x, pt.y);
				this.sizers[2].setCursor(crs[mxUtils.mod(2 + da, crs.length)]);
				
				pt.x = s.x;
				pt.y = cy;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[3], pt.x, pt.y);
				this.sizers[3].setCursor(crs[mxUtils.mod(7 + da, crs.length)]);

				pt.x = r;
				pt.y = cy;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[4], pt.x, pt.y);
				this.sizers[4].setCursor(crs[mxUtils.mod(3 + da, crs.length)]);

				pt.x = s.x;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[5], pt.x, pt.y);
				this.sizers[5].setCursor(crs[mxUtils.mod(6 + da, crs.length)]);

				pt.x = cx;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[6], pt.x, pt.y);
				this.sizers[6].setCursor(crs[mxUtils.mod(5 + da, crs.length)]);

				pt.x = r;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[7], pt.x, pt.y);
				this.sizers[7].setCursor(crs[mxUtils.mod(4 + da, crs.length)]);
				
				this.moveSizerTo(this.sizers[8], cx + this.state.absoluteOffset.x, cy + this.state.absoluteOffset.y);
			}
			else if (this.state.width >= 2 && this.state.height >= 2)
			{
				this.moveSizerTo(this.sizers[0], cx + this.state.absoluteOffset.x, cy + this.state.absoluteOffset.y);
			}
			else
			{
				this.moveSizerTo(this.sizers[0], this.state.x, this.state.y);
			}
		}
	}

	if (this.rotationShape != null)
	{
		var alpha = mxUtils.toRadians((this.currentAlpha != null) ? this.currentAlpha : this.state.style[mxConstants.STYLE_ROTATION] || '0');
		var cos = Math.cos(alpha);
		var sin = Math.sin(alpha);
		
		var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
		var pt = mxUtils.getRotatedPoint(new mxPoint(s.x + s.width / 2, s.y + this.rotationHandleVSpacing), cos, sin, ct);

		if (this.rotationShape.node != null)
		{
			this.moveSizerTo(this.rotationShape, pt.x, pt.y);
		}
	}
	
	if (this.selectionBorder != null)
	{
		this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	}
	
	if (this.edgeHandlers != null)
	{		
		for (var i = 0; i < this.edgeHandlers.length; i++)
		{
			this.edgeHandlers[i].redraw();
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			var temp = this.customHandles[i].shape.node.style.display;
			this.customHandles[i].redraw();
			this.customHandles[i].shape.node.style.display = temp;
		}
	}

	this.updateParentHighlight();
};

/**
 * Function: updateParentHighlight
 * 
 * Updates the highlight of the parent if <parentHighlightEnabled> is true.
 */
mxVertexHandler.prototype.updateParentHighlight = function()
{
	// If not destroyed
	if (this.selectionBorder != null)
	{
		if (this.parentHighlight != null)
		{
			var parent = this.graph.model.getParent(this.state.cell);
	
			if (this.graph.model.isVertex(parent))
			{
				var pstate = this.graph.view.getState(parent);
				var b = this.parentHighlight.bounds;
				
				if (pstate != null && (b.x != pstate.x || b.y != pstate.y ||
					b.width != pstate.width || b.height != pstate.height))
				{
					this.parentHighlight.bounds = pstate;
					this.parentHighlight.redraw();
				}
			}
			else
			{
				this.parentHighlight.destroy();
				this.parentHighlight = null;
			}
		}
		else if (this.parentHighlightEnabled)
		{
			var parent = this.graph.model.getParent(this.state.cell);
			
			if (this.graph.model.isVertex(parent))
			{
				var pstate = this.graph.view.getState(parent);
				
				if (pstate != null)
				{
					this.parentHighlight = this.createParentHighlightShape(pstate);
					// VML dialect required here for event transparency in IE
					this.parentHighlight.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
					this.parentHighlight.pointerEvents = false;
					this.parentHighlight.rotation = Number(pstate.style[mxConstants.STYLE_ROTATION] || '0');
					this.parentHighlight.init(this.graph.getView().getOverlayPane());
				}
			}
		}
	}
};

/**
 * Function: drawPreview
 * 
 * Redraws the preview.
 */
mxVertexHandler.prototype.drawPreview = function()
{
	if (this.preview != null)
	{
		this.preview.bounds = this.bounds;
		
		if (this.preview.node.parentNode == this.graph.container)
		{
			this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1);
			this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1);
		}
	
		this.preview.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
		this.preview.redraw();
	}
	
	this.selectionBorder.bounds = this.bounds;
	this.selectionBorder.redraw();
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.redraw();
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxVertexHandler.prototype.destroy = function()
{
	if (this.escapeHandler != null)
	{
		this.state.view.graph.removeListener(this.escapeHandler);
		this.escapeHandler = null;
	}
	
	if (this.preview != null)
	{
		this.preview.destroy();
		this.preview = null;
	}
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.destroy();
		this.parentHighlight = null;
	}
	
	if (this.selectionBorder != null)
	{
		this.selectionBorder.destroy();
		this.selectionBorder = null;
	}
	
	this.labelShape = null;
	this.removeHint();

	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			this.sizers[i].destroy();
		}
		
		this.sizers = null;
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].destroy();
		}
		
		this.customHandles = null;
	}
};
