﻿/** Submit-button attributes:
*   onclick="return validate(this);" // required
*   onclick="return validate(this,summaryElementID);" // Place an errorsummary in the summaryElement
*   errormessage=CDATA - the error message in the summary
*/

/** INPUT attributes
* validation=required?,pattern? - which validator to use. Separate with whitespace
* pattern=CDATA - a regular expression to be used with the patternvalidator
* (validationtype)message=CDATA - the error message for the specific input-element
*/

/* Validation functions */
var validationFunctions = new Object();
validationFunctions['required'] = isRequired;
validationFunctions['pattern'] = isPattern;
validationFunctions['url'] = isURL;
validationFunctions['email'] = isEmail;
validationFunctions['negatepattern'] = isNegatePattern;
validationFunctions['selectone'] = isSelected;
validationFunctions['compare'] = isSame;
validationFunctions['minlength'] = isMinLength;
validationFunctions['simpleemail'] = isEmailSimple;
validationFunctions['compareend'] = isEqualEnd;

function isEqualEnd(obj)
{
	var thisValue = obj.value;
	
	if (thisValue.length == 0)
		return false;

	if (obj.getAttribute("compareto") == null)
		return false;
		
	var otherValue = document.getElementById(obj.getAttribute("compareto")).value;
	
	return getEnd(thisValue) == getEnd(otherValue);
}

function getEnd(string)
{
	if (string.indexOf('@') >= 0)
		string = string.substring(string.indexOf('@') + 1);
	while (string.indexOf('.') != string.lastIndexOf('.'))
		string = string.substring(string.indexOf('.') + 1)
	return string;
}

function isRequired(obj)
{
	return isPattern(obj, '\\S+');
}

function isMinLength(obj)
{
	var minlength = parseFloat(obj.getAttribute('minlength'));
	return obj.value.length >= minlength;
}

function isPattern(obj,pattern,flags)
{
	if (!pattern) pattern = obj.getAttribute('pattern');
	flags = (flags) ? flags : "";
		
	var regExp = new RegExp(pattern,flags);
	var correct = regExp.test(obj.value);
	
	return correct;
}

function isSelected(obj)
{
	if (obj.type == "select-one")
	{
		return obj.selectedIndex != 0;	
	}
	if (obj.type == "checkbox")
	{
		return obj.checked;
	}
	if (obj.type == "radio")
	{
		objects = document.getElementsByName(obj.name);
		var selected = false;
		for (i = 0; i < objects.length && !selected; i++)
		{
			selected = objects[i].selected;			
		}
		return selected;
	}
	else
		return true;
}

function isNegatePattern(obj)
{
	return !isPattern(obj);
}

function isURL(obj)
{
	return isPattern(obj,'^((ht|f)tp(s?)\:\/\/|~/|/)?([\\w]+:\\w+@)?([a-zA-Z]{1}([\\w\-]+\\.)+([\\w]{2,5}))(:[\\d]{1,5})?((/?\\w+/)+|/?)(\\w+\.[\\w]{3,4})?((\\?\\w+(=\\w+)?)(&\\w+(=\\w+)?)*)?',"i");
}

function isSame(obj)
{
	if (obj.getAttribute("compareto") != null)
	{
		var elm = document.getElementById(obj.getAttribute("compareto"));
		if (elm != null)
			return obj.value == elm.value;
		else
			return false;	
	}
	else
		return false;
}

function isEmailSimple(obj)
{
	return isPattern(obj,'[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?',"i");
}

function isEmail(obj)
{
	var valid = isPattern(obj,'[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?',"i");
	
	if (!valid)
		return false;
		
	// See if this address has already been checked
	if (validationFunctions["emailAddress"] && validationFunctions["emailAddress"] == obj.value)
		return validationFunctions["emailValid"];
	
	checkEmail(obj, obj.value);

	return true;
}

function checkEmail(obj, email)
{
	if (Browser.Engine.trident && Browser.Engine.version == 4)
		// Disable this advanced check for IE6
		return;

	var request = new Request({ url: '/ValidateEmail.aspx?' + email,
		onSuccess: function(responseText, responseXML)
		{
			var firstLine = responseText.substring(0, responseText.indexOf('\r\n'));

			validationFunctions['emailValid'] = (firstLine != 'invalid');
			validationFunctions['emailAddress'] = email;

			validateField(obj, validationFunctions['placeholderID']);
		}
	});

	request.send();
}

// Don't remove
function empty()
{
	return true;
}

/* Style */
var validationStyle = new Object();
validationStyle['valid'] = function()
{
	var obj = arguments[0];
	if (obj)
	{
		obj.style.borderColor = "black";
	}
};
validationStyle['invalid'] = function()
{
	var obj = arguments[0];
	if (obj)
	{
		obj.style.borderColor = "red";
	}  
};
 

var placeholders = new Object();
var idPrefix = "__validationsummary__";



function validate(submitButton,placeholderID)
{
	if (placeholderID && !placeholders[placeholderID]) 
	{
		placeholders[placeholderID] = new Placeholder(document.getElementById(placeholderID));
	}   
	
	var valid = true;
	var focused = false;
	
	var elements = (arguments.length > 2) ? findElements(arguments) : theForm.elements;
	
	if (placeholderID)
	{
		placeholders[placeholderID].errorList.clear();
		placeholders[placeholderID].errorMessage = submitButton.getAttribute('errormessage');
	}
	
	for (var i = 0; i < elements.length; i++)
	{
		var error = checkField(elements[i]);
		if (error)
		{
			if (placeholderID)
				placeholders[placeholderID].errorList.add(error);
			
			if (!focused)
			{
				if (!elements[i].disabled && elements[i].style.display != 'none')
				{
					elements[i].focus();
					focused = true;
				}
			}
			valid = false; 
		}

		markField(elements[i], error ? false : true);
	}
	
	if (!valid && placeholderID)
		placeholders[placeholderID].generateList();

	return valid;
}

// For asyncrously adding validation errors
function addValidationError(obj, placeHolderID)
{
	if (! placeHolderID)
		return;
		
	if (!placeholders[placeholderID])
		placeholders[placeholderID] = new Placeholder(document.getElementById(placeholderID));
	
	placeholders[placeholderID].errorList.clear(obj);
	if (error)
		placeholders[placeholderID].errorList.add(error);
	placeholders[placeholderID].generateList();
}

function validateField(obj, placeholderID)
{
	if (placeholderID && !placeholders[placeholderID])
	{
		placeholders[placeholderID] = new Placeholder(document.getElementById(placeholderID));
		validationFunctions["placeholderID"] = placeholderID;
	}
	
	var valid = true;
	var error = checkField(obj);
	
	if (placeholderID)
	{
		placeholders[placeholderID].errorList.clear(obj);
		if (error)
			placeholders[placeholderID].errorList.add(error);
		placeholders[placeholderID].generateList();
	}

	valid = (error) ? false : true;
	
	markField(obj, valid);
	return valid;
}

function checkField(obj)
{
	var req = obj.getAttribute("validation");
	if (!req) return null;
	var reqs = req.split(' ');
	
	var error = null;
	for (var i = 0; i < reqs.length && !error; i++)
	{
		if (!validationFunctions[reqs[i]])
			validationFunctions[reqs[i]] = empty;
		var elmValid = validationFunctions[reqs[i]](obj);
		if (!elmValid)
			error = new Error(obj,reqs[i],obj.getAttribute(reqs[i]+"message"));
 
	}

	return error;
}

function markField(obj,valid)
{
	if (valid)
	{
		validationStyle['valid'](obj);  
	}
	else
	{
		validationStyle['invalid'](obj);
	}   
}

function findElements(argumentList)
{
	var elements = new Array();
	for (var i = 2; i < argumentList.length; i++)
	{
		elements[elements.length] = document.getElementById(argumentList[i]);
	}
	return elements;	
}

function Placeholder(element)
{
	if (!element)
		return;
	this.element = element;
	this.errorMessage = "";
	this.errorList = new ErrorList();
	this.generateList = function()
	{
		this.clearList();
		
		if (this.errorList.errors.length > 0)
		{
			var summary = document.createElement('div');
			summary.setAttribute("id",idPrefix+this.element.id);
			summary.className = "validationsummary";
		
			if (this.errorMessage)
			{
				var summaryHeader = document.createElement('div');
				summaryHeader.className = "validationsummaryheader";
				summaryHeader.appendChild(document.createTextNode(this.errorMessage));
	 
				summary.appendChild(summaryHeader);
			}
			var list = generateErrorList(this.errorList.errors);
			if (list.childNodes.length > 0)
				summary.appendChild(list);
			
			element.appendChild(summary);
		}
	}
	
	this.clearList = function()
	{
		var prevSummary = document.getElementById(idPrefix+this.element.id);
		if (prevSummary)
			this.element.removeChild(prevSummary);
	}	
}

function generateErrorList(errors)
{
	var list = document.createElement("ul");
	for (var i = 0; i < errors.length; i++)
	{
		if (errors[i].message)
		{
			var listItem = document.createElement("li");
			listItem.appendChild(document.createTextNode(errors[i].message));
			list.appendChild(listItem);
		}
	}
	return list;
}


function Error(obj,type,message)
{
	this.object = obj;
	this.type = type;
	this.message = message;
}

function ErrorList()
{
	this.errors = new Array();
	this.add = function(error)
	{
		var idx = this.indexOf(error);
		if (idx > -1)
			this.errors[idx] = error;
		else
			this.errors[this.errors.length] = error;
	}
	
	this.indexOf = function(error)
	{
		var idx = -1;
		for (var i = 0; i < this.errors.length && idx == -1; i++)
		{
			if (this.errors[i].object == error.object &&
			this.errors[i].type == error.type &&
			this.errors[i].message == error.message)
				idx = i;
		}
		return i;
	}
	
	this.clear = function(obj)
	{
		if (obj)
		{
			for (var i = 0; i < this.errors.length; i++)
			{
				if (this.errors[i].object == obj) {
					var temp = this.errors[this.errors.length-1];
					this.errors[this.errors.length-1] = this.errors[i];
					this.errors[i] = temp;
					this.errors[this.errors.length-1] = null;
					this.errors.length -= 1;
				}
			}
			
		}
		else
		{
			this.errors.length = 0;
		}
	}
}