function Left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}
function Right(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function invertSelect(selectField) {
	if (selectField.type == "select-multiple") {
		for (var i = selectField.options.length-1; i >= 0; i--) {
			selectField.options[i].selected = !selectField.options[i].selected;
		}
	}
}

function selectAll(selectField,selected) {
	if (selectField.type == "select-multiple") {
		for (var i = selectField.options.length-1; i >= 0; i--) {
			if (selected == true)
				selectField.options[i].selected = true;
			else
				selectField.options[i].selected = false;
		}
	}
}

// Handle text fields with default text (assumes ID = default value)
function defTxtCkFocusSearch(field) {
	if (field.value == field.id) {
		field.className = 'searchFld';
		field.value = '';
	}
}
function defTxtCkBlurSearch(field) {
	if (field.value == field.id || field.value == '') {
		field.className = 'txtFieldDef searchFld';
		field.value = field.id;
	} else {
		field.className = 'searchFld';
	}
}

function defTxtCkFocus(field) {
	if (field.value == field.id) {
		field.className = 'none';
		field.value = '';
	}
}
function defTxtCkBlur(field) {
	if (field.value == field.id || field.value == '') {
		field.className = 'txtFieldDef';
		field.value = field.id;
	} else {
		field.className = 'none';
	}
}

function defSelCkFocus(field) {
	field.className = 'none';
}

function defSelCkBlur(field) {
	if (field.options[field.selectedIndex].value == '') {
		field.className = 'txtFieldDef';
	} else {
		field.className = 'none';
	}
}

function toggleLayer(whichLayer) {
	var elem, vis;
	if (document.getElementById) // this is the way the standards work    
		elem = document.getElementById(whichLayer);
	else if (document.all) // this is the way old msie versions work      
		elem = document.all[whichLayer];
	else if (document.layers) // this is the way nn4 works    
		elem = document.layers[whichLayer];
	vis = elem.style;
	// if the style.display value is blank we try to figure it out here  
	if (vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
		vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
	vis.display = (vis.display==''||vis.display=='block')?'none':'block';
}

// Load a new page in the current window
function redirect(url) {
	window.location.href = url;
}

function confirmRedirect(dispMessage,url) {
	input_box=confirm(dispMessage);
	if (input_box) {
		redirect(url);
	}
}

// Build URL (for links we don't want search engines to follow)
function jsLink(filePath,fileName,fileExt,queryStr) {
	queryStr = queryStr!=''?'?'+queryStr:'';
	redirect(filePath + fileName + '.' + fileExt + queryStr);
}

function checkboxAlert(checkboxField,bStatus,dispMessage) {
	if (checkboxField.checked == bStatus) {
		alert(dispMessage);
	}
}
		
// Check the length of a textarea field and warn user if they've entered greater than a given number of characters.
function checkTextareaLength(field,maxLength,fieldDesc) {
	if (field.value.length > maxLength) {
		alert('Warning. "' + fieldDesc + '" can accept a maximum of ' + maxLength + ' characters. It currently contains ' + field.value.length + ' characters and must be revised before proceding.');
		field.focus();
		field.select();
	}
}

// Standardize year given browser differences
function formatYear(year) {
	return (year < 1000) ? year + 1900 : year;
}

// Validate Date
function validateDate(pDate) {	// assumes date is in format mdy
	var month,day,year,leap=false;
	if (pDate.length == 0) return true;
	month = getDatePart(pDate,'m');
	day = getDatePart(pDate,'d');
	year = getDatePart(pDate,'y');
	if (isNaN(month) || isNaN(day) || isNaN(year)) return false; // date parts include non-numerics
	if (year.length == 2) year = '20'+year;	// assume 2-digit years are 20xx
	if ((month < 1 || month > 12) || (day < 1 || day > 31) || (year.length != 4 || year < 1900)) return false;
	if ((day == 31) && ((month == 4) || (month == 6) || (month == 9) || (month == 11))) return false;
	// February validation
	if ((year % 4 == 0) || (year % 100 == 0) || (year % 400 == 0)) leap = true;
	if ((month == 2) && ((leap && day > 29) || (!leap && day > 28))) return false;
	return true;
}

// Compare Two Dates:	return -1 if first date is before second, 0 if same, 1 if first is after second;
// 										precision can be "y", "m", or "d" (default).
function dateCompare(date1,date2,precision) {	// assumes dates are in format mdy
	var month1,day1,year1,month2,day2,year2;
	month1 = parseInt(getDatePart(date1,'m'));
	day1 = parseInt(getDatePart(date1,'d'));
	year1 = parseInt(getDatePart(date1,'y'));
	month2 = parseInt(getDatePart(date2,'m'));
	day2 = parseInt(getDatePart(date2,'d'));
	year2 = parseInt(getDatePart(date2,'y'));
	if (precision == 'y') {
		if (year1 < year2) return -1;
		else if (year == year2) return 0;
		else return 1;
	} else if (precision == 'm') {
		if (year1 < year2) return -1;
		else if (year1 > year2) return 1;
		else if (month1 < month2) return -1;
		else if (month1 == month2) return 0;
		else return 1;
	} else {
		if (year1 < year2) return -1;
		else if (year1 > year2) return 1;
		else if (month1 < month2) return -1;
		else if (month1 > month2) return 1;
		else if (day1 < day2) return -1;
		else if (day1 == day2) return 0;
		else return 1;
	}
}

// Return Date Part
function getDatePart(pDate,pPart) {	// assumes date is in format mdy
	var p,q,separator;
	if (pDate.indexOf('/')>0) separator = '/';
	else if (pDate.indexOf('-')>0) separator = '-';
	else if (pDate.indexOf('.')>0) separator = '.';
	else return false;	// don't recognize date part separators
	p = pDate.indexOf(separator);
	q = pDate.substring(p+1).indexOf(separator);
	if (pPart == 'm') return pDate.substring(0,p);
	else if (pPart == 'd') return pDate.substring(p+1,p+q+1);
	else if (pPart == 'y') return pDate.substring(p+q+2);
	else return false;	// invalid date part requested
}

// Popup Calendar screen.availHeight screen.availWidth
function popCal(field,evt) {
	var month,year,width,height,left,top,prp='',qStr='';
	// Set popup window size
	width = 175;
	height = 175;
	// Make sure if they already have a date, it's valid
	if (!validateDate(field.value)) {
		alert(field.value+' is an invalid date (mm\/dd\/yyyy).');
		return false;
	}
	// Set popup window month/year to existing, or now() by default
	month = getDatePart(field.value,'m');
	year = getDatePart(field.value,'y');
	if (month) qStr += 'month='+month+'&';
	if (year) qStr += 'year='+year+'&';
	qStr += 'field='+field.name;
	// Set window properties
	if (evt != null) {
		if ((evt.screenX+10+width) < screen.availWidth) prp += 'left='+(evt.screenX+10)+',';
		else prp += 'left='+(evt.screenX-10-width)+',';
		if ((evt.screenY+height) < screen.availHeight) prp += 'top='+(evt.screenY)+',';
		else prp += 'top='+(evt.screenY-10-height)+',';
	}
	prp += 'scrollbars=no,resizable=no,width='+width+',height='+height;
  popWin = window.open('calendar.cfm?'+qStr,'popCal',prp);
	popWin.focus();
}

// Popup Notes Edit Window
function popNotes(field,id,len,evt) {
	var width,height,left,top,prp='';
	// Set popup window size
	width = 400;
	height = 310;
	// Set window properties
	if (evt != null) {
		if ((evt.screenX+10+width) < screen.availWidth) prp += 'left='+(evt.screenX+10)+',';
		else prp += 'left='+(evt.screenX-10-width)+',';
		if ((evt.screenY+height) < screen.availHeight) prp += 'top='+(evt.screenY)+',';
		else prp += 'top='+(evt.screenY-10-height)+',';
	}
	prp += 'scrollbars=no,resizable=no,width='+width+',height='+height;
  popWin = window.open('','popNotes'+id,prp);
  if (popWin.document.forms[0] == null) {
    var page='';
    page += '<html><head><title>Editor</title><script language="JavaScript">\n';
		page += 'function checkForm() {';
		page += 'if ((' + len + ' != -1) && (document.edit.notes.value.length > ' + len + ')) alert(\'The maximum number of characters allowed is ' + len + '. The string currently contains \' + document.edit.notes.value.length + \' characters.\');';
		page += 'else {';
		page += 'window.opener.replaceNotes(\''+field.name+'\',document.edit.notes.value);';
		page += 'window.close();';
		page += '}}\n';
		page += '</script></head><body>';
		page += '</head><body>';
    page += '<form name="edit" onsubmit="return false;">';
    page += '<textarea name="notes" rows="15" cols="40">';
    page += field.value;
    page += '</textarea><br>';
    page += '<input name="Submit" type="Submit" value="Save" onclick="checkForm();">&nbsp;&nbsp;';
    page += '<input name="Cancel" type="Submit" value="Cancel" onclick="window.close();">';
    page += '</form></body></html>';
    popWin.document.write(page);
  }
  popWin.document.edit.notes.focus();
}

// Takes output from Popup Note Edit Window and inserts in appropriate field
function replaceNotes(fieldName,text) {
  field = MM_findObj(fieldName);
  field.value = text;
  field.onchange();
}

// Set hidden updated-record flag to true
function updRec(fieldName) {
  field = MM_findObj(fieldName);
  field.value = 'true';
}

// Enable/disable add-record fields
// Arguments:  list of fields that are affected followed by boolean indicating current state of checkbox
function enableAddRec() {
  var args=enableAddRec.arguments;
  for (i=0; i<(args.length-1); i++) {
    obj=MM_findObj(args[i]);
    if (obj) {
			if (obj.type == 'text' || obj.type == 'password')
     		obj.readOnly = !(args[args.length-1]);
			else if (obj.type != 'hidden' || (obj.type == 'hidden' && obj.disabled))
     		obj.disabled = !(args[args.length-1]);
			
			if (obj.type != 'radio' && obj.type != 'checkbox') {
				if (args[args.length-1])
					obj.className='fieldEnabled';
				else
					obj.className='fieldDisabled';
			}
    }
  }
}

// return the value of the radio button that is checked
// return an empty string if none are checked, or
// there are no radio buttons
function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

// set the radio button with the given value as being checked
// do nothing if there are no radio buttons
// if the given value does not exist, all the radio buttons
// are reset to unchecked
function setCheckedValue(radioObj, newValue, fireOnClick) {
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
			if(fireOnClick)
				radioObj[i].click();
		}
	}
}

// Macromedia functions
function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_validateForm() { //v4.0 -Mods by BCA (display ID in error msg; enhanced email check)
	  var i,e,p,q,nm,test,num,min,max,errors='',args=MM_validateForm.arguments;
		  for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=MM_findObj(args[i]);
		    if (val) {if(val.id=='')nm=val.name;else nm=val.id; if ((val=val.value)!=""&&val!=nm) {
		      if (test.indexOf('isEmail')!=-1) { 
						p=val.indexOf(' ');
		        if (p>0) errors+='- '+nm+' must contain a valid e-mail address.\n';
						p=val.indexOf('@');
		        if (p<1 || p==(val.length-1)) errors+='- '+nm+' must contain a valid e-mail address.\n';
						else { e=val.substring(p).indexOf('.');
		        	if (e<2 || e==(val.substring(p).length-1)) errors+='- '+nm+' must contain a valid e-mail address.\n';
						} } else if (test!='R') {
		        if (isNaN(val)) errors+='- '+nm+' must contain a number.\n';
		        if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
		          min=test.substring(8,p); max=test.substring(p+1);
		          if (val<min || max<val) errors+='- '+nm+' must contain a number between '+min+' and '+max+'.\n';
		    } } } else if (test.charAt(0) == 'R') errors += '- '+nm+' is required.\n'; }
		  } if (errors) alert('The following error(s) occurred:\n'+errors);
	  document.MM_returnValue = (errors == '');
	}

function MM_openBrWindow(theURL,winName,features) { //v2.0 (BCA - added focus)
  popWin = window.open(theURL,winName,features);
	popWin.focus();
}

function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function MM_showHideLayers() { //v6.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
    obj.visibility=v; }
}

/**
 * Code below taken from - http://www.evolt.org/article/document_body_doctype_switching_and_more/17/30655/
 *
 * Modified 4/22/04 to work with Opera/Moz (by webmaster at subimage dot com)
 *
 * Gets the full width/height because it's different for most browsers.
 */
function getViewportHeight() {
	if (window.innerHeight!=window.undefined) return window.innerHeight;
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientHeight;
	if (document.body) return document.body.clientHeight; 
	return window.undefined; 
}

function getViewportWidth() {
	if (window.innerWidth!=window.undefined) return window.innerWidth; 
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientWidth; 
	if (document.body) return document.body.clientWidth; 
	return window.undefined; 
}

function CloseIframe(){//if the parent contains this function, then we are using modal iframe
if (window.parent.hidePopWin) window.parent.hidePopWin(null); else self.close();
}

/**
 * X-browser event handler attachment and detachment
 *
 * @argument obj - the object to attach event to
 * @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
 * @argument fn - function to call
 */
function addEvent(obj, evType, fn){
 if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
 } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
 } else {
    return false;
 }
}

function removeEvent(obj, evType, fn, useCapture){
  if (obj.removeEventListener){
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.detachEvent){
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
}

function getPopupCaller() {
if (window.parent.hidePopWin) return window.parent; else return window.opener;
}
// End of IFrame Popup Routines

function IE7Up()
{ 											
	var agt = navigator.userAgent.toLowerCase();
	var major = parseInt(navigator.appVersion);
	var ie4 = ((major == 4) && (agt.indexOf("msie 4")!=-1));
		var ie5 = ((major == 4) && (agt.indexOf("msie 5")!=-1));
	var ie6 = ((major == 4) && (agt.indexOf("msie 6")!=-1));
		return IE6Up = (!ie4 && !ie5 && !ie6 && major >= 4);		       
}
