function isEmptyObject(obj) {
	return (obj == "undefined" || obj == "Undefined" || typeof (obj) === "undefined");
}
function isNullOrUndefined(obj) {
	return (isEmptyObject(obj) || obj == null || obj === null || obj === "null");
}
function isArray(obj) {
	return obj && !(obj.propertyIsEnumerable('length')) && typeof obj === 'object' && typeof obj.length === 'number';
}
function isObject(obj) {
	return obj && (typeof obj === 'object');
}
function isEmptyString(str) {
	return (isNullOrUndefined(str) || !str || str == "" || str === "");
}

function hasData(str) {
	return !isEmptyString(str);
}

function nonNull(str) {
	return (isEmptyString(str) ? '' : str);
}

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

function change_parent_url(url) {
	document.location = url;
}
function printObjectRecursive(obj, depth) {
	var str = '';
	depth++;
	if (depth < 100 && !isNullOrUndefined(obj)) {
		var isarray = isArray(obj);
		str += '<br />';
		for (var prop in obj) {
			str += (isarray ? "Array Element " : "") + prop + ': ' + (isObject(obj[prop]) ? printObjectRecursive(obj[prop], depth) : obj[prop]) + '<br />\n'; //Concate prop and its value from object
		}
	}

	return str;
}
function printObject(obj) {
	var str = '';
	if (!isNullOrUndefined(obj)) {
		var isarray = isArray(obj);
		str += '<br />';
		for (var prop in obj) {
			str += (isarray ? "Array Element " : "") + prop + ': ' + (isObject(obj[prop]) ? printObjectRecursive(obj[prop], 1) : obj[prop]) + '<br />\n'; //Concate prop and its value from object
		}
	}

	return str;
}

function wrapString(left, str, right) {
	return nonNull(left) + nonNull(str) + nonNull(right);
}
function quoteString(str) {
	return wrapString("'", str, "'");
}
function dquoteString(str) {
	return wrapString('"', str, '"');
}
function parenString(str) {
	return wrapString('(', str, ')');
}
function equalString(name, value, valueWrapper) {
	if (hasData(name))
		return name + '=' + (hasData(valueWrapper) ? wrapString(valueWrapper, value, valueWrapper) : nonNull(value));

	return '';
}
function equalStringQuoted(name, value, useSingleQuote) {
	if (hasData(name))
		return name + '=' + ((useSingleQuote || false) ? quoteString(value) : dquoteString(value));

	return '';
}

function urlAttribute(attName, attValue, isFirst) {
	if (hasData(attName) && hasData(attValue))
		return ((isFirst || false) ? '?' : '&') + equalString(attName, attValue);

	return '';
}

function attributeString(attName, attValue, useSingleQuote) {
	if (hasData(attName))
		return ' ' + attName + '=' + ((useSingleQuote || false) ? quoteString(attValue) : dquoteString(attValue));

	return '';
}
function startTagString(tagName, className, useSingleQuote) {
	if (hasData(tagName))
		return wrapString('<', tagName + (hasData(className) ? attributeString('class', className, useSingleQuote) : ''), '>');

	return '';
}
function startTagStringWithAttribute(tagName, attName, attValue, className, useSingleQuote) {
	if (hasData(tagName))
		return startTagString(tagName + (hasData(attName) ? attributeString(attName, attValue, useSingleQuote) : ''), className, useSingleQuote);

	return '';
}
function endTagString(tagName) {
	if (hasData(tagName))
		return wrapString('</', tagName, '>');

	return '';
}
function emptyTagString(tagName) {
	if (hasData(tagName))
		return wrapString('<', tagName, ' />');

	return '';
}
function getTagString(tagName, data, className, useSingleQuote) {
	if (hasData(tagName))
		return startTagString(tagName, className, useSingleQuote) + nonNull(data) + endTagString(tagName);

	return '';
}
function getTagStringtd(data, className, useSingleQuote) {
	return getTagString('td', data, className, useSingleQuote);
}
function getTagStringWithAttribute(tagName, data, attName, attValue, className, useSingleQuote) {
	if (hasData(tagName))
		return startTagStringWithAttribute(tagName, attName, attValue, className, useSingleQuote) + nonNull(data) + endTagString(tagName);

	return '';
}

function getTagStringSubscript(str) {
	return getTagString('sub', str);
}
function startTagAnchor(href, className, useSingleQuote) {
	return startTagStringWithAttribute('a', 'href', href, className, useSingleQuote);
}
function startTagAnchorJavascript(href, className, useSingleQuote) {
	return startTagAnchor('javascript:' + nonNull(href), className, useSingleQuote);
}
function getTagAnchorJavascript(data, href, className, useSingleQuote) {
	return startTagAnchorJavascript(href, className, useSingleQuote) + nonNull(data) + endTagString('a');
}

function getTagStringTD(str) {
	return getTagString('td', hasData(str) ? str : "&nbsp;");
}
function getTagStringTR(str) {
	return getTagString('tr', str);
}
function getNameValueRow(name, value) {
	var str = getTagStringTD(name);
	str += getTagStringTD(value);

	return getTagStringTR(str);
}

function getInnerHTML(elementName) {
	var element = document.getElementById(elementName);
	if (element)
		return nonNull(element.innerHTML);

	return '';
}
function setInnerHTML(elementName, text) {
	var element = document.getElementById(elementName);
	if (element) {
		element.innerHTML = text;
		return true;
	}

	return false;
}

function getElementValue(elementName) {
	var element = document.getElementById(elementName);
	if (element)
		return element.value;

	return '';
}
function getElementValueInt(elementName) {
	var str = getElementValue(elementName);

	if (hasData(str))
		return str.replace(/\,/g, '');

	return 0;
}
function setElementValue(elementId, value) {
	if (hasData(elementId)) {
		var ctl = document.getElementById(elementId);
		if (ctl != null) {
			ctl.value = nonNull(value);
			return true;
		}
	}

	return false;
}
function getElementText(elementName) {
	var element = document.getElementById(elementName);
	if (element)
		return element.text;

	return '';
}
function setElementText(elementId, value) {
	if (hasData(elementId)) {
		var ctl = document.getElementById(elementId);
		if (ctl != null) {
			ctl.text = nonNull(value);
			return true;
		}
	}

	return false;
}

function getElementsByClass(rootobj, className) {
	var temparray = new Array();
	var i = 0;
	var inc = 0;
	var rootlength = 0;
	if (rootobj != null && hasData(className)) {
		rootlength = rootobj.length;
		for (i = 0; i < rootlength; i++) {
			if (rootobj[i].className == className)
				temparray[inc++] = rootobj[i];
		}
	}

	return temparray;
}

function setElementsText(elementName, str) {
	var i = 0;
	var elements = document.getElementsByName(elementName);
	if (elements != null) {
		for (i = 0; i < elements.length; ++i) {
			elements[i].innerHTML = str;
		}
	}

	return i;
}

function getSelectedIndexName(ddlDropDown) {
	var ddl = document.getElementById(ddlDropDown);
	if (ddl && ddl.options && ddl.selectedIndex >= 0)
			return ddl.options[ddl.selectedIndex].text;

	return '';
}
function getSelectedIndexValue(ddlDropDown) {
	var ddl = document.getElementById(ddlDropDown);
	if (ddl && ddl.options && ddl.selectedIndex >= 0)
		return ddl.options[ddl.selectedIndex].value;

	return '';
}
function setSelectedItemFromValue(ddlListBox, itemValue) {
	var i = 0;
	var ddl = document.getElementById(ddlListBox);
	if (ddl && ddl.options && hasData(itemValue)) {
		for (i = 0; i < ddl.options.length; ++i) {
			if (ddl.options[i].value == itemValue) {
				ddl.options[i].selected = true;
				break;
			}
		}
	}
}

// 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 getRadioCheckedValue(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 setRadioCheckedValue(radioObj, newValue) {
	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;
		}
	}
}

function getSelectedRadioGroupItem(radioGroupName) {
	var i = 0;
	var j = 0;
	var items = null;
	var node = document.getElementById(radioGroupName);
	if (node != null)
		items = node.getElementsByTagName("input");
	if (items != null) {
		for (i = 0; i < items.length; ++i) {
			if (items[i].checked) {
				var lbl = items[i].nextSibling;
				if (lbl != null) {
					return lbl.innerHTML;
				}
			}
		}
	}

	return '';
}

function setDisableControl(elementID, state) {
	if (hasData(elementID)) {
		var ctl = document.getElementById(elementID);
		if (ctl != null) {
			ctl.disabled = (state || false);
			return true;
		}
	}

	return false;
}
function disableControl(elementID) {
	return setDisableControl(elementID, true);
}
function enableControl(elementID) {
	return setDisableControl(elementID, false);
}

function getChecked(elementName) {
	var element = document.getElementById(elementName);
	if (element)
		return element.checked;

	return false;
}
function setChecked(elementName, truefalse) {
	var element = document.getElementById(elementName);
	if (element) {
		element.checked = (truefalse || false);
		return true;
	}

	return false;
}

function clickClear(txtbox, defaulttext) {
	var defaultValue = (defaulttext || txtbox.defaultValue);
	if (txtbox.value == defaultValue)
		txtbox.value = '';

	txtbox.style.backgroundColor = '#ddffdd';

	return true;
}

function clickRecall(txtbox, defaulttext) {
	if (txtbox.value == '') {
		txtbox.value = (defaulttext || txtbox.defaultValue);
	}

	txtbox.style.backgroundColor = '#ffffff';

	return true;
}

// Adds commas to a number string.
function addCommas(sValue) {
	var sRegExp = new RegExp('(-?[0-9]+)([0-9]{3})');

	while (sRegExp.test(sValue)) {
		sValue = sValue.replace(sRegExp, '$1,$2');
	}

	return sValue;
}
function addCommas2(nStr) {
	nStr += '';
	var x = nStr.split('.');
	var x1 = x[0];
	var x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}

	return x1 + x2;
}

//--------------- Date Methods ---------------
function getCurrentDateTime(showTheTime) {
	var d = new Date();
	var monthname = ["January", "February", "March", "April", "May", "June", "July", "August",
	                  "September", "October", "November", "December"];
	//Ensure correct for language. English is "January 1, 2004"
	var TODAY = monthname[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear();
	var sTime = d.getHours();
	sTime += ":";
	if (d.getMinutes() < 10)
		sTime += "0";
	sTime += d.getMinutes();
	sTime += ":";
	if (d.getSeconds() < 10)
		sTime += "0";
	sTime += d.getSeconds();
	sTime += ".";
	if (d.getMilliseconds() < 100) {
		sTime += "0";
		if (d.getMilliseconds() < 10) {
			sTime += "0";
		}
	}
	sTime += d.getMilliseconds();

	if (showTheTime || false)
		return TODAY + " " + sTime;

	return TODAY;
}
/*
* Date Format 1.2.3
* (c) 2007-2009 Steven Levithan <stevenlevithan.com>
* MIT license
*
* Includes enhancements by Scott Trenda <scott.trenda.net>
* and Kris Kowal <cixar.com/~kris.kowal/>
*
* Accepts a date, a mask, or a date and a mask.
* Returns a formatted version of the given date.
* The date defaults to the current date/time.
* The mask defaults to dateFormat.masks.default.
*/
var dateFormat = function() {
	var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function(val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function(date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date)) throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var _ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d: d,
				dd: pad(d),
				ddd: dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m: m + 1,
				mm: pad(m + 1),
				mmm: dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy: String(y).slice(2),
				yyyy: y,
				h: H % 12 || 12,
				hh: pad(H % 12 || 12),
				H: H,
				HH: pad(H),
				M: M,
				MM: pad(M),
				s: s,
				ss: pad(s),
				l: pad(L, 3),
				L: pad(L > 99 ? Math.round(L / 10) : L),
				t: H < 12 ? "a" : "p",
				tt: H < 12 ? "am" : "pm",
				T: H < 12 ? "A" : "P",
				TT: H < 12 ? "AM" : "PM",
				Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
} ();

// Some common format strings
dateFormat.masks = {
	"default": "ddd mmm dd yyyy HH:MM:ss",
	shortDate: "m/d/yy",
	mediumDate: "mmm d, yyyy",
	longDate: "mmmm d, yyyy",
	fullDate: "dddd, mmmm d, yyyy",
	shortTime: "h:MM TT",
	mediumTime: "h:MM:ss TT",
	longTime: "h:MM:ss TT Z",
	isoDate: "yyyy-mm-dd",
	isoTime: "HH:MM:ss",
	isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
//Date.prototype.formatDate = function(mask, utc) {
//	return dateFormat(this, mask, utc);
//};

function popWin(winPage, winName, winProp) {
	var newPop = window.open(winPage, winName, winProp);
	newPop.focus();
}

function getCheckBoxValue(id) {
	var cb = document.getElementById(id);
	if (cb != null)
		return cb.checked;

	return false;
}

function CheckBoxDeleteAll() {
	var bCheck = document.frm.chkDeleteAll.checked;
	var cnt = document.frm.chkDelete.length;
	if (cnt < 1) {
		document.frm.chkDelete.checked = bCheck;
	}
	else {
		for (var i = 0; i < cnt; i++) {
			document.frm.chkDelete[i].checked = bCheck;
		}
	}

	return true;
}

function CheckDelete() {
	var b = false;
	var cnt = document.frm.chkDelete.length;
	if (cnt < 1) {
		if (document.frm.chkDelete.checked == true)
			b = true;
	}
	else {
		for (var i = 0; i < cnt; i++) {
			if (document.frm.chkDelete[i].checked) {
				b = true;
				break;
			}
		}
	}

	return b;
}

function StringBuilder() {
	this.strings = new Array(''),
	this.append = function(value) {
		if (value)
			this.strings.push(value);
	},
	this.clear = function() {
		this.strings.length = 1;
	},
	this.toString = function() {
		return this.strings.join('');
	}
}

function escapeNameValue(name, value) {
	if (hasData(name))
		return name + '=' + escape(nonNull(value));

	return '';
}

var GACookies = {
	getCookie: function(name) {
		var str = this.getCookieNull(name);
		return nonNull(str);
	},

	getCookieNull: function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for (var i = 0; i < ca.length; i++) {
			var c = ca[i];
			while (c.charAt(0) == ' ')
				c = c.substring(1, c.length);
			if (c.indexOf(nameEQ) == 0)
				return unescape(c.substring(nameEQ.length, c.length));
		}

		return null;
	},

	setCookie: function(name, value, days) {
		var expires = "";
		if (days) {
			var dateToday = new Date();
			var millis = dateToday.getTime();
			dateToday.setTime(millis);

			millis += (days * 24 * 60 * 60 * 1000);
			var dateExpires = new Date(dateToday.getTime() + millis);
			expires = "; expires=" + dateExpires.toUTCString();
		}

		//alert(expires);
		var str = name + "=" + escape(value) + expires + "; path=";
		//alert(str);
		document.cookie = str;
	},

	checkTheCookie: function(sXMLJSON) {
		if (hasData(sxmlJSON)) {
			this.setCookie(CONST_cookiestartPoints, sxmlJSON, 60);
			return true;
		}

		return false;
	},

	deleteCookie: function(name) {
		this.setCookie(name, "", -1);
	},

	getexpirydate: function(numdays) {
		var Today = new Date();
		var nomilli = Date.parse(Today);
		Today.setTime(nomilli + numdays * 24 * 60 * 60 * 1000);
		return Today.toUTCString();
	}
}

var GACookieManager = function(cookieName) {
	this._cookieName = nonNull(cookieName);
	this.getCookie = function() {
		return GACookies.getCookie(this._cookieName);
	},

	this.setCookie = function(value, duration) {
		return GACookies.setCookie(this._cookieName, value, duration);
	},

	this.checkTheCookie = function(sXMLJSON) {
		return GACookies.checkTheCookie(sXMLJSON);
	},

	this.deleteCookie = function() {
		return GACookies.deleteCookie(this._cookieName);
	}
}

function GAMetricConversion() {
	this._CookieManager = new GACookieManager('UseMetric');
	this._UseMetric = -1;

	this.CONST_Standard = 0;
	this.CONST_Metric = 1;

	// Cookie state routines
	this.isMetric = function() {
		if (this._UseMetric < 0 || this._UseMetric > 1) {
			var str = this._CookieManager.getCookie();
			if (hasData(str) && str == '1')
				this._UseMetric = this.CONST_Metric;
			else if (hasData(str) && str == '0')
				this._UseMetric = this.CONST_Standard;
			else
				this.setStandard();
		}

		return this._UseMetric;
	},

    this.setUnitValue = function(unitValue) {
    	if (this._UseMetric != unitValue && (unitValue == this.CONST_Standard || unitValue == this.CONST_Metric)) {
    		this._UseMetric = unitValue;
    		this._CookieManager.setCookie(unitValue, 60);
    		return true;
    	}

    	return false;
    },

    this.setMetric = function() {
    	return this.setUnitValue(this.CONST_Metric);
    },

    this.setStandard = function() {
    	return this.setUnitValue(this.CONST_Standard);
    },

	// Raw conversion routines
	this.convertLbToKg = function(weightPounds) {
		return (weightPounds * 0.4536);
	},
	this.convertKgToLb = function(weightKilograms) {
		return (weightKilograms * 2.2);
	},
	this.getKgFromKgLb = function(weight) {
		if (this.isMetric())
			return weight;

		return this.convertLbToKg(weight);
	},
	this.getLbFromKgLb = function(weight) {
		if (this.isMetric())
			return this.convertKgToLb(weight);

		return weight;
	},
    this.getKgLbFromKg = function(weightKg) {
    	if (this.isMetric())
    		return weightKg;

    	return this.convertKgToLb(weightKg);
    },
    this.getKgLbFromLb = function(weightPounds) {
    	if (this.isMetric())
    		return this.convertLbToKg(weightPounds);

    	return weightPounds;
    },

	this.convertMiToKm = function(distanceMi) {
		return distanceMi * 1.609;
	},
	this.convertKmToMi = function(distanceKm) {
		return distanceKm * 0.621371192;
	},
    this.getKmFromKmMi = function(distance) {
    	if (this.isMetric())
    		return distance;

    	return this.convertMiToKm(distance);
    },
    this.getMiFromKmMi = function(distance) {
    	if (this.isMetric())
    		return this.convertKmToMi(distance);

    	return distance;
    },
    this.getKmMiFromKm = function(distanceKm) {
    	if (this.isMetric())
    		return distanceKm;

    	return this.convertKmToMi(distanceKm);
    },
    this.getKmMiFromMi = function(distanceMi) {
    	if (this.isMetric())
    		return this.convertMiToKm(distanceMi);

    	return distanceMi;
    },

	this.convertLToG = function(volumeL) {
		return volumeL * 0.2642;
	},
	this.convertGToL = function(volumeG) {
		return volumeG * 3.785;
	},
    this.getLFromLG = function(volume) {
    	if (this.isMetric())
    		return volume;

    	return this.convertGToL(volume);
    },
    this.getGFromLG = function(volume) {
    	if (this.isMetric())
    		return this.convertLToG(volume);

    	return volume;
    },
    this.getLGFromL = function(volumeL) {
    	if (this.isMetric())
    		return volumeL;

    	return this.convertLToG(volumeL);
    },
    this.getLGFromG = function(volumeG) {
    	if (this.isMetric())
    		return this.convertGToL(volumeG);

    	return volumeG;
    },

	this.convertM3ToFt3 = function(volumeM3) {
		return (volumeM3 * 35.314); 	// Converted to cubic meters (m3)
	},
	this.convertFt3ToM3 = function(volumeFt3) {
		return (volumeFt3 * 0.02832); // Converted to cubic feet (ft3)
	},
	this.getM3FromM3Ft3 = function(volume) {
		if (this.isMetric())
			return volume;

		return this.convertFt3ToM3(volume);
	},
	this.getFt3FromM3Ft3 = function(volume) {
		if (this.isMetric())
			return this.convertM3ToFt3(volume);

		return volume;
	},
    this.getM3FT3FromM3 = function(volumeM3) {
    	if (this.isMetric())
    		return volumeM3;

    	return this.convertM3ToFt3(volumeM3);
    },
    this.getM3FT3FromFt3 = function(volumeFt3) {
    	if (this.isMetric())
    		return this.convertFt3ToM3(volumeFt3);

    	return volumeFt3;
    },

	// Display routines
    this.getFormattedValue = function(distance) {
    	var decimalPlaces = (distance > 1000) ? 0 : 1;
    	//decimalPlaces = 1;
    	var msg = 'getFormattedKmMi\n';

    	msg += 'Distance=';
    	msg += distance.toFixed(decimalPlaces);
    	msg += '\n';
    	//		alert(msg);

    	return addCommas(distance.toFixed(decimalPlaces));
    	//	return distance.toFixed(decimalPlaces);
    },

    this.MILES = function() {
    	this.label = 'miles',
	    this.f = function(distance) {
	    	//var msg = "";
	    	//msg += distance;
	    	//msg += "\n";
	    	//msg += (distance/1609.344);
	    	//alert(msg);

	    	return (distance / 1609.344);
	    },
	    this.getDistanceString = function(dist) {
	    	var str = getFormattedKmMi(this.f(dist));
	    	str += ' miles';
	    	return str;
	    }
    },

    this.KMS = function() {
    	this.label = 'km',
	    this.f = function(distance) {
	    	return distance / 1000;
	    },
	    this.getDistanceString = function(dist) {
	    	var str = getFormattedKmMi(this.f(dist));
	    	str += ' kilometers';
	    	return str;
	    }
    },

    this.numberFormat = function(number) {
    	var nStr = number + '';
    	var x = nStr.split('.');
    	var x1 = x[0];
    	var x2 = x.length > 1 ? '.' + x[1] : '';
    	var rgx = /(\d+)(\d{3})/;
    	while (rgx.test(x1)) {
    		x1 = x1.replace(rgx, '$1' + ',' + '$2');
    	}
    	return x1 + x2;
    },

    this.numberFormatDouble = function(d, decimalPlaces, decimalCutoffNumber) {
    	var num = new Number(d);
    	var nStr = '';
    	if (num == 0) {
    		return '0';
    	}
    	else {
    		if (decimalPlaces && decimalPlaces > 0)
    			nStr += num.toFixed(decimalPlaces);
    		else
    			nStr += num;

    		var x = nStr.split('.');
    		var x1 = x[0];
    		var x2 = x.length > 1 ? '.' + x[1] : '';
    		if (decimalCutoffNumber && num >= decimalCutoffNumber)
    			x2 = '';
    		var rgx = /(\d+)(\d{3})/;
    		while (rgx.test(x1)) {
    			x1 = x1.replace(rgx, '$1' + ',' + '$2');
    		}
    	}

    	return x1 + x2;
    },

	this.getKmMiText = function(longwords) {
		var lw = (longwords || false);
		var s = '';
		if (lw) {
			if (this.isMetric())
				s += 'kilometers';
			else
				s += 'miles';
		}
		else {
			if (this.isMetric())
				s += 'km';
			else
				s += 'mi';
		}

		return s;
	},

    this.getDistanceStringFromKm = function(distanceKm, decimalPlaces, decimalCutoffNumber, longwords) {
    	var s = '';
    	var distance = this.getKmMiFromKm(distanceKm);

    	s += this.numberFormatDouble(distance, decimalPlaces, decimalCutoffNumber);
    	s += ' ';
    	s += this.getKmMiText(longwords);

    	return s;
    },

	this.convertKgLbFromLbWithCommas = function(num) {
		return addCommas(this.getKgLbFromLb(num).toFixed(0));
	},
	this.convertKgLbFromKgWithCommas = function(num) {
		return addCommas(this.getKgLbFromKg(num).toFixed(0));
	},

	this.getKgLbText = function(longwords) {
		var lw = (longwords || false);
		var s = '';
		if (lw) {
			if (this.isMetric())
				s += 'kilograms';
			else
				s += 'pounds';
		}
		else {
			if (this.isMetric())
				s += 'kg';
			else
				s += 'lb';
		}

		return s;
	},

    this.getWeightStringFromPounds = function(weightPounds, decimalPlaces, decimalCutoffNumber, longwords) {
    	var s = '';
    	var distance = this.getKgLbFromLb(weightPounds);

    	s += this.numberFormatDouble(distance, decimalPlaces, decimalCutoffNumber);
    	s += ' ';
    	s += this.getKgLbText(longwords);

    	return s;
    },

    this.GetCO2 = function(volume, decimalPlaces, decimalCutoffNumber) {
    	var s = '';
    	volume = this.getM3FT3FromM3(volume);

    	s += this.numberFormatDouble(volume, decimalPlaces, decimalCutoffNumber);
    	s += ' ';
    	if (this.isMetric())
    		s += 'm';
    	else
    		s += 'ft';

    	s += '<sup>3</sup>';

    	return s;
    },

    this.GetCH4 = function(volume, decimalPlaces, decimalCutoffNumber) {
    	return this.GetCO2(volume, decimalPlaces, decimalCutoffNumber);
    },

    this.GetH2O = function(volume, decimalPlaces, decimalCutoffNumber) {
    	return this.GetCO2(volume, decimalPlaces, decimalCutoffNumber);
    },

    this.GetNOx = function(volume, decimalPlaces, decimalCutoffNumber) {
    	return this.GetCO2(volume, decimalPlaces, decimalCutoffNumber);
    }
}

var MetricConversion = new GAMetricConversion();

function AjaxManager() {
	/** opts is a hash with the following keys:
	*   method:			either "GET" or "POST"  (default GET)
	*   params:			an object that contains all query parameters to send to the server
	*   onSuccess:		function to call after request if request succeeds. function 
	*					has one paramater, the response string
	*   onSuccessEval:	function to use instead of onSuccess to do an automatic eval on the response text.
	*					Returns the object in an obj parameter.
	*   onFailure:		function to call after request if request fails.
	*					has one parameter, the status returned from the failure.
	*/
	this.newAjaxRequest = function(url, opts) {
		if (!isNullOrUndefined(opts)) {
			var req = this.getAjaxRequest();
			if (req) {
				// Create a function that will receive data sent from the server
				req.onreadystatechange = function() {
					if (req.readyState == 4) {
						if (req.status >= 200 && req.status < 300) {
							if (opts.onSuccess) {
								opts.onSuccess(req.responseText);
							}
							else if (opts.onSuccessEval) {
								var obj = null;
								if (hasData(req.responseText))
									obj = eval('(' + req.responseText + ')');
								//else
								//	obj = {};

								opts.onSuccessEval(obj)
							}
						}
						else {
							if (opts.onFailure)
								opts.onFailure(req.status);
						}
					}
				}

				var method = (opts.method || "get").toUpperCase();
				var postBody = null;
				var strQueryParams = this.toQueryParams(opts.params);
				//TODO: handle the case where URL already has some query params
				if (method == "GET") {
					if (hasData(strQueryParams)) {
						url += ((url.indexOf("?") == -1) ? "?" : "&");
						url += strQueryParams;
					}
				}
				else if (method == "POST") {
					postBody = strQueryParams;
				}

				req.open(method, url, true);
				//req.setRequestHeader("Accept", "application/json");
				req.send(postBody);
			}
		}
	},

	this.getAjaxRequest = function() {
		try {
			// Opera 8.0+, Firefox, Safari
			return new XMLHttpRequest();
		}
		catch (e) { }
		// Internet Explorer Browsers
		try {
			return new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) { }
		try {
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch (e) {
			// Something went wrong
			alert("Your browser does not appear to support AJAX!");
			return false;
		}
	},

 	this.toQueryParams = function(obj) {
 		var str = "";
 		if (obj instanceof Array) {
 			for (var i = 0; i < obj.length; ++i) {
 				for (var v1 in obj[i])
 					str += v1 + '=' + encodeURIComponent(obj[i][v1]) + '&';
 			}
 		}
 		else {
 			for (var v in obj)
 				str += v + '=' + encodeURIComponent(obj[v]) + '&';
 		}

 		return (hasData(str) ? str.substr(0, str.length - 1) : str);
 	}
}

function skkyjsonGetPopupMenuHTML(popupMenus, varName) {
	if (hasData(varName) && !isNullOrUndefined(popupMenus) && isArray(popupMenus)) {
		for (i = 0; i < popupMenus.length; ++i) {
			if (popupMenus[i].key == varName) {
				return popupMenus[i].value.innerHTML;
			}
		}
	}

	return '';
}

// addEvent and removeEvent, designed by Aaron Moore
function addEvent(element, listener, handler) {
	//if the system is not set up, set it up, and
	// store any outside script's event registration in the first handler slot
	if (typeof element[listener] != 'function' ||
	typeof element[listener + '_num'] == 'undefined') {
		element[listener + '_num'] = 0;
		if (typeof element[listener] == 'function') {
			element[listener + 0] = element[listener];
			element[listener + '_num']++;
		}
		element[listener] = function(e) {
			var r = true;
			e = (e) ? e : window.event;
			for (var i = 0; i < element[listener + '_num']; i++)
				if (element[listener + i](e) === false) r = false;
			return r;
		}
	}
	//if handler is not already stored, assign it
	for (var i = 0; i < element[listener + '_num']; i++)
		if (element[listener + i] == handler) return;
	element[listener + element[listener + '_num']] = handler;
	element[listener + '_num']++;
}
function removeEvent(element, listener, handler) {
	//if the system is not set up, or there are no handlers to remove, exit
	if (typeof element[listener] != 'function' ||
	typeof element[listener + '_num'] == 'undefined' ||
	element[listener + '_num'] == 0) return;
	//loop through handlers,
	//  if target handler is reached, begin overwriting each
	//  handler with the handler in front of it until one before the last
	var found = false;
	for (var i = 0; i < element[listener + '_num']; i++) {
		if (!found)
			found = element[listener + i] == handler;
		if (found && (i + 1) < element[listener + '_num'])
			element[listener + i] = element[listener + (i + 1)];
	}
	//if handler was found, decrement the handler count
	if (found)
		element[listener + '_num']--;
}

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}

			func();
		}
	}
}
function addUnloadEvent(func) {
	var oldonunload = window.onunload;
	if (typeof window.onunload != 'function') {
		window.onunload = func;
	}
	else {
		window.onunload = function() {
			if (oldonunload) {
				oldonunload();
			}

			func();
		}
	}
}
