/**
 * Returns a new string in which leading and trailing spaces have been removed
 */
String.prototype.trimSpaces = function() {
	return this.replace(/^\s+/, '').replace(/\s+$/, '');
}

var TAXIUtils = {
	
	/**
	 * Swaps the src of an image and saves its old value for an eventual restoreImage
	 * |imgOrId| is an Image (or DOM) object or it can be a string representing the id
	 * of an image. Requires DOM support.
	 */
	swapImage : function(imgOrId, newPath) {
		var imgElement = TAXIUtils.getElement(imgOrId);
		if(imgElement && imgElement.src) {
			// We create a new attribute in this image to store its original src
			imgElement.origSrc = imgElement.src;
			imgElement.src = newPath;
			return true;
		}
		return false;
	},
	
	/**
	 * Restores the src of an image to the one before a swapImage() was done.
	 */
	restoreImage : function(imgOrId) {
		var imgElement = TAXIUtils.getElement(imgOrId);
		if(imgElement && imgElement.origSrc) {
			imgElement.src = imgElement.origSrc;
		}
		return false;
	},
	
	getElement : function(strOrObj) {
		if(typeof strOrObj != "string")
			return strOrObj;
		if(document.getElementById)
			return document.getElementById(strOrObj);
		return null;
	},
	
	/**
	 * Will return the first image element (first level) of a specified node.
	 * Generally used by <a> elements that need to change their <img> tag inside
	 * on mouse over.
	 */
	getFirstImage : function(nodeOrStr) {
		return TAXIUtils.getFirstElement("img", nodeOrStr);
	},
	
	/**
	 * Returns the first element named |elemName| in the |node| element.
	 * First level only. Requires DOM
	 */
	getFirstElement : function(elemName, nodeOrStr) {
		elemName = elemName.toUpperCase();
		var node = TAXIUtils.getElement(nodeOrStr);
		if(node && node.childNodes) {
			for(var i=0,iEnd=node.childNodes.length; i<iEnd; i++) {
				var child = node.childNodes[i];
				if(child.nodeName.toUpperCase() == elemName)
					return child;
			}
		}
		return null;
	},
	
	/**
	 * Returns true if the frequently called DOM methods are supported
	 */
	isDOMSupported : function() {
		return (document.getElementById != undefined &&
						document.createElement != undefined &&
						document.getElementsByTagName != undefined);
	},
	
	/**
	 * Returns a number in money format
	 */
	moneyFormat : function(nb, decimalStr) {
		return this.decimalFormat(nb, 2, decimalStr);
	},
	
	/**
	 * Returns a number (or a string) formatted as a string decimal number
	 * with the specified number of decimals.
	 */
	decimalFormat : function(nb, nbDecimals, decimalStr) {
		if(typeof nbDecimals != "number" || nbDecimals < 0)
			nbDecimals = 0;
			
		if(typeof decimalStr != "string")
			decimalStr = ".";
			
		if(typeof nb != "number") {
			nb = nb.toString().replace(",", ".");
			nb = parseFloat(nb);
		}
		
		if(nb == NaN)
			return null;
			
		var strNb = nb.toString();
		var indexOfSeparator = strNb.indexOf(".");
		
		if(nbDecimals == 0) {
			if(indexOfSeparator > -1) {
				strNb = strNb.substring(0, indexOfSeparator);
			}
		} else {
			var currentNumberOfDecimals;
			// If we don't yet have decimals, we add a .
			if(indexOfSeparator == -1) {
				strNb += ".";
				currentNumberOfDecimals = 0;
			} else {
				currentNumberOfDecimals = strNb.length - (indexOfSeparator + 1);
			}
			if(currentNumberOfDecimals >= nbDecimals) {
				strNb = strNb.substring(0, indexOfSeparator + nbDecimals + 1);
			} else {
				for(var i=currentNumberOfDecimals, iEnd=nbDecimals; i<iEnd; i++) {
					strNb += "0";
				}
			}
			
		}
		return strNb.replace(".", decimalStr);
	}
}

/**
 * List of frequently used regular expressions
 */
TAXIUtils.regExp = {
	email : /^[a-z0-9_\-]+(\.[a-z0-9_\-]+)*@[a-z0-9_\-]+(\.[a-z0-9_\-]+)+$/i
}

TAXIUtils.formValidation = {
	/**
	 * Returns true if the field doesn't have a value entered or selected
	 */
	isFieldEmpty : function(field, trimSpaces) {
		var value = this.getFieldValue(field);
		if(value == undefined)
			return true;
		return ((trimSpaces ? value.trimSpaces() : value) == "");
	},
	
	/**
	 * Validates the value of a field with a regular expression
	 */
	isFieldValid : function(field, regExp) {
		var value = this.getFieldValue(field);
		if(!regExp || !regExp.test)
			return false;
		return regExp.test(value);
	},
	
	/**
	 * Shortcut to isFieldValid with a pre-defined regular expression
	 */
	isEmailFieldValid : function(field) {
		return this.isFieldValid(field, TAXIUtils.regExp.email);
	},
	
	/**
	 * Returns the value of the field. Will be supported selects, inputs, checkboxes, radio, ...
	 * For now, we only have
	 * - inputs
	 */
	getFieldValue : function(field) {
		return field.value;
	}
}