/*
	L'Ecuyer's two-sequence generator with a Bays-Durham shuffle
	on the back-end.  Schrage's algorithm is used to perform
	64-bit modular arithmetic within the 32-bit constraints of
	JavaScript.

	Bays, C. and S. D. Durham.  ACM Trans. Math. Software: 2 (1976)
			59-64.
	L'Ecuyer, P.  Communications of the ACM: 31 (1968) 742-774.
	Schrage, L.  ACM Trans. Math. Software: 5 (1979) 132-138.
*/

function uGen(old, a, q, r, m) {      // Schrage's modular multiplication algorithm
	var t;
	t = Math.floor(old / q);
	t = a * (old - (t * q)) - (t * r);
	return Math.round((t < 0) ? (t + m) : t);
}

function LEnext() {                   // Return next raw value
	var i;
	this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
	this.gen2 = uGen(this.gen2, 40692, 52774, 3791, 2147483399);
	/* Extract shuffle table index from most significant part
		 of the previous result. */
	i = Math.floor(this.state / 67108862);
	// New state is sum of generators modulo one of their moduli
	this.state = Math.round((this.shuffle[i] + this.gen2) % 2147483563);
	// Replace value in shuffle table with generator 1 result
	this.shuffle[i] = this.gen1;
	return this.state;
}

//  Return next random integer between 0 and n inclusive

function LEnint(n) {
   return Math.floor(this.next() / (1 + 2147483562 / (n + 1)));
}

//  Constructor.  Called with seed value

function LEcuyer(s) {
	var i;
	this.shuffle = new Array(32);
	this.gen1 = this.gen2 = (s & 0x7FFFFFFF);
	for (i = 0; i < 19; i++) {
			this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
	}
	// Fill the shuffle table with values
	for (i = 0; i < 32; i++) {
			this.gen1 = uGen(this.gen1, 40014, 53668, 12211, 2147483563);
			this.shuffle[31 - i] = this.gen1;
	}
	this.state = this.shuffle[0];
	this.next = LEnext;
	this.nextInt = LEnint;
}
