// include the VBSCompat script for common VB Functions
// *******************************************************************************************
// Removes spaces on the left side of a string
// *******************************************************************************************

function LTrim(str) {
    var whitespace = new String(" \t\n\r");
    var s = new String(str);
    if (whitespace.indexOf(s.charAt(0)) != -1) {
        var j = 0, i = s.length;
        while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
            j++;
        s = s.substring(j, i);
    }
    return s;
}

// *******************************************************************************************
// Removes spaces on the right side of a string
// *******************************************************************************************

function RTrim(str) {
    var whitespace = new String(" \t\n\r");
    var s = new String(str);
    if (whitespace.indexOf(s.charAt(s.length - 1)) != -1) {
        var i = s.length - 1;
        while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
            i--;
        s = s.substring(0, i + 1);
    }
    return s;
}

// *******************************************************************************************
// Returns the number of characters in a string
// *******************************************************************************************

function Len(str) {
    return String(str).length;
}

// *******************************************************************************************
// Removes spaces on both the left and the right side of a string
// *******************************************************************************************

function Trim(str) {
    return RTrim(LTrim(str));
}

// *******************************************************************************************
// Returns a specified number of characters from the left side of a string
// *******************************************************************************************

function Left(str, n) {
    if (n <= 0)
        return "";
    else if (n > String(str).length)
        return str;
    else
        return String(str).substring(0, n);
}

// *******************************************************************************************
// Returns a specified number of characters from the right side of a string
// *******************************************************************************************

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);
    }
}

// *******************************************************************************************
// Returns a specified number of characters from a string
// *******************************************************************************************

function Mid(str, start, n) {
    if (start < 0 || n < 0) {
        return "";
    }
    var iEnd, iLen = String(str).length;
    if (start + n > iLen) {
        iEnd = iLen;
    } else {
        iEnd = start + n;
    }
    return String(str).substring(start, iEnd);
}

// *******************************************************************************************
// Converts a specified string to lowercase
// *******************************************************************************************

function LCase(str) {
    return String(str).toLowerCase();
}

// *******************************************************************************************
// Converts a specified string to uppercase
// *******************************************************************************************

function UCase(str) {
    return String(str).toUpperCase();
}

// *******************************************************************************************
// Returns the position of the first occurrence of one string within another. The search
// begins at the first character of the string
// *******************************************************************************************

function InStr(strSearch, charSearchFor) {
    var iLength1;
    var iLength2;
    iLength1 = Len(strSearch);
    iLength2 = Len(charSearchFor);
    for (var i = 0; i < iLength1; i++) {
        if (LCase(charSearchFor) === Mid(LCase(strSearch), i, iLength2)) {
            return i;
        }
    }
    return -1;
}

// *******************************************************************************************
// Returns a zero-based, one-dimensional array that contains a specified number of substrings
// *******************************************************************************************

function Split(str, delimiter) {
    return String(str).split(delimiter);
}

// *******************************************************************************************
// Returns the largest subscript for the indicated dimension of an array
// *******************************************************************************************

function UBound(arry) {
    return arry.length;
}

// *******************************************************************************************
// Returns the smallest subscript for the indicated dimension of an array (always 0)
// *******************************************************************************************

function LBound(arry) {
    return 0;
}
// *******************************************************************************************
// Replaces a specified part of a string with another string a specified number of times
// *******************************************************************************************

function Replace(str, strFind, strReplace) {
    var strRegExp;

    strRegExp = new RegExp(strFind, "gi");
    return String(str).replace(strRegExp, strReplace);
}

// *******************************************************************************************
// Converts an expression to a variant of subtype String
// *******************************************************************************************

function CStr(value) {
    return String(value);
}

// *******************************************************************************************
// Converts an expression to a variant of subtype Double
// *******************************************************************************************

function CDbl(value) {
    var val;
    
    if (InStr(value,"$")===0){
		val=Right(value,Len(value)-1);
    } else {
    	val=value;
    }
    
    val = Replace(val, ",", "");
	
    return parseFloat(val);
}

// *******************************************************************************************
// Converts an expression to a variant of subtype Integer
// *******************************************************************************************

function CInt(value) {
    return Number(Round(value, 0));
}

// *******************************************************************************************
// Returns the integer part of a specified number
// *******************************************************************************************

function Fix(value) {
    return parseInt(value);
}

// *******************************************************************************************
// Rounds a number
// *******************************************************************************************

function Round(num, dec) {
    var num1 = new Number(num);
    num1.toFixed(dec)

    return Number(num1.toFixed(dec));
}

// *******************************************************************************************
// Returns the position of the first occurrence of one string within another. The search
// begins at the last character of the string
// *******************************************************************************************

function InStrRev(strSearch, charSearchFor) {
    return String(LCase(strSearch)).lastIndexOf(LCase(charSearchFor));
}

// *******************************************************************************************
// Returns a Boolean value that indicates whether a specified expression can be evaluated as
// a number
// *******************************************************************************************

function IsNumeric(value) {
    var ValidChars = "0123456789.$,-";
    var IsNumber = true;
    var Char, i;

    if (value === "" || value === "." || value === "$" || value === "," || value === "-") {
        IsNumber = false;
    } else {
        for (i = 0; i < Len(value) && IsNumber === true; i++) {
            Char = value.charAt(i);
            if (ValidChars.indexOf(Char) == -1) {
                IsNumber = false;
            }
        }
    }

    return IsNumber;
}

// *******************************************************************************************
// date variables and constants
// *******************************************************************************************

// constants
vbGeneralDate = 0; vbLongDate = 1; vbShortDate = 2; vbLongTime = 3; vbShortTime = 4;  // NamedFormat
vbUseSystemDayOfWeek = 0; vbSunday = 1; vbMonday = 2; vbTuesday = 3; vbWednesday = 4; vbThursday = 5; vbFriday = 6; vbSaturday = 7; // FirstDayOfWeek
vbUseSystem = 0; vbFirstJan1 = 1; vbFirstFourDays = 2; vbFirstFullWeek = 3; // FirstWeekOfYear

// arrays (1-based)
Date.MonthNames = [null, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
Date.WeekdayNames = [null, 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

// *******************************************************************************************
// Returns a Boolean value that indicates if the evaluated expression can be converted to
// a date
// *******************************************************************************************

Date.IsDate = function(value) {
    return !isNaN(new Date(value)); 	// <-- review further
}
IsDate = Date.IsDate;

// *******************************************************************************************
// Converts a valid date and time expression to the variant of subtype Date
// *******************************************************************************************

Date.CDate = function(value) {
    if (Date.IsDate(value)) { return new Date(value); }

    var strTry = value.replace(/\-/g, '/').replace(/\./g, '/').replace(/ /g, '/'); // fix separators
    strTry = strTry.replace(/pm$/i, " pm").replace(/am$/i, " am"); // and meridian spacing
    if (Date.IsDate(strTry)) { return new Date(strTry); }

    var strTryYear = strTry + '/' + new Date().getFullYear(); // append year
    if (Date.IsDate(strTryYear)) { return new Date(strTryYear); }


    if (strTry.indexOf(":")) {	// if appears to have time
        var strTryYear2 = strTry.replace(/ /, '/' + new Date().getFullYear() + ' '); // insert year
        if (Date.IsDate(strTryYear2)) { return new Date(strTryYear2); }

        var strTryDate = new Date().toDateString() + ' ' + value; // pre-pend current date
        if (Date.IsDate(strTryDate)) { return new Date(strTryDate); }
    }

    return false; // double as looser IsDate
    //throw("Error #13 - Type mismatch");	// or is this better? 
}
CDate = Date.CDate;

// *******************************************************************************************
// Returns a date to which a specified time interval has been added
// *******************************************************************************************

Date.DateAdd = function(interval, num, date) {
    if (!Date.CDate(date)) { return "invalid date: '" + date + "'"; }
    if (isNaN(num)) { return "invalid number: '" + num + "'"; }

    num = new Number(num);
    var dt = Date.CDate(date);

    switch (interval.toLowerCase()) {
        case "yyyy":
            {
                dt.setFullYear(dt.getFullYear() + num);
                break;
            }
        case "q":
            {
                dt.setMonth(dt.getMonth() + (num * 3));
                break;
            }
        case "m":
            {
                dt.setMonth(dt.getMonth() + num);
                break;
            }
        case "y": 		// day of year
        case "d": 		// day
        case "w":
            {		// weekday
                dt.setDate(dt.getDate() + num);
                break;
            }
        case "ww":
            {	// week of year
                dt.setDate(dt.getDate() + (num * 7));
                break;
            }
        case "h":
            {
                dt.setHours(dt.getHours() + num);
                break;
            }
        case "n":
            {		// minute
                dt.setMinutes(dt.getMinutes() + num);
                break;
            }
        case "s":
            {
                dt.setSeconds(dt.getSeconds() + num);
                break;
            }
        case "ms":
            {	// JS extension
                dt.setMilliseconds(dt.getMilliseconds() + num);
                break;
            }
        default:
            {
                return "invalid interval: '" + interval + "'";
            }
    }
    return dt;
}
DateAdd = Date.DateAdd;

// *******************************************************************************************
// Returns the number of intervals between two dates
// *******************************************************************************************

Date.DateDiff = function(interval, date1, date2, p_FirstDayOfWeek) {
    if (!Date.CDate(date1)) { return "invalid date: '" + date1 + "'"; }
    if (!Date.CDate(date2)) { return "invalid date: '" + date2 + "'"; }
    p_FirstDayOfWeek = (isNaN(p_FirstDayOfWeek) || p_FirstDayOfWeek == 0) ? vbSunday : parseInt(p_FirstDayOfWeek); // set default & cast

    var dt1 = Date.CDate(date1);
    var dt2 = Date.CDate(date2);

    // correct DST-affected intervals ("d" & bigger)
    if ("h,n,s,ms".indexOf(interval.toLowerCase()) == -1) {
        if (date1.toString().indexOf(":") == -1) { dt1.setUTCHours(0, 0, 0, 0) }; // no time, assume 12am
        if (date2.toString().indexOf(":") == -1) { dt2.setUTCHours(0, 0, 0, 0) }; // no time, assume 12am
    }

    // get ms between UTC dates and make into "difference" date
    var iDiffMS = dt2.valueOf() - dt1.valueOf();
    var dtDiff = new Date(iDiffMS);

    // calc various diffs
    var nYears = dt2.getUTCFullYear() - dt1.getUTCFullYear();
    var nMonths = dt2.getUTCMonth() - dt1.getUTCMonth() + (nYears != 0 ? nYears * 12 : 0);
    var nQuarters = parseInt(nMonths / 3); //<<-- different than VBScript, which watches rollover not completion

    var nMilliseconds = iDiffMS;
    var nSeconds = parseInt(iDiffMS / 1000);
    var nMinutes = parseInt(nSeconds / 60);
    var nHours = parseInt(nMinutes / 60);
    var nDays = parseInt(nHours / 24); // <-- now fixed for DST switch days
    var nWeeks = parseInt(nDays / 7);

    if (interval.toLowerCase() == 'ww') {
        // set dates to 1st & last FirstDayOfWeek
        var offset = Date.DatePart("w", dt1, p_FirstDayOfWeek) - 1;
        if (offset) { dt1.setDate(dt1.getDate() + 7 - offset); }
        var offset = Date.DatePart("w", dt2, p_FirstDayOfWeek) - 1;
        if (offset) { dt2.setDate(dt2.getDate() - offset); }
        // recurse to "w" with adjusted dates
        var nCalWeeks = Date.DateDiff("w", dt1, dt2) + 1;
    }
    // TODO: similar for 'w'?

    // return difference
    switch (interval.toLowerCase()) {
        case "yyyy": return nYears;
        case "q": return nQuarters;
        case "m": return nMonths;
        case "y": 		// day of year
        case "d": return nDays;
        case "w": return nWeeks;
        case "ww": return nCalWeeks; // week of year	
        case "h": return nHours;
        case "n": return nMinutes;
        case "s": return nSeconds;
        case "ms": return nMilliseconds; // not in VBScript
        default: return "invalid interval: '" + interval + "'";
    }
}
DateDiff = Date.DateDiff;

// *******************************************************************************************
// Returns the specified part of a given date
// *******************************************************************************************

Date.DatePart = function(part, date, p_FirstDayOfWeek) {
    if (!Date.CDate(date)) { return "invalid date: '" + date + "'"; }

    var dtPart = Date.CDate(date);

    switch (part.toLowerCase()) {
        case "yyyy": return dtPart.getFullYear();
        case "q": return parseInt(dtPart.getMonth() / 3) + 1;
        case "m": return dtPart.getMonth() + 1;
        case "y": return Date.DateDiff("y", "1/1/" + dtPart.getFullYear(), dtPart) + 1; // day of year
        case "d": return dtPart.getDate();
        case "w": return Date.Weekday(dtPart.getDay() + 1, p_FirstDayOfWeek); 	// weekday
        case "ww": return Date.DateDiff("ww", "1/1/" + dtPart.getFullYear(), dtPart, p_FirstDayOfWeek) + 1; // week of year
        case "h": return dtPart.getHours();
        case "n": return dtPart.getMinutes();
        case "s": return dtPart.getSeconds();
        case "ms": return dtPart.getMilliseconds(); // <-- JS extension, NOT in VBScript
        default: return "invalid interval: '" + part + "'";
    }
}
DatePart = Date.DatePart;

// *******************************************************************************************
// Returns the name of a specified month
// *******************************************************************************************

Date.MonthName = function(month, abbrev) {
    if (isNaN(month)) {	// v0.94- compat: extract real param from passed date
        if (!Date.CDate(month)) { return "invalid month: '" + month + "'"; }
        month = DatePart("m", Date.CDate(month));
    }

    var retVal = Date.MonthNames[month];
    if (abbrev == true) { retVal = retVal.substring(0, 3) } // abbr to 3 chars
    return retVal;
}
MonthName = Date.MonthName;

// *******************************************************************************************
// Returns the weekday name of a specified day of the week
// *******************************************************************************************

Date.WeekdayName = function(day_num, abbrev, p_FirstDayOfWeek) {
    if (isNaN(day_num)) {	// v0.94- compat: extract real param from passed date
        if (!Date.CDate(day_num)) { return "invalid weekday: '" + day_num + "'"; }
        day_num = DatePart("w", Date.CDate(day_num));
    }
    p_FirstDayOfWeek = (isNaN(p_FirstDayOfWeek) || p_FirstDayOfWeek == 0) ? vbSunday : parseInt(p_FirstDayOfWeek); // set default & cast

    var nWeekdayNameIdx = ((p_FirstDayOfWeek - 1 + parseInt(day_num) - 1 + 7) % 7) + 1; // compensate nWeekdayNameIdx for p_FirstDayOfWeek
    var retVal = Date.WeekdayNames[nWeekdayNameIdx];
    if (abbrev == true) { retVal = retVal.substring(0, 3) } // abbr to 3 chars
    return retVal;
}
WeekdayName = Date.WeekdayName;

// *******************************************************************************************
// Returns a number that represents the day of the week (between 1 and 7, inclusive)
// *******************************************************************************************

Date.Weekday = function(day_num, p_FirstDayOfWeek) {
    p_FirstDayOfWeek = (isNaN(p_FirstDayOfWeek) || p_FirstDayOfWeek == 0) ? vbSunday : parseInt(p_FirstDayOfWeek); // set default & cast

    return ((parseInt(day_num) - p_FirstDayOfWeek + 7) % 7) + 1;
}
Weekday = Date.Weekday;

// *******************************************************************************************
// Returns an expression formatted as a date or time
// *******************************************************************************************

Date.FormatDateTime = function(date, dtformat) {
    if (date.toUpperCase().substring(0, 3) == "NOW") { date = new Date() };
    if (!Date.CDate(date)) { return "invalid date: '" + date + "'"; }
    if (isNaN(dtformat)) { dtformat = vbGeneralDate };

    var dt = Date.CDate(date);

    switch (parseInt(dtformat)) {
        case vbGeneralDate: return dt.toString();
        case vbLongDate: return FormatDate(date, 'DDDD, MMMM D, YYYY');
        case vbShortDate: return FormatDate(date, 'MM/DD/YYYY');
        case vbLongTime: return dt.toLocaleTimeString();
        case vbShortTime: return FormatDate(date, 'HH:MM:SS');
        default: return "invalid NamedFormat: '" + dtformat + "'";
    }
}
FormatDateTime = Date.FormatDateTime;

// *******************************************************************************************
// returns a formatted date string from date using open format dtformat
// *******************************************************************************************

Date.Format = function(date, dtformat, p_FirstDayOfWeek, p_FirstWeekOfYear) {
    if (!Date.CDate(date)) { return "invalid date: '" + date + "'"; }
    if (!dtformat || dtformat == '') { return dt.toString() };

    var dt = Date.CDate(date);

    // Zero-padding formatter
    this.pad = function(p_str) {
        if (p_str.toString().length == 1) { p_str = '0' + p_str }
        return p_str;
    }

    var ampm = dt.getHours() >= 12 ? 'PM' : 'AM'
    var hr = dt.getHours();
    if (hr == 0) { hr = 12 };
    if (hr > 12) { hr -= 12 };
    var strShortTime = hr + ':' + this.pad(dt.getMinutes()) + ':' + this.pad(dt.getSeconds()) + ' ' + ampm;
    var strShortDate = (dt.getMonth() + 1) + '/' + dt.getDate() + '/' + new String(dt.getFullYear()).substring(2, 4);
    var strLongDate = Date.MonthName(dt.getMonth() + 1) + ' ' + dt.getDate() + ', ' + dt.getFullYear(); 	//

    var retVal = dtformat;

    // switch tokens whose alpha replacements could be accidentally captured
    retVal = retVal.replace(new RegExp('C', 'gi'), 'CCCC');
    retVal = retVal.replace(new RegExp('mmmm', 'gi'), 'XXXX');
    retVal = retVal.replace(new RegExp('mmm', 'gi'), 'XXX');
    retVal = retVal.replace(new RegExp('dddddd', 'gi'), 'AAAAAA');
    retVal = retVal.replace(new RegExp('ddddd', 'gi'), 'AAAAA');
    retVal = retVal.replace(new RegExp('dddd', 'gi'), 'AAAA');
    retVal = retVal.replace(new RegExp('ddd', 'gi'), 'AAA');
    retVal = retVal.replace(new RegExp('timezone', 'gi'), 'ZZZZ');
    retVal = retVal.replace(new RegExp('time24', 'gi'), 'TTTT');
    retVal = retVal.replace(new RegExp('time', 'gi'), 'TTT');

    // now do simple token replacements
    retVal = retVal.replace(new RegExp('yyyy', 'gi'), dt.getFullYear());
    retVal = retVal.replace(new RegExp('yy', 'gi'), new String(dt.getFullYear()).substring(2, 4));
    retVal = retVal.replace(new RegExp('y', 'gi'), Date.DatePart("y", dt));
    retVal = retVal.replace(new RegExp('q', 'gi'), Date.DatePart("q", dt));
    retVal = retVal.replace(new RegExp('mm', 'gi'), (dt.getMonth() + 1));
    retVal = retVal.replace(new RegExp('m', 'gi'), (dt.getMonth() + 1));
    retVal = retVal.replace(new RegExp('dd', 'gi'), this.pad(dt.getDate()));
    retVal = retVal.replace(new RegExp('d', 'gi'), dt.getDate());
    retVal = retVal.replace(new RegExp('hh', 'gi'), this.pad(dt.getHours()));
    retVal = retVal.replace(new RegExp('h', 'gi'), dt.getHours());
    retVal = retVal.replace(new RegExp('nn', 'gi'), this.pad(dt.getMinutes()));
    retVal = retVal.replace(new RegExp('n', 'gi'), dt.getMinutes());
    retVal = retVal.replace(new RegExp('ss', 'gi'), this.pad(dt.getSeconds()));
    retVal = retVal.replace(new RegExp('s', 'gi'), dt.getSeconds());
    retVal = retVal.replace(new RegExp('t t t t t', 'gi'), strShortTime);
    retVal = retVal.replace(new RegExp('am/pm', 'g'), dt.getHours() >= 12 ? 'pm' : 'am');
    retVal = retVal.replace(new RegExp('AM/PM', 'g'), dt.getHours() >= 12 ? 'PM' : 'AM');
    retVal = retVal.replace(new RegExp('a/p', 'g'), dt.getHours() >= 12 ? 'p' : 'a');
    retVal = retVal.replace(new RegExp('A/P', 'g'), dt.getHours() >= 12 ? 'P' : 'A');
    retVal = retVal.replace(new RegExp('AMPM', 'g'), dt.getHours() >= 12 ? 'pm' : 'am');
    // (always proceed largest same-lettered token to smallest)

    // now finish the previously set-aside tokens 
    retVal = retVal.replace(new RegExp('XXXX', 'gi'), Date.MonthName(dt.getMonth() + 1, false)); //
    retVal = retVal.replace(new RegExp('XXX', 'gi'), Date.MonthName(dt.getMonth() + 1, true)); //
    retVal = retVal.replace(new RegExp('AAAAAA', 'gi'), strLongDate);
    retVal = retVal.replace(new RegExp('AAAAA', 'gi'), strShortDate);
    retVal = retVal.replace(new RegExp('AAAA', 'gi'), Date.WeekdayName(dt.getDay() + 1, false, p_FirstDayOfWeek)); // 
    retVal = retVal.replace(new RegExp('AAA', 'gi'), Date.WeekdayName(dt.getDay() + 1, true, p_FirstDayOfWeek)); // 
    retVal = retVal.replace(new RegExp('TTTT', 'gi'), dt.getHours() + ':' + this.pad(dt.getMinutes()));
    retVal = retVal.replace(new RegExp('TTT', 'gi'), hr + ':' + this.pad(dt.getMinutes()) + ' ' + ampm);
    retVal = retVal.replace(new RegExp('CCCC', 'gi'), strShortDate + ' ' + strShortTime);

    // finally timezone
    tz = dt.getTimezoneOffset();
    timezone = (tz < 0) ? ('GMT-' + tz / 60) : (tz == 0) ? ('GMT') : ('GMT+' + tz / 60);
    retVal = retVal.replace(new RegExp('ZZZZ', 'gi'), timezone);

    return retVal;
}
FormatDate = Date.Format;

// *******************************************************************************************
// Returns the current system date and time
// *******************************************************************************************

function Now(){
	var now = Date();
	return now;
}

// *******************************************************************************************
// Returns a number that represents the hour of the day (between 0 and 23, inclusive)
// *******************************************************************************************

function Hour(date){
	var now = CDate(date);
	return now.getHours();
}

// *******************************************************************************************
// Returns a number that represents the minute of the hour (between 0 and 59, inclusive)
// *******************************************************************************************

function Minute(date){
	var now = CDate(date);
	return now.getMinutes();
}

// *******************************************************************************************
// Returns a number that represents the second of the minute (between 0 and 59, inclusive)
// *******************************************************************************************

function Second(date){
	var now = CDate(date);
	return now.getSeconds();
}

// *******************************************************************************************
// Returns a number that represents the month of the year (between 1 and 12, inclusive)
// *******************************************************************************************

function Month(date){
	var now = CDate(date);
	return now.getMonth();
}

// *******************************************************************************************
// Returns a number that represents the day of the month (between 1 and 31, inclusive)
// *******************************************************************************************

function Day(date){
	var now = CDate(date);
	return now.getDate();
}

// *******************************************************************************************
// Returns a number that represents the year
// *******************************************************************************************

function Year(date){
	var now = CDate(date);
	return now.getFullYear();
}

// *******************************************************************************************
// Returns the current system date
// *******************************************************************************************

function getDate(){
	return FormatDateTime(Now(),vbShortDate);
}

// *******************************************************************************************
// Returns the current system time
// *******************************************************************************************

function getTime(){
	return FormatDateTime(Now(),vbLongTime);
}

// *******************************************************************************************
// Converts the first letter in a string to ANSI code
// *******************************************************************************************

function Asc(chr){
	return chr.charCodeAt(0);
}

// *******************************************************************************************
// Converts the specified ANSI code to a character
// *******************************************************************************************

function Chr(AsciiNum){
	return String.fromCharCode(AsciiNum);
}

// *******************************************************************************************
// Converts an expression to a variant of subtype Boolean
// *******************************************************************************************

function CBool(value){
	var val1 = CStr(value);
	
	if (val1==="true" || val1==="1") {
		return new Boolean(true);
	} else {
		return new Boolean(false);
	}
}

// *******************************************************************************************
// Returns a random number less than 1 but greater or equal to 0
// *******************************************************************************************

function Rnd(max) { 
	var rndnum = max * Math.random();
	rndnum = Math.ceil(rndnum);
	
	return rndnum;
} 

// *******************************************************************************************
// Returns the absolute value of a specified number
// *******************************************************************************************

function Abs(num) { 
	return Math.abs(num);
} 

// *******************************************************************************************
// Returns the cosine of a specified number (angle)
// *******************************************************************************************

function Cos(num) { 
	return Math.cos(num);
} 

// *******************************************************************************************
// Returns num raised to a power
// *******************************************************************************************

function Exp(num) { 
	return Math.exp(num);
} 

// *******************************************************************************************
// Returns the tangent of a specified number (angle)
// *******************************************************************************************

function Tan(num) { 
	return Math.tan(num);
} 

// *******************************************************************************************
// Returns the square root of a specified number
// *******************************************************************************************

function Sqr(num) { 
	return Math.sqrt(num);
} 

// *******************************************************************************************
// Returns a string that consists of a number of substrings in an array
// *******************************************************************************************

function Join(arry, delimiter) { 
	var j; s=arry[0];
	var del;
	
	if (delimiter === '' || !delimiter || delimiter == null) {
		del = " ";
	} else {
		del = delimiter;
	}

	for (j=1;j<=UBound(arry)-1;j++){
		s += del + arry[j];
	}
	
	return s;
} 

// *******************************************************************************************
// Returns a string that consists of a specified number of spaces
// *******************************************************************************************

function Space(num) { 
	var j, s="";
	
	for (j=1;j<=num;j++){
		s += " ";
	}
	
	return s;
} 

// *******************************************************************************************
// Returns a Boolean value that indicates whether a specified expression contains no valid
// data (Null)
// *******************************************************************************************

function IsNull(value) {
	if (!value || value == null ) {
		return true;
	} else {
		return false;
	}
}

// *******************************************************************************************
// Returns a Boolean value that indicates whether a specified variable has been initialized
// or not
// *******************************************************************************************

function IsEmpty(value) {
	if (!value) {
		return true;
	} else {
		return false;
	}
}

// *******************************************************************************************
// Returns an expression formatted as a number
// *******************************************************************************************

function FormatNumber(num,decimalNum,bolLeadingZero,bolParens){ 
	var bolCommas=true;
	
    if (isNaN(parseInt(num))) return "NaN";

	var tmpNum = num;
	var iSign = num < 0 ? -1 : 1;		// Get sign of number
	
	// Adjust number so only the specified number of numbers after
	// the decimal point are shown.
	tmpNum *= Math.pow(10,decimalNum);
	tmpNum = Math.round(Math.abs(tmpNum))
	tmpNum /= Math.pow(10,decimalNum);
	tmpNum *= iSign;					// Readjust for sign
	
	// Create a string object to do our formatting on
	var tmpNumStr = new String(tmpNum);

	// See if we need to strip out the leading zero or not.
	if (!bolLeadingZero && num < 1 && num > -1 && num != 0)
		if (num > 0)
			tmpNumStr = tmpNumStr.substring(1,tmpNumStr.length);
		else
			tmpNumStr = "-" + tmpNumStr.substring(2,tmpNumStr.length);
		
	// See if we need to put in the commas
	if (bolCommas && (num >= 1000 || num <= -1000)) {
		var iStart = tmpNumStr.indexOf(".");
		if (iStart < 0)
			iStart = tmpNumStr.length;

		iStart -= 3;
		while (iStart >= 1) {
			tmpNumStr = tmpNumStr.substring(0,iStart) + "," + tmpNumStr.substring(iStart,tmpNumStr.length)
			iStart -= 3;
		}		
	}

	// See if we need to use parenthesis
	if (bolParens && num < 0)
		tmpNumStr = "(" + tmpNumStr.substring(1,tmpNumStr.length) + ")";

	return tmpNumStr;		// Return our formatted string!
}

// *******************************************************************************************
// Returns an expression formatted as a percentage
// *******************************************************************************************

function FormatPercent(num){
	var tmpStr = new String(FormatNumber(num*100,0));

	if (tmpStr.indexOf(")") != -1) {
		// We know we have a negative number, so place '%' inside of ')'
		tmpStr = tmpStr.substring(0,tmpStr.length - 1) + "%)";
		return tmpStr;
	}
	else
		return tmpStr + "%";			// Return formatted string!
}

// *******************************************************************************************
// Returns an expression formatted as a currency value
// *******************************************************************************************

function FormatCurrency(num,decimalNum){
	var tmpStr = new String(FormatNumber(num,decimalNum));

	if (tmpStr.indexOf("(") != -1 || tmpStr.indexOf("-") != -1) {
		// We know we have a negative number, so place '$' inside of '(' / after '-'
		if (tmpStr.charAt(0) == "(")
			tmpStr = "($"  + tmpStr.substring(1,tmpStr.length);
		else if (tmpStr.charAt(0) == "-")
			tmpStr = "-$" + tmpStr.substring(1,tmpStr.length);
			
		return tmpStr;
	}
	else
		return "$" + tmpStr;		// Return formatted string!
}

// *******************************************************************************************
// Reverses a string
// *******************************************************************************************

function StrReverse(str){
	var j; s="";
	
	for (j=Len(str);j>=0;j--){
		s += Mid(str,j,1);
	}
	
	return s;
}

// *******************************************************************************************
// Returns the hexadecimal value of a specified number
// *******************************************************************************************

function Hex(d){
	return d.toString(16);
}

// *******************************************************************************************
// Returns a zero-based array that contains a subset of a string array based on a filter
// criteria
// *******************************************************************************************

function Filter(arry,match) {
	var j = 0;
	var s = "";
	var returnarr =  new Array();

	for ( var i = 0; i < UBound(arry); i++ ){
		if ( InStr(arry[i],match)>=0 ) {
			returnarr[j] = arry[i]; // match found
			j++;
		}
	}

	return returnarr;
}

// *******************************************************************************************
// Returns a Boolean value that indicates whether a specified variable is an array
// *******************************************************************************************

function IsArray(obj) {
	if (InStr(obj.constructor.toString(),"Array") == -1){
		return false;
	} else {
		return true;
	}
}

// *******************************************************************************************
// Returns a value that indicates the subtype of a specified variable
// *******************************************************************************************

function VarType(obj) {
	var ret=0;
	
	try{
		var s=obj.constructor.toString();
		
		if (InStr(s,"string")>=0){
			ret=8;
		} else if (InStr(s,"number")>=0){
			ret=2;
		} else if (InStr(s,"date")>=0){
			ret=7;
		} else if (InStr(s,"boolean")>=0){
			ret=11;
		} else if (InStr(s,"array")>=0){
			ret=8192;
		}
	} catch(err) {
		ret=0;
	}
	
	return ret;
}

// *******************************************************************************************
// Returns the subtype of a specified variable
// *******************************************************************************************

function TypeName(obj) {
	var s="";
	try{
		s=obj.constructor.toString();
		
		s=Replace(s,"function ","");
		s=Left(s,InStr(s,"("));
		
	} catch(err) {
		s="";
	}
	
	return s;
}

// *******************************************************************************************
// Returns a string that contains a repeating character of a specified length
// *******************************************************************************************

function BuildString(num,chr){
	var s="";
	
	for (var i = 1;i<=num;i++){
		s+=chr;
	}
	
	return s;
}

// *******************************************************************************************
// 
// *******************************************************************************************

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();











// ************************************************************************************************

var sResponse = "";

function loadXMLDoc(url) {
    var xmlHttp;

    try {
        if (BrowserDetect.browser.toLowerCase() == "explorer") {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
            xmlHttp = new XMLHttpRequest();
        }

        xmlHttp.open("GET", url, false);
        xmlHttp.send();

        //may want to massage data at this poInt???;
        return xmlHttp.responseText;

    } catch(err) {
        alert(err.description);
    }
}

// ************************************************************************************************

function submitLogin() {
    if (CheckAgent()) {
        window.parent.location.href = "http://www.hanoverxs.com/setcookie.asp?a=" + document.fLogin.agent.value + "&e=" + document.fLogin.email.value + "&v=" + sResponse;
    } else {
        alert("The information you entered could not be verified at this time.  Please try again.");
        document.fLogin.agent.focus();
    }
}

// ************************************************************************************************

function submitLookup(sType) {
    if (sType.toLowerCase() == "a") {
        sResponse = CheckStatus(document.fLookup.policy.value, document.fLookup.agent.value, sType);
    } else {
        sResponse = CheckStatus(document.fLookup.policy.value, document.fLookup.zip.value, sType);
    }

    if (Trim(sResponse.toLowerCase()) == "invalid") {
        alert("The information you entered could not be verified.  Please try again.");
        document.fLookup.policy.value = "";
        if (sType.toLowerCase() == "a") {
            document.fLookup.agent.value = "";
        } else {
            document.fLookup.zip.value = "";
        }
        document.fLookup.status.value = "";
        document.fLookup.policy.focus();
    } else {
        document.fLookup.status.value = sResponse;
    }
}

// ************************************************************************************************

function CheckAgent() {
	var url = "http://www.hanoverxs.com/lookup/login_worker.asp?agent=" + document.fLogin.agent.value + "&email=" + document.fLogin.email.value;
	sResponse = loadXMLDoc(url);
    
    if (Left(sResponse.toLowerCase(),4)=="true") {
        return true;
    } else {
        return false;
    }
}

// ************************************************************************************************

function CheckStatus(Parm1, Parm2, Parm3) {
    var result;

    if (Parm3.toLowerCase() == "i") {
        result = loadXMLDoc("http://www.hanoverxs.com/lookup/insured.asp?policy=" + Parm1 + "&zip=" + Parm2);
    } else if (Parm3.toLowerCase() == "a") {
        result = loadXMLDoc("http://www.hanoverxs.com/lookup/agent.asp?policy=" + Parm1 + "&agent=" + Parm2);
    }

    return result;
}
