/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxClipboard =
{
	/**
	 * Class: mxClipboard
	 * 
	 * Singleton that implements a clipboard for graph cells.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxClipboard.copy(graph);
	 * mxClipboard.paste(graph2);
	 * (end)
	 *
	 * This copies the selection cells from the graph to the clipboard and
	 * pastes them into graph2.
	 * 
	 * For fine-grained control of the clipboard data the <mxGraph.canExportCell>
	 * and <mxGraph.canImportCell> functions can be overridden.
	 * 
	 * To restore previous parents for pasted cells, the implementation for
	 * <copy> and <paste> can be changed as follows.
	 * 
	 * (code)
	 * mxClipboard.copy = function(graph, cells)
	 * {
	 *   cells = cells || graph.getSelectionCells();
	 *   var result = graph.getExportableCells(cells);
	 *   
	 *   mxClipboard.parents = new Object();
	 *   
	 *   for (var i = 0; i < result.length; i++)
	 *   {
	 *     mxClipboard.parents[i] = graph.model.getParent(cells[i]);
	 *   }
	 *   
	 *   mxClipboard.insertCount = 1;
	 *   mxClipboard.setCells(graph.cloneCells(result));
	 *   
	 *   return result;
	 * };
	 * 
	 * mxClipboard.paste = function(graph)
	 * {
	 *   if (!mxClipboard.isEmpty())
	 *   {
	 *     var cells = graph.getImportableCells(mxClipboard.getCells());
	 *     var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
	 *     var parent = graph.getDefaultParent();
	 *     
	 *     graph.model.beginUpdate();
	 *     try
	 *     {
	 *       for (var i = 0; i < cells.length; i++)
	 *       {
	 *         var tmp = (mxClipboard.parents != null && graph.model.contains(mxClipboard.parents[i])) ?
	 *              mxClipboard.parents[i] : parent;
	 *         cells[i] = graph.importCells([cells[i]], delta, delta, tmp)[0];
	 *       }
	 *     }
	 *     finally
	 *     {
	 *       graph.model.endUpdate();
	 *     }
	 *     
	 *     // Increments the counter and selects the inserted cells
	 *     mxClipboard.insertCount++;
	 *     graph.setSelectionCells(cells);
	 *   }
	 * };
	 * (end)
	 * 
	 * Variable: STEPSIZE
	 * 
	 * Defines the step size to offset the cells after each paste operation.
	 * Default is 10.
	 */
	STEPSIZE: 10,

	/**
	 * Variable: insertCount
	 * 
	 * Counts the number of times the clipboard data has been inserted.
	 */
	insertCount: 1,

	/**
	 * Variable: cells
	 * 
	 * Holds the array of <mxCells> currently in the clipboard.
	 */
	cells: null,

	/**
	 * Function: setCells
	 * 
	 * Sets the cells in the clipboard. Fires a <mxEvent.CHANGE> event.
	 */
	setCells: function(cells)
	{
		mxClipboard.cells = cells;
	},

	/**
	 * Function: getCells
	 * 
	 * Returns  the cells in the clipboard.
	 */
	getCells: function()
	{
		return mxClipboard.cells;
	},
	
	/**
	 * Function: isEmpty
	 * 
	 * Returns true if the clipboard currently has not data stored.
	 */
	isEmpty: function()
	{
		return mxClipboard.getCells() == null;
	},
	
	/**
	 * Function: cut
	 * 
	 * Cuts the given array of <mxCells> from the specified graph.
	 * If cells is null then the selection cells of the graph will
	 * be used. Returns the cells that have been cut from the graph.
	 *
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be cut.
	 * cells - Optional array of <mxCells> to be cut.
	 */
	cut: function(graph, cells)
	{
		cells = mxClipboard.copy(graph, cells);
		mxClipboard.insertCount = 0;
		mxClipboard.removeCells(graph, cells);
		
		return cells;
	},

	/**
	 * Function: removeCells
	 * 
	 * Hook to remove the given cells from the given graph after
	 * a cut operation.
	 *
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be cut.
	 * cells - Array of <mxCells> to be cut.
	 */
	removeCells: function(graph, cells)
	{
		graph.removeCells(cells);
	},

	/**
	 * Function: copy
	 * 
	 * Copies the given array of <mxCells> from the specified
	 * graph to <cells>. Returns the original array of cells that has
	 * been cloned. Descendants of cells in the array are ignored.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be copied.
	 * cells - Optional array of <mxCells> to be copied.
	 */
	copy: function(graph, cells)
	{
		cells = cells || graph.getSelectionCells();
		var result = graph.getExportableCells(graph.model.getTopmostCells(cells));
		mxClipboard.insertCount = 1;
		mxClipboard.setCells(graph.cloneCells(result));

		return result;
	},

	/**
	 * Function: paste
	 * 
	 * Pastes the <cells> into the specified graph restoring
	 * the relation to <parents>, if possible. If the parents
	 * are no longer in the graph or invisible then the
	 * cells are added to the graph's default or into the
	 * swimlane under the cell's new location if one exists.
	 * The cells are added to the graph using <mxGraph.importCells>
	 * and returned.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> to paste the <cells> into.
	 */
	paste: function(graph)
	{
		var cells = null;
		
		if (!mxClipboard.isEmpty())
		{
			cells = graph.getImportableCells(mxClipboard.getCells());
			var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
			var parent = graph.getDefaultParent();
			cells = graph.importCells(cells, delta, delta, parent);
			
			// Increments the counter and selects the inserted cells
			mxClipboard.insertCount++;
			graph.setSelectionCells(cells);
		}
		
		return cells;
	}

};
