/**
 * Shows message, sets focus to desired element, and returns false.
 */
function messageHelperOld(el, msg) {
  if (el != null) {
  	if (el.select != null)
		el.select();
		
	if (el.formJsFocusProxy != null)
		el.formJsFocusProxy.focus();
	else if (el.focus != null)
  		el.focus();
  }

  if (msg != null)
  	alert(msg);

  if (el != null) {
	if (el.formJsFocusProxy != null)
		el.formJsFocusProxy.focus();
	else if (el.focus != null)
  		el.focus();
  }

  return false;
}

var SPAN_MESSAGE_PROMPT = "_message_prompt___1";

/**
 * Call this at the beginning of form validation.
 */
function initMessage(frm) {
	if (document.all == null) return "";
	
	var spanEls = document.all.tags("SPAN");
	for (var i = 0; i < spanEls.length; i++) {
		var el = spanEls[i];
		if (el.className != "message" || el.id == null) continue;
		if (el.id.indexOf(SPAN_MESSAGE_PROMPT) != el.id.length - SPAN_MESSAGE_PROMPT.length) continue;
		el.style.display = 'none';
	}
	
	frm.focusEl = null;
	frm.messageDisplayed = false;
	frm.fancyValidation = true;
	
	return "";
}


/**
 * Shows message, sets focus to desired element (if not focussed already), and returns "".
 * If this is NS, or we cannot set focus, then an alert is displayed.
 */
function messageHelper(el, msg) {
	if (document.all == null || document.createElement == null || el == null || el.form.fancyValidation != true) return messageHelperOld(el, msg);

	if (el.select != null) el.select();
	if (el.form.focusEl == null) {
		if (el.formJsFocusProxy != null) {
			el.formJsFocusProxy.focus();
			el.form.focusEl = el.formJsFocusProxy; // don't repeatedly focus guys
		} else if (el.focus != null) {
			el.focus();
			el.form.focusEl = el; // don't repeatedly focus guys
		}
	}

	var pnm = el.name+SPAN_MESSAGE_PROMPT;
	var promptEl = document.all[pnm];
	if (promptEl == null) {
		promptEl = document.createElement("SPAN");
		el.parentElement.insertAdjacentElement("beforeEnd", promptEl);
		promptEl.className = "message";
		promptEl.id = pnm;
	}
	msg = replaceIllegals(msg, "\r\n", "  ");
	el.form.messageDisplayed = true;
	promptEl.innerText = msg;
	promptEl.style.display = 'inline';

	return true;
}

/**
 * Call this at the end of form validation.
 * (Returns true if an error has occurred.)
 */
function noMessage(frm) {
	if (frm.messageDisplayed == false) return true;
	if (frm.focusEl != null) frm.focusEl.focus();
	return false;
}

/**
 * Implements the checkFloat and checkInt functions.
 */
function checkNumber(el, msg, minimum, maximum, allowDecimals) {
  var val = el.value;
  var len = val.length;
  if (len == 0) return messageHelper(el, msg);
  
  var negAlreadyFound = false;
  var decimalAlreadyFound = false;
  
  for (var i = 0; i < len; i++) {
    var ch = val.charAt(i);
    if ("0123456789".indexOf(ch) != -1) {
      // this is good... continue
    } else if (ch == '-') {
      if (negAlreadyFound) return messageHelper(el, msg);
      negAlreadyFound = true;
    } else if (ch == '.') {
      if (decimalAlreadyFound) return messageHelper(el, msg);
      if (!allowDecimals) return messageHelper(el, msg);
      decimalAlreadyFound = true;
    } else 
      return messageHelper(el, msg); // not a number, sign, or decimal
  }
  
  if (minimum != null) {
    if (parseFloat(val) < minimum) return messageHelper(el, msg);
  }
  if (maximum != null) {
    if (parseFloat(val) > maximum) return messageHelper(el, msg);
  }
  
  return true;
}
  

/**
 * Verifies that the element contains a valid floating point number, and
 * displays an error message if needed.
 */ 
function checkFloat(el, msg, minimum, maximum) {
  return checkNumber(el, msg, minimum, maximum, true);
}

/**
 * Verifies that the element contains a valid integer, and
 * displays an error message if needed.
 */ 
function checkInt(el, msg, minimum, maximum) {
  return checkNumber(el, msg, minimum, maximum, false);
}

function arry() {}
var x_days_per_month = new arry();
x_days_per_month[1] = 31; x_days_per_month[2] = 29; x_days_per_month[3] = 31;
x_days_per_month[4] = 30; x_days_per_month[5] = 31; x_days_per_month[6] = 30;
x_days_per_month[7] = 31; x_days_per_month[8] = 31; x_days_per_month[9] = 30;
x_days_per_month[10] = 31; x_days_per_month[11] = 30; x_days_per_month[12] = 31;
function daysInMonth(m, y) {
  if (m == 2) return getFebDays(y);
  else return x_days_per_month[m];
}

/**
 * Verifies that the elements contain a valid date, and displays an 
 * error message if needed.
 */
function checkDate(mm, dd, yyyy, msg) {
  var m, d, y; // month, day, and year as integers
  
  if (!checkInt(mm, msg+"\r\n"+"Please enter a valid month.", 1, 12)) return false;
  m = parseFloat(mm.value);
  
  // february check is performed below, after we know the year
  if (!checkInt(dd, msg+"\r\n"+"Please enter a valid day.", 1, x_days_per_month[m])) return false;
  d = parseFloat(dd.value);

  if (!checkInt(yyyy, msg+"\r\n"+"Please enter a valid year.", 0)) return false;
  y = parseFloat(yyyy.value);
  if (y < 100) return messageHelper(yyyy, msg+"\r\n"+"Please enter a four-digit year.");
  if (y < 1900) return messageHelper(yyyy, msg+"\r\n"+"Please enter a year after 1900.");
  if (y > 2100) return messageHelper(yyyy, msg+"\r\n"+"Please enter a year before 2100.");
  
  // perform february check
  if ((m == 2) && d > getFebDays(y)) return messageHelper(dd, "Please enter a valid day.");
  
  return true;
}

/**
 * Verifies that the elements contain a valid time, and displays an 
 * error message if needed.
 */
function checkTimeSelects(hh, mm, ampm, msg, is_optional) {
	var h, m, p;

	h = parseFloat(hh.options[hh.selectedIndex].value);
	m = parseFloat(mm.options[mm.selectedIndex].value);
	
	if (is_optional && (h < 0) && (m < 0)) return true;
	if (h<0) {
		return messageHelper(hh, msg+"\r\n"+"Please select a valid hour of the day.");
	} else if (m<0) {
		return messageHelper(mm, msg+"\r\n"+"Please select a valid minute.");
	}
	
	return true;
}

/**
 * Rounds the specified string to the nearest cents if a decimal point is present,
 * or returns the string as is if no decimal point is present.
 */
function moneyRound(str) {
    var perLoc = str.indexOf('.');
    if (perLoc == -1) return str;
    if (perLoc == str.length-3) return str;
    if (perLoc < str.length-3) return 0.01*Math.round(parseFloat(str)*100);
    return (str+"00").substring(0,perLoc+3);
}


/**
 * Verifies that the SELECTs contain a valid date, and displays an
 * error message if needed.  This function assumes that the lists
 * only contain valid months, days, and years.
 */
function checkDateSelects(mm, dd, yyyy, msg, is_optional) {
	if (mm == null || dd == null || yyyy == null) return true;
	
  var m, d, y; // month, day, and year as integers
  m = parseFloat(mm.options[mm.selectedIndex].value);
  d = parseFloat(dd.options[dd.selectedIndex].value);
  y = parseFloat(yyyy.options[yyyy.selectedIndex].value);
  
  if (is_optional && (m<=0) && (d<=0) && (y<=0))
    return true;
    
  if (m<=0) {
    return messageHelper(mm, msg+"\r\n"+"Please select a valid month.");
  } else if (d<=0) {
    return messageHelper(dd, msg+"\r\n"+"Please select a valid day.");
  } else if (y<=0) {
    return messageHelper(yyyy, msg+"\r\n"+"Please select a valid year.");
  }
  
  if ( (x_days_per_month[m] < d) || ((m == 2) && d > getFebDays(y)) ) {
    return messageHelper(dd, msg+"\r\n"+"Please select a valid day.");
  }
    
  return true;
}


/**
 * Makes sure that the specified input's value has one of the specified
 * extensions (which must be a comma-separated list).
 */
function checkExtensions(el, msg, extensions) {
	var str = el.value;
	extensions = extensions.split(',');
	for (var i = 0; i < extensions.length; i++) {
		var idx = str.lastIndexOf(extensions[i]);
		if (idx != -1 && idx == str.length - extensions[i].length)
			return true;
	}
	return messageHelper(el, msg);
}

/**
 * Makes sure that at least one of the specified radio buttons is checked.
 */
function checkSelected(els, msg) {
	var lenx = (els != null ? els.length : 0);
	if (lenx == null) lenx = 0;
	
	for (var i = 0; i < lenx; i++) {
		if (els[i].checked) return true;
	}
	return messageHelper(els[0], msg);
}

// pass in year, get back days in that year's February
function getFebDays(y) {
  var febDays = 28;
  if (y % 4 == 0) {
    febDays = 29;
    if (y % 100 == 0) {
      febDays = 28;
      if (y % 400 == 0) {
        febDays = 29;
      }
    }
  }
  return febDays;
}

/**
 * 
 * Returns true iff the specified field's value contains an @ and a period,
 * and at least one character before the @ and at least one char after the period.
 */
function checkEmail(el, msg) {
	var msgDetail = null;
	var value = trim(el.value);
	
	var atloc = value.indexOf('@');
	if (value.length < 1) 
		msgDetail = "";
	else if (atloc < 1)
		msgDetail = "\r\nEmail addresses have a username followed by an @ symbol.";
	else if (value.lastIndexOf('.') < atloc)
		msgDetail = "\r\nThe @ symbol should be followed by an email domain.";
	
	if (msgDetail != null) 
		return messageHelper(el, msg+"\r\n"+msgDetail);
	else
		return true;
}





function checkEmail2(el) {
	var msgDetail = null;
	var value = trim(el.value);
	var email = el.value;

	var at_pos;
	var pd_pos;
	var sp_pos;
	var em_len;
  
  // Make sure there is a value
  em_len = email.length;
  if (em_len < 1) {
	  msgDetail = "Email address must contain a value.";
	  return messageHelper(el, msgDetail);
  }
  
  // Check for spaces
  sp_pos = email.indexOf(" ",0);
  if (sp_pos != -1) {
	  msgDetail = "Spaces are not allowed in email addresses.";
	  return messageHelper(el, msgDetail);
  }
  
  // Check for @ symbol
  at_pos = email.indexOf("@",0);
  if (at_pos == -1) {
	  msgDetail = "There must be a @ symbol in an email address.";
	  return messageHelper(el, msgDetail);
  }
  
  // Check for a period after the @ symbol
  pd_pos = email.indexOf(".",at_pos);
  if (pd_pos == -1) {
	  msgDetail = "There must be a period after the @ symbol in an email address.";
	  return messageHelper(el, msgDetail);
  }
  
  // Check for period as last character
  if (pd_pos == (em_len - 1)) {
	  msgDetail = "Email address cannot end with a period.";
	  return messageHelper(el, msgDetail);
  }

  // Make sure there is at least one character between @ and .
  if (pd_pos == (at_pos + 1)) {
	  msgDetail = "There must be at least 1 character between the @ symbol and period.";
	  return messageHelper(el, msgDetail);
  }
   

  // Make sure address doesn't start with @ 
  if (at_pos == 0) {
	  msgDetail = "Email addresses cannot begin with a @ symbol.";
	  return messageHelper(el, msgDetail);
  }
  
	
  return true;
}




/**
 * Returns true iff the specified field only contains a valid zip code.
 * Valid zips are 5 digits long or are 5 digits plus a hyphen plus 4 digits.
 * If mustBe5digitZip is specified true, then only 5-digit zips will be allowed.
 */
function checkZip(el, msg, mustBe5digitZip) {
	var value = trim(el.value);

	if (!mustBe5digitZip && value.length == 10 && value.charAt(5) == '-')
		value = value.substring(0,5)+value.substring(6);
	else if (value.length != 5)
		return messageHelper(el, msg);
	
	var lenx = value.length;
	for (var i = 0; i < lenx; i++) {
		if ("0123456789".indexOf(value.charAt(i)) == -1)
			return messageHelper(el, msg);
	}
	return true;
}


/*
  Verifies that the element has some text in it.
*/
function checkNonEmpty(el, msg) {
	if (trim(el.value) == '') return messageHelper(el, msg);
	return true;
}

/*
  Trims left side spaces from the given value and returns trimed string
 */
function ltrim(value) {
	if (value == null) return value;
	if (value.length < 1) return value;
	var result = new String(value);
	while (result.length > 0 && result.charAt(0) <= ' ')
	{
		result = result.substr(1);
	}
	return result;
}

/*
  Trims right side spaces in the given value and returns trimed string
 */
function rtrim(value) {
	if (value == null) return value;
	if (value.length < 1) return value;
	var result = new String(value);
	while (result.length > 0 && result.charAt(result.length - 1) <= ' ')
	{
		result = result.substring(0, result.length - 1);
	}
	return result;
}

/*
  Trims spaces from both ends in the given value and returns trimed string
 */
function trim(value) {
	return rtrim(ltrim(value));
}

/*
  Forces the element's value to be no longer than maxlen characters.
*/
function restrictArea(el, wind, maxlen) {
    if (wind.event.type == 'paste') {
        var proposed_value = el.value + wind.clipboardData.getData("Text");
        
        if (proposed_value.length > maxlen) {
            el.value = proposed_value.substring(0, maxlen);
            wind.event.cancelBubble = true;
            wind.event.returnValue = false;
            return false;
        }
    } else {
        var spaceNeeded = 1;
        if (wind.event.keyCode == 13) spaceNeeded = 2;
        if (el.value.length + spaceNeeded > maxlen) {
            wind.event.cancelBubble = true;
            wind.event.returnValue = false;
            return false;
        } 
    }
    return true;
}

/*
  Ensures that people can't select an invalid day for the specified month/year.
  Pass in a month, day, and year select object.
*/
function repairDays(mm, dd, yyyy) {
  var m = parseFloat(mm.options[mm.selectedIndex].value);
  if (isNaN(m)) m = mm.selectedIndex+1;


  var y = parseFloat(yyyy.options[yyyy.selectedIndex].value);
  if ((m <= 0) || (y <= 0)) return;
  var d_sel = dd.selectedIndex;
  var d_max_valid = top.daysInMonth(m, y);

  var offset = 1;
  if (parseFloat(dd.options[0].value) <= 0) offset = 0;
  for (var i = 31; i >= 28; i--) {
    if (i > d_max_valid) {
      dd.options[i-offset] = null;
    } else {
      dd.options[i-offset] = new Option(""+i, ""+i);
    }
  }
  if (dd.options[d_sel] != null)
    dd.selectedIndex = d_sel;
  else
    dd.selectedIndex = dd.options.length - 1;
  
}

/**
 * Replaces each character in invalidChars with the corresponding 
 * character in newChars (which should be the same length as invalidChars).
 */
function replaceIllegals(str, invalidChars, newChars) {	
	invalidChars = invalidChars.substring(0, Math.min(invalidChars.length, newChars.length)); // so we don't go too far!
	
	var retval = "";
	var lenx = str.length;
	for (var i = 0; i < lenx; i++) {
		var ch = str.charAt(i);
		var idx = invalidChars.indexOf(ch);
		retval += (idx == -1 ? ch : newChars.charAt(idx));
	}
	return retval;
}


/**
 * Returns the string located at the specified location.
 */
function getUrlContents(url) {
	var httpObject = new ActiveXObject("Microsoft.XMLHTTP");
	httpObject.open("GET", url, false);
	httpObject.send();
	return httpObject.responseText;
}


/**
 * Shows the source of a file in a popup.
 */
function showSource(url) {
	var src = getUrlContents(url);
	if (document.showSourceWindow != null && !document.showSourceWindow.closed) document.showSourceWindow.close();
	
	var wnd = window.open("about:blank", "popup");
	var dc = wnd.document;
	dc.open("text/plain");
	dc.write(src);
	dc.close();
	wnd.focus();
	document.showSourceWindow = wnd;
}


function VerifyAge(validAge, bmonth, bday, byear) {
 
  var today = new Date();								// full date of today
  var currYear = today.getYear();						// year of today
  var currMonth = today.getMonth();						// month of today (0-11)
  var currDay = today.getDate();						// day of today (1-31)

  currMonth += 1;				
  var yearsDiff = currYear - byear;		


  
  if (yearsDiff > validAge) {			// if yearsdiff > the valid age, let it pass
    return true; }
  else if (yearsDiff < validAge) {		// yearsdiff < validage, fail
    return false; }
  else {								// same year as threshold; use month/day to determine
    if (bmonth < currMonth) {			// had birthday in prior month this year - pass
		return true; }
	else if (bmonth > currMonth)  {		// haven't had your birthday yet this year - fail
		return  false; }  
	else {								// birthday is this month		
		if (bday <=	currDay) {			// birthday earlier this month or today
			return true;  }				
		else {							// birthday later this month - fail
			return false;   } 
		}  
		return false; } 
	return  false; 
}  
