/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxMorphing
 * 
 * Implements animation for morphing cells. Here is an example of
 * using this class for animating the result of a layout algorithm:
 * 
 * (code)
 * graph.getModel().beginUpdate();
 * try
 * {
 *   var circleLayout = new mxCircleLayout(graph);
 *   circleLayout.execute(graph.getDefaultParent());
 * }
 * finally
 * {
 *   var morph = new mxMorphing(graph);
 *   morph.addListener(mxEvent.DONE, function()
 *   {
 *     graph.getModel().endUpdate();
 *   });
 *   
 *   morph.startAnimation();
 * }
 * (end)
 * 
 * Constructor: mxMorphing
 * 
 * Constructs an animation.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * steps - Optional number of steps in the morphing animation. Default is 6.
 * ease - Optional easing constant for the animation. Default is 1.5.
 * delay - Optional delay between the animation steps. Passed to <mxAnimation>.
 */
function mxMorphing(graph, steps, ease, delay)
{
	mxAnimation.call(this, delay);
	this.graph = graph;
	this.steps = (steps != null) ? steps : 6;
	this.ease = (ease != null) ? ease : 1.5;
};

/**
 * Extends mxEventSource.
 */
mxMorphing.prototype = new mxAnimation();
mxMorphing.prototype.constructor = mxMorphing;

/**
 * Variable: graph
 * 
 * Specifies the delay between the animation steps. Defaul is 30ms.
 */
mxMorphing.prototype.graph = null;

/**
 * Variable: steps
 * 
 * Specifies the maximum number of steps for the morphing.
 */
mxMorphing.prototype.steps = null;

/**
 * Variable: step
 * 
 * Contains the current step.
 */
mxMorphing.prototype.step = 0;

/**
 * Variable: ease
 * 
 * Ease-off for movement towards the given vector. Larger values are
 * slower and smoother. Default is 4.
 */
mxMorphing.prototype.ease = null;

/**
 * Variable: cells
 * 
 * Optional array of cells to be animated. If this is not specified
 * then all cells are checked and animated if they have been moved
 * in the current transaction.
 */
mxMorphing.prototype.cells = null;

/**
 * Function: updateAnimation
 *
 * Animation step.
 */
mxMorphing.prototype.updateAnimation = function()
{
	var move = new mxCellStatePreview(this.graph);

	if (this.cells != null)
	{
		// Animates the given cells individually without recursion
		for (var i = 0; i < this.cells.length; i++)
		{
			this.animateCell(this.cells[i], move, false);
		}
	}
	else
	{
		// Animates all changed cells by using recursion to find
		// the changed cells but not for the animation itself
		this.animateCell(this.graph.getModel().getRoot(), move, true);
	}
	
	this.show(move);
	
	if (move.isEmpty() || this.step++ >= this.steps)
	{
		this.stopAnimation();
	}
};

/**
 * Function: show
 *
 * Shows the changes in the given <mxCellStatePreview>.
 */
mxMorphing.prototype.show = function(move)
{
	move.show();
};

/**
 * Function: animateCell
 *
 * Animates the given cell state using <mxCellStatePreview.moveState>.
 */
mxMorphing.prototype.animateCell = function(cell, move, recurse)
{
	var state = this.graph.getView().getState(cell);
	var delta = null;

	if (state != null)
	{
		// Moves the animated state from where it will be after the model
		// change by subtracting the given delta vector from that location
		delta = this.getDelta(state);

		if (this.graph.getModel().isVertex(cell) && (delta.x != 0 || delta.y != 0))
		{
			var translate = this.graph.view.getTranslate();
			var scale = this.graph.view.getScale();
			
			delta.x += translate.x * scale;
			delta.y += translate.y * scale;
			
			move.moveState(state, -delta.x / this.ease, -delta.y / this.ease);
		}
	}
	
	if (recurse && !this.stopRecursion(state, delta))
	{
		var childCount = this.graph.getModel().getChildCount(cell);

		for (var i = 0; i < childCount; i++)
		{
			this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
		}
	}
};

/**
 * Function: stopRecursion
 *
 * Returns true if the animation should not recursively find more
 * deltas for children if the given parent state has been animated.
 */
mxMorphing.prototype.stopRecursion = function(state, delta)
{
	return delta != null && (delta.x != 0 || delta.y != 0);
};

/**
 * Function: getDelta
 *
 * Returns the vector between the current rendered state and the future
 * location of the state after the display will be updated.
 */
mxMorphing.prototype.getDelta = function(state)
{
	var origin = this.getOriginForCell(state.cell);
	var translate = this.graph.getView().getTranslate();
	var scale = this.graph.getView().getScale();
	var x = state.x / scale - translate.x;
	var y = state.y / scale - translate.y;

	return new mxPoint((origin.x - x) * scale, (origin.y - y) * scale);
};

/**
 * Function: getOriginForCell
 *
 * Returns the top, left corner of the given cell. TODO: Improve performance
 * by using caching inside this method as the result per cell never changes
 * during the lifecycle of this object.
 */
mxMorphing.prototype.getOriginForCell = function(cell)
{
	var result = null;
	
	if (cell != null)
	{
		var parent = this.graph.getModel().getParent(cell);
		var geo = this.graph.getCellGeometry(cell);
		result = this.getOriginForCell(parent);
		
		// TODO: Handle offsets
		if (geo != null)
		{
			if (geo.relative)
			{
				var pgeo = this.graph.getCellGeometry(parent);
				
				if (pgeo != null)
				{
					result.x += geo.x * pgeo.width;
					result.y += geo.y * pgeo.height;
				}
			}
			else
			{
				result.x += geo.x;
				result.y += geo.y;
			}
		}
	}
	
	if (result == null)
	{
		var t = this.graph.view.getTranslate();
		result = new mxPoint(-t.x, -t.y);
	}
	
	return result;
};
