/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxHandle
 * 
 * Implements a single custom handle for vertices.
 * 
 * Constructor: mxHandle
 * 
 * Constructs a new handle for the given state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be handled.
 */
function mxHandle(state, cursor, image)
{
	this.graph = state.view.graph;
	this.state = state;
	this.cursor = (cursor != null) ? cursor : this.cursor;
	this.image = (image != null) ? image : this.image;
	this.init();
};

/**
 * Variable: cursor
 * 
 * Specifies the cursor to be used for this handle. Default is 'default'.
 */
mxHandle.prototype.cursor = 'default';

/**
 * Variable: image
 * 
 * Specifies the <mxImage> to be used to render the handle. Default is null.
 */
mxHandle.prototype.image = null;

/**
 * Variable: image
 * 
 * Specifies the <mxImage> to be used to render the handle. Default is null.
 */
mxHandle.prototype.ignoreGrid = false;

/**
 * Function: getPosition
 * 
 * Hook for subclassers to return the current position of the handle.
 */
mxHandle.prototype.getPosition = function(bounds) { };

/**
 * Function: setPosition
 * 
 * Hooks for subclassers to update the style in the <state>.
 */
mxHandle.prototype.setPosition = function(bounds, pt, me) { };

/**
 * Function: execute
 * 
 * Hook for subclassers to execute the handle.
 */
mxHandle.prototype.execute = function() { };

/**
 * Function: copyStyle
 * 
 * Sets the cell style with the given name to the corresponding value in <state>.
 */
mxHandle.prototype.copyStyle = function(key)
{
	this.graph.setCellStyles(key, this.state.style[key], [this.state.cell]);
};

/**
 * Function: processEvent
 * 
 * Processes the given <mxMouseEvent> and invokes <setPosition>.
 */
mxHandle.prototype.processEvent = function(me)
{
	var scale = this.graph.view.scale;
	var tr = this.graph.view.translate;
	var pt = new mxPoint(me.getGraphX() / scale - tr.x, me.getGraphY() / scale - tr.y);
	
	// Center shape on mouse cursor
	if (this.shape != null && this.shape.bounds != null)
	{
		pt.x -= this.shape.bounds.width / scale / 4;
		pt.y -= this.shape.bounds.height / scale / 4;
	}

	// Snaps to grid for the rotated position then applies the rotation for the direction after that
	var alpha1 = -mxUtils.toRadians(this.getRotation());
	var alpha2 = -mxUtils.toRadians(this.getTotalRotation()) - alpha1;
	pt = this.flipPoint(this.rotatePoint(this.snapPoint(this.rotatePoint(pt, alpha1),
			this.ignoreGrid || !this.graph.isGridEnabledEvent(me.getEvent())), alpha2));
	this.setPosition(this.state.getPaintBounds(), pt, me);
	this.positionChanged();
	this.redraw();
};

/**
 * Function: positionChanged
 * 
 * Called after <setPosition> has been called in <processEvent>. This repaints
 * the state using <mxCellRenderer>.
 */
mxHandle.prototype.positionChanged = function()
{
	if (this.state.text != null)
	{
		this.state.text.apply(this.state);
	}
	
	if (this.state.shape != null)
	{
		this.state.shape.apply(this.state);
	}
	
	// Needed to force update of text bounds
	this.state.unscaledWidth = null;
	this.graph.cellRenderer.redraw(this.state, true);
};

/**
 * Function: getRotation
 * 
 * Returns the rotation defined in the style of the cell.
 */
mxHandle.prototype.getRotation = function()
{
	if (this.state.shape != null)
	{
		return this.state.shape.getRotation();
	}
	
	return 0;
};

/**
 * Function: getTotalRotation
 * 
 * Returns the rotation from the style and the rotation from the direction of
 * the cell.
 */
mxHandle.prototype.getTotalRotation = function()
{
	if (this.state.shape != null)
	{
		return this.state.shape.getShapeRotation();
	}
	
	return 0;
};

/**
 * Function: init
 * 
 * Creates and initializes the shapes required for this handle.
 */
mxHandle.prototype.init = function()
{
	var html = this.isHtmlRequired();
	
	if (this.image != null)
	{
		this.shape = new mxImageShape(new mxRectangle(0, 0, this.image.width, this.image.height), this.image.src);
		this.shape.preserveImageAspect = false;
	}
	else
	{
		this.shape = this.createShape(html);
	}
	
	this.initShape(html);
};

/**
 * Function: createShape
 * 
 * Creates and returns the shape for this handle.
 */
mxHandle.prototype.createShape = function(html)
{
	var bounds = new mxRectangle(0, 0, mxConstants.HANDLE_SIZE, mxConstants.HANDLE_SIZE);
	
	return new mxRectangleShape(bounds, mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
};

/**
 * Function: initShape
 * 
 * Initializes <shape> and sets its cursor.
 */
mxHandle.prototype.initShape = function(html)
{
	if (html && this.shape.isHtmlAllowed())
	{
		this.shape.dialect = mxConstants.DIALECT_STRICTHTML;
		this.shape.init(this.graph.container);
	}
	else
	{
		this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
		
		if (this.cursor != null)
		{
			this.shape.init(this.graph.getView().getOverlayPane());
		}
	}

	mxEvent.redirectMouseEvents(this.shape.node, this.graph, this.state);
	this.shape.node.style.cursor = this.cursor;
};

/**
 * Function: redraw
 * 
 * Renders the shape for this handle.
 */
mxHandle.prototype.redraw = function()
{
	if (this.shape != null && this.state.shape != null)
	{
		var pt = this.getPosition(this.state.getPaintBounds());
		
		if (pt != null)
		{
			var alpha = mxUtils.toRadians(this.getTotalRotation());
			pt = this.rotatePoint(this.flipPoint(pt), alpha);
	
			var scale = this.graph.view.scale;
			var tr = this.graph.view.translate;
			this.shape.bounds.x = Math.floor((pt.x + tr.x) * scale - this.shape.bounds.width / 2);
			this.shape.bounds.y = Math.floor((pt.y + tr.y) * scale - this.shape.bounds.height / 2);
			
			// Needed to force update of text bounds
			this.shape.redraw();
		}
	}
};

/**
 * Function: isHtmlRequired
 * 
 * Returns true if this handle should be rendered in HTML. This returns true if
 * the text node is in the graph container.
 */
mxHandle.prototype.isHtmlRequired = function()
{
	return this.state.text != null && this.state.text.node.parentNode == this.graph.container;
};

/**
 * Function: rotatePoint
 * 
 * Rotates the point by the given angle.
 */
mxHandle.prototype.rotatePoint = function(pt, alpha)
{
	var bounds = this.state.getCellBounds();
	var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
	var cos = Math.cos(alpha);
	var sin = Math.sin(alpha); 

	return mxUtils.getRotatedPoint(pt, cos, sin, cx);
};

/**
 * Function: flipPoint
 * 
 * Flips the given point vertically and/or horizontally.
 */
mxHandle.prototype.flipPoint = function(pt)
{
	if (this.state.shape != null)
	{
		var bounds = this.state.getCellBounds();
		
		if (this.state.shape.flipH)
		{
			pt.x = 2 * bounds.x + bounds.width - pt.x;
		}
		
		if (this.state.shape.flipV)
		{
			pt.y = 2 * bounds.y + bounds.height - pt.y;
		}
	}
	
	return pt;
};

/**
 * Function: snapPoint
 * 
 * Snaps the given point to the grid if ignore is false. This modifies
 * the given point in-place and also returns it.
 */
mxHandle.prototype.snapPoint = function(pt, ignore)
{
	if (!ignore)
	{
		pt.x = this.graph.snap(pt.x);
		pt.y = this.graph.snap(pt.y);
	}
	
	return pt;
};

/**
 * Function: setVisible
 * 
 * Shows or hides this handle.
 */
mxHandle.prototype.setVisible = function(visible)
{
	if (this.shape != null && this.shape.node != null)
	{
		this.shape.node.style.display = (visible) ? '' : 'none';
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handle by setting its visibility to true.
 */
mxHandle.prototype.reset = function()
{
	this.setVisible(true);
	this.state.style = this.graph.getCellStyle(this.state.cell);
	this.positionChanged();
};

/**
 * Function: destroy
 * 
 * Destroys this handle.
 */
mxHandle.prototype.destroy = function()
{
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
};
