function isEmpty( value ){
	return /^\s*$/i.test( value );
}

function isEmail( value ){
	value = decode_utf8( trim( value ) );
	// "Borrowed" from PEAR::HTML_QuickForm
	return /^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/.test( value );
}

function isURL( value, bMulti ) {
	bMulti = bMulti||false;
	if ( !bMulti )
		return (/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test( value ));
	return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test( value );
}

function isInteger( value ) {
	return /^\d+$/.test( value );
}

function isNumber( value ) {
	return /^\d+\.{0,1}\d*$/.test( value );
}

function isMoney( value ) {
	return /^\s*\$?[\d\s\,]+\.{0,1}\s*\d*$/.test( value );
}


function markIfEmpty( id, message ) {
	var element = $( id );
	return mark( id, message, isEmpty( element.value ) );
}

function markIfNotMail( id, message ) {
	var element = $( id );
	return mark( id, message, !isEmail( element.value ) );
}

function markIfNotURL( id, message ) {
	var element = $( id );
	return mark( id, message, !isURL( element.value ) );
}

function markIfNotDate( id, message ) {
	var element = $( id );
	//return mark( id, message, !isURL( element.value ) );
}

function mark( id, message, trueFalse ){
	var element = $( id );
	if( trueFalse ) {
		_errorMessage += '<a href="javascript:setFocus(\'' + id + '\');">' + message + '</a><br />';
		element.className = 'error';
		return true;
	} else {
		element.className = '';
		return false;
	}
}

function maxLength( element, limit, counter ) {
	if( element.value.length > limit ) {
		element.value = element.value.substr( 0, limit );
		element.focus();
	}
	counter.innerHTML = ( limit - element.value.length );
}

function checkboxSelected( inputs ) {
	return isCheckedOne( inputs );
}

function isCheckedOne( inputs ) {
	var selected = false;
	for( var i=0; i<inputs.length; i++ ) {
		if( ( /^checkbox$/i.test( inputs[i].type ) || /^radio$/i.test( inputs[i].type ) ) && inputs[i].checked ) {
			selected = true;
			break;
		}
	}
	return selected;
}
/* return the number of selected checkboxes */
function checkedElements( form ) {
	var inputs = form.getElementsByTagName('tbody')[0].getElementsByTagName( 'input' );
	var total = 0;
	for( var i=0; i<inputs.length; i++ ){
		if( /^checkbox$/i.test( inputs[i].type ) && inputs[i].checked )
			total++;
	}
	return total;
}

/**
 * Tests if the given Credit Card Number 'value' seems to be valid. If optional
 * parameter 'cardType' is given, the function also checks that the number is
 * well formed for that credit card type/brand.
 *
 * @author Gonzalo Núñez <gnunezr@gmail.com>
 * @param {Object} value : The Credit Card Number to test
 * @param {Object}[Optional] cardType: The card type the number is supposed to belong to
 */
function isCreditCardNumber( value, cardType ) {
	cardType = cardType||false;
	value = value.replace( /\D/g, '' );
	var empty = /^\s*$/;
	if ( empty.test( value ) ) {
		return false;
	}
	var cardRes = [
		{ type: 'visa', regExp: /^4\d{12}(\d\d\d){0,1}$/ },	// visa
		{ type: 'mastercard', regExp: /^5[12345]\d{14}$/ },	// mastercard
		{ type: 'amex', regExp: /^3[47]\d{13}$/ },		// amex
		{ type: 'discover', regExp: /^6011\d{12}$/ },		// discover
		{ type: 'diners', regExp: /^30[012345]\d{11}$/ },	// diners
		{ type: 'diners', regExp: /^3[68]\d{12}$/ }		// diners
	];
	var valid = false;
	for( var r = 0, rl = cardRes.length; r < rl; r++ ) {
		var c = cardRes[ r ];
		if ( c.regExp.test( value ) ) {
			valid = cardType ? cardType == c.type : true;
			break;
		}
	}
/*	
	if ( valid ) {
		// mod 10 checksum algorithm 
		var revcode = ( value.replace( /\D/, '' ) );
		var checksum = 0;
		for ( var il = revcode.length - 1; -1 < il; il--) {
			current_num = parseInt( revcode[ il ], 10 );
			if ( il & 1 ) {               // Odd position 
				current_num *= 2;
			}
			// Split digits and add.
			checksum += current_num % 10;
			if (current_num > 9) {
				checksum += 1;
			}
		}
		valid = ( ( checksum % 10 ) === 0 );
	}
*/	
	return valid;
}
var _errorMessage='';
