   IE4 = document.all;
   NS4 = document.layers;

// check for empty or null string
function isEmpty(s) {
    if ( s != null && (s == "XXX" || s == "" || s.length == 0 ) ) {
        return true;
    } else {
        return false;
    }
}

function newParseFloat(s) {
var c,i,n,tmp;
    tmp = "";
    for ( i=0; i<s.length; i++ ) {
        c = s.charAt(i);
        if ( c != "," ) tmp += c;
    }
    return parseFloat(tmp);
}

// check for empty or numeric string that evaluates to 0
function isZero(s) {
    var nNumber=0;
    if ( isEmpty(s) ) return true;
    if ( s == ".00" || s == "0.00" || s == "0" ) return true;
    if ( isNumber(s, true) ) {
        nNumber = newParseFloat(s);
        if ( nNumber == 0 ) return true;
    } else {
        return true;
    }
    return false;
}

// is character a digit
function isDigit(c) {
    return (c>="0" && c<="9" ? true : false);
}

// check if string is a valid number
function isNumber(s, bAllowDec) {
var c,i
    if ( bAllowDec == null ) bAllowDec = false;
    for ( i=0; i<s.length; i++ ) {
        c = s.charAt(i);
        if  ( !isDigit(c) ) {
            return ( c=='.' ? bAllowDec : (c==",") );
        }
    }
    return true;
}

// round a number to specified number of decimal places
function roundOff(nVal, nDec) {
var nIValue=nVal * Math.pow(10, nDec);
    nIValue = Math.round(nIValue);
    return (nIValue / Math.pow(10, nDec));
}

// validation function to validate a number
function ValNumber(field, bAllowDec, bAllowZero, nMinLength) {
var s
    if ( bAllowDec == null ) bAllowDec = false;
    if ( bAllowZero == null ) bAllowZero = true;
    if (isEmpty(field.value)) return true;
    s = StripZero(field.value);
    if ( !isNumber(s, bAllowDec) ) {
        alert("This field should be a number.\(Invalid value)");
        cFocusClass = "errorin";
        field.select();
        field.focus();
        return false;
    }
    if ( !bAllowZero && isZero(s) ) {
        alert("Zero not allowed.");
        cFocusClass = "errorin";
        field.select();
        field.focus();
        return false;
    }
    if ( nMinLength ) {
        return MinLength(field, nMinLength);
    }
    return true;
}

function ValCurrency(field, bAllowZero) {
var sValue;
    if ( !ValNumber(field, true, bAllowZero, 1) ) return false;
    sValue = field.value;

    //  Parse the value into a float number
	var iValue = newParseFloat(sValue);
	iValue = (Math.round(iValue * 100)) / 100;

	//  If the value is not a number, return an error
	if (isNaN(iValue))
	{
	    alert("Not a valid amount");
        field.focus();
	    return false;
    }

    //  Return the value to a string to apply formatting
    sValue = iValue.toString();

    //
    //  Fill in zeros (if necessary) to show two digits to the right
    //  of the decimal
    //
    if (sValue.indexOf(".") == -1)
    {
        sValue = sValue + ".00";
    }
    else
    {
        if (sValue.indexOf(".") == sValue.length - 1)
        {
            sValue = sValue + "00";
        }
        else if (sValue.indexOf(".") == sValue.length - 2)
        {
            sValue = sValue + "0";
        }
    }

    //  Add commas if necessary
    if (sValue.indexOf(".") > 3)
    {
        sValue = sValue.substring(0,sValue.indexOf(".") - 3) + ","
            + sValue.substring(sValue.indexOf(".") - 3,sValue.length);
    }
    if ( sValue.indexOf(",") > 3) {
        sValue = sValue.substring(0,sValue.indexOf(",") - 3) + ","
            + sValue.substring(sValue.indexOf(",") - 3,sValue.length);
    }

	field.value = sValue;
    return true;
}



// validation function to validate a number within a specified range
function ValRange(fld, bAllowDec, bAllowZero, nLowRange, nHiRange, nMinLength) {
var nValue;
var s
    if (isEmpty(fld.value)) return true;
	s=StripZero(fld.value);
    if ( !ValNumber(fld, bAllowDec, bAllowZero, nMinLength) ) return false;

    if ( bAllowDec ) {
    	nValue = newParseFloat(s);
    } else {
        nValue = parseInt(s);
    }
    if ( nValue < nLowRange || nValue > nHiRange ) {
        alert("Outside of range\n(" + nLowRange.toString() + " to " + nHiRange.toString() + ")");
        fld.focus();
        return false;
    }
    return true;
}

// validate that a field has a minimum number of characters entered
function MinLength(fld, nMinLen) {
    if ( fld.value ) {
        if ( fld.value.length < nMinLen ) {
            alert("Must be at least " + nMinLen.toString() + " characters");
            fld.focus();
            return false;
        }
    }
    return true;
}

function checkNumber(el, nNumDec, bAllowComma) {
    // Make sure IE4
    if (!document.all) return true
    if ( bAllowComma == null ) bAllowComma = false;
    // Convert key code to character
    var key = String.fromCharCode(event.keyCode), dotRelationship, allowDigit
    var checkDot = false
    var allowDigit = false
    // Check if number of digits following decimal point is cached
    if (el._digits==null) {
      el._digits = (nNumDec==0 ? -1 : nNumDec);
    }

    // Make sure a digit or a decimal point
    if (!isNaN(key) || key=="." || (bAllowComma && key==",")) {
      // Get selection (either insertion point or text selection)
      var selectionRange = document.selection.createRange()
      // Store a copy for use in comparisons
      var tempSel = selectionRange.duplicate()

      // Variable for the input range
      var inputRange = el.createTextRange()

      // Get index of the dot
      var dotPos = el.value.indexOf(".")

      // If decimal point, check if new character valid
      if (dotPos>-1) {
        // Locate existing decimal point
        inputRange.findText(".")
        // When user types decimal, it is only accepted if
        // replacing existing decimal point
        if ((key==".")  && (el._digits>-1)) {
          if (tempSel.findText("."))
          // Test if existing decimal in selection
          checkDot = selectionRange.inRange(tempSel)
        } else {
          // Determine whether the selection is before or after the decimal point
          dotRelationship = inputRange.compareEndPoints("EndToStart",selectionRange)
          // Test if new input is an allowable digit
          allowDigit = ((dotRelationship<=0 && (el.value.length - dotPos -1 < el._digits || selectionRange.text.length>0)) || (dotRelationship==1 && key!="."))
        }
      } else {
        // If inserting a decimal, test number of following digits
        if (key==".")
          tempSel.moveEnd("textEdit",1)
        allowDigit = (key=="." && (tempSel.text.length - 1 < el._digits)) || !isNaN(key) || (bAllowComma && key==",")
      }
    }
    // Return whether the key is allowed
    return (checkDot || allowDigit)
}

// strip leading zeros from a numeric string (Javascript parseInt() function messes up trying to convert
// a string with leading zeros
function StripZero(s) {
var cRet="",i
var b1stNonZero=false;
    for (i=0; i<s.length; i++) {
        c = s.charAt(i);
        if ( b1stNonZero ) {
			cRet += c;
        } else if ( c != "0" ) {
            b1stNonZero = true;
			cRet += c;
        }
    }
    if ( !b1stNonZero ) cRet = "0";
    return cRet;
}

// turn a number into a string with a leading zero if less than 10
function LeadZero(nNum) {
    return (nNum<10 ? "0" : "" ) + nNum.toString();
}

// convert a numeric string to a float, default to 0 if empty
function cvt2Float(s) {
    return(isEmpty(s)? 0 : newParseFloat(s));
}

// validation function for Social Security number
function ValidSSN(field) {
    return ValidMask(field, "999-99-9999", "Social Security Number");
}

// validation function for US type phone number
function ValidPhone(field) {
    return ValidMask(field, "999-999-9999", "Phone Number");
}

/*
    Generic field mask validation
    cMask:
        9 - digit only
        A - alpha char only
        X - don't care
        any other - match that char
        Ex: phone#: "999-999-9999"
    cMsg - usually name of field. Do not include this if you only want to return t/f (no alert)
*/
function ValidMask(field, cMask, cFldName, cMsg, nMinLength) {
var m,i,c,s,cErrMsg;
var nLen=cMask.length;
var bRet=true;
	s=field.value;
    if ( !nMinLength ) nMinLength = nLen
    if (isEmpty(s)) return true;
    if ( s == cMask ) {
        alert("Invalid " + (!cFldName ? "value" : cFldName));
        field.focus();
        return false;
    }

    if ( !cMsg ) {
		cErrMsg = cFldName + " should be in " + cMask + " format.";
    } else {
        cErrMsg = cMsg;
    }
    if (s.length < nMinLength) {
        cErrMsg = cFldName + " must be at least " + nMinLength.toString() + " characters";
		bRet = false;
    }
    nLen = s.length;
    if ( bRet ) {
        for (i=0; i<nLen; i++) {
            c = s.charAt(i);
            m = cMask.charAt(i);
            if ( m == "9" ) {
                if ( !isDigit(c) ) {
                    bRet = false;
                    break;
                }
            } else if ( m == "A" ) {
                    if ( !((c>="A" && c<="Z") || (c>="a" && c<="z")) ) {
                        bRet = false;
                        break;
                    }
            } else if ( m == "T" ) {
                    if ( !((c>="A" && c<="Z") || (c>="a" && c<="z") || (c==" ")) ) {
                        bRet = false;
                        break;
                    }

            } else if ( m == "X" ) {
            } else if ( c != m ) {
					bRet = false;
                    break;
            }
        }
    }
    if ( !bRet && cErrMsg ) {
        alert(cErrMsg);
        cFocusClass = "errorin";
        field.focus();
        return false;
    }
    return bRet;
}

// dateObject class definition
// Usage oDate = new(xDate)
function dateObject(xDate) {
    xDate = (!xDate ? new Date() : xDate);
    if (typeof xDate=="string") {
		dDate =  Str2Date(xDate);
        this.dateStr = xDate;
    } else {
		dDate = xDate;
	    this.dateStr = Date2Str(dDate);
    }
    this.now = dDate;
    this.year = this.now.getYear();
    this.year = (this.year < 1900) ? this.year+1900 : this.year;
    this.month = this.now.getMonth();
    this.day = this.now.getDate();
    this.dateNumber = this.year*10000 + (this.month+1)*100 + this.day;
}

// convert date datatype to a string MM/DD/YYYY
function Date2Str(dDate) {
var nMon=dDate.getMonth()+1;
var nDay=dDate.getDate();
var nYear=dDate.getFullYear();
    return LeadZero(nMon) + "/" + LeadZero(nDay) + "/" + nYear.toString();
}

// convert date string MM/DD/YYYY to a date datatype
function Str2Date(cDateStr) {
var nMon,nDay,nYear;
	nMon = (cDateStr.substring(0,2)=="00" ? 0 : parseInt(StripZero(cDateStr.substring(0,2))));
    nDay = (cDateStr.substring(3,5)=="00" ? 0 : parseInt(StripZero(cDateStr.substring(3,5))));
    nYear = parseInt(cDateStr.substring(6,10));
    return new Date(nYear, nMon-1, nDay);
}


// validation function for date input (MM/DD/YYYY)
function ValidDate(field, nDateTest, nMinYear) {
var sValue=field.value;
var i1,i2,nMon,nDay,nYear;
var oToday = new dateObject();
var cMsg="Invalid date. Date must be\n in MM/DD/YYYY format.";
var bRet=true,nErr=0;
var aDaysInMonth = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var iToday = new Date();
    if ( nDateTest == null ) nDateTest = 0;
    if ( nMinYear == null ) nMinYear = 1900;
    if ( isEmpty(sValue) ) return true;

    i1 = sValue.indexOf("/");
    if ( i1 == -1 ) {
        alert(cMsg);
        field.focus();
        return false;
    }


    nMon = parseInt(StripZero(sValue.substring(0,i1)));
	if ( isNaN(nMon) ) {
           alert("Invalid Month");
           field.focus();
           return false;
    }

    i2 = sValue.indexOf("/", i1+1);
    if ( i2 == -1 ) {
        nDay = parseInt(StripZero(sValue.substring(i1+1)));
        nYear = iToday.getFullYear();
    } else {
        nDay = parseInt(StripZero(sValue.substring(i1+1,i2)));
        nYear = parseInt(sValue.substring(i2+1));
        if ( isNaN(nYear) ) {
            alert("Invalid Year");
            field.focus();
            return false;
        }
        if ( nYear < 90 ) {
			nYear += 2000;
        } else if (nYear>=90 && nYear<=100) {
            nYear += 1900;
        } else if ( nYear >= 100 && nYear <1000 ) {
            alert("Invalid Year");
            field.focus();
            return false;
        }
    }
    if ( isNaN(nDay) ) {
           alert("Invalid Day");
           field.focus();
           return false;
    }


    if ( nMon <1 || nMon > 12 ) {
        bRet = false;
        nErr=6;
        cMsg = "Invalid Month.";
    }

    if ( bRet && nYear < nMinYear ) {
        nErr=7;
        bRet = false;
        cMsg = "Invalid Year.";
    }


    if ( bRet ) {
        if ( nDay < 1 ) {
            nErr=8;
            bRet = false;
        }
        aDaysInMonth[1] =  (  ((nYear % 4 == 0) && ( (!(nYear % 100 == 0)) || (nYear % 400 == 0) ) ) ? 29 : 28 );

        if ( !bRet || (nDay > aDaysInMonth[nMon-1]) ) {
            nErr=9;
            bRet = false;
            cMsg = "Invalid Day.";
        }
    }
    sValue = LeadZero(nMon) + "/" + LeadZero(nDay) + "/" + nYear.toString();

    if ( bRet && nDateTest != 0 ) {
        oThisDate = new dateObject(sValue);
        //alert("Datems="+oThisDate.dateNumber.toString()+"\ntodayms="+nTodayDateValue.toString()+"\nDateTest=");
        if ( nDateTest < 0 && oThisDate.dateNumber < oToday.dateNumber ) {
            bRet = false;
            nErr = 20;
            cMsg = "Dates in the past not allowed\n(System today=" + oToday.dateStr + ")";
        }
        if ( nDateTest > 0 && oThisDate.dateNumber > oToday.dateNumber ) {
            bRet = false;
            nErr = 21;
            cMsg = "Dates in the future not allowed\n(System today=" + oToday.dateStr + ")";
        }
    }
    if ( !bRet ) {
        alert("Err " + nErr.toString()+ ": " + cMsg);
        field.focus();
        return false;
    } else {
        field.value = sValue;
        return true;
    }
}


// validation function for time field HH:MM in 24 hr time
function ValidTime(field, bEmptyOK) {
var cTime=field.value;
var nColonPos=cTime.indexOf(":");
var cMsg="Invalid time. Must be in HH:MM (24 hr) format."
    if ( isEmpty(cTime) ) {
		if ( bEmptyOK ) {
			return true;
        } else {
            alert("Time is required HH:MM");
	        cFocusClass = "errorin";
            field.focus();
            return false;
        }
    }
    if ( !ValidMask(field, "99:99", "Time", cMsg) ) {
        return false;
    } else {
        cHours = cTime.substring(0, nColonPos);
        cMinutes = cTime.substring(nColonPos+1, cTime.length);
        if ( !isNumber(cHours) || !isNumber(cMinutes) ) {
        	alert(cMsg);
	        cFocusClass = "errorin";
        	field.focus();
        	return false;
        } else {
            nHours = parseInt(StripZero(cHours));
            nMinutes = parseInt(StripZero(cMinutes));
            if ( nHours > 23 || nMinutes > 59 ) {
        		alert(cMsg);
		        cFocusClass = "errorin";
        		field.focus();
        		return false;
            } else {
                cTime = LeadZero(nHours) + ":" + LeadZero(nMinutes);
                field.value = cTime;
                return true;
            }
        }
    }
}

// given month and year, returns a date string which is last day of that month
function LastDayOfMonth(cMon, cYear) {
var aDaysInMonth = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var nMon, nYear
    nMon = parseInt(StripZero(cMon));
    nYear = parseInt(cYear);
    aDaysInMonth[1] =  (  ((nYear % 4 == 0) && ( (!(nYear % 100 == 0)) || (nYear % 400 == 0) ) ) ? 29 : 28 );
    return cMon + "/" + LeadZero(aDaysInMonth[nMon-1]) + "/" + cYear;
}


// validation function for comparing two dates
function CompareDates(cDate1, cDate2, cOp, cMsg, fld) {
var bRet=false;
    if ( isEmpty(cDate1) || isEmpty(cDate2) ) return true;
	var oDate1 = new dateObject(cDate1);
	var oDate2 = new dateObject(cDate2);
    if ( cOp == "<" ) {
        bRet = ( oDate1.dateNumber < oDate2.dateNumber ? true : false);
    } else if ( cOp == "<=" ) {
        bRet = ( oDate1.dateNumber <= oDate2.dateNumber ? true : false);
    } else if ( cOp == ">" ) {
        bRet = ( oDate1.dateNumber > oDate2.dateNumber ? true : false);
    } else if ( cOp == ">=" ) {
        bRet = ( oDate1.dateNumber >= oDate2.dateNumber ? true : false);
    } else if ( cOp == "==" ) {
        bRet = ( oDate1.dateNumber == oDate2.dateNumber ? true : false);
    } else if ( cOp == "!=" ) {
        bRet = ( oDate1.dateNumber != oDate2.dateNumber ? true : false);
    }
    if ( !bRet ) {
        alert(cMsg);
        fld.focus();
        return false;
    }
    return true;
}

// validation function for checking expiration (date earlier than today)
function CheckExpire(cDate, fld, cMsg) {
var oToday = new dateObject();
    return CompareDates(cDate, oToday.dateStr, ">=", cMsg + "\n(System Today=" + oToday.dateStr + ")", fld);
}

// pop up a new window with cPage in it. Good for popoup help
function ShowHelp(cPage) {
var remote = open(cPage, "helpwindow", "height=400,width=500,resizable=no,scrollbars=yes,status=no,titlebar=yes");
    return remote;
}

// validation function to ensure required field is entered
function FldRequired(fld, cFldName) {
var bSuccess=true;
    if ( !cFldName ) cFldName = fld.name;
    if ( fld.type.indexOf("select") != -1 ) {
        bSuccess = (fld.selectedIndex == 0 ? false : true);
    } else if (fld.type.indexOf("checkbox") != -1 ) {
        bSuccess = fld.checked;
    } else {
    	bSuccess = !isEmpty(fld.value);
	}
	if (!bSuccess) {
        alert(cFldName + " is a required field.");
        cFocusClass = "errorin";
        fld.focus();
        return false;
    }
    return true;
}



