// Name: formatCurrency
// Description: This script accepts a number or string and formats it 
// like U.S. currency. 
// Source: http://javascript.internet.com/forms/currency-format.html
// --------------------------------------------------
function formatCurrency(num) {
  num = num.toString().replace(/\$|\,/g,'');
  if(isNaN(num)) {
    num = "0";
  }

  sign = (num == (num = Math.abs(num)));
  num = Math.floor(num*100+0.50000000001);
  cents = num%100;
  num = Math.floor(num/100).toString();
  if(cents<10) {
    cents = "0" + cents;
  }
  
  for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++) {
     num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
  }
  
  return (((sign)?'':'-') + '$' + num + '.' + cents);
}

// Name: textCounter
// Description: This script controls a maximum textarea input amount and 
// updates a small counter with how many characters are left with each 
// keystroke.
// Source: http://javascript.internet.com/forms/limit-textarea.html
// --------------------------------------------------
function textCounter(field, countfield, maxlimit) {
  if (document.gform.elements["gift[text]"].value.length > maxlimit) {
    document.gform.elements["gift[text]"].value = document.gform.elements["gift[text]"].value.substring(0, maxlimit);
  } else {    
	document.getElementById("x").innerHTML = maxlimit - document.gform.elements["gift[text]"].value.length;
  }
}

// Name: Popups
// Description: Group of functions to create accessible pop-up links.
// Source: http://www.alistapart.com/articles/popuplinks/
// --------------------------------------------------
var _POPUP_FEATURES = 'location=no,statusbar=no,menubar=no,resizable=yes,scrollbars=yes,width=350,height=400';

function isUndefined(v) { 
   var undef;
   return v===undef;
}

function raw_popup(url, target, features) {
  if (isUndefined(features)) {
    features = _POPUP_FEATURES;
  }
  if (isUndefined(target)) {
    target = '_blank';
  }
  var theWindow =
    window.open(url, target, features);
  theWindow.focus();
  return theWindow;
}

function link_popup(src, features) {
  return raw_popup(src.getAttribute('href'),
    src.getAttribute('target') || '_blank',
    features);
}


// Name: dynamiccontentNS6
// Description: Implements dynamic HTML content for NS6 using DOM methods.
// Source: http://wsabstract.com/javatutors/dynamiccontent4.shtml
// --------------------------------------------------
function dynamiccontentNS6(elementid,content){
  if (document.getElementById){
    rng = document.createRange();
    el = document.getElementById(elementid);
    rng.setStartBefore(el);
    htmlFrag = rng.createContextualFragment(content);
 
    while (el.hasChildNodes()) {
      el.removeChild(el.lastChild);
    }
   
    el.appendChild(htmlFrag); 
  }
}

// Name: isEmpty
// Description: Returns true if the string is empty
// --------------------------------------------------
function isEmpty(str){
	return (str == null) || (str.length == 0);
}

// Name: isLength
// Description: Returns true if the string's length equals "len"
// --------------------------------------------------
function isLength(str, len){
	return str.length == len;
}

// Name: isLengthBetween
// Description: Returns true if the string's length is between "min" and "max"
// --------------------------------------------------
function isLengthBetween(str, min, max){
	return (str.length >= min)&&(str.length <= max);
}

// Name: isPhoneNumber
// Description: Returns true if the string is a US phone number formatted as 000-000-0000
// --------------------------------------------------
function isPhoneNumber(str) {
	var re = /^\d{3}-\d{3}-\d{4}$/;
	return re.test(str);
}

// Name: isAlphanumeric
// Description: 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;
}

// Name: isNumeric
// Description: 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;
}

// Name: isAlpha
// Description: 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;
}

// Name: isMatch
// Description: Returns true if "str1" is the same as the "str2"
// --------------------------------------------------
function isMatch(str1, str2){
	return str1 == str2;
}

// Name: isUri
// Description: 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;
}

// Name: isValidEmail
// Description: 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;
}

// Name: isFreeEmail
// Description: Check that an email address is not a "free" address
//Basically we want to exclude certain domains
//Returns False if one is detected as it is the Failure condition
// --------------------------------------------------
function isFreeEmail(address) {
   if (address != '' && address.match) {
      if (address.match(/(gmail|yahoo|msn|aol|hotmail|comcast|earthlink)/)){
	  	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;
}

// Name: isValidEmailStrict
// Description: 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;
}

// Name: isValidZipcode
// Description: 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;
}

// Name: isValidCreditCard
// Description: 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;
}

// Name: removeBadCharacters
// Description: Remove characters that might cause security problems from a string 
// --------------------------------------------------
function removeBadCharacters(string) {
   if (string.replace) {
      string.replace(/[<>\"\'%;\)\(&\+]/, '');
   }
   return string;
}

// Name: removeSpaces
// Description: 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;
}

// Name: trimWhitespace
// Description: 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;
}

// Name: getMod10
// Description: 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);
}

// Name: errorAlert
// Description: 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';
    var errorMessage = 'In order to continue, the following information is required:\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.';
	errorMessage += '\nPlease complete all the required fields.';
	alert(errorMessage);
    return true;
  }
  return false;
}