// form_utils.js
//
// R. Daugherty -- added functions for "easy" e-mail/zip checking - Sept. 2, 2003
// SUMMARY
//
// This is a set of JavaScript functions for validating input on
// an HTML form.
//

var whitespace = " \t\n\r";
var illegalUserChars = whitespace + ":,/?'<>%`\\\"";
var numberChars = "0123456789";

/*
var reportStatus = new Array();

function report ( msg ) {
    reportStatus.push ( msg );
}
function showReport ( err ) {
    alert ( reportStatus.join ( "\n" ) );
}

window.onerror = function ( err, url, line ) {
    report ( err + " [" + url + " - line " + line + "]" );
    showReport();
}
*/

function getElementTopPos(inputObj)
{
  var returnValue = inputObj.offsetTop;
  while((inputObj = inputObj.offsetParent) != null){
      if(inputObj.tagName!='HTML'){
          returnValue += inputObj.offsetTop;
          if(document.all)returnValue+=inputObj.clientTop;
      }
  }
  return returnValue;
}
// }}}


// {{{ getLeftPos()
/**
 * This method will return the left coordinate(pixel) of an object
 *
 * @param Object inputObj = Reference to HTML element
 * @public
 */
function getElementLeftPos(inputObj)
{
  var returnValue = inputObj.offsetLeft;
  while((inputObj = inputObj.offsetParent) != null){
      if(inputObj.tagName!='HTML'){
          returnValue += inputObj.offsetLeft;
          if(document.all)returnValue+=inputObj.clientLeft;
      }
  }
  return returnValue;
}


function assignContent(id_1, id_2)
{
// todo: update to use the function below
	if (document.getElementById || document.all) {
		var el = document.getElementById? document.getElementById(id_1): document.all[id_1];
		if (el && typeof el.innerHTML != "undefined") {
			var e2 = document.getElementById? document.getElementById(id_2): document.all[id_2];
			e2.innerHTML = e1.innerHTML;
		}
	}
}

function getContent(id)
{
// todo: update to use the function below
   if (document.getElementById || document.all) {
	  var el = document.getElementById? document.getElementById(id): document.all[id];
	  if (el && typeof el.innerHTML != "undefined") return el.innerHTML;
   }
   return "";
}

function changeContent(id,shtml)
{
// todo: update to use the function below
   if (document.getElementById || document.all) {
	  var el = document.getElementById? document.getElementById(id): document.all[id];
	  if (el && typeof el.innerHTML != "undefined") el.innerHTML = unescape(shtml);
   }
}

function getElementId(id)
{
   if (document.getElementById || document.all) {
	  var el = document.getElementById? document.getElementById(id): document.all[id];
	  return el;
   }
	return null;
}

function soon()
{
    alert("We're sorry. This feature is not yet available. Please check back.");
}

function formField(frmName, x)
{
	return document.forms[frmName].elements[x];
}

function formElement(x)
{
	return document.forms[0].elements[x];
}

function executeForm(frmName, url)
{
	document.forms[frmName].action = url;
	document.forms[frmName].submit();
}

function setSelectValue(f, value)
{
	if (f.length) {
		for (i=0;i<f.length;i++){
			if (f[i].value == value) {
				f.selectedIndex = i;
				return;
			}
		}
	}
}

function getRadioValue(f)
{
	if (f.length) {
		for (i=0;i<f.length;i++){
			if (f[i].checked) {
				return f[i].value;
			}
		}
	} else {
		if (f.checked) return f.value;
	}
	return -1;
}

function setRadioValue(f, value)
{
	if (f.length) {
		for (i=0;i<f.length;i++) {
			f[i].checked = (f[i].value == value) ;
		}
	}
}

function getSelectedCheckboxes(nm)
{
	var str = '';
	var ct = 0;
	var e = document.getElementsByTagName("input");

	for (i=0; i < e.length; i++) {
		var f = e[i];
		if (f.id == nm) {
			if (f.checked) {
				if (str.length > 0) str += ',';
				str += f.value;
			}
		}
	}
	return str;
}

function getSelectedCheckboxesX(nm)
{
	var str = '';
	var ct = 0;
	var e = document.getElementsByTagName("input");

	for (i=0; i < e.length; i++) {
		var f = e[i];
		if (f.name == nm) {
			if (f.checked) {
				if (str.length > 0) str += ',';
				str += f.value;
			}
		}
	}
	return str;
}

function countSelectedCheckboxes(nm)
{
	var ct = 0;
	var e = document.getElementsByTagName("input");
	for (i=0; i < e.length; i++) {
		var f = e[i];
		if (f.id == nm) {
			if (f.checked) ct++;
		}
	}
	return ct;
}

function countSelectedCheckboxesX(nm)
{
	var ct = 0;
	var e = document.getElementsByTagName("input");
	for (i=0; i < e.length; i++) {
		var f = e[i];
		if (f.name == nm) {
			if (f.checked) ct++;
		}
	}
	return ct;
}

function checkUserField(formField, minimumSize, displayMsg)
{
	var passLength = checkLength(formField, minimumSize, displayMsg);
    if (passLength == true) {
        if (hasCharsInBag(formField.value, illegalUserChars)) {
            return warn(formField, 'Special characters may not be used in usernames or passwords.');
        }
        return true;
    }
    return false;
}

function checkLengthBogus(formField, minimumSize, displayMsg)
{
	var passLength = checkLength(formField, minimumSize, displayMsg);

	if (passLength == true) {
		var bag1 = formField.value.indexOf("sdf");
		var bag2 = formField.value.indexOf("asdf");
		var bag3 = formField.value.indexOf("hjk");
		if ((bag1 > -1) || (bag2 > -1) || (bag3 > -1)) {
			return warn(formField, displayMsg);
		} else {
			return true;
		}
	} else {
		return false;
	}
}

function checkLength(formField, minimumSize, displayMsg)
{
    var xx = trim(formField.value);
	try {
    	formField.value = xx;
	} catch (err) {
		// ignored - this might be an upload field - editing the field is not permitted
	}
    if (xx.length < minimumSize) return warn(formField, displayMsg);
    return true;
}

function checkName(theField, isEmptyOK, displayMsg)
{
	var checkStr;

	checkStr = theField.value;
	if ( isEmptyOK && isEmpty(checkStr))
		return true;

    if (isWhitespace(checkStr)) {
		warn(theField, displayMsg);
		return false;
	}

    if (theField.value.replace(/\d/g,"") != theField.value) {
		warn(theField, displayMsg);
		return false;
	}

	var tmp = stripCharsNotInBag(theField.value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz- '");
    if (tmp != theField.value) {
		warn(theField, displayMsg);
		return false;
	}

	return true;
}

function checkEmail(theField, isEmptyOK, displayMsg)
{
	var checkStr;

	checkStr = theField.value;
	if (isEmptyOK && isEmpty(checkStr))
		return true;

    if (checkStr == "" || checkStr.lastIndexOf("@") == -1 || checkStr.lastIndexOf(".") == -1) {
		if (displayMsg) warn(theField, displayMsg);
		return false;
	}

	var emailArr = checkStr.split("@");
	var user = emailArr[0];
	var domainAddress = emailArr[1];

	var domainAddressArr = domainAddress.split(".");
	var domain = domainAddressArr[0];
	var net = domainAddressArr[1];

	if (user.length == 0 || domain.length == 0 || net.length == 0) {
		if (displayMsg) warn(theField, displayMsg);
		return false;
	}

   	if (theField.value.replace("www","") != theField.value) {
		if (displayMsg) warn(theField, displayMsg);
		return false;
	}

   	if (theField.value.replace(/^[0123456789]+@/,"") != theField.value) {
		if (displayMsg) warn(theField, displayMsg);
		return false;

	}
	return true;
}

function autoTab(aevent, formField, len, nxtField)
{
	var k = aevent.keyCode;

	var x = formField.value;
	if (x.length == len) {
		if (k == 9 || k == 16) {
			formField.select();
			return;
		}
		nxtField.focus();
	}
}

function cleanField(formField, regex)
{
	var regexp = new RegExp(regex);
	var x = formField.value.replace(regexp, "");
	if (x != formField.value) formField.value = x;
}

function warn(formField, displayMsg)
{
    alert(displayMsg);
    formField.focus();
    formField.select();
    return false;
}

function trim(s)
{
    // Remove leading spaces and carriage returns
    while ((s.substring(0,1) == ' ') || (s.substring(0,1) == '\n') || (s.substring(0,1) == '\r')) {
        s = s.substring(1,s.length);
    }

    // Remove trailing spaces and carriage returns
    while ((s.substring(s.length-1,s.length) == ' ') || (s.substring(s.length-1,s.length) == '\n') || (s.substring(s.length-1,s.length) == '\r')) {
        s = s.substring(0,s.length-1);
    }
    return s;
}

function isWhitespace (s)
{
	var i;
    if (isEmpty(s))
		return true;
    for (i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        if (whitespace.indexOf(c) == -1)
			return false;
    }
    return true;
}

function hasCharsInBag(s, bag)
{
    var i;

    for (i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        if (bag.indexOf(c) != -1) return true;
    }
    return false;
}

function stripCharsNotInBag(s, bag)
{
    var i;
    var returnString = "";

    for (i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        if (bag.indexOf(c) != -1) returnString += c;
    }
    return returnString;
}

function cleanNumberField(formField)
{
    formField.value = stripCharsNotInBag(formField.value, numberChars);
}

function isAreaCodeValid(n)
{
    if (n.length != 3) return false;
	if (n.charAt(0) == '0') return false;
	if ((n.charAt(0) == n.charAt(1)) && (n.charAt(1) == n.charAt(2))) return false;
	if (n == "555") return false;
    return true;
}

function isExchangeValid(n)
{
    if (n.length != 3) return false;
    return true;
}

function isNumberValid(n)
{
    if (n.length != 4) return false;
    return true;
}

function isEmpty(s)
{
	return ((s == null) || (s.length == 0))
}

function processSeparatePhone(frm, fld)
{
	var hid = formField(frm, fld);
	var ac = formField(frm, fld + "_AC");
	var exc = formField(frm, fld + "_EXC");
	var nbr = formField(frm, fld + "_NO");

	cleanNumberField(ac);
	cleanNumberField(exc);
	cleanNumberField(nbr);

	var str = ac.value + exc.value + nbr.value;

	hid.value = '';
	if (str.length == 0) return;
	hid.value = ac.value + "-" + exc.value + "-" + nbr.value;
}


function checkSeparatePhone(frm, fld, isEmptyOK, displayMsg)
{
	return checkSeparatePhoneX(frm, fld, isEmptyOK, displayMsg, false);
}

function checkSeparatePhoneX(frm, fld, isEmptyOK, displayMsg, addDash)
{
	var hid = formField(frm, fld);
	var ac = formField(frm, fld + "_AC");
	var exc = formField(frm, fld + "_EXC");
	var nbr = formField(frm, fld + "_NO");

	cleanNumberField(ac);
	cleanNumberField(exc);
	cleanNumberField(nbr);

	var str = ac.value + exc.value + nbr.value;

	hid.value = '';

	if (str.length == 0 && isEmptyOK) return true;

	if (addDash) {
		hid.value = ac.value + "-" + exc.value + "-" + nbr.value;
	} else {
		hid.value = str;
	}
	// force a phone number to be entered
	if (!isAreaCodeValid(ac.value)) {
		warn(ac, displayMsg);
		return false;
	}
	if (!isExchangeValid(exc.value)) {
		warn(exc, displayMsg);
		return false;
	}
	if (!isNumberValid(nbr.value)) {
		warn(nbr, displayMsg);
		return false;
	}
	return true;
}

function isNum(argvalue)
{
	argvalue = argvalue.toString();

	if (argvalue.length == 0) return false;

	for (var n = 0; n < argvalue.length; n++) {
		if (argvalue.substring(n, n+1) < "0" || argvalue.substring(n, n+1) > "9") return false;
	}
	return true;
}

function luhnCheck(CardNumber)
{
	if (!isNum(CardNumber)) {
		return false;
	}

	var no_digit = CardNumber.length;
	var oddoeven = no_digit & 1;
	var sum = 0;

	for (var count = 0; count < no_digit; count++) {
		var digit = parseInt(CardNumber.charAt(count));
		if (!((count & 1) ^ oddoeven)) {
			digit *= 2;
			if (digit > 9) digit -= 9;
		}
		sum += digit;
	}

	if (sum % 10 == 0) {
		return true;
	} else {
		return false;
	}
}

var CARD_VISA = 1;      // VISA = 13,16 numbers starting with a 4
var CARD_MC = 2;        // MC = 16 numbers starting with a 5 (51-55)
var CARD_DISC = 3;      // Disc = 16 numbers starting with 6011
var CARD_AMEX = 4;      // AMEX = 15 numbers starting with 34,37
var CARD_JCB = 5;       // JCB = 16 numbers starting with 3088,3096,3112,3158,3337,3528
var CARD_DIN = 6;       // DINERS = 14 numbers starting with 30,36,38

function checkCreditCard(theField, cardType, displayMsg)    // theField is the card #, card Type is an integer
{
	var CardNumber = theField.value;
	var luhn = luhnCheck(CardNumber);
	if (!luhn) return warn(theField, displayMsg);

	if (cardType == CARD_VISA) {
		if (CardNumber.substring(0,1) != '4') return warn(theField, displayMsg);
		if (CardNumber.length != 13) {
			if (CardNumber.length != 16) {
				return warn(theField, displayMsg);
			}
		}
		return true;
	}

	if (cardType == CARD_MC) {
		if (CardNumber.substring(0,1) != '5') return warn(theField, displayMsg);
		if (CardNumber.length != 16) return warn(theField, displayMsg);
		return true;
	}

	if (cardType == CARD_DISC) {
		if (CardNumber.substring(0,4) != '6011') return warn(theField, displayMsg);
		if (CardNumber.length != 16) return warn(theField, displayMsg);
		return true;
	}

	if (cardType == CARD_AMEX) {
		if (CardNumber.substring(0,1) != '3') return warn(theField, displayMsg);
		if (CardNumber.length != 15) return warn(theField, displayMsg);
		return true;
	}

	return warn(theField, displayMsg);
}

// RFC 1918 (Nextel seems to use 11.0.0.0 as internal... go figure)
function checkIPAddress(theField, displayMsg, allowInternal)
{
	var IPvalue = theField.value;
	// sample value: 10.1.10.255
	var ipPattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
	var ipArray = IPvalue.match(ipPattern);
	var thisSegment;

	if (ipArray.length != 5) {
		return warn(theField, displayMsg + " (length: " + ipArray.length + ")");
	}

	if (ipArray[1] == ipArray[2] == ipArray[3] == ipArray[4]) {
		return warn(theField, displayMsg + " (same)");
	}

	if (ipArray[1] == 127 && ipArray[2] == 0 && ipArray[3] == 0 && ipArray[4] == 1) return warn(theField, displayMsg + " (local)");

	for (i = 1; i < 5; i++) {
		thisSegment = ipArray[i];
		if (i == 1) {
			// things we don't allow in octet 0
			if (thisSegment <= 0) return warn(theField, displayMsg + " (0)");
			if (thisSegment >= 255) return warn(theField, displayMsg + "(255)");
		}
		if (thisSegment < 0 || thisSegment > 255) {
			return warn(theField, displayMsg + " (0-255)");
		}
	}
	if (!allowInternal) {
		if (ipArray[1] == 192 && ipArray[2] == 168) return warn(theField, displayMsg + " (192.168)");
		if (ipArray[1] == 10) return warn(theField, displayMsg + " (10)");
		if (ipArray[1] == 172) {
			if (ipArray[2] >= 16 && ipArray[2] <= 31) return warn(theField, displayMsg + " (172.16-31)");
		}
	}
	return true;
}

