var nbsp = 160;    // non-breaking space char
var node_text = 3; // DOM text node-type
var emptyString = /^\s*$/
var glb_vfld;      // retain vfld for timer thread
var minYear = 1900;
var maxYear = 2100;

function trim(str) {
  return str.replace(/^\s+|\s+$/g, '');
}

function isInteger(s){
	var i;
  for (i = 0; i < s.length; i++){   
    var c = s.charAt(i);
    if (((c < "0") || (c > "9"))) return false;
  }
  return true;
}

function stripCharsInBag(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 daysInFebruary (year){
  return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}

function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {
      this[i] = 30;
    }
		if (i==2) {
      this[i] = 29;
    }
   } 
   return this;
}

function setFocusDelayed() {
  glb_vfld.focus();
}

function setfocus(vfld) {
  // save vfld in global variable so value retained when routine exits
  glb_vfld = vfld;
  setTimeout( 'setFocusDelayed()', 100 );
}

// -----------------------------------------
//                  msg
// Display warn/error message in HTML element
// commonCheck routine must have previously been called
// -----------------------------------------

function msg(fld,     // id of element to display message in
             msgtype, // class to give element ("warn" or "error")
             message) // string to display
{
  if (fld == null) return; // Get out if the msg field is empty

  // setting an empty string can give problems if later set to a 
  // non-empty string, so ensure a space present. (For Mozilla and Opera one could 
  // simply use a space, but IE demands something more, like a non-breaking space.)
  var dispmessage;
  if (emptyString.test(message)) 
    dispmessage = String.fromCharCode(nbsp);    
  else  
    dispmessage = message;

  var elem = document.getElementById(fld);
  elem.firstChild.nodeValue = dispmessage;  
  
  //elem.className = msgtype;   // set the CSS class to adjust appearance of message
};

// -----------------------------------------
//            commonCheck
// Common code for all validation routines to:
// (a) check for older / less-equipped browsers
// (b) check if empty fields are required
// Returns true (validation passed), 
//         false (validation failed) or 
//         proceed (don't know yet)
// -----------------------------------------

var proceed = 2;  

function commonCheck    (vfld,   // element to be validated
                         ifld,   // id of element to receive info/error msg
                         reqd)   // true if required
{
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server
/*  var elem = document.getElementById(ifld);
  if (!elem.firstChild)
    return true;  // not available on this browser 
  if (elem.firstChild.nodeType != node_text)
    return true;  // ifld is wrong type of node  
*/
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }
  return proceed;
}

function setValidationError(vfld, ifld) {
  msg (ifld, "error", "*");  
  setfocus(vfld);
}

function clearValidationError(ifld) {
  msg (ifld, "warn", "");  
}

// -----------------------------------------
//            validatePresent
// Validate if something has been entered
// Returns true if so 
// -----------------------------------------

function validatePresent(vfld,   // element to be validated
                         ifld )  // id of element to receive info/error msg
{
  var stat = commonCheck (vfld, ifld, true);
  if (stat != proceed) return stat;
  msg (ifld, "warn", "");
  return true;
};

function validateSet    (vfld,   // element to be validated
                         ifld )  // id of element to receive info/error msg
{
	if ((vfld.value == 0) || (vfld.value == -1)) {
		msg (ifld, "error", "*");
	    return false;
	}  
	else {
		msg (ifld, "warn", "");
		return true;
	}
};

function checkEmail (vfld, ifld, reqd) {

  var emailFilter=/^.+@.+\..{2,3}$/;
  var illegalChars= /[\(\)\<\>\,\;\:\\\"\[\]]/;
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }

  if (!(emailFilter.test(vfld.value))) { 
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "*");   // OK
      return false;  
    }
  }
  if (vfld.value.match(illegalChars)) { 
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }

  // Success
  msg (ifld, "warn", "");
  return true;  
}

function checkCurrency (vfld, ifld, reqd) {

  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }

  // Get the value
  num = vfld.value.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;
  }
  value = parseFloat(num + '.' + cents);

  if (value <= 0) { 
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }

  // Success
  msg (ifld, "warn", "");
  return true;  
}

function checkPhone (vfld, ifld, reqd) {

  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }
  var strng = vfld.value;
  var stripped = strng.replace(/[\(\)\.\-\ ]/g, ''); //strip out acceptable non-numeric characters
  if (isNaN(parseInt(stripped))) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "*");   // OK
      return false;  
    }
  }
  if (stripped.length != 10) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  } 

  // Success
  msg (ifld, "warn", "");
  return true;  
}

function checkPassword(vfld, ifld, reqd) {
  
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
  } else {
  if (vfld.value.length < 4) {
	msg(ifld, "error", "not long enough");
	setfocus(vfld);
	return false;
  }
  else {
    msg (ifld, "warn", "");   // OK
    return true;
  }
 }
}

function checkPassword2(vfld, cfld, ifld, reqd) {
  
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
  } else {
  if (vfld.value != cfld.value) {
    msg(ifld, "error", "does not match");
    setfocus(vfld);
    return false;
  } else {
    msg (ifld, "warn", "");   // OK
    return true;
  }
 }
}

function checkDropdown(vfld, ifld, reqd, checkvalue) {

  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  if (vfld.value == checkvalue) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  } 

  // Success
  msg (ifld, "warn", "");
  return true; 
}

function checkCheckBox(vfld, ifld, reqd) {

  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server
  if (vfld.checked == false) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
    else {
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  } 

  // Success
  msg (ifld, "warn", "");
  return true; 
}

function checkNumber(vfld, ifld, reqd) {
  
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
  } else {
    if (parseInt(vfld.value) < 1) {
      msg(ifld, "error", "*");
      setfocus(vfld);
      return false;
    } else {
      msg (ifld, "warn", "");   // OK
      return true;
    }
  }
}

function checkEmail2(vfld, cfld, ifld, reqd) {
  
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Test the values
  if (emptyString.test(vfld.value)) {
    if (reqd) {
      msg (ifld, "error", "*");  
      setfocus(vfld);
      return false;
    }
  } else {
    if (vfld.value != cfld.value) {
      msg(ifld, "error", "does not match");
      setfocus(vfld);
      return false;
    } else {
      msg (ifld, "warn", "");   // OK
      return true;
    }
  }
}

function checkDate(vfld, ifld, reqd) {

  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server

  // Get out if blank and not required
  if (!reqd && (vfld.value.length == 0)) {
    return true;
  }

  // Get the values
  var dtStr = vfld.value;
	var daysInMonth = DaysArray(12);
  var dtCh = "";
  if (dtStr.indexOf("/") != -1) {
    dtCh = "/";
  } else {
    dtCh = "-";
  }
  var pos1 = dtStr.indexOf(dtCh);
  var pos2 = dtStr.indexOf(dtCh, pos1 + 1);
  var strMonth = dtStr.substring(0, pos1);
  var strDay = dtStr.substring(pos1 + 1, pos2);
  var strYear = dtStr.substring(pos2 + 1);

	strYr = strYear;
	if ((strDay.charAt(0) == "0") && (strDay.length > 1)) strDay = strDay.substring(1);
	if ((strMonth.charAt(0) == "0") && (strMonth.length > 1)) strMonth = strMonth.substring(1);
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0) == "0" && strYr.length > 1) strYr = strYr.substring(1);
	}
	month = parseInt(strMonth);
	day = parseInt(strDay);
	year = parseInt(strYr);
	if ((pos1 == -1) || (pos2 == -1)){
      msg(ifld, "error", "*");  
      setfocus(vfld);
		return false;
	}
	if ((strMonth.length < 1) || (month < 1) || (month > 12)){
      msg(ifld, "error", "*");  
      setfocus(vfld);
		return false;
	}
	if ((strDay.length < 1) || (day < 1) || (day > 31) || ((month == 2) && (day > daysInFebruary(year))) || (day > daysInMonth[month])){
      msg(ifld, "error", "*");
      setfocus(vfld);
		return false;
	}
	if ((strYear.length != 4) || (year == 0) || (year < minYear) || (year > maxYear)){
      msg(ifld, "error", "*");  
      setfocus(vfld);
		return false;
	}
	if ((dtStr.indexOf(dtCh,pos2+1) != -1) || (isInteger(stripCharsInBag(dtStr, dtCh)) == false)){
      msg(ifld, "error", "*");  
      setfocus(vfld);
		return false;
	}
  return true;
}
