//Selects a field and shouts an error
function fieldAlert(field, msg)
{
	alert(msg);
	field.focus();
	if (field.select) field.select();
	return false;
}

//disables submit buttons and prevents form from being resubmitted
function freezeForm(form)
{
	if (form.submitted) { alert('You have already submitted this form!'); return false; }
	for (cnt = 0; cnt < form.elements.length; cnt++)
		if (form.elements[cnt].type == 'submit' || form.elements[cnt].type == 'reset') form.elements[cnt].disabled = true;
	form.submitted = true; //mark form as submitted (to catch older browsers)
	return true;
}

//checks through form to make sure required fields are filled in
function checkRequired(form)
{
	for (cnt = 1; cnt < arguments.length; cnt++)
	{
		field = form.elements[arguments[cnt]];
		if (field.type == 'select-one') //is an option list
		{ if (field.selectedIndex == 0) return fieldAlert(field, 'Please select an option!'); }
		else if (!field.value) return fieldAlert(field, 'Please fill in this required field!');
	}
	return true;
}

//checks through form to make sure email addresses are valid
function checkEmail(form)
{
	error = false;
	for (cnt = 1; cnt < arguments.length; cnt++)
	{
		field = form.elements[arguments[cnt]];
		if (field.value)
		{ //field isn't empty so validate it
			email = field.value;
			email = email.split('@'); //split email into user & host
			if (email.length != 2) error = true; //there was less/more than one @
			else if (window.RegExp)
			{	//if browser supports regular expressions, validate it further
				//matches regular (blah_blah) or quoted ("blah blah") user
				userEx = /^\"[^\"]*\"$|^[0-9a-z]([-_.]?[0-9a-z])*$/i;
				//matches numeric IP host (127.0.0.1) or symbolic domain (blah.co.nz)
				hostEx = /^(\d{1,3}\.){3}\d{1,3}$|^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,3}$/i;

				if (!userEx.test(email[0])) error = true; //check user
				else if (!hostEx.test(email[1])) error = true; //check domain
			}
		}
		if (error) return fieldAlert(field, 'You have entered an invalid email address!');
	}
	return true;
}

function checkMod10(cardNum)
{
	cardArray = new Array(16);
	checksum = 0;

	// assign each digit of the card number to a space in the array	
	for (cnt = 0; cnt < cardNum.length; cnt++) cardArray[cnt] = parseInt(cardNum.charAt(cnt));

	// if the card number is an even number then start at the first digit (position 0), otherwise start from the second (position 1)
	for (cnt = (cardNum.length % 2); cnt < cardNum.length; cnt += 2)
	{
		num = cardArray[cnt] * 2;
		if (num >= 10)
		{ //add the two digits together
			num = num.toString();
			num = parseInt(num.charAt(0)) + parseInt(num.charAt(1));
		}
		cardArray[cnt] = num;
	}

	// add up all of the digits in the array
	for (cnt = 0; cnt < cardNum.length; cnt++) checksum += cardArray[cnt];

	// if the checksum is evenly divisble by 10 then this is a valid card number
	return !(checksum % 10);
}

function cleanNum(cardNum)
{
	newNum = '';

	// walk through the string character by character to build a new string with numbers only
	for (cnt = 0; cnt < cardNum.length; cnt++)
	{
		// get the current character
		num = cardNum.charAt(cnt);
		// if the current character is a digit then add it to the numbers-only string we're building
		if (num >= '0' && num <= '9') newNum += num;
		// not a digit, so check if its a dash or a space
		else if (num != ' ' && num != '-') return false;
	}
	return newNum;
}

function checkCredit(form, typeField, numField)
{	
	typeField = form.elements[typeField];
	numField = form.elements[numField];

	cardType = typeField[typeField.selectedIndex].value.toLowerCase();
	cardNum = numField.value;

	//credit-card details haven't been entered, bail out
	//(if details are required, use checkRequired() beforehand)
	if (!cardType || !cardNum) return false;

	// clean up any spaces or dashes in the card number
	cardNum = cleanNum(cardNum);
	if (!cardNum) return fieldAlert(numField, 'This card number contains invalid characters!');

	// check the first digit and length to see if it matches the card type
	cardStart = cardNum.charAt(0);
	cardLength = cardNum.length;
	// make sure the number matches the card type
	checkType = ( 
		(cardType == 'visa' && cardStart == '4' && (cardLength == 13 || cardLength == 16)) ||
		(cardType == 'mastercard' && cardStart == '5' && cardLength == 16) ||
		(cardType == 'american express' && cardStart == '3' && cardLength == 15) );
	if (!checkType)
		return fieldAlert(numField, 'Make sure you have selected the correct card type, and entered all the digits of your number.');

	// check with Mod10
	if (!checkMod10(cardNum)) return fieldAlert(numField, 'Make sure you have entered your card number correctly.');
	else return true;
}