RowReorder = function ( dt, opts ) {
	// Sanity check that we are using DataTables 1.10 or newer
	if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.8' ) ) {
		throw 'DataTables RowReorder requires DataTables 1.10.8 or newer';
	}

	// User and defaults configuration object
	this.c = $.extend( true, {},
		DataTable.defaults.rowReorder,
		RowReorder.defaults,
		opts
	);

	// Internal settings
	this.s = {
		/** @type {integer} Scroll body top cache */
		bodyTop: null,

		/** @type {DataTable.Api} DataTables' API instance */
		dt: new DataTable.Api( dt ),

		/** @type {function} Data fetch function */
		getDataFn: DataTable.ext.oApi._fnGetObjectDataFn( this.c.dataSrc ),

		/** @type {array} Pixel positions for row insertion calculation */
		middles: null,

		/** @type {Object} Cached dimension information for use in the mouse move event handler */
		scroll: {},

		/** @type {integer} Interval object used for smooth scrolling */
		scrollInterval: null,

		/** @type {function} Data set function */
		setDataFn: DataTable.ext.oApi._fnSetObjectDataFn( this.c.dataSrc ),

		/** @type {Object} Mouse down information */
		start: {
			top: 0,
			left: 0,
			offsetTop: 0,
			offsetLeft: 0,
			nodes: []
		},

		/** @type {integer} Window height cached value */
		windowHeight: 0
	};

	// DOM items
	this.dom = {
		/** @type {jQuery} Cloned row being moved around */
		clone: null,

		/** @type {jQuery} DataTables scrolling container */
		dtScroll: $('div.dataTables_scrollBody', this.s.dt.table().container())
	};

	// Check if row reorder has already been initialised on this table
	var settings = this.s.dt.settings()[0];
	var exisiting = settings.rowreorder;
	if ( exisiting ) {
		return exisiting;
	}

	settings.rowreorder = this;
	this._constructor();
}
RowReorder provides the ability in DataTables to click and drag rows to
reorder them. When a row is dropped the data for the rows effected will be
updated to reflect the change. Normally this data point should also be the
column being sorted upon in the DataTable but this does not need to be the
case. RowReorder implements a "data swap" method - so the rows being
reordered take the value of the data point from the row that used to occupy
the row's new position.

Initialisation is done by either:

* `rowReorder` parameter in the DataTable initialisation object
* `new $.fn.dataTable.RowReorder( table, opts )` after DataTables
  initialisation.

 @class
 @param {object} settings DataTables settings object for the host table
 @param {object} [opts] Configuration options
 @requires jQuery 1.7+
 @requires DataTables 1.10.7+