function initValidation(fieldName)
{
	var fieldJQ = $('input[name="' + fieldName + '"]');
	var field = fieldJQ.get(0);
	if(!field)
	{
		alert("Field not found: " + fieldName);
	}
	else
	{
		if(/text/i.test(field.type))
		{
			field.onblur = field.onchange = field.onkeypress = validateField;
		}
		if(/checkbox/.test(field.type))
		{
			field.onclick = validateField;
		}
		field.rule = rule;
	}
}

for(var i = 0; i < validationRules.length; i++)
{
	var rule = validationRules[i];

	switch(rule.type)
	{
		case 'regex':
			initValidation(rule.field);
			break;
		case 'atLeastOne':
			for(var j = 0; j < rule.fields.length; j++)
			{
				initValidation(rule.fields[j]);
			}
			break;
	}
}

var messageQueue = [];

function validateField()
{
	var divId = (this.rule.errorDivId || this.id) + "Error";
	var errorDiv = _.id(divId);

	var valid = true;

	switch(this.rule.type)
	{
		case 'regex':
			valid = this.rule.regex.test(this.value);
			break;
		case 'atLeastOne':
			valid = false;
			for(var i = 0; i < this.rule.fields.length; i++)
			{
				var field = $('input[name="' + this.rule.fields[i] + '"]').get(0);
				if(/text/i.test(field.type) && field.value ||
				/checkbox/i.test(field.type) && field.checked)
				if(field.value || field.checked)
				{
					valid = true;
					break;
				}
			}
			break;
	}

	var html = '';

	if(!valid)
	{
		html = '<p>' + this.rule.errorMessage + '</p>';
	}

	messageQueue.push({id:divId, html:html});
	if(errorDiv.timeout)
	{
		clearTimeout(errorDiv.timeout);
	}
	errorDiv.timeout = setTimeout(displayError, 300);
}

function displayError()
{
	var details;
	while(details = messageQueue.shift())
	{
		var errorDiv = _.id(details.id);
		errorDiv.innerHTML = details.html;
		errorDiv.timeout = 0;
	}
}

