//  -----   feel free to use this stuff   ---   play with it   ---   copy as You  like   -----
//  -----   but leave this authors 2 lines untouched: pseliger@gmx.net [november 2007]   -----
//
//  extended javascript-api-methods       :
//  * jsApi-extension-name / file-name    : "jsApi.Math.randomize.dev.js"
//  * original download-location          : "http://www.pseliger.de/jsExtendedApi/jsApi.Math.randomize.dev.js"
//
//  second review       :november 28-2007 - code refurnishing in order to remain state of the art.
//  first review        :november 08-2004 - introducing new method "Math.getNOutOfM" that returns an array of randomly chosen indices out of a given set.
//  first public release:    june 27-2003 - an additional randomize function that generates more ideal rows of numbers than the system implementet "Math.random()" does.
//

//  eine zusaetzliche zufallsfunktion, die idealere reihen als die systemimplementierte "Math.random()" liefert;
//  - parameterlose oder parameterungueltige aufrufe erhalten als rueckgabeparameter eine 'gebrochene zahl', deren wert zwischen 0 und kleiner 1 liegt;
//  - aufrufe mit genau einem und noch dazu gueltigem ganzzahligen parameter geben eine ganze zahl zurueck, deren wert von 0 bis inklusive aufrufendem parameter reichen kann;
//  - aufrufe mit genau zwei und noch dazu gueltigen ganzzahligen parametern geben eine ganze zahl zurueck, deren wert vom minimum bis inklusive maximum der beiden aufrufenden parameter reichen kann;
//  - sollten im letztgenannten fall beide parameter den gleichen wert haben, wird ein wert entsprechend dem erstgenannten fall zurueckgegeben;
//
//  an additional randomize function that generates more ideal rows of numbers than the system implementet "Math.random()" does;
//  - calls with invalid or without any parameters will return a 'fraction number' thats value ranges from 0 to less than 1;
//  - calls with exactly one valid integer parameter return an integer as well thats value ranges from 0 to the calling parameter inclusive;
//  - calls with exactly two valid integer parameters return an integer thats value ranges from the minimum to the maximum inclusive of both calling parameters;
//  - if both parameters of the last mentioned case feature the same value a value that correspond to the first mentioned example gets returned;
//


	Math.randomize = (function () {

		var a = 4096, b = 150889, c = 714025;						// prime numbers are taken from the example out of David Flanagans
		var startValue = ((new Date()).getTime() % c);	// _"JavaScript - The definitive Guide (second edition)"_js_bible_

		return (function(/*[minValue:[number|Number|string|String][INT][, maxValue:[number|Number|string|String][INT]]]*/) {

			var minValue = 0, maxValue = 0;
			if (arguments.length == 1) {
				maxValue = ((isNaN(Number(arguments[0]))) ? (maxValue) : (parseInt(arguments[0], 10)));
			} else if (arguments.length == 2) {
				minValue = ((isNaN(Number(arguments[0]))) ? (minValue) : (parseInt(arguments[0], 10)));
				maxValue = ((isNaN(Number(arguments[1]))) ? (maxValue) : (parseInt(arguments[1], 10)));
			}
			if (maxValue < minValue) {
				var tmpValue = minValue;
				minValue = maxValue;
				maxValue = tmpValue;
				delete tmpValue;
			}
			startValue = (((startValue * a) + b) % c);
		//return Math.round(maxValue * startValue / c);

			return ((minValue == maxValue) ? (startValue / c) : (minValue + Math.floor((maxValue - minValue + 1) * startValue / c)));
		});

	})();/*

//BrainJar Crunchinator:
	Math.randomize = (function(){var a=4096,b=150889,c=714025;var startValue=((new Date()).getTime()%c);return(function(){var minValue=0,maxValue=0;if(arguments.length==1){maxValue=((isNaN(Number(arguments[0])))?(maxValue):(parseInt(arguments[0],10)));}else if(arguments.length==2){minValue=((isNaN(Number(arguments[0])))?(minValue):(parseInt(arguments[0],10)));maxValue=((isNaN(Number(arguments[1])))?(maxValue):(parseInt(arguments[1],10)));}if(maxValue<minValue){var tmpValue=minValue;minValue=maxValue;maxValue=tmpValue;delete tmpValue;}startValue=(((startValue*a)+b)%c);return((minValue==maxValue)?(startValue/c):(minValue+Math.floor((maxValue-minValue+1)*startValue/c)));});})();

//http://dean.edwards.name/packer/
	Math.randomize = (function(){var a=4096,b=150889,c=714025;var startValue=((new Date()).getTime()%c);return(function(){var minValue=0,maxValue=0;if(arguments.length==1){maxValue=((isNaN(Number(arguments[0])))?(maxValue):(parseInt(arguments[0],10)))}else if(arguments.length==2){minValue=((isNaN(Number(arguments[0])))?(minValue):(parseInt(arguments[0],10)));maxValue=((isNaN(Number(arguments[1])))?(maxValue):(parseInt(arguments[1],10)))}if(maxValue<minValue){var tmpValue=minValue;minValue=maxValue;maxValue=tmpValue;delete tmpValue}startValue=(((startValue*a)+b)%c);return((minValue==maxValue)?(startValue/c):(minValue+Math.floor((maxValue-minValue+1)*startValue/c)))})})(); // standard packed
	Math.randomize = (function(){var a=4096,b=150889,c=714025;var f=((new Date()).getTime()%c);return(function(){var d=0,maxValue=0;if(arguments.length==1){maxValue=((isNaN(Number(arguments[0])))?(maxValue):(parseInt(arguments[0],10)))}else if(arguments.length==2){d=((isNaN(Number(arguments[0])))?(d):(parseInt(arguments[0],10)));maxValue=((isNaN(Number(arguments[1])))?(maxValue):(parseInt(arguments[1],10)))}if(maxValue<d){var e=d;d=maxValue;maxValue=e;delete e}f=(((f*a)+b)%c);return((d==maxValue)?(f/c):(d+Math.floor((maxValue-d+1)*f/c)))})})(); // variables shrinked

*/



	Array.prototype.shuffle = (function () {

		var randomize = ((typeof Math.randomize == "function") ? (Math.randomize) : (Math.random));

		return (function () {

			this.sort(function () {

				return (0.5 - randomize());
			});
		});

	})();/*

//BrainJar Crunchinator:
	Array.prototype.shuffle = (function(){var randomize=((typeof Math.randomize=="function")?(Math.randomize):(Math.random));return(function(){this.sort(function(){return(0.5-randomize());});});})();

//http://dean.edwards.name/packer/
	Array.prototype.shuffle = (function(){var randomize=((typeof Math.randomize=="function")?(Math.randomize):(Math.random));return(function(){this.sort(function(){return(0.5-randomize())})})})(); // standard packed
	Array.prototype.shuffle = (function(){var a=((typeof Math.randomize=="function")?(Math.randomize):(Math.random));return(function(){this.sort(function(){return(0.5-a())})})})(); // variables shrinked

*/ /*

	test at [http://www.squarefree.com/shell/shell.html]:

	Math.randomize = (function(){var a=4096,b=150889,c=714025;var f=((new Date()).getTime()%c);return(function(){var d=0,maxValue=0;if(arguments.length==1){maxValue=((isNaN(Number(arguments[0])))?(maxValue):(parseInt(arguments[0],10)))}else if(arguments.length==2){d=((isNaN(Number(arguments[0])))?(d):(parseInt(arguments[0],10)));maxValue=((isNaN(Number(arguments[1])))?(maxValue):(parseInt(arguments[1],10)))}if(maxValue<d){var e=d;d=maxValue;maxValue=e;delete e}f=(((f*a)+b)%c);return((d==maxValue)?(f/c):(d+Math.floor((maxValue-d+1)*f/c)))})})();
	Array.prototype.shuffle = (function(){var a=((typeof Math.randomize=="function")?(Math.randomize):(Math.random));return(function(){this.sort(function(){return(0.5-a())})})})();
	var arr = [0,1,2,3,4,5,6,7,8,9];
	arr.shuffle();
	alert(arr);

*/



	Math.getNOutOfM = (function() {

	//var randomize = ((typeof Math.randomize == "function") ? (Math.randomize) : (Math.random));
		var randomize = ((typeof Math.randomize == "function") ? (Math.randomize) : (function (min, max) {

			min = Math.abs(parseInt(min, 10));
			max = Math.abs(parseInt(max, 10));
			var diff = Math.abs(max - min);

			return ((isNaN(diff) || (diff === 0)) ? (Math.random()) : (Math.min(min, max) + Math.floor((diff + 1) * Math.random())));
		}));

		return (function(/*amountOfIndicesToGet:[number|Number|string|String][INT], outOfASetContainingMElements:[number|Number|string|String][INT]*/) {

			var arr = [];
			if (arguments.length == 2) {

				var idcAmount = ((isNaN(Number(arguments[0]))) ? (0) : (parseInt(arguments[0], 10)));
				var elmAmount = ((isNaN(Number(arguments[1]))) ? (0) : (parseInt(arguments[1], 10)));
				if ((idcAmount >= 1) && (elmAmount >= 1) && (idcAmount <= elmAmount)) {

					var i, series = [];
					for (i=1; i<=elmAmount; ++i) {
						series.push(i);
					}
					for (i=0; i<idcAmount; ++i) {
					//alert("series.length : " + series.length + "\narr.length : " + arr.length);
						series.shuffle();
						arr = arr.concat(series.splice(randomize(0, (series.length - 1)), 1));
					}
				}
			}
			return arr.sort(function (a, b) {
				return ((a < b) ? (-1) : ((a > b) ? (1) : (0)));
			});
		});

	})();/*

//BrainJar Crunchinator:
	Math.getNOutOfM = (function(){var randomize=((typeof Math.randomize=="function")?(Math.randomize):(function(min,max){min=Math.abs(parseInt(min,10));max=Math.abs(parseInt(max,10));var diff=Math.abs(max-min);return((isNaN(diff)||(diff===0))?(Math.random()):(Math.min(min,max)+Math.floor((diff+1)*Math.random())));}));return(function(){var arr=[];if(arguments.length==2){var idcAmount=((isNaN(Number(arguments[0])))?(0):(parseInt(arguments[0],10)));var elmAmount=((isNaN(Number(arguments[1])))?(0):(parseInt(arguments[1],10)));if((idcAmount>=1)&&(elmAmount>=1)&&(idcAmount<=elmAmount)){var i,series=[];for(i=1;i<=elmAmount;++i){series.push(i);}for(i=0;i<idcAmount;++i){series.shuffle();arr=arr.concat(series.splice(randomize(0,(series.length-1)),1));}}}return arr.sort(function(a,b){return((a<b)?(-1):((a>b)?(1):(0)));});});})();

//http://dean.edwards.name/packer/
	Math.getNOutOfM = (function(){var randomize=((typeof Math.randomize=="function")?(Math.randomize):(function(min,max){min=Math.abs(parseInt(min,10));max=Math.abs(parseInt(max,10));var diff=Math.abs(max-min);return((isNaN(diff)||(diff===0))?(Math.random()):(Math.min(min,max)+Math.floor((diff+1)*Math.random())))}));return(function(){var arr=[];if(arguments.length==2){var idcAmount=((isNaN(Number(arguments[0])))?(0):(parseInt(arguments[0],10)));var elmAmount=((isNaN(Number(arguments[1])))?(0):(parseInt(arguments[1],10)));if((idcAmount>=1)&&(elmAmount>=1)&&(idcAmount<=elmAmount)){var i,series=[];for(i=1;i<=elmAmount;++i){series.push(i)}for(i=0;i<idcAmount;++i){series.shuffle();arr=arr.concat(series.splice(randomize(0,(series.length-1)),1))}}}return arr.sort(function(a,b){return((a<b)?(-1):((a>b)?(1):(0)))})})})(); // standard packed
	Math.getNOutOfM = (function(){var f=((typeof Math.randomize=="function")?(Math.randomize):(function(a,b){a=Math.abs(parseInt(a,10));b=Math.abs(parseInt(b,10));var c=Math.abs(b-a);return((isNaN(c)||(c===0))?(Math.random()):(Math.min(a,b)+Math.floor((c+1)*Math.random())))}));return(function(){var c=[];if(arguments.length==2){var d=((isNaN(Number(arguments[0])))?(0):(parseInt(arguments[0],10)));var e=((isNaN(Number(arguments[1])))?(0):(parseInt(arguments[1],10)));if((d>=1)&&(e>=1)&&(d<=e)){var i,series=[];for(i=1;i<=e;++i){series.push(i)}for(i=0;i<d;++i){series.shuffle();c=c.concat(series.splice(f(0,(series.length-1)),1))}}}return c.sort(function(a,b){return((a<b)?(-1):((a>b)?(1):(0)))})})})(); // variables shrinked

*/ /*

	test at [http://www.squarefree.com/shell/shell.html]:

	Math.randomize = (function(){var a=4096,b=150889,c=714025;var f=((new Date()).getTime()%c);return(function(){var d=0,maxValue=0;if(arguments.length==1){maxValue=((isNaN(Number(arguments[0])))?(maxValue):(parseInt(arguments[0],10)))}else if(arguments.length==2){d=((isNaN(Number(arguments[0])))?(d):(parseInt(arguments[0],10)));maxValue=((isNaN(Number(arguments[1])))?(maxValue):(parseInt(arguments[1],10)))}if(maxValue<d){var e=d;d=maxValue;maxValue=e;delete e}f=(((f*a)+b)%c);return((d==maxValue)?(f/c):(d+Math.floor((maxValue-d+1)*f/c)))})})();
	Array.prototype.shuffle = (function(){var a=((typeof Math.randomize=="function")?(Math.randomize):(Math.random));return(function(){this.sort(function(){return(0.5-a())})})})();
	Math.getNOutOfM = (function(){var f=((typeof Math.randomize=="function")?(Math.randomize):(function(a,b){a=Math.abs(parseInt(a,10));b=Math.abs(parseInt(b,10));var c=Math.abs(b-a);return((isNaN(c)||(c===0))?(Math.random()):(Math.min(a,b)+Math.floor((c+1)*Math.random())))}));return(function(){var c=[];if(arguments.length==2){var d=((isNaN(Number(arguments[0])))?(0):(parseInt(arguments[0],10)));var e=((isNaN(Number(arguments[1])))?(0):(parseInt(arguments[1],10)));if((d>=1)&&(e>=1)&&(d<=e)){var i,series=[];for(i=1;i<=e;++i){series.push(i)}for(i=0;i<d;++i){series.shuffle();c=c.concat(series.splice(f(0,(series.length-1)),1))}}}return c.sort(function(a,b){return((a<b)?(-1):((a>b)?(1):(0)))})})})();
	alert(Math.getNOutOfM(6, 49));
*/