/*	js_lib.js
	copyleft Thomas Baspeyras 2004-2005

index :
	Array.prototype.add(element)
	Array.prototype.append(that)
	Array.prototype.has(element)
	Array.prototype.push([...]) for IE < 5.5
	Array.prototype.random([from], [to])
	Array.prototype.randomIndex([from], [to])

	debug([...])

	Math.nxor(a, b)
	Math.range(minLimit, value, maxLimit)
	Math.xor(a, b)

	String.prototype.has(word)
*/

Array.prototype.add = function(element) {
/*	a method to add an element if it is not yet present
	une méthode pour ajouter un élément si il n'est pas déjà présent
*/
	for (var i = 0; i < this.length; i++) if (this[i] == element) return;
	this.push(element);
}

Array.prototype.append = function(that) {
/*	a method to append another array to this one
	une méthode pour ajouter un autre tableau à celui-ci
*/
	for (var i = 0; i < that.length; i++) this.push(that[i]);
}

Array.prototype.has = function(element) {
/*	a method to check the existence of an element
	une méthode pour vérifier la présence d'un élément
*/
	for (var i = 0; i < this.length; i++) if (this[i] == element) return true;
	return false;
}

if (typeof Array.prototype.push == "undefined") {
/*	Just to save IE prior to 5.5 - I should not do that, oh no...
	Juste pour sauver IE antérieur à 5.5 - je devrais pas faire ça, oh non...
*/
	Array.prototype.push = function() {
	/*	a method to add elements
		une méthode pour ajouter des éléments
	*/
		for (var i = 0; i < arguments.length; i++) {
			this[this.length] = arguments[i];
		}
		return this.length;
	}
}

Array.prototype.random = function(from, to) {
/*	a method to pick an element randomly
	une méthode de tirage au sort d'un élément
*/
	if (!from) from = 0;
	if (!to) to = this.length; else to = 1*to + 1;
	return this[Math.floor((to - from) * Math.random()) + 1*from];
}

Array.prototype.randomIndex = function(from, to) {
/*	a method to pick an index randomly
	une méthode de tirage au sort d'un index
*/
	if (!from) from = 0;
	if (!to) to = this.length; else to = 1*to + 1;
	return Math.floor((to - from) * Math.random()) + 1*from;
}

function debug() {
/*	somehow like 'alert' but display properties of its arguments
	un peu comme "alert" mais affiche les propriétés de ces arguments
*/
	function thingToString(thing) {
		var toReturn = "";
		switch (typeof thing) {
			case "boolean": toReturn += "boolean: " + thing; break;
			case "function": toReturn += "function: " + thing; break;
			case "null": toReturn += "null"; break;
			case "number": toReturn += "number: " + thing; break;
			case "object": toReturn += thing; break;
			case "string": toReturn += "\"" + thing + "\""; break;
			case "undefined": toReturn += "undefined"; break;
			default: toReturn += object + "(" + typeof thing + " ?)";
		}
		return toReturn;
	}

	var toDisplay = "";
	for (var i = 0; i < arguments.length; i++) {
		if (i > 0) toDisplay += "\n--------------------\n";
		var thing  = arguments[i];
		if (typeof thing == "object") {
			toDisplay += "{ ";
			var first = true;
			for (var j in thing) {
				if (typeof thing[j] != "function") {
					if (first) first = false; else toDisplay += "; ";
					toDisplay += j + " = " + thingToString(thing[j]);
				}
			}
			toDisplay += " }";
		}
		else toDisplay += thingToString(thing);
	}
	alert(toDisplay);
	return arguments[0];
}

Math.hexadecimal = function (n) {
/*	decimal to hexadecimal conversion
	conversion de décimal à hexadécimal
*/
	var figures = new Array;
	do {
		var quotient = Math.floor(n / 16);
		var remainder = n % 16;
		if (remainder > 9) figures.push(String.fromCharCode(55 + 1*remainder));
		else figures.push(remainder);
		n = quotient;
	} while (n > 0);
	return (figures.reverse()).join("");
}

Math.nxor = function(a, b) {
/*	'not exclusive or', equivalence relation
	"non ou exclusif", relation d'équivalence
*/
	return ((a && b) || (!a && !b));
}

Math.range = function(minLimit, value, maxLimit) {
/*	limits numeric value inside a given range
	limite une valeur numérique à une plage donnée
*/
	if (minLimit < maxLimit) return this.max(minLimit, this.min(maxLimit, value));
	else return this.max(maxLimit, this.min(minLimit, value));
}

Math.xor = function(a, b) {
/*	'exclusive or', non-equivalence relation
	"ou exclusif", relation de non équivalence
*/
	return ((a || b) && (!a || !b));
}

String.prototype.has = function(word) {
/*	a method to check the existence of a word
	une méthode pour vérifier la présence d'un mot
*/
	return (this.split(" ")).has(word);
}
