/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxFastOrganicLayout
 * 
 * Extends <mxGraphLayout> to implement a fast organic layout algorithm.
 * The vertices need to be connected for this layout to work, vertices
 * with no connections are ignored.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxFastOrganicLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxCompactTreeLayout
 * 
 * Constructs a new fast organic layout for the specified graph.
 */
function mxFastOrganicLayout(graph)
{
	mxGraphLayout.call(this, graph);
};

/**
 * Extends mxGraphLayout.
 */
mxFastOrganicLayout.prototype = new mxGraphLayout();
mxFastOrganicLayout.prototype.constructor = mxFastOrganicLayout;

/**
 * Variable: useInputOrigin
 * 
 * Specifies if the top left corner of the input cells should be the origin
 * of the layout result. Default is true.
 */
mxFastOrganicLayout.prototype.useInputOrigin = true;

/**
 * Variable: resetEdges
 * 
 * Specifies if all edge points of traversed edges should be removed.
 * Default is true.
 */
mxFastOrganicLayout.prototype.resetEdges = true;

/**
 * Variable: disableEdgeStyle
 * 
 * Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
 * modified by the result. Default is true.
 */
mxFastOrganicLayout.prototype.disableEdgeStyle = true;

/**
 * Variable: forceConstant
 * 
 * The force constant by which the attractive forces are divided and the
 * replusive forces are multiple by the square of. The value equates to the
 * average radius there is of free space around each node. Default is 50.
 */
mxFastOrganicLayout.prototype.forceConstant = 50;

/**
 * Variable: forceConstantSquared
 * 
 * Cache of <forceConstant>^2 for performance.
 */
mxFastOrganicLayout.prototype.forceConstantSquared = 0;

/**
 * Variable: minDistanceLimit
 * 
 * Minimal distance limit. Default is 2. Prevents of
 * dividing by zero.
 */
mxFastOrganicLayout.prototype.minDistanceLimit = 2;

/**
 * Variable: minDistanceLimit
 * 
 * Minimal distance limit. Default is 2. Prevents of
 * dividing by zero.
 */
mxFastOrganicLayout.prototype.maxDistanceLimit = 500;

/**
 * Variable: minDistanceLimitSquared
 * 
 * Cached version of <minDistanceLimit> squared.
 */
mxFastOrganicLayout.prototype.minDistanceLimitSquared = 4;

/**
 * Variable: initialTemp
 * 
 * Start value of temperature. Default is 200.
 */
mxFastOrganicLayout.prototype.initialTemp = 200;

/**
 * Variable: temperature
 * 
 * Temperature to limit displacement at later stages of layout.
 */
mxFastOrganicLayout.prototype.temperature = 0;

/**
 * Variable: maxIterations
 * 
 * Total number of iterations to run the layout though.
 */
mxFastOrganicLayout.prototype.maxIterations = 0;

/**
 * Variable: iteration
 * 
 * Current iteration count.
 */
mxFastOrganicLayout.prototype.iteration = 0;

/**
 * Variable: vertexArray
 * 
 * An array of all vertices to be laid out.
 */
mxFastOrganicLayout.prototype.vertexArray;

/**
 * Variable: dispX
 * 
 * An array of locally stored X co-ordinate displacements for the vertices.
 */
mxFastOrganicLayout.prototype.dispX;

/**
 * Variable: dispY
 * 
 * An array of locally stored Y co-ordinate displacements for the vertices.
 */
mxFastOrganicLayout.prototype.dispY;

/**
 * Variable: cellLocation
 * 
 * An array of locally stored co-ordinate positions for the vertices.
 */
mxFastOrganicLayout.prototype.cellLocation;

/**
 * Variable: radius
 * 
 * The approximate radius of each cell, nodes only.
 */
mxFastOrganicLayout.prototype.radius;

/**
 * Variable: radiusSquared
 * 
 * The approximate radius squared of each cell, nodes only.
 */
mxFastOrganicLayout.prototype.radiusSquared;

/**
 * Variable: isMoveable
 * 
 * Array of booleans representing the movable states of the vertices.
 */
mxFastOrganicLayout.prototype.isMoveable;

/**
 * Variable: neighbours
 * 
 * Local copy of cell neighbours.
 */
mxFastOrganicLayout.prototype.neighbours;

/**
 * Variable: indices
 * 
 * Hashtable from cells to local indices.
 */
mxFastOrganicLayout.prototype.indices;

/**
 * Variable: allowedToRun
 * 
 * Boolean flag that specifies if the layout is allowed to run. If this is
 * set to false, then the layout exits in the following iteration.
 */
mxFastOrganicLayout.prototype.allowedToRun = true;

/**
 * Function: isVertexIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored as a
 * vertex. This returns true if the cell has no connections.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> whose ignored state should be returned.
 */
mxFastOrganicLayout.prototype.isVertexIgnored = function(vertex)
{
	return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
		this.graph.getConnections(vertex).length == 0;
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>. This operates on all children of the
 * given parent where <isVertexIgnored> returns false.
 */
mxFastOrganicLayout.prototype.execute = function(parent)
{
	var model = this.graph.getModel();
	this.vertexArray = [];
	var cells = this.graph.getChildVertices(parent);
	
	for (var i = 0; i < cells.length; i++)
	{
		if (!this.isVertexIgnored(cells[i]))
		{
			this.vertexArray.push(cells[i]);
		}
	}
	
	var initialBounds = (this.useInputOrigin) ?
			this.graph.getBoundingBoxFromGeometry(this.vertexArray) :
				null;
	var n = this.vertexArray.length;

	this.indices = [];
	this.dispX = [];
	this.dispY = [];
	this.cellLocation = [];
	this.isMoveable = [];
	this.neighbours = [];
	this.radius = [];
	this.radiusSquared = [];

	if (this.forceConstant < 0.001)
	{
		this.forceConstant = 0.001;
	}

	this.forceConstantSquared = this.forceConstant * this.forceConstant;

	// Create a map of vertices first. This is required for the array of
	// arrays called neighbours which holds, for each vertex, a list of
	// ints which represents the neighbours cells to that vertex as
	// the indices into vertexArray
	for (var i = 0; i < this.vertexArray.length; i++)
	{
		var vertex = this.vertexArray[i];
		this.cellLocation[i] = [];
		
		// Set up the mapping from array indices to cells
		var id = mxObjectIdentity.get(vertex);
		this.indices[id] = i;
		var bounds = this.getVertexBounds(vertex);

		// Set the X,Y value of the internal version of the cell to
		// the center point of the vertex for better positioning
		var width = bounds.width;
		var height = bounds.height;
		
		// Randomize (0, 0) locations
		var x = bounds.x;
		var y = bounds.y;
		
		this.cellLocation[i][0] = x + width / 2.0;
		this.cellLocation[i][1] = y + height / 2.0;
		this.radius[i] = Math.min(width, height);
		this.radiusSquared[i] = this.radius[i] * this.radius[i];
	}

	// Moves cell location back to top-left from center locations used in
	// algorithm, resetting the edge points is part of the transaction
	model.beginUpdate();
	try
	{
		for (var i = 0; i < n; i++)
		{
			this.dispX[i] = 0;
			this.dispY[i] = 0;
			this.isMoveable[i] = this.isVertexMovable(this.vertexArray[i]);

			// Get lists of neighbours to all vertices, translate the cells
			// obtained in indices into vertexArray and store as an array
			// against the orginial cell index
			var edges = this.graph.getConnections(this.vertexArray[i], parent);
			var cells = this.graph.getOpposites(edges, this.vertexArray[i]);
			this.neighbours[i] = [];

			for (var j = 0; j < cells.length; j++)
			{
				// Resets the points on the traversed edge
				if (this.resetEdges)
				{
					this.graph.resetEdge(edges[j]);
				}

			    if (this.disableEdgeStyle)
			    {
			    	this.setEdgeStyleEnabled(edges[j], false);
			    }

				// Looks the cell up in the indices dictionary
				var id = mxObjectIdentity.get(cells[j]);
				var index = this.indices[id];

				// Check the connected cell in part of the vertex list to be
				// acted on by this layout
				if (index != null)
				{
					this.neighbours[i][j] = index;
				}

				// Else if index of the other cell doesn't correspond to
				// any cell listed to be acted upon in this layout. Set
				// the index to the value of this vertex (a dummy self-loop)
				// so the attraction force of the edge is not calculated
				else
				{
					this.neighbours[i][j] = i;
				}
			}
		}
		this.temperature = this.initialTemp;

		// If max number of iterations has not been set, guess it
		if (this.maxIterations == 0)
		{
			this.maxIterations = 20 * Math.sqrt(n);
		}
		
		// Main iteration loop
		for (this.iteration = 0; this.iteration < this.maxIterations; this.iteration++)
		{
			if (!this.allowedToRun)
			{
				return;
			}
			
			// Calculate repulsive forces on all vertices
			this.calcRepulsion();

			// Calculate attractive forces through edges
			this.calcAttraction();

			this.calcPositions();
			this.reduceTemperature();
		}

		var minx = null;
		var miny = null;
		
		for (var i = 0; i < this.vertexArray.length; i++)
		{
			var vertex = this.vertexArray[i];
			
			if (this.isVertexMovable(vertex))
			{
				var bounds = this.getVertexBounds(vertex);
				
				if (bounds != null)
				{
					this.cellLocation[i][0] -= bounds.width / 2.0;
					this.cellLocation[i][1] -= bounds.height / 2.0;
					
					var x = this.graph.snap(this.cellLocation[i][0]);
					var y = this.graph.snap(this.cellLocation[i][1]);
					
					this.setVertexLocation(vertex, x, y);
					
					if (minx == null)
					{
						minx = x;
					}
					else
					{
						minx = Math.min(minx, x);
					}
					
					if (miny == null)
					{
						miny = y;
					}
					else
					{
						miny = Math.min(miny, y);
					}
				}
			}
		}
		
		// Modifies the cloned geometries in-place. Not needed
		// to clone the geometries again as we're in the same
		// undoable change.
		var dx = -(minx || 0) + 1;
		var dy = -(miny || 0) + 1;
		
		if (initialBounds != null)
		{
			dx += initialBounds.x;
			dy += initialBounds.y;
		}
		
		this.graph.moveCells(this.vertexArray, dx, dy);
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: calcPositions
 * 
 * Takes the displacements calculated for each cell and applies them to the
 * local cache of cell positions. Limits the displacement to the current
 * temperature.
 */
mxFastOrganicLayout.prototype.calcPositions = function()
{
	for (var index = 0; index < this.vertexArray.length; index++)
	{
		if (this.isMoveable[index])
		{
			// Get the distance of displacement for this node for this
			// iteration
			var deltaLength = Math.sqrt(this.dispX[index] * this.dispX[index] +
				this.dispY[index] * this.dispY[index]);

			if (deltaLength < 0.001)
			{
				deltaLength = 0.001;
			}

			// Scale down by the current temperature if less than the
			// displacement distance
			var newXDisp = this.dispX[index] / deltaLength
				* Math.min(deltaLength, this.temperature);

			var newYDisp = this.dispY[index] / deltaLength
				* Math.min(deltaLength, this.temperature);

			// reset displacements
			this.dispX[index] = 0;
			this.dispY[index] = 0;

			// Update the cached cell locations
			this.cellLocation[index][0] += newXDisp;
			this.cellLocation[index][1] += newYDisp;
		}
	}
};

/**
 * Function: calcAttraction
 * 
 * Calculates the attractive forces between all laid out nodes linked by
 * edges
 */
mxFastOrganicLayout.prototype.calcAttraction = function()
{
	// Check the neighbours of each vertex and calculate the attractive
	// force of the edge connecting them
	for (var i = 0; i < this.vertexArray.length; i++)
	{
		for (var k = 0; k < this.neighbours[i].length; k++)
		{
			// Get the index of the othe cell in the vertex array
			var j = this.neighbours[i][k];
			
			// Do not proceed self-loops
			if (i != j &&
				this.isMoveable[i] &&
				this.isMoveable[j])
			{
				var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
				var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];

				// The distance between the nodes
				var deltaLengthSquared = xDelta * xDelta + yDelta
						* yDelta - this.radiusSquared[i] - this.radiusSquared[j];

				if (deltaLengthSquared < this.minDistanceLimitSquared)
				{
					deltaLengthSquared = this.minDistanceLimitSquared;
				}
				
				var deltaLength = Math.sqrt(deltaLengthSquared);
				var force = (deltaLengthSquared) / this.forceConstant;

				var displacementX = (xDelta / deltaLength) * force;
				var displacementY = (yDelta / deltaLength) * force;
				
				this.dispX[i] -= displacementX;
				this.dispY[i] -= displacementY;
				
				this.dispX[j] += displacementX;
				this.dispY[j] += displacementY;
			}
		}
	}
};

/**
 * Function: calcRepulsion
 * 
 * Calculates the repulsive forces between all laid out nodes
 */
mxFastOrganicLayout.prototype.calcRepulsion = function()
{
	var vertexCount = this.vertexArray.length;

	for (var i = 0; i < vertexCount; i++)
	{
		for (var j = i; j < vertexCount; j++)
		{
			// Exits if the layout is no longer allowed to run
			if (!this.allowedToRun)
			{
				return;
			}

			if (j != i &&
				this.isMoveable[i] &&
				this.isMoveable[j])
			{
				var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
				var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];

				if (xDelta == 0)
				{
					xDelta = 0.01 + Math.random();
				}
				
				if (yDelta == 0)
				{
					yDelta = 0.01 + Math.random();
				}
				
				// Distance between nodes
				var deltaLength = Math.sqrt((xDelta * xDelta)
						+ (yDelta * yDelta));
				var deltaLengthWithRadius = deltaLength - this.radius[i]
						- this.radius[j];

				if (deltaLengthWithRadius > this.maxDistanceLimit)
				{
					// Ignore vertices too far apart
					continue;
				}

				if (deltaLengthWithRadius < this.minDistanceLimit)
				{
					deltaLengthWithRadius = this.minDistanceLimit;
				}

				var force = this.forceConstantSquared / deltaLengthWithRadius;

				var displacementX = (xDelta / deltaLength) * force;
				var displacementY = (yDelta / deltaLength) * force;
				
				this.dispX[i] += displacementX;
				this.dispY[i] += displacementY;

				this.dispX[j] -= displacementX;
				this.dispY[j] -= displacementY;
			}
		}
	}
};

/**
 * Function: reduceTemperature
 * 
 * Reduces the temperature of the layout from an initial setting in a linear
 * fashion to zero.
 */
mxFastOrganicLayout.prototype.reduceTemperature = function()
{
	this.temperature = this.initialTemp * (1.0 - this.iteration / this.maxIterations);
};
