// Returns true if the string is empty
function isEmpty(str){
	return (str == null) || (str.length == 0);
}

// Returns true if the string's length equals "len"
function isLength(str, len){
	return str.length == len;
}

// Returns true if the string's length is between "min" and "max"
function isLengthBetween(str, min, max){
	return (str.length >= min)&&(str.length <= max);
}

// Returns true if the string is a US phone number.
function isPhoneNumber(str) {
	var stripped = str.replace(/[\(\)\.\-\ ]/g, '');
	if (isNaN(parseInt(stripped))) {
		return false;
	}
	
	if (!(stripped.length == 7) || !(stripped.length == 10)) {
		return false;
	}
	
	return true;
}

// Returns true if the string only contains characters A-Z, a-z or 0-9
function isAlphaNumeric(str){
	var re = /[^a-zA-Z0-9- ]/g;
	if (re.test(str)) return false;
	return true;
}

// Returns true if the string only contains characters 0-9
function isNumeric(str) {
	var re = /[\D]/g;
	if (re.test(str)) return false;
	return true;
}

// Returns true if the string only contains characters A-Z or a-z
function isAlpha(str) {
	var re = /[^a-zA-Z]/g;
	if (re.test(str)) return false;
	return true;
}

// Returns true if "str1" is the same as the "str2"
function isMatch(str1, str2){
	return str1 == str2;
}

// Returns true if str is a valid uri
function isUri(str) {
	var re = new RegExp("^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*$"); 
	if (re.test(str)) return true;
	return false;
}

// Check that an email address is valid based on RFC 821 (?)
function isValidEmail(address) {
   if (address != '' && address.search) {
      if (address.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1) return true;
      else return false;
   }
   
   // allow empty strings to return true - screen these with either a 'required' test or a 'length' test
   else return true;
}

// Check that an email address has the form something@something.something
// This is a stricter standard than RFC 821 (?) which allows addresses like postmaster@localhost
function isValidEmailStrict(address) {
   if (isValidEmail(address) == false) return false;
   var domain = address.substring(address.indexOf('@') + 1);
   if (domain.indexOf('.') == -1) return false;
   if (domain.indexOf('.') == 0 || domain.indexOf('.') == domain.length - 1) return false;
   return true;
}

// Check that a US zip code is valid
function isValidZipcode(zipcode) {
   zipcode = removeSpaces(zipcode);
   if (!(zipcode.length == 5 || zipcode.length == 9 || zipcode.length == 10)) return false;
   if ((zipcode.length == 5 || zipcode.length == 9) && !isNumeric(zipcode)) return false;
   if (zipcode.length == 10 && zipcode.search && zipcode.search(/^\d{5}-\d{4}$/) == -1) return false;
   return true;
}

// Check that a credit card number is valid based using the LUHN formula (mod10 is 0)
function isValidCreditCard(number) {
   number = '' + number;
   
   if (number.length > 16 || number.length < 13 ) return false;
   else if (getMod10(number) != 0) return false;
   else if (arguments[1]) {
      var type = arguments[1];
      var first2digits = number.substring(0, 2);
      var first4digits = number.substring(0, 4);
      
      if (type.toLowerCase() == 'visa' && number.substring(0, 1) == 4 &&
         (number.length == 16 || number.length == 13 )) return true;
      else if (type.toLowerCase() == 'mastercard' && number.length == 16 &&
         (first2digits == '51' || first2digits == '52' || first2digits == '53' || first2digits == '54' || first2digits == '55')) return true;
      else if (type.toLowerCase() == 'american express' && number.length == 15 && 
         (first2digits == '34' || first2digits == '37')) return true;
      else if (type.toLowerCase() == 'diners club' && number.length == 14 && 
         (first2digits == '30' || first2digits == '36' || first2digits == '38')) return true;
      else if (type.toLowerCase() == 'discover' && number.length == 16 && first4digits == '6011') return true;
      else if (type.toLowerCase() == 'enroute' && number.length == 15 && 
         (first4digits == '2014' || first4digits == '2149')) return true;
      else if (type.toLowerCase() == 'jcb' && number.length == 16 &&
         (first4digits == '3088' || first4digits == '3096' || first4digits == '3112' || first4digits == '3158' || first4digits == '3337' || first4digits == '3528')) return true;
      
    // if the above card types are all the ones that the site accepts, change the line below to 'else return false'
    else return true;
   }
   else return true;
}

// Remove characters that might cause security problems from a string 
function removeBadCharacters(string) {
   if (string.replace) {
      string.replace(/[<>\"\'%;\)\(&\+]/, '');
   }
   return string;
}

// Remove all spaces from a string
function removeSpaces(string) {
   var newString = '';
   for (var i = 0; i < string.length; i++) {
      if (string.charAt(i) != ' ') newString += string.charAt(i);
   }
   return newString;
}

// Remove leading and trailing whitespace from a string
function trimWhitespace(string) {
   var newString  = '';
   var substring  = '';
   beginningFound = false;
   
   // copy characters over to a new string
   // retain whitespace characters if they are between other characters
   for (var i = 0; i < string.length; i++) {
      
      // copy non-whitespace characters
      if (string.charAt(i) != ' ' && string.charCodeAt(i) != 9) {
         
         // if the temporary string contains some whitespace characters, copy them first
         if (substring != '') {
            newString += substring;
            substring = '';
         }
         newString += string.charAt(i);
         if (beginningFound == false) beginningFound = true;
      }
      
      // hold whitespace characters in a temporary string if they follow a non-whitespace character
      else if (beginningFound == true) substring += string.charAt(i);
   }
   return newString;
}

// Returns a checksum digit for a number using mod 10
function getMod10(number) {
   
   // convert number to a string and check that it contains only digits
   // return -1 for illegal input
   number = '' + number;
   number = removeSpaces(number);
   if (!isNumeric(number)) return -1;
   
   // calculate checksum using mod10
   var checksum = 0;
   for (var i = number.length - 1; i >= 0; i--) {
      var isOdd = ((number.length - i) % 2 != 0) ? true : false;
      digit = number.charAt(i);
      
      if (isOdd) checksum += parseInt(digit);
      else {
         var evenDigit = parseInt(digit) * 2;
         if (evenDigit >= 10) checksum += 1 + (evenDigit - 10);
         else checksum += evenDigit;
      }
   }
   return (checksum % 10);
}

// Given an array, pops up a javascript alert message with the contents formatted nicely.
function errorAlert(errors) {
  if (errors.length > 0 ) {
    var errorMessage = 'The form was not submitted due to the following problem' + ((errors.length > 1) ? 's' : '') + ':\n\n';
    for (var errorIndex = 0; errorIndex < errors.length; errorIndex++) {
      errorMessage += '* ' + errors[errorIndex] + '\n';
    }
    errorMessage += '\nPlease fix ' + ((errors.length > 1) ? 'these' : 'this') + ' problem' + ((errors.length > 1) ? 's' : '') + ' and resubmit the form.';
    alert(errorMessage);
    return true;
  }
  return false;
}
