/////////////////////// 3rd party fcns /////////////////////////////
/* Script from Ajax Cookbook */
/* license granted on http://ajaxcookbook.org/faq/ */
function fnDisableSelection(str_elem)
{
	if (!str_elem)
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
    elem.onselectstart = function() {
        return false;
    };
    elem.unselectable = "on";
    elem.style.MozUserSelect = "none";
    elem.style.cursor = "default";
}

/* from http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/ */
function loadScript(url, callback)
{
    var script = document.createElement("script")
    script.type = "text/javascript";
    if (script.readyState) { //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" || script.readyState == "complete")
            {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            callback();
        };
    }
    script.src = url;
    document.body.appendChild(script);
}

/**
* Javascript trim, ltrim, rtrim
* http://www.webtoolkit.info/
**/
function trim(str, chars) {
    return ltrim(rtrim(str, chars), chars);
}
function ltrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
function rtrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function checkTimeZone() {
   var rightNow = new Date();
   var date1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
   var date2 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0);
   var temp = date1.toGMTString();
   var date3 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
   temp = date2.toGMTString();
   var date4 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
   var hoursDiffStdTime = (date1 - date3) / (1000 * 60 * 60);
   var hoursDiffDaylightTime = (date2 - date4) / (1000 * 60 * 60);

   /*
   if (hoursDiffDaylightTime == hoursDiffStdTime) {
      alert("Time zone is GMT " + hoursDiffStdTime + ".\nDaylight Saving Time is NOT observed here.");
   } else {
      alert("Time zone is GMT " + hoursDiffStdTime + ".\nDaylight Saving Time is observed here.");
   }
   */

   return hoursDiffStdTime*60;
}

// based on code from http://www.quirksmode.org/js/findpos.html 
function fnGetPos(str_elem)
{
	if (!fnDoesStrHaveValue(str_elem))
		return [0,0];
	elem = document.getElementById(str_elem);
	if (!fnDoesObjHaveValue(elem))
		return [0,0];	
	var curleft=0;
	var curtop=0;
	if (elem.offsetParent)
	{
	 	do
	 	{
	 		curleft += elem.offsetLeft;
	 		curtop += elem.offsetTop;
	 	} while (elem =elem.offsetParent);
	}
	return [curleft,curtop];
}
function fnGetPos2(str_elem,str_parent)
{
	if (!fnDoesStrHaveValue(str_elem) || !fnDoesStrHaveValue(str_parent))
		return [0,0];
	var elem = document.getElementById(str_elem);
	if (!fnDoesObjHaveValue(elem))
		return [0,0];	
	var parent = document.getElementById(str_parent);
	if (!fnDoesObjHaveValue(parent))
		return [0,0];	
	var curleft=0;
	var curtop=0;
	if (elem.offsetParent && elem!=parent)
	{
	 	do
	 	{
	 		curleft += elem.offsetLeft;
	 		curtop += elem.offsetTop;
	 		elem =elem.offsetParent;
	 	} while (elem && (elem!=parent));
	}
	return [curleft,curtop];
}
///////////////////// end of 3rd party fcn ///////////////////////////


/////////////////////// Utility Functions ////////////////////////////
function nyi()
{
	alert("Sorry.  This feature is not yet implemented.");
}

function fnLogError(the_msg)
{
	if (DEBUG_MODE != 0)
	{
		var str_msg = "" + the_msg;
		alert(str_msg);
	}
}

function fnLogInfo(the_msg)
{
	if (DEBUG_MODE > 1)
	{
		var str_msg = "" + the_msg;
		alert(str_msg);
	}
}

function fnClone(obj)
{
	return fnCloneStep(obj, 0);
}
function fnCloneStep(obj, level)
{
	if ((typeof(obj) != 'object') || (obj == null))
		return obj;

	var obj2 = new Object();

	var j=0;
	var r_test = null;
	var r_match=0;
	for (var i in obj)
	{
		r_match =0;
		r_test =obj[i];

		if ((typeof(r_test) == 'object') && r_test)
		{
			for (j=level; j>=0 && !r_match; j--)
			{
				if ((typeof(r_test) == 'object') && r_test)
				{
					r_test =r_test.clone_parent;
					if ((typeof(r_test) == 'object') && r_test && (r_test==obj[i]))
					{
						obj2[i] =obj2;
						r_match=1;
					}
				}
			}
			if (!r_match)
			{
				obj[i].clone_parent = obj;
				obj2[i] = fnCloneStep(obj[i], level+1);
			}
		}
		else
			obj2[i]=obj[i];
	}

	return obj2;
}


function fnRemoveAnySpecialChar(str_in)
{
	var str_out = str_in;
	var str_out2 = str_in;
	var	regEx = /\W/g;
	str_out2 = str_out.replace(regEx, "");
	return str_out2;
}

function fnHTMLToPlaintext(str_in)
{
	var str_out = str_in;
	var str_out2 = str_in;
	var	regEx = /~/g;

	str_out2 = str_out.replace(regEx, "");
	str_out = str_out2;

	regEx = /(<br>)/ig;
	str_out2 = str_out.replace(regEx, "~");
	str_out = str_out2;

	regEx = /(<p>)/ig;
	str_out2 = str_out.replace(regEx, "~");
	str_out = str_out2;

	var i = 0;
	var j = 0;
	var array1 = str_out.split("<");
	var array2;

	str_out = "";

	for (i=0; i<array1.length; i++)
	{
		array2 = array1[i].split(">");
		if (array2.length>1)
			str_out += array2[1];
		else
			str_out += array2[0];
	}

	regEx = /~/g;
	str_out2 = str_out.replace(regEx, "<br>");
	str_out = str_out2;

	return str_out;
}

function fnHTMLToPlaintext2(str_in)
{
	var str_out = str_in;
	var str_out2 = str_in;
	var	regEx = /~/g;

	str_out2 = str_out.replace(regEx, "");
	str_out = str_out2;

	regEx = /(<br>)/ig;
	str_out2 = str_out.replace(regEx, "~");
	str_out = str_out2;

	regEx = /(<p>)/ig;
	str_out2 = str_out.replace(regEx, "~");
	str_out = str_out2;

	var i = 0;
	var j = 0;
	var array1 = str_out.split("<");
	var array2;

	str_out = "";

	for (i=0; i<array1.length; i++)
	{
		array2 = array1[i].split(">");
		if (array2.length>1)
			str_out += array2[1];
		else
			str_out += array2[0];
	}

	regEx = /~/g;
	str_out2 = str_out.replace(regEx, "\n");
	str_out = str_out2;

	return str_out;
}

function fnGetMouseInString()
{
	if (browser.isIE)
		return "onmouseenter";
	else
		return "onmouseover";
}

function fnGetMouseOutString()
{
	if (browser.isIE)
		return "onmouseleave";
	else
		return "onmouseout";
}

function setOpacity(elem, the_value)
{
	elem.style.opacity = the_value/10;
	elem.style.filter = 'alpha(opacity=' + the_value*10 + ')';
}

function fnFadeOut(str_elem)
{
	fnFadeOut_recur(str_elem, 10);
}

function fnFadeOut_recur(str_elem, i)
{
	var elem = document.getElementById(str_elem);
	if (null == elem)
	{
		return;
	}

	setOpacity(elem, i);
	i--;
	if (i<=0)
	{
		elem.style.display = "none";
		return;
	}
	var	str_fn = "fnFadeOut_recur('" + str_elem + "'," + i + ")";
	g_fade_out_timer= window.setTimeout(str_fn, 100);
}
function fnFadeOut_ClearTimer()
{
	if (g_fade_out_timer != null)
	{
		clearInterval(g_fade_out_timer);
		g_fade_out_timer = null;
	}
}

function fnCloneArray(array_dest, array_src)
{
	array_dest = new Array();
	if (!array_src)
		return;
	var i=0;
	for (i=0; i<array_src.length; i++)
	{
		array_dest[i]=array_src[i];
	}
}

function fnTextArea2HTML(strIn)
{
	var strOut = "";
	var	regEx = /\n/g;
	strOut = strIn.replace(regEx, "<br>");
	regEx = /\r/g;
	strOut = strOut.replace(regEx, "");
	return strOut;
}

function fnText2HTML(str_in)
{
	var str_out = "";
	var	regEx = /\</g;
	str_out = str_in.replace(regEx, "");
	regEx = /\>/g;
	str_out = str_out.replace(regEx, "");
	regEx = /\n/g;
	str_out = str_out.replace(regEx, "<br>");
	regEx = /\r/g;
	str_out = str_out.replace(regEx, "");
	return str_out;
}

function fnText2HTML2(str_in)
{
	var str_out = "";
	var	regEx = /\</g;
	str_out = str_in.replace(regEx, "&lt;");
	regEx = /\>/g;
	str_out = str_out.replace(regEx, "&gt;");
	regEx = /\n/g;
	str_out = str_out.replace(regEx, "<br>");
	regEx = /\r/g;
	str_out = str_out.replace(regEx, "");
	regEx = /\\/g;
	str_out = str_out.replace(regEx, "");
	return str_out;
}

function fnSafeText4HTML(str_in)
{
	var str_out = "";
	if (typeof(str_in)=="undefined")
		return "";
	if (typeof(str_in)!="string")
		str_in = "" +str_in;
	var	regEx = /\</g;
	str_out = str_in.replace(regEx, "&lt;");
	regEx = /\>/g;
	str_out = str_out.replace(regEx, "&gt;");
	return str_out;
}

function fnSafeText4HTML2(str_in)
{
	var str_out = "";
	if (typeof(str_in)=="undefined")
		return "";
	if (typeof(str_in)!="string")
		str_in = "" +str_in;

	var array_temp;
	var str_iter=""+str_in;
	var done=0;
	while (!done)
	{
		if (!fnDoesStrHaveValue(str_iter))
			done=1;
		else
		{
			array_temp =str_iter.split("<");
			str_out += array_temp[0];
			if (array_temp.length<2)
				done=1;
			else
			{
				array_temp = array_temp[1].split(">");
				if (array_temp.length<2)
					done=1;
				else
					str_iter =array_temp[1];
			}
		}
	}
	return str_out;
}

function fnEncodeEvalParam(str_in)
{
	var str_out = str_in;
	var	regEx = /~/g;
	str_out = str_out.replace(regEx, "~0");
	regEx = /(\n)/g;
	str_out = str_out.replace(regEx, "~1");
	regEx = /(\r)(\b)(\t)(\a)(\e)(\f)(\v)/g;
	str_out = str_out.replace(regEx, "");
	return str_out;
}

function fnDecodeEvalParam(str_in)
{
	var str_out = str_in;
	var	regEx = /(~1)/g;
	str_out = str_out.replace(regEx, "\n");
	regEx = /(~0)/g;
	str_out = str_out.replace(regEx, "~");
	return str_out;
}

function fnDandecode(strIn)
{
	if (!fnDoesStrHaveValue(strIn))
		return "";

	var strOut = "";
	var	regEx = /(z2)/g;

	if ((strIn != null) && (strIn != ""))
	{
		strOut = strIn.replace(regEx, ">");

		regEx = /(z1)/g;
		strOut = strOut.replace(regEx, "<");

		regEx = /(z3)/g;
		strOut = strOut.replace(regEx, "&");

		regEx = /(z0)/g;
		strOut = strOut.replace(regEx, "z");
	}

	return strOut;
}

function fnCatdecode(strIn)
{
	if (!fnDoesStrHaveValue(strIn))
		return "";
	var regEx = /(z0)/g;
	return strIn.replace(regEx, "z");
}

function fnQTdecode(str_in)
{
	var str_out = "";
	if (((typeof str_in) == "undefined") || (str_in == null) || (str_in == ""))
		return str_out;
	var reg_ex;

	reg_ex = /(z6)/g;
	str_out = str_in.replace(reg_ex, "~");

	reg_ex = /(z5)/g;
	str_out = str_out.replace(reg_ex, "!");

	reg_ex = /(z4)/g;
	str_out = str_out.replace(reg_ex, "&");

	reg_ex = /(z3)/g;
	str_out = str_out.replace(reg_ex, "=");

	reg_ex = /(z2)/g;
	str_out = str_out.replace(reg_ex, "#");

	reg_ex = /(z1)/g;
	str_out = str_out.replace(reg_ex, "^");

	reg_ex = /(z0)/g;
	str_out = str_out.replace(reg_ex, "z");	// This transformation must be done last!!

	return str_out;
}

function fnQuoteDecode(str_in)
{
	var str_out = "";
	if (((typeof str_in) == "undefined") || (str_in == null) || (str_in == ""))
		return str_out;
	var reg_ex;

	try
	{
		reg_ex = /(z2)/g;
		str_out = str_in.replace(reg_ex, "\"");

		reg_ex = /(z1)/g;
		str_out = str_out.replace(reg_ex, "'");

		reg_ex = /(z0)/g;
		str_out = str_out.replace(reg_ex, "z");	// This transformation must be done last!!
	}
	catch (err)
	{
		return "";
	}

	return str_out;
}

function fnQuoteEncode(str_in)
{
	var str_out = "";
	if (((typeof str_in) == "undefined") || (str_in == null) || (str_in == ""))
		return str_out;
	var reg_ex;
	try
	{
		reg_ex = /(z)/g;
		str_out = str_in.replace(reg_ex, "z0");	// This transformation must be done first!!

		reg_ex = /(")/g;
		str_out = str_out.replace(reg_ex, "z2");

		reg_ex = /(')/g;
		str_out = str_out.replace(reg_ex, "z1");
	}
	catch (err)
	{
		return "";
	}

	return str_out;
}


// Convert from MM/DD/YYYY or MM/DD to JS date (is tolerant of other separators , . - and of YY)
function fnDisplayDate2JSDate(display_date)
{
	var js_date = new Date();

	if ((display_date == null) || (display_date == ""))
		return null;

	var	regEx = /\s/g;
	display_date = display_date.replace(regEx, "");
	var	array_date = display_date.split("/");
	if (2 > array_date.length)
	{
		array_date = display_date.split("-");
		if (2 > array_date.length)
		{
			array_date = display_date.split(".");
			if (2 > array_date.length)
			{
				array_date = display_date.split(",");
				if (2 > array_date.length)
				{
					return null;
				}
			}
		}
	}
	if (array_date.length>2)
	{
		var n_year = parseInt(array_date[2],10);
		if (n_year>=100)
			js_date.setFullYear(n_year);
		else
		{
			n_year += js_date.getFullYear() - (js_date.getFullYear() % 100);
			js_date.setFullYear(n_year);
		}
	}
	var n_month = parseInt(array_date[0],10);
	var n_day = parseInt(array_date[1],10);
	js_date.setMonth(n_month-1,n_day);

	return js_date;
}

// Compares the day of 2 dates
// returns: true: day is teh same
//			false: day is not the same
function fnSameDates(date_left, date_right)
{
	if (	(date_left.getFullYear() == date_right.getFullYear())
		&& 	(date_left.getMonth() == date_right.getMonth())
		&& 	(date_left.getDate() == date_right.getDate()))
		return true;
	else
		return false;
}

/* returns number of days from date_left to date_right */
/*
function fnDateDiff(date_left, date_right)
{
	var date_left_day = new Date();
	date_left_day.setFullYear(date_left.getFullYear());
	date_left_day.setMonth(date_left.getMonth());
	date_left_day.setDate(date_left.getDate());
	date_left_day.setHours(0);
	date_left_day.setMinutes(0);
	date_left_day.setSeconds(0);
	date_right_day.setFullYear(date_right.getFullYear());
	date_right_day.setMonth(date_right.getMonth());
	date_right_day.setDate(date_right.getDate());
	date_right_day.setHours(0);
	date_right_day.setMinutes(0);
	date_right_day.setSeconds(0);

	var diff_ms = date_right_day.getTime() - date_left_day.getTime();
	var diff_days = (diff_ms * 60000) *60 *24;
	return diff_days;
}
*/
/* 	fnCompareJSDates
	Granularity = day
	returns:
		-1: day of date_left is less than date_right
		 0: day of date_left is equal to date_right
		 1: day of date_left is more than date_right
*/
function fnCompareJSDates(date_left, date_right)
{
	if (date_left.getFullYear() < date_right.getFullYear())
		return -1;
	if (date_left.getFullYear() > date_right.getFullYear())
		return 1;
	if (date_left.getMonth() < date_right.getMonth())
		return -1;
	if (date_left.getMonth() > date_right.getMonth())
		return 1;
	if (date_left.getDate() < date_right.getDate())
		return -1;
	if (date_left.getDate() > date_right.getDate())
		return 1;
	return 0;
}

function fnIsMoreThanWeekFromNow(jsdate)
{
	var jsdate_week_later = new Date();
	jsdate_week_later.setDate(jsdate_week_later.getDate()+7);
	if (fnCompareJSDates(jsdate,jsdate_week_later)>0)
		return 1;
	return 0;
}

function fnIsMoreThanAWeekOld(jsdate)
{
	var jsdate_week_ago = new Date();
	jsdate_week_ago.setDate(jsdate_week_ago.getDate()-7);
	if (fnCompareJSDates(jsdate,jsdate_week_ago)<0)
		return 1;
	return 0;
}

/* 	fnCompareJSDatetimes
	Granularity = ms
	returns:
		-1: day of date_left is less than date_right
		 0: day of date_left is equal to date_right
		 1: day of date_left is more than date_right
*/
function fnCompareJSDatetimes(date_left, date_right)
{
	if (date_left.getTime() < date_right.getTime())
		return -1;

	if (date_left.getTime() > date_right.getTime())
		return 1;

	return 0;
}


// returns: true: time is the same
//			false: time is not the same
function fnSameTime(time_left, time_right)
{
	if (time_left==time_right)
		return true;

	var array_left = time_left.split(":");
	var array_right = time_right.split(":");
	var done = false;
	var n_left = 0;
	var n_right = 0;
	var i = 0;

	for (i=0; (i<array_left.length) || (i<array_right.length); i++)
	{
		n_left = 0;
		n_right = 0;
		if (array_left.length > i)
			n_left = parseInt(array_left[i],10);
		if (array_right.length > i)
			n_right = parseInt(array_right[i],10);

		if (n_left != n_right)
			return false;
	}
	return true;
}

// to 07/15/2007 4:01p
function fnSQLTS2DisplayDatetime(sql_ts)
{
	if ((sql_ts == null) || (sql_ts == ""))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";

	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate(array_datetime[0],"/");
	if (array_datetime.length > 1)
	{
		str_out += " ";
		str_out += DBTimeToString2(array_datetime[1]);
	}
	return str_out;
}

// to 7.15.2007 4:01p
function fnSQLTS2DisplayDatetime6(sql_ts)
{
	if ((sql_ts == null) || (sql_ts == ""))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";
	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate10(array_datetime[0],".");
	if (array_datetime.length > 1)
	{
		str_out += " ";
		str_out += DBTimeToString2(array_datetime[1]);
	}
	return str_out;
}

// to 7/15/2007 4:01p
function fnSQLTS2DisplayDatetime5(sql_ts)
{
	if ((sql_ts == null) || (sql_ts == ""))
		return "";
	var str_out =fnSQLTS2DisplayDatetime(sql_ts);
	if (fnDoesStrHaveValue(str_out) && str_out.charAt(0)=='0')
		return str_out.slice(1);
	return str_out;
}

function fnSQLTS2DisplayDate(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";

	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate7(array_datetime[0]);
	return str_out;
}

// to July 01, 2007 - 4:01p
function fnSQLTS2DisplayDatetime2(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";

	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate2(array_datetime[0]);
	if (array_datetime.length > 1)
	{
		str_out += "  ";
		str_out += DBTimeToString2(array_datetime[1]);
	}
	return str_out;
}

// to Mon, July 01, 2007 - 4:01p
function fnSQLTS2DisplayDatetime4(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";

	var js_date = fnSQLDatetime2JSDate(array_datetime[0],array_datetime[1]);
	str_out += fnDOTW2AbbrevStr(js_date.getDay()+1);
	str_out += " ";

	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate(array_datetime[0],"-");
	if (array_datetime.length > 1)
	{
		str_out += " ";
		str_out += DBTimeToString2(array_datetime[1]);
	}
	return str_out;
}

// to 07-15-2007 4:01p
function fnSQLTS2DisplayDatetime3(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";
	var	array_datetime = sql_ts.split(" ");
	var str_out = "";

	if (array_datetime.length > 0)
		str_out += fnSQLDate2DisplayDate(array_datetime[0],"-");
	if (array_datetime.length > 1)
	{
		str_out += " ";
		str_out += DBTimeToString2(array_datetime[1]);
	}
	return str_out;
}

function fnSQLTS2CompactDatetime(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";

	var str_out = "";
	var	array_date_target = sql_ts.split(" ");
	if ((!array_date_target) || (array_date_target.length<2))
		return str_out;
	var js_date_target = fnSQLDatetime2JSDate(array_date_target[0],array_date_target[1]);
	var js_date_today = new Date();
	var str_temp = "";

	if (js_date_target.getFullYear() == js_date_today.getFullYear())
	{
		// If it is this year
		if (	(js_date_target.getMonth() == js_date_today.getMonth())
			&& 	(js_date_target.getDate() == js_date_today.getDate()))
		{
			// It is this month and day, just show time
			str_out = fnJSDate2DisplayTime2(js_date_target);
		}
		else
		{
			// It is a different month or day, just show month and day
			// js date month is 0-indexed
			str_out = fnJSDate2Month(js_date_target);
			str_out += " " + js_date_target.getDate();
		}
	}
	else
	{
		// If it is a diff year, just show year
		str_out = js_date_target.getFullYear();
	}
	return str_out;
}

// Month and Year on diff year
function fnSQLTS2CompactDatetime2(sql_ts)
{
	if (!fnDoesStrHaveValue(sql_ts))
		return "";
	var str_out = "";
	var	array_date_target = sql_ts.split(" ");
	if ((!array_date_target) || (array_date_target.length<2))
		return str_out;
	var js_date_target = fnSQLDatetime2JSDate(array_date_target[0],array_date_target[1]);
	var js_date_today = new Date();
	var str_temp = "";

	if (js_date_target.getFullYear() == js_date_today.getFullYear())
	{
		// If it is this year
		if (	(js_date_target.getMonth() == js_date_today.getMonth())
			&& 	(js_date_target.getDate() == js_date_today.getDate()))
		{
			// It is this month and day, just show time
			str_out = fnJSDate2DisplayTime2(js_date_target);
		}
		else
		{
			// It is a different month or day, just show month and day
			// js date month is 0-indexed
			str_out = fnJSDate2Month(js_date_target);
			str_out += " " + js_date_target.getDate();
		}
	}
	else
	{
		// If it is a diff year, just show year
		str_out = fnJSDate2Month(js_date_target) + " " + js_date_target.getFullYear();
	}
	return str_out;
}

function fnJSDate2DisplayDateFull(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = fnJSDate2DOTW(jsdate);
	str_out += ", " + fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	var jsdate_today = new Date();
	if (jsdate.getFullYear() != jsdate_today.getFullYear())
		str_out += ", " + jsdate.getFullYear();

	return str_out;
}

function fnJSDate2DisplayDate(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = fnJSDate2DOTW(jsdate);
	str_out += ", " + fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	var jsdate_today = new Date();
	if (jsdate.getFullYear() != jsdate_today.getFullYear())
		str_out += ", " + jsdate.getFullYear();

	return str_out;
}

function fnJSDate2DisplayWeek(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	var jsdate_end = fnCloneDate(jsdate);
	jsdate_end.setDate(jsdate.getDate()+6);
	str_out += fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	str_out += " - " +fnJSDate2Month(jsdate_end);
	str_out += " " + jsdate_end.getDate();
	return str_out;
}

function fnJSDate2DisplayDate3a(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getFullYear();
	return str_out;
}
function fnJSDate2DisplayDate3b(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = jsdate.getDate();
	return str_out;
}
function fnJSDate2DisplayDate3c(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = fnDOTW2Str(jsdate.getDay()+1);
	return str_out;
}


function fnJSDate2SlashDate(js_date)
{
	if (!fnDoesObjHaveValue(js_date))
		return "";
	var str_out = (js_date.getMonth()+1);
	str_out += "/" + js_date.getDate();
	str_out += "/" + js_date.getFullYear();
	return str_out;
}

function fnJSDate2DisplayDate2(jsdate)
{
	var	str_out = "";

	if (!jsdate)
		return str_out;

	str_out = fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	str_out += ", " + jsdate.getFullYear();

	return str_out;
}

function fnJSDate2SQLDate(js_date)
{
	if (!js_date)
		return null;
	var str_out = js_date.getFullYear();
	str_out += "-";
	var n_temp = js_date.getMonth()+1;
	if (n_temp<10)
		str_out += "0";
	str_out += n_temp;
	n_temp = js_date.getDate();
	str_out += "-";
	if (n_temp<10)
		str_out += "0";
	str_out += n_temp;
	return str_out;
}

function fnJSDate2DisplayDate_NoYear(jsdate)
{
	var	str_out = "";
	if (!jsdate)
		return str_out;
	str_out = fnJSDate2DOTW(jsdate);
	str_out += ", " + fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	return str_out;
}

function fnJSDate2DisplayDate_NoYear2(jsdate)
{
	var	str_out = "";
	if (!jsdate)
		return str_out;
	str_out += fnJSDate2Month(jsdate);
	str_out += " " + jsdate.getDate();
	return str_out;
}

function fnGetTodayDateString()
{
	var	str_out = "";
	var date1 = new Date();
	var theDay = date1.getDate();
	var	theMonth = date1.getMonth()+1;
	var	theFullYear = date1.getFullYear();

	str_out += theMonth + "/" + theDay + "/" + theFullYear;
	return str_out;
}

function fnGetTodayDateAsSQLDate()
{
	var	str_out = "";
	var date1 = new Date();
	var theDay = date1.getDate();
	var	theMonth = date1.getMonth()+1;
	var	theFullYear = date1.getFullYear();

	str_out += theFullYear + "-" + theMonth + "-" + theDay;
	return str_out;
}

function fnDate2SQLTime_no_sec(in_date)
{
	var	str_out = "";
	var theHour = in_date.getHours();
	var	theMin = in_date.getMinutes();
	var str_hour = "";
	var str_min = "";

	str_hour += theHour;
	str_min += theMin;

	if (theMin<10)
		str_min = "0" + str_min;

	str_out += str_hour + ":" + str_min + ":00";
	return str_out;
}

// Convert from MM/DD/YYYY to YYYY-MM-DD
function fnDisplayDate2SQLDate(display_date)
{
	var sql_date = "";

	if ((display_date == null) || (display_date == ""))
		return DEFAULT_DATE;

	var	regEx = /\s/g;
	display_date = display_date.replace(regEx, "");
	var	array_date = display_date.split("/");

	if (3 > array_date.length)
		return DEFAULT_DATE;

	sql_date = array_date[2] + "-" + array_date[0] + "-" + array_date[1];

	return sql_date;
}

// Convert from MM/DD/YYYY or MM/DD to SQL date (is tolerant of other separators , . - and of YY)
function fnDisplayDate2SQLDate3(display_date)
{
	var js_date = null;

	if ((display_date == null) || (display_date == ""))
		return "";

	display_date =display_date.replace(/[^A-Za-z0-9]/g,"/");
	display_date =display_date.replace(/\/\//g,"/");
	display_date =display_date.replace(/\/\//g,"/");
	display_date =display_date.replace(/\/\//g,"/");

	var	array_date = display_date.split("/");
	if (2 > array_date.length)
	{
		return "";
	}
	var n_year = 0;
	if (array_date.length>2)
	{
		n_year = fnSafeParseInt(array_date[2],-1);
		if (n_year<100)
			js_date = new Date();
		if (n_year<0)
			n_year = js_date.getFullYear();
		if (n_year<100)
			n_year += js_date.getFullYear() - (js_date.getFullYear() % 100);
	}
	else
	{
		js_date = new Date();
		n_year = js_date.getFullYear();
	}
	var n_month = fnParseMonth(array_date[0]);
	if (n_month==-1)
		return "";
	var n_day = fnSafeParseInt(array_date[1],-1);
	if (n_day==-1)
		return "";
	var sql_date = n_year +"-" +n_month +"-" +n_day;
	return sql_date;
}

function fnParseMonth(str_month)
{
	str_month = str_month.toLowerCase();
	if (str_month.match("jan"))
		return 1;
	if (str_month.match("feb"))
		return 2;
	if (str_month.match("mar"))
		return 3;
	if (str_month.match("apr"))
		return 4;
	if (str_month.match("may"))
		return 5;
	if (str_month.match("jun"))
		return 6;
	if (str_month.match("jul"))
		return 7;
	if (str_month.match("aug"))
		return 8;
	if (str_month.match("sep"))
		return 9;
	if (str_month.match("oct"))
		return 10;
	if (str_month.match("nov"))
		return 11;
	if (str_month.match("dec"))
		return 12;
	return fnSafeParseInt(str_month, -1);
}


// Convert from YYYY-MM-DD to MM/DD/YYYY
function fnSQLDate2DisplayDate(sql_date,sep)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return "";

	if (!fnDoesStrHaveValue(sep))
		sep="/";

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");

	if (3 > array_date.length)
		return DEFAULT_DATE;

	display_date = array_date[1] + sep + array_date[2] + sep + array_date[0];

	return display_date;
}

// Convert from YYYY-MM-DD to M/D/YYYY
function fnSQLDate2DisplayDate10(sql_date,sep)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return ""

	if (!fnDoesStrHaveValue(sep))
		sep="/";

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");

	if (3 > array_date.length)
		return DEFAULT_DATE;

	if (fnDoesStrHaveValue(array_date[1]) && array_date[1].charAt(0)=='0')
		array_date[1] =array_date[1].slice(1);

	if (fnDoesStrHaveValue(array_date[2]) && array_date[2].charAt(0)=='0')
		array_date[2] =array_date[2].slice(1);

	display_date = array_date[1] + sep + array_date[2] + sep + array_date[0];

	return display_date;
}

// Convert from YYYY-MM-DD to MM/DD/YYYY or just time if today
function fnSQLDate2DisplayDate9(sql_date,sep)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return "";


	var js_date = fnSQLDatetime2JSDatetime(sql_date);
	if (!fnCompareJSDates(js_date, new Date()))
		return fnJSDate2DisplayTime2(js_date);

	if (!fnDoesStrHaveValue(sep))
		sep="/";

	sql_date =(sql_date.split(" "))[0];

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");

	if (3 > array_date.length)
		return DEFAULT_DATE;

	display_date = fnSafeParseInt(array_date[1],0) + sep + fnSafeParseInt(array_date[2],0) + sep + array_date[0];

	return display_date;
}

// to dotw mm-dd-yyyy
function fnSQLDate2DisplayDate7(sql_date)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return "";

	var js_date = fnSQLDate2JSDate(sql_date);
	if (!js_date)
		return "";
	var dotw = js_date.getDay()+1;

	display_date += fnDOTW2AbbrevStr(dotw);
	display_date += "&nbsp;";

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");

	if (3 > array_date.length)
		return "";

	display_date += array_date[1] + "-" + array_date[2] + "-" + array_date[0];

	return display_date;
}

// to mm-dd-yyyy
function fnSQLDate2DisplayDate8(sql_date)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return "";

	var	array_temp = sql_date.split(" ");
	sql_date = array_temp[0];

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");

	if (3 > array_date.length)
		return "";

	display_date += array_date[1] + "-" + array_date[2] + "-" + array_date[0];

	return display_date;
}

// to dotw mm-dd-yyyy hh:mm a/p
function fnTS2DisplayDatetime(sql_datetime)
{
	var display_date = "";
	if ((sql_datetime == null) || (sql_datetime == ""))
		return "";

	var array_date = sql_datetime.split(" ");
	display_date = fnSQLDate2DisplayDate7(array_date[0]);
	if (array_date.length>1)
	{
		display_date += " ";
		display_date += fnSQLTime2DisplayTime(array_date[1]);
	}
	return display_date;
}

function fnParseLiterals1(str_in)
{
	return str_in.replace(/\$/gi,"$0");
}

// Convert from YYYY-MM-DD to dotw, Month Day, YYYY
function fnSQLDate2DisplayDate2(sql_date)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return DEFAULT_DATE;

	var js_date = fnSQLDate2JSDate(sql_date);
	var dotw = js_date.getDay()+1;

	switch (dotw)
	{
		case 1:
			display_date += "Sun, ";
			break;
		case 2:
			display_date += "Mon, ";
			break;
		case 3:
			display_date += "Tue, ";
			break;
		case 4:
			display_date += "Wed, ";
			break;
		case 5:
			display_date += "Thu, ";
			break;
		case 6:
			display_date += "Fri, ";
			break;
		case 7:
			display_date += "Sat, ";
			break;
	}

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");	// array is [YYYY][MM][DD]

	if (3 > array_date.length)
		return DEFAULT_DATE;

	display_date += fnMonth2Str(parseInt(array_date[1],10));
	display_date += " ";
	display_date += array_date[2];
	display_date += ", ";
	display_date += array_date[0];

	return display_date;
}

// Convert from YYYY-MM-DD to dotw, Month Day and sometimes YYYY
function fnSQLDate2DisplayDate3(sql_date)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return "";

	var js_date = fnSQLDate2JSDate(sql_date);
	var dotw = js_date.getDay()+1;

	display_date += fnDOTW2AbbrevStr(dotw);
	display_date += ", ";

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");	// array is [YYYY][MM][DD]

	if (3 > array_date.length)
		return DEFAULT_DATE;

	display_date += fnMonth2Str(parseInt(array_date[1],10));
	display_date += " ";
	display_date += array_date[2];
	// Show the year iff the date is in teh past or is in the future more than around 10 months
	var jsdate_today = new Date();
	var time_diff = js_date.getTime() - jsdate_today.getTime();
	if (time_diff<-15920000000 || time_diff>25920000000)
	{
		display_date += ", ";
		display_date += array_date[0];
	}
	return display_date;
}

// Convert from YYYY-MM-DD to Month Day, YYYY
function fnSQLDate2DisplayDate4(sql_date)
{
	var display_date = "";

	if ((sql_date == null) || (sql_date == ""))
		return DEFAULT_DATE;

	var js_date = fnSQLDate2JSDate(sql_date);

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");	// array is [YYYY][MM][DD]

	if (3 > array_date.length)
		return DEFAULT_DATE;

	display_date += fnMonth2Str(parseInt(array_date[1],10));
	display_date += " ";
	display_date += array_date[2];
	display_date += ", ";
	display_date += array_date[0];

	return display_date;
}

function fnDOTW2Str(n_dotw)
{
	var str_dotw = "";
	switch (n_dotw)
	{
		case 1:
			str_dotw = "Sunday";
			break;
		case 2:
			str_dotw = "Monday";
			break;
		case 3:
			str_dotw = "Tuesday";
			break;
		case 4:
			str_dotw = "Wednesday";
			break;
		case 5:
			str_dotw = "Thursday";
			break;
		case 6:
			str_dotw = "Friday";
			break;
		case 7:
			str_dotw = "Saturday";
			break;
	}
	return str_dotw;
}

function fnDOTW2AbbrevStr(n_dotw)
{
	var str_dotw = "";
	switch (n_dotw)
	{
		case 1:
			str_dotw += "Sun";
			break;
		case 2:
			str_dotw += "Mon";
			break;
		case 3:
			str_dotw += "Tue";
			break;
		case 4:
			str_dotw += "Wed";
			break;
		case 5:
			str_dotw += "Thu";
			break;
		case 6:
			str_dotw += "Fri";
			break;
		case 7:
			str_dotw += "Sat";
			break;
	}
	return str_dotw;
}

function fnDOTW2AbbrevStr2(n_dotw)
{
	var str_dotw = "";
	switch (n_dotw)
	{
		case 0:
			str_dotw += "Sun";
			break;
		case 1:
			str_dotw += "Mon";
			break;
		case 2:
			str_dotw += "Tue";
			break;
		case 3:
			str_dotw += "Wed";
			break;
		case 4:
			str_dotw += "Thu";
			break;
		case 5:
			str_dotw += "Fri";
			break;
		case 6:
			str_dotw += "Sat";
			break;
	}
	return str_dotw;
}

function fnMonth2Str(n_month)
{
	var str_month="";
	switch (n_month)
	{
		case 1:
			str_month = "Jan";
			break;
		case 2:
			str_month = "Feb";
			break;
		case 3:
			str_month = "Mar";
			break;
		case 4:
			str_month = "Apr";
			break;
		case 5:
			str_month = "May";
			break;
		case 6:
			str_month = "June";
			break;
		case 7:
			str_month = "July";
			break;
		case 8:
			str_month = "Aug";
			break;
		case 9:
			str_month = "Sep";
			break;
		case 10:
			str_month = "Oct";
			break;
		case 11:
			str_month = "Nov";
			break;
		case 12:
			str_month = "Dec";
			break;
	}
	return str_month;
}

function fnMonth2StrVerbose(n_month)
{
	var str_month="";
	switch (n_month)
	{
		case 1:
			str_month = "January";
			break;
		case 2:
			str_month = "February";
			break;
		case 3:
			str_month = "March";
			break;
		case 4:
			str_month = "April";
			break;
		case 5:
			str_month = "May";
			break;
		case 6:
			str_month = "June";
			break;
		case 7:
			str_month = "July";
			break;
		case 8:
			str_month = "August";
			break;
		case 9:
			str_month = "September";
			break;
		case 10:
			str_month = "October";
			break;
		case 11:
			str_month = "November";
			break;
		case 12:
			str_month = "December";
			break;
	}
	return str_month;
}

function fnSQLDate2SectionHeaderDate(sql_date)
{
	var display_date = "";
	var str_dotw = "";

	if ((sql_date == null) || (sql_date == ""))
		return DEFAULT_DATE;

	var js_date = fnSQLDate2JSDate(sql_date);
	display_date += "<span>";
	display_date += fnDOTW2Str(js_date.getDay()+1);
	display_date += "</span>";

	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");	// array is [YYYY][MM][DD]

	if (3 > array_date.length)
		return DEFAULT_DATE;
/*
	display_date += "<span class='style_weekly_section_header_date'>";
	display_date += fnMonth2Str(parseInt(array_date[1],10));
	display_date += " ";
	display_date += array_date[2];
	display_date += ", ";
	display_date += array_date[0];
	display_date += "</span>";
*/
	return display_date;
}

function fnSQLDatetime2JSDate(sql_date, sql_time)
{
	var	js_date = fnSQLDate2JSDate(sql_date);
	var str_min = "0";
	if (sql_time)
	{
		str_min = DBTimeToMin(sql_time);
		js_date.setHours(DBTimeTo24Hour2(sql_time));
		js_date.setMinutes(parseInt(str_min, 10));
	}
	return js_date;
}

function fnSQLDatetime2JSDate2(sql_datetime)
{
	var	array_date = sql_datetime.split(" ");
	return fnSQLDate2JSDate(array_date[0]);
}

function fnSQLDatetime2JSDatetime(sql_datetime)
{
	var	array_date = sql_datetime.split(" ");
	var js_date = fnSQLDate2JSDate(array_date[0]);
	if (array_date.length>1)
	{
		var str_min = DBTimeToMin(array_date[1]);
		js_date.setHours(DBTimeTo24Hour2(array_date[1]));
		js_date.setMinutes(parseInt(str_min, 10));
	}
	return js_date;
}

function fnSQLDatetime2DisplayTime(sql_datetime)
{
	var	array_date =sql_datetime.split(" ");
	if (array_date.length<2)
		return;
	return fnSQLTime2DisplayTime2(array_date[1]);
}

function fnSQLTime2DisplayTime2(sql_time)
{
	var str_out ="";
	var pm=0;
  var n_temp=0;
	var array_time =sql_time.split(":");
	if (array_time.length>0)
	{
		n_temp = fnSafeParseInt(array_time[0], 0);
		if (n_temp>=12)
		{
			pm =1;
			if (n_temp>12)
				n_temp -=12;
		}
		else if (n_temp==0)
			n_temp = 12;
		str_out += n_temp;
	}
	str_out += ":";
	if (array_time.length<=1 || array_time[1].length==0)
		str_out += "00";
	else if (array_time.length>=2)
	{
		if (array_time[1].length<=1)
			str_out += "0";
		str_out += array_time[1];
	}
	if (pm)
		str_out += " pm";
	else
		str_out += " am";
	return str_out;
}

function fnSQLTime2DisplayTime(sql_time)
{
	if (!fnDoesStrHaveValue(sql_time))
		return "";
  var n_temp=0;
	var str_out ="";
	var pm=0;
	var array_time =sql_time.split(":");
	if (array_time.length>0)
	{
		n_temp = fnSafeParseInt(array_time[0], 0);
		if (n_temp>=12)
		{
			pm =1;
			if (n_temp>12)
				n_temp -=12;
		}
		else if (n_temp==0)
			n_temp = 12;
		str_out += n_temp;
	}
	if (array_time.length>1)
	{
		n_temp = fnSafeParseInt(array_time[1], 0);
		if (n_temp)
		{
			str_out += ":";
			if (n_temp<10)
				str_out += "0";
			str_out += n_temp;
		}
	}
	if (pm)
		str_out += "p";
	else
		str_out += "a";
	return str_out;
}

function fnSQLTime2JSDate(sql_time)
{
	var	js_date = new Date();
	var str_min = DBTimeToMin(sql_time);
	js_date.setHours(DBTimeTo24Hour2(sql_time));
	js_date.setMinutes(parseInt(str_min, 10));
	return js_date;
}

function fnSQLDate2JSDate(sql_date)
{
	var js_date =new Date();
	if (!fnDoesStrHaveValue(sql_date))
		return js_date;
	var array_dt = sql_date.split(" ");
	sql_date = array_dt[0];
	var	regEx = /\s/g;
	sql_date = sql_date.replace(regEx, "");
	var	array_date = sql_date.split("-");
	if (3 > array_date.length)
		return null;
	var n_year = parseInt(array_date[0],10);
	var n_month = parseInt(array_date[1],10)-1;
	var n_day = parseInt(array_date[2],10);

	js_date.setFullYear(n_year);
	js_date.setMonth(n_month,n_day);

	return js_date;
}

function fnIsDigit(c)
{
	if ('0'==c)
		return true;
	else if ('1'==c)
		return true;
	else if ('2'==c)
		return true;
	else if ('3'==c)
		return true;
	else if ('4'==c)
		return true;
	else if ('5'==c)
		return true;
	else if ('6'==c)
		return true;
	else if ('7'==c)
		return true;
	else if ('8'==c)
		return true;
	else if ('9'==c)
		return true;

	return false;
}

function fnStrTime2SQLTime(str_time)
{
	var str_out = "";
	var the_hour=0;
	var the_min=0;
	var the_sec=0;
	var	i = 0;
	var	j = 0;
	var c;
	var ampm='a';
	var str_temp="";
	var str_temp2="";
	var n_temp = 0;

	if ((str_time == null) || (str_time == ""))
		return DEFAULT_TIME;

	var	regEx = /\s/g;
	str_time = str_time.replace(regEx, "");
	if (str_time.search(/p/i)>=0)
		ampm='p';
	var	array_time = str_time.split(":");

	// Now we have dealt with the ampm and the :, we no longer need non digits, so strip them out once and for all
	for (i=0; i<array_time.length; i++)
	{
		array_time[i]=array_time[i].replace(/\D/g,"");
	}

	if (array_time.length>=2)
	{
		if (array_time[0].length<1)
			return DEFAULT_TIME;
		the_hour = parseInt(array_time[0], 10);
		if (array_time[1].length>0)
			the_min = parseInt(array_time[1], 10);
	}
	else
	{
		str_temp = array_time[0];
		n_temp = str_temp.length;
		if (n_temp<=2)
		{
			the_hour = parseInt(str_temp, 10);
		}
		else
		{
			// strip off the last two digits to use for minutes
			str_temp2="";
			str_temp2 += str_temp.charAt(n_temp-2);
			str_temp2 += str_temp.charAt(n_temp-1);
			the_min = parseInt(str_temp2,10);
			str_temp2="";
			for (i=0; i<n_temp-2; i++)
			{
				c = str_temp.charAt(i);
				str_temp2 += c;
			}
			the_hour = parseInt(str_temp2, 10);
		}
	}

	if ((the_hour<13) && (ampm=='p'))
		the_hour+=12;
	else if ((ampm=='a') && (the_hour==12))
		the_hour=0;
	if (24==the_hour)
		the_hour=12;

	str_out = the_hour + ":" + the_min + ":00";
	return str_out;
}

function fnJSDate2DisplayTime(the_date)
{
	var	str_out = "";
	var	the_hour = 0;
	var	the_min = 0;
	var the_pm = 0;

	the_hour = the_date.getHours();

	if (the_date.getHours()==12)
	{
		the_pm = 1;
	}
	else if (the_date.getHours()>12)
	{
		the_pm = 1;
		the_hour -= 12;
	}
	else if (the_date.getHours()==0)
	{
		the_pm = 0;
		the_hour = 12;
	}

	the_min = the_date.getMinutes();

	str_out += the_hour + ":";
	if (the_min<10)
		str_out += "0";
	str_out += the_min;

	if (the_pm == 0)
		str_out += "am";
	else
		str_out += "pm";

	return str_out;
}

function fnJSDate2SQLTS(js_date)
{
	var	str_out = fnJSDate2SQLDate(js_date);
	str_out += " " +js_date.getHours() +":" + js_date.getMinutes() +":" +js_date.getSeconds();
	return str_out;
}

function fnJSDate2DisplayTime2(the_date)
{
	var	str_out = "";
	var	the_hour = 0;
	var	the_min = 0;
	var the_pm = 0;

	the_hour = the_date.getHours();

	if (the_date.getHours()==12)
	{
		the_pm = 1;
	}
	else if (the_date.getHours()>12)
	{
		the_pm = 1;
		the_hour -= 12;
	}
	else if (the_date.getHours()==0)
	{
		the_pm = 0;
		the_hour = 12;
	}

	the_min = the_date.getMinutes();

	str_out += the_hour + ":";
	if (the_min<10)
		str_out += "0";
	str_out += the_min;

	if (the_pm == 0)
		str_out += "a";
	else
		str_out += "p";

	return str_out;
}

function fnJSDate2DisplayTime3(the_date)
{
	var	str_out = "";
	var	the_hour = 0;
	var	the_min = 0;
	var the_pm = 0;

	the_hour = the_date.getHours();

	if (the_date.getHours()==12)
	{
		the_pm = 1;
	}
	else if (the_date.getHours()>12)
	{
		the_pm = 1;
		the_hour -= 12;
	}
	else if (the_date.getHours()==0)
	{
		the_pm = 0;
		the_hour = 12;
	}

	the_min = the_date.getMinutes();

	str_out += the_hour;
	var str_min = "" + the_min;
	if (the_min!=0)
	{
		str_out += ":";
		if (str_min.length<2)
			str_out += "0";
		str_out += str_min;
	}

	if (the_pm == 0)
		str_out += "a";
	else
		str_out += "p";

	return str_out;
}

function ReturnDateString()
{
	var strOut = "";
	var date1 = new Date();
	var the_year = date1.getFullYear();
	var the_month = date1.getMonth() + 1; 	// sql is 1-indexed, java & javascript are 0-indexed.  I am using 1-indexed months
	var the_day = date1.getDate();

	strOut = the_year + "-" + the_month + "-" + the_day;
	return strOut;
}

function fnJSDate2DOTW(js_date)
{
	var str_out = "";
	if (!js_date)
		return str_out;
	var n_dotw = js_date.getDay();
	switch (n_dotw)
	{
		case 0:
			str_out = "Sun";
			break;
		case 1:
			str_out = "Mon";
			break;
		case 2:
			str_out = "Tue";
			break;
		case 3:
			str_out = "Wed";
			break;
		case 4:
			str_out = "Thu";
			break;
		case 5:
			str_out = "Fri";
			break;
		case 6:
			str_out = "Sat";
			break;
	}
	return str_out;
}

function fnJSDate2Month(js_date)
{
	var str_out = "";
	if (!js_date)
		return str_out;
	var n_month = js_date.getMonth();
	switch (n_month)
	{
		case 0:
			str_out += "Jan";
			break;
		case 1:
			str_out += "Feb";
			break;
		case 2:
			str_out += "Mar";
			break;
		case 3:
			str_out += "Apr";
			break;
		case 4:
			str_out += "May";
			break;
		case 5:
			str_out += "June";
			break;
		case 6:
			str_out += "July";
			break;
		case 7:
			str_out += "Aug";
			break;
		case 8:
			str_out += "Sep";
			break;
		case 9:
			str_out += "Oct";
			break;
		case 10:
			str_out += "Nov";
			break;
		case 11:
			str_out += "Dec";
			break;
	}
	return str_out;
}

function JSDateToSQLDate(date1)
{
	var strOut = "";
	var the_year = date1.getFullYear();
	var the_month = date1.getMonth() + 1; 	// sql is 1-indexed, java & javascript are 0-indexed.  I am using 1-indexed months
	var the_day = date1.getDate();

	strOut = the_year + "-" + the_month + "-" + the_day;
	return strOut;
}

function DBTimeToString(the_time)
{
	var str_time = "";
	str_time += DBTimeToHour(the_time);
	str_time += ":";
	str_time += DBTimeToMin(the_time);
	str_time += DBTimeToAmPm(the_time);
	return str_time;
}

// Shows a,p instead of am,pm
function DBTimeToString2(the_time)
{
	var strTime = "";
	strTime += DBTimeToHour(the_time);
	strTime += ":";
	strTime += DBTimeToMin(the_time);
	strTime += DBTimeToAmPm2(the_time);

	return strTime;
}

function Time24ToDisplayTime(hh,mm)
{
	var	ampm = "a";
	var str_hh = "";
	var str_mm = "";
	var	str_out = "";

	if (hh==24)
	{
		ampm = "a";
		hh -= 12;
	}
	else if (hh==0)
	{
		ampm = "a";
		hh = 12;
	}
	else if (hh>12)
	{
		ampm = "p";
		hh -= 12;
	}
	else if (hh==12)
	{
		ampm = "p";
	}

	str_out += hh;
	str_out += ampm;

	return str_out;
}

function DBTimeToHour(the_time)
{
	var strOut = "";
	var offset = 0;
	var	nTime = 0;

	offset = the_time.indexOf(":");

	nTime = parseInt(the_time.substring(0, offset),10);

	if (nTime>12)
		nTime -= 12;

	if (nTime<1)
		nTime = 12;

	strOut += nTime;

	return strOut;
}

function DBTimeTo24Hour(the_time)
{
	var strOut = "";
	var offset = 0;
	var	nTime = 0;

	offset = the_time.indexOf(":");

	nTime = parseInt(the_time.substring(0, offset),10);

	if (nTime<1)
		nTime = 12;

	strOut += nTime;

	return strOut;
}

/* Convert DBTime to just the hour part as a 24 hr numerical value */
function DBTimeTo24Hour2(the_time)
{
	var offset = 0;
	var nHour = 0;

	offset = the_time.indexOf(":");
	nHour = parseInt(the_time.substring(0, offset),10);

	return nHour;
}

/* convert from SQL time (not date) to num of mins since the midnight start of day */
function fnSQLTime2TotalMins(sql_time)
{
	var n_hour = DBTimeTo24Hour2(sql_time);
	var n_min = parseInt(DBTimeToMin(sql_time),10);
	return (n_hour*60 + n_min);
}

/* Convert SQLTime to a num of half hours since 0 */
function SQLTimeToHalfHrNum(sql_time)
{
	var array_str_time = sql_time.split(":");
	var n_hour = 0;
	var n_half = 0;
	var n_out = 0;

	if (array_str_time.length<2)
		return n_out;

	n_hour = parseInt(array_str_time[0],10);
	var n_min = parseInt(array_str_time[1],10);

	n_out = n_hour * 2;
	if (n_min>15)
		n_out++;

	return n_out;
}

function fnHourTo24HourCode(the_hour, and_a_half)
{
	var str_out = "";

	if (the_hour<=9)
		str_out += "0";
	str_out += the_hour;
	if (and_a_half)
		str_out += "30";
	else
		str_out += "00";

	return str_out;
}

function fnHourToDisplayTime(the_hour, and_a_half)
{
	var mm ="00";
	var ampm ="am";
	if (and_a_half)
		mm ="30";
	var hh = Math.round(the_hour);
	if (hh>=12)
		ampm ="pm";
	if (hh>12)
	{
		hh-=12;
	}
	if (0==hh)
		hh=12;
	return (hh +":" +mm +ampm);
}

function fnHalfHourToDisplayTime(half_hr)
{
	half_hr = Math.round(half_hr);
	return fnHourToDisplayTime(Math.floor(half_hr/2), Math.round(half_hr)%2);
}

function fnHalfHoursTo24HourCode(half_hours)
{
	var the_hour = Math.floor(half_hours/(2.0));
	var and_a_half = false;
	if ((half_hours % 2) != 0)
		and_a_half = true;

	return fnHourTo24HourCode(the_hour, and_a_half);
}


function fnHourTo24HourCode2(sql_time)
{
	var str_out = "";
	var str_hour = DBTimeTo24Hour2(sql_time);
	var str_min = DBTimeToMin(sql_time);
	var the_hour = parseInt(str_hour, 10);
	var the_min = parseInt(str_min, 10);

	if (the_hour<=9)
		str_out += "0";
	str_out += str_hour;

	if (the_min<30)
		str_out += "00";
	else
		str_out += "30";

	return str_out;
}

function DBTimeToAmPm(the_time)
{
	var strOut = "am";
	var offs = 0;
	var	nTime = 0;

	offs = the_time.indexOf(":");
	nTime = parseInt(the_time.substring(0, offs),10);
	if (nTime>=12)
		strOut = "pm";
	return strOut;
}

// Shows a,p instead of am,pm
function DBTimeToAmPm2(the_time)
{
	var strOut = "a";
	var offs = 0;
	var	nTime = 0;

	offs = the_time.indexOf(":");
	nTime = parseInt(the_time.substring(0, offs),10);

	if (nTime>=12)
		strOut = "p";

	return strOut;
}

function DBTimeToMin(the_time)
{
	var strOut = "";
	var offs = 0;
	var	strMin = "";

	offs = the_time.indexOf(":");
	strMin += the_time.charAt(offs+1);
	if (the_time.charAt(offs+2)!=':')
		strMin += the_time.charAt(offs+2);

	if (strMin.length<1)
		strOut+="0";
	if (strMin.length<2)
		strOut+="0";
	strOut += strMin;

	return strOut;
}

function fnShowHide(bShow, elem)
{
	if (bShow)
	{
		fnShow(elem);
	}
	else
	{
		fnHide(elem);
	}
}

function fnShow(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).style.display = "";
	}
}

function fnHide(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).style.display = "none";
	}
}

function fnShow2(str_elem)
{
	if (null != str_elem)
	{
		var elem = document.getElementById(str_elem);
		if (elem)
		{
			elem.style.display = "";
			elem.style.visiblity = "visible";
		}
	}
}

function fnHide2(str_elem)
{
	if (null != str_elem)
	{
		var elem = document.getElementById(str_elem);
		if (elem)
		{
			elem.style.display = "none";
			elem.style.visiblity = "hidden";
		}
	}
}

function fnShowBlock(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).style.display = "block";
	}
}

function fnShowAbs(str_elem)
{
	if (!str_elem)
		return null;
	var elem = document.getElementById(str_elem);
	if (null == elem)
		return null;
	elem.style.visiblity = "visible";
}
function fnHideAbs(str_elem)
{
	if (!str_elem)
		return null;
	var elem = document.getElementById(str_elem);
	if (null == elem)
		return null;
	elem.style.visiblity = "hidden";
}

function fnHideRel(str_elem)
{
	if (!str_elem)
		return null;
	var elem = document.getElementById(str_elem);
	if (null == elem)
		return null;
	elem.style.visiblity = "hidden";
	elem.style.position = "absolute";
}
function fnEnableDisable(bEnable, str_elem)
{
	if (bEnable)
		fnEnable(str_elem);
	else
		fnDisable(str_elem);
	return bEnable;
}

function fnEnable(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (elem!= null)
	{
		elem.disabled = false;
		if (!(browser.isIE))
		{
			elem.style.color = "#000000";
			elem.style.borderTopColor="#909080";
			elem.style.borderLeftColor="#909080";
			elem.style.borderRightColor="#010101";
			elem.style.borderBottomColor="#010101";
		}
	}
}

function fnDisableElem(elem)
{
	if (elem!= null)
	{
		elem.disabled = true;
		if (!(browser.isIE))
		{
			elem.style.color = "#aaaaaa";
			elem.style.borderTopColor="#aaaaaa";
			elem.style.borderLeftColor="#aaaaaa";
			elem.style.borderRightColor="#aaaaaa";
			elem.style.borderBottomColor="#aaaaaa";
		}
	}
}

function fnDisable(str_elem)
{
	var elem = document.getElementById(str_elem);
	fnDisableElem(elem);
}

function fnDisable2(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.disabled = true;
}

function fnEnable2(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.disabled = false;
}

function fnEnableButtonBar(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.style.color ="#000000";
}

function fnDisableButtonBar(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.style.color ="#e0e0e0";
}

function fnChangeClass(str_elem, str_newclass)
{
	if (null != str_elem)
	{
		if (document.getElementById(str_elem))
			document.getElementById(str_elem).className = str_newclass;
	}
}

function fnChangeClass2(elem, str_newclass)
{
	if (null != elem)
		elem.className = str_newclass;
}

function fnSetBGColor(elem,str_color)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).style.backgroundColor = str_color;
	}
}

function fnIsElemValid(str_elem)
{
	if (!fnDoesStrHaveValue(str_elem))
		return 0;
	elem = 	document.getElementById(str_elem);
	if (!fnDoesObjHaveValue(elem))
		return 0;
	return 1;
}

function fnSetChecked(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).checked = true;
	}
}
function fnSetUnchecked(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).checked = false;
	}
}
function fnGetChecked(str_elem)
{
	if (!str_elem)
		return 0;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return 0;
	if (typeof(elem)=="undefined")
		return 0;
	if (typeof(elem.checked)=="undefined")
		return 0;
	return (elem.checked?1:0);
}

function fnSetSelectedIndex(elem, the_index)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			document.getElementById(elem).selectedIndex = the_index;
	}
}

function fnGetSelectedIndex(elem)
{
	if (null != elem)
	{
		if (document.getElementById(elem))
			return document.getElementById(elem).selectedIndex;
	}
	return 0;
}

function fnGetSelectedValue(str_elem, n_default)
{
	if (null == str_elem)
		return n_default;
	var elem = document.getElementById(str_elem);
	if (null == elem)
		return n_default;
	return elem.options[elem.selectedIndex].value;
}

function fnFocus(elem)
{
	if ((document.getElementById(elem)!= null) && (document.getElementById(elem).disabled == false) && (document.getElementById(elem).display != "none"))
		document.getElementById(elem).focus();
}

function fnResetInnerhtml(elem)
{
	if (document.getElementById(elem)!= null)
		document.getElementById(elem).innerHTML = "";
}

function fnSetInnerhtml(str_elem, str_value)
{
	if (!fnDoesStrHaveValue(str_elem))
		return;
	var elem =document.getElementById(str_elem)	;
	if (!fnDoesObjHaveValue(elem))
		return;
	var str_value2 = "";
	if (fnDoesStrHaveValue(str_value))
		str_value2 = str_value;
	elem.innerHTML = str_value2;
}

function fnGetInnerhtml(str_elem)
{
	if (document.getElementById(str_elem)!= null)
		return document.getElementById(str_elem).innerHTML;
	return "";
}

function fnSetValue(elem, str_value)
{
	if (document.getElementById(elem)!= null)
		document.getElementById(elem).value = str_value;
}

function fnResetInnertext(str_elem)
{
	if (document.getElementById(str_elem)!= null)
	{
		if (browser.isIE)
			document.getElementById(str_elem).innerText = "";
		else
			document.getElementById(str_elem).textContent = "";
	}
}

function fnSetInnertext(str_elem, str_value)
{
	if (!fnDoesStrHaveValue(str_elem))
		return;
	var elem =document.getElementById(str_elem)	;
	if (!fnDoesObjHaveValue(elem))
		return;

	var str_value2 = "";
	if (fnDoesStrHaveValue(str_value))
		str_value2 = str_value;

	if (browser.isIE)
		elem.innerText = str_value2;
	else
		elem.textContent = str_value2;
}

function fnGetInnertext(str_elem)
{
	if (document.getElementById(str_elem)!= null)
	{
		if (browser.isIE)
			return document.getElementById(str_elem).innerText;
		else
			return document.getElementById(str_elem).textContent;
	}
	return "";
}

function fnGetElemValue(str_elem)
{
	if (document.getElementById(str_elem)!= null)
		return document.getElementById(str_elem).value;
	return "";
}

function fnSetElemValue(elem, str_value)
{
	if (document.getElementById(elem)!= null)
		document.getElementById(elem).value = str_value;
}

function fnSetElemColor(elem, str_value)
{
	if (document.getElementById(elem)!= null)
		document.getElementById(elem).style.color = str_value;
}

function fnStripFinalChar(str_in)
{
	var str_out = "";
	var i = 0;
	var new_len = str_in.length - 1;

	for (i = 0; i<new_len; i++)
	{
		str_out += str_in.charAt(i);
	}

	return str_out;
}

function PXValToInt(str_px, ndefault)
{
	if (null == str_px)
		return ndefault;

	var str_temp = "";
	str_temp += str_px;

	if ("" == str_px)
		return ndefault;

	var val_array = str_temp.split("p");
	var n_out = parseInt(val_array[0],10);

	return n_out;
}

function fnNameAndHandleToStr(str_name, str_handle)
{
	var str_out = "";

	if ((str_name) && (str_name!=""))
	{
		str_out += str_name;
		if ((str_handle) && (str_handle!=""))
		{
			str_out += " <";
			str_out += str_handle;
			str_out += ">";
		}
	}
	else if ((str_handle) && (str_handle!=""))
	{
		str_out += str_handle;
	}

	return str_out;
}

function fnNameOrHandleToStr(str_name, str_handle)
{
	var str_out = "";
	if (fnDoesStrHaveValue(str_name))
		str_out += str_name;
	else if (fnDoesStrHaveValue(str_handle))
		str_out += str_handle;
	return str_out;
}

function fnSetScrollTop(str_elem, n_value)
{
	if (document.getElementById(str_elem)!=null)
		document.getElementById(str_elem).scrollTop = n_value;
}

function fnSetFocus(str_elem)
{
	if (!str_elem || (str_elem == ""))
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.focus();
}


function fnIEBugWorkaround1(str_elem)
{
	if (!(browser.isIE))
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	fnSetBGColor(str_elem,"#fffffe");
	fnSetBGColor(str_elem,"#ffffff");
	elem.fireEvent("onmouseleave");
	elem.style.display = "none";
	elem.style.display = "block";
	//setTimeout(
}

function fnBlur(str_elem)
{
	if (!str_elem)
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.blur();
}

// From http://www.mredkj.com/tutorials/tutorial005.html
// http://www.mredkj.com/legal.html "Code marked as public domain is without copyright, and can be used without restriction."
// Modified by me, Dan Burke
function fnInsertOptionBefore(str_select,str_text,str_value)
{
	var elem_sel = document.getElementById(str_select);
	if (!elem_sel)
  		return;
	if (elem_sel.selectedIndex >= 0)
	{
		var elem_new_opt = document.createElement('option');
		elem_new_opt.text = str_text;
		elem_new_opt.value = str_value;
		var elem_old_opt = elem_sel.options[elem_sel.selectedIndex];
		if (browser.isIE)
			elem_sel.add(elem_new_opt, elem_sel.selectedIndex);
		else
		  	elem_sel.add(elem_new_opt, elem_old_opt);
	}
}
function fnRemoveOptionSelected(str_select)
{
	var elem_sel = document.getElementById(str_select);
	if (!elem_sel)
  		return;
	var i;
	if (elem_sel.length<1)
		return;
	for (i = elem_sel.length - 1; i>=0; i--)
	{
		if (elem_sel.options[i].selected)
			elem_sel.remove(i);
	}
}
function fnAppendOptionLast(str_select,str_text,str_value)
{
	var elem_new_opt = document.createElement('option');
	if (!elem_new_opt)
  		return;
	elem_new_opt.text = str_text;
	elem_new_opt.value = str_value;
	var elem_sel = document.getElementById(str_select);
	if (!elem_sel)
  		return;
	if (browser.isIE)
		elem_sel.add(elem_new_opt);
	else
	  	elem_sel.add(elem_new_opt, null);
}
function fnRemoveOptionLast(str_select)
{
	var elem_sel = document.getElementById(str_select);
	if (!elem_sel)
		return;
	if (elem_sel.length > 0)
		elem_sel.remove(elem_sel.length - 1);
}
// End of modified select functions

function fnCompareIgnoreCase(str_left, str_right)
{
	var str_a = "" +str_left;
	var str_b = "" +str_right;
	return ((str_a.toLowerCase())==(str_b.toLowerCase()));
}

function fnSafeParamAssign(the_in, the_default)
{
	if (typeof(the_in)=="undefined")
		return the_default;
	if ((typeof(the_in)=="string") && !the_in)
		return the_default;
	return the_in;
}

// Safely parse numbers, so that if the input string is invalid, we return the default given
function fnSafeParseInt(str_num, n_default)
{
	if (typeof(str_num)=="undefined")
		return n_default;

	if (str_num == "")
		return n_default;

	if (!str_num)
		return n_default;

	var n_out = n_default;

	try
	{
		n_out = parseInt(str_num,10);
	}
	catch (err)
	{
		n_out = n_default;
	}
	return n_out;
}


// returns date_left - date_right
function fnDaysDiff(date_left, date_right)
{
	var date_left2 = new Date();
	date_left2.setFullYear(date_left.getFullYear());
	date_left2.setMonth(date_left.getMonth(),date_left.getDate());
	date_left2.setHours(0);
	date_left2.setMinutes(0);
	date_left2.setSeconds(0);
	date_left2.setMilliseconds(0);
	var date_right2 = new Date();
	date_right2.setFullYear(date_right.getFullYear());
	date_right2.setMonth(date_right.getMonth(),date_right.getDate());
	date_right2.setHours(0);
	date_right2.setMinutes(0);
	date_right2.setSeconds(0);
	date_right2.setMilliseconds(0);
	var diff_days = Math.round((date_left2.getTime() - date_right2.getTime()) / 86400000);
	return diff_days;
}

// returns date_left - date_right
function fnMonthsDiff(date_left, date_right)
{
	var diff_months = (date_left.getFullYear() - date_right.getFullYear())*12 + (date_left.getMonth() - date_right.getMonth());
	return diff_months;
}

function fnSQLTime2TinyStr(sql_time)
{
	var jsdate = fnSQLTime2JSDate(sql_time);
	return fnJSDate2DisplayTime3(jsdate);
}

function fnIsSQLDateValid(str_in)
{
	if (!fnDoesStrHaveValue(str_in))
		return 0;
	var array_temp = str_in.split("-");
	if (array_temp.length!=3)
		return 0;
	return 1;
}

function fnDoesStrHaveValue(str_in)
{
	if (typeof(str_in)=="undefined")
		return false;
	if (!str_in)
		return false;
	if (str_in.length<1)
		return false;
	if (""==str_in)
		return false;
	if (str_in=="null")
		return false;
	if (str_in=="Null")
		return false;
	if (str_in=="NULL")
		return false;
	if (str_in==" ")
		return false;
	if (str_in=="  ")
		return false;
	//var str2 = str_in.replace(/\s/g, "");
	//if (str2=="")
	//	return false;
	return true;
}

function fnJSDate2Range(js_date_start, num_days)
{
	if (!fnDoesObjHaveValue(js_date_start))
		return "";
	var js_date_end = fnCloneDate(js_date_start);
	js_date_end.setDate(js_date_end.getDate()+num_days-1);

	var str_out ="";
	str_out +=fnMonth2Str(js_date_start.getMonth()+1);
	str_out +=" ";
	str_out +=js_date_start.getDate();
	if (js_date_start.getFullYear() != js_date_end.getFullYear())
	{
		str_out +=", ";
		str_out +=js_date_start.getFullYear();
	}
	str_out +=" - ";
	if (js_date_start.getMonth() != js_date_end.getMonth())
	{
		str_out +=fnMonth2Str(js_date_end.getMonth()+1);
		str_out +=" ";
	}
	str_out +=js_date_end.getDate();
	str_out +=", ";
	str_out +=js_date_end.getFullYear();

	return str_out;
}

function fnJSDate2MiniRange(js_date_start, num_days)
{
	if (!fnDoesObjHaveValue(js_date_start))
		return "";
	var js_date_end = fnCloneDate(js_date_start);
	js_date_end.setDate(js_date_end.getDate()+num_days-1);

	var str_out ="";
	str_out += (js_date_start.getMonth()+1);
	str_out += "/";
	str_out += js_date_start.getDate();
	str_out +=" - ";
	str_out +=(js_date_end.getMonth()+1);
	str_out +="/";
	str_out +=js_date_end.getDate();

	return str_out;
}

function fnIsNumNonzero(str_in)
{
	if (typeof(str_in)=="undefined")
		return false;
	if (!str_in)
		return false;
	if (""==str_in)
		return false;
	if (str_in=="0")
		return false;
	return true;
}

function fnIsNumPositive(n_in)
{
	if (typeof(n_in)=="undefined")
		return false;
	if (n_in<0)
		return false;
	return true;
}

function fnDoesArrayHaveValue(array_in)
{
	if (typeof(array_in)=="undefined")
		return false;
	if (!array_in)
		return false;
	if (typeof(array_in.length)=="undefined")
		return false;
	if (array_in.length<=0)
		return false;
	return true;
}

function fnDoesObjHaveValue(obj_in)
{
	if (typeof(obj_in)=="undefined")
		return false;
	if (!obj_in)
		return false;
	return true;
}

function fnDoesParsedArrayHaveValue(array_in)
{
	if (!fnDoesArrayHaveValue(array_in))
		return false;
	if ((array_in.length==1) && (array_in[0]==""))
		return false;
	return true;
}

function fnSetVisible(str_elem)
{
	if (!str_elem)
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.style.visibility = "visible";
}
function fnSetInvisible(str_elem)
{
	if (!str_elem)
		return;
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.style.visibility = "hidden";
}
// Determines if the DOM node id matches teh given string or if one of its ancestors does
function fnHasAncestor(elem, str_id)
{
	while (elem && (typeof (elem) != "undefined"))
	{
		if (elem.id == str_id)
			return 1;
		elem = elem.parentNode;
	}
	return 0;
}

function fnCloneDate(jsdate)
{
	return (jsdate?(new Date(jsdate.getFullYear(),jsdate.getMonth(),jsdate.getDate())):null);
}

function fnName2WikipediaLink(str_name)
{
	if ((null==str_name) || (""==str_name))
		return STR_UNKNOWN;
	var str_name_display = "" +str_name;
	var	regEx = /\./g;
	var str_name_link = str_name.replace(regEx, "");
	regEx = /\W/g;
	str_name_link = str_name_link.replace(regEx, "_");
	regEx = /(<)/g;
	var str_name_display = str_name_display.replace(regEx, "");
	regEx = /(>)/g;
	var str_name_display = str_name_display.replace(regEx, "");
	var str_out = "<a href='http://en.wikipedia.org/wiki/" +str_name_link +"' target='_new' class='link_q'>" +str_name_display +"</a>";
	return str_out;
}

function IsBlankStr(str_in)
{
	return (((typeof str_in)=="undefined") || (str_in==null) || (str_in==""));
}

function fnFormatURL(str_in)
{
	if (IsBlankStr(str_in))
		return "return false;";
	var str_out = "" +str_in;
	if (!(str_in.match("://")))	// match against any protocol (i.e http, https, ftp)
		str_out = "http://" + str_in;	// default
	return str_out;
}

function fnFormatPhone(str_in)
{
	var str_out="";
	if (!fnDoesStrHaveValue(str_in))
		return str_out;
	var	regex_nonnum = /\D/g;

	// Split for extension
	var array_x = str_in.split("x");
	var str_ext = "";
	if (array_x.length>1)
		str_ext = " x" +array_x[1].replace(regex_nonnum, "");
	str_out = array_x[0];

	str_out = str_out.replace(regex_nonnum, "");

	var num_digits = str_out.length;
	if (str_out[0]=="1" && num_digits==11)
		str_out = str_out.slice(1,4) +"." +str_out.slice(4,7) +"." +str_out.slice(7,11);
	else if (num_digits>10)
		return str_in;
	else if (num_digits==10)
		str_out = str_out.slice(0,3) +"." +str_out.slice(3,6) +"." +str_out.slice(6,10);
	else if (num_digits==7)
		str_out = str_out.slice(0,3) +"." +str_out.slice(3,7);
	else if (num_digits==7)
		return str_in;

	str_out += str_ext;
	return str_out;
}

function fnPutDivAtMouse(dialog_div)
{
	var x=g_mouse_x;
	var cw = xClientWidth();
	if (cw>1000)
		x=x-(cw-1000)/2;
	var y=g_mouse_y;
	if (x<0) x=0;
	if (y<0) y=0;
	xLeft(dialog_div,x);
	xTop(dialog_div,y);
}
/*
function fnPutDivAtMouse2(dialog_div, x_offset, y_offset)
{
	var x=g_mouse_x+x_offset;
	var y=g_mouse_y+y_offset;
	if (x<0) x=0;
	if (y<0) y=0;
	xLeft(dialog_div,x);
	xTop(dialog_div,y);
}
*/
function fnPutDivAtMouse2(dialog_div)
{
	var x=g_mouse_x;
	var y=g_mouse_y;
	var w=0;
	var elem = document.getElementById(dialog_div);
	if (elem)
		w= xWidth(dialog_div);
	x-=10;
	if (x+w>1000)
		x=1000-w;
	if (x<0) x=0;
	if (y<0) y=0;
	xLeft(dialog_div,x);
	xTop(dialog_div,y);
}

function fnPutDivAtMouse3(dialog_div)
{
	var x=g_mouse_x;
	var y=g_mouse_y;
	var w=0;
	var elem = document.getElementById(dialog_div);
	if (elem)
		w= xWidth(dialog_div);
	x-=10;
	if (x+w>1000)
		x=1000-w;
	if (x<0) x=0;
	if (y<0) y=0;

	xLeft(dialog_div,x);
	xTop(dialog_div,y);
}

function fnORSingleBitLongs(val1, val2)
{
	if (val1==val2)
		return val1;
	return val1+val2;
}

function fnCommaDelimStr(str_in)
{
	var str_out="";
	var len=str_in.length;
	var i=len;
	var j=i-3;
	if (j<0) j=0;
	var first=1;
	var done=0;
	var i_safety=100;

	while(!done && i_safety)
	{
		if (!first)
			str_out = "," +str_out;
		else
			first=0;
		str_out = str_in.slice(j,i) +str_out;
		if (j<=0)
			done=1;
		else
		{
			j-=3;
			if (j<0) j=0;
			i-=3;
		}
		i_safety--;
	}
	return str_out;
}
function fnFileSize2Str(str_num_bytes, html_mode)
{
	var str_out = "";
	var str_unit = "";
	var str_sep ="";
	var num_bytes = fnSafeParseInt(str_num_bytes,0);
	if (html_mode)
		str_sep = "&nbsp;";
	else
		str_sep = " ";
	if (num_bytes>=2048)
	{
		num_bytes = Math.round(num_bytes/1024);
		str_unit = str_sep +"KB";
	}
	else
	{
		num_bytes = Math.round(num_bytes);
		str_unit = str_sep +"Bytes";
	}
	str_out = fnCommaDelimStr(""+num_bytes);
	str_out += str_unit;
	return str_out;
}

function fnFileSize2Str2(str_num_bytes, html_mode)
{
	var str_out = "";
	var str_sep ="";
	var num_bytes = fnSafeParseInt(str_num_bytes,0);
	if (html_mode)
		str_sep = "&nbsp;";
	else
		str_sep = " ";
	str_out = fnCommaDelimStr(""+num_bytes) +str_sep +"Bytes";
	return str_out;
}

function fnCents2Display(num_cents)
{
	if (!num_cents)
		return "$0.00";
	var str_a = "" +num_cents;
	if (!str_a || !(str_a.length))
		return "$0.00";
	var str_out ="";
	var len = str_a.length;
	if (len==1)
		str_out = "$0.0" +str_a;
	else if (len==2)
		str_out = "$0." +str_a;
	else
	{
		var str_c = "0";
		if (len>2)
			str_c = str_a.slice(0, len-2);
		str_out = "$" +str_c + "." +str_a.slice(len-2, len);
	}
	return str_out;
}

function fnCents2Display2(num_cents)
{
	if (!num_cents)
		return "0.00";
	var str_a = "" +num_cents;
	if (!str_a || !(str_a.length))
		return "0.00";
	var str_out ="";
	var len = str_a.length;
	if (len==1)
		str_out = "0.0" +str_a;
	else if (len==2)
		str_out = "0." +str_a;
	else
	{
		var str_c = "0";
		if (len>2)
			str_c = str_a.slice(0, len-2);
		str_out = str_c + "." +str_a.slice(len-2, len);
	}
	return str_out;
}

function fnDisplay2Cents(str_dollars)
{
	if (!fnDoesStrHaveValue(str_dollars))
		return 0;
	var array_seg = str_dollars.split(".");
	array_seg[0]=array_seg[0].replace(/\D/g,"");
	if (array_seg.length>1)
		array_seg[1]=array_seg[1].replace(/\D/g,"");
	var num_dollars = fnSafeParseInt(array_seg[0],0);
	var num_cents_only = 0;
	if (array_seg.length>1)
	{
		var str_temp ="";
		if (array_seg[1].length>0)
		{
			str_temp +=array_seg[1].charAt(0);
			if (array_seg[1].length>1)
				str_temp +=array_seg[1].charAt(1);
			else
				str_temp +="0";
		}
		num_cents_only = fnSafeParseInt(str_temp,0);
	}
	var n_cents =num_dollars*100 + num_cents_only;
	return n_cents;
}

function fnSetInnerhtml(str_elem, str_value)
{
	if (!fnDoesStrHaveValue(str_elem))
		return;
	var elem =document.getElementById(str_elem)	;
	if (!fnDoesObjHaveValue(elem))
		return;
	var str_value2 = "";
	if (fnDoesStrHaveValue(str_value))
		str_value2 = str_value;
	elem.innerHTML = str_value2;
}

function fnFFoxWrapFix(str_in, text_mode, param_chunk_size)
{
	if (!fnDoesObjHaveValue(param_chunk_size))
		return "";
	var chunk_size =param_chunk_size;
	if (chunk_size<1)
		chunk_size=20;
	if (text_mode==1)
		str_in = fnSafeText4HTML(str_in);
	else if (text_mode)
		str_in = fnSafeText4HTML2(str_in);

	if (browser.isGecko || browser.isNSCompatible)
	{
		if (!text_mode)
			str_in = fnHTMLToPlaintext2(str_in);
		try
		{
			var len = 0;
			var len_left = 0;
			var str_out="";
			var str_segment ="";
			var i = 0;
			var done=0;
			var array_str_in = null;
			var j=0;
			var first_segment=1;
			var first_iter=1;

			//if (text_mode)
			//{
			array_str_in =str_in.split(" ");

			for (j=0; j<array_str_in.length; j++)
			{
				done=0;
				str_segment =array_str_in[j];
				len =str_segment.length;
				len_left =len;
				i =0;
				first_iter=1;
				while (!done)
				{
					if (len_left<chunk_size)
					{
						if (len_left>0)
						{
							if (!first_segment && first_iter)
								str_out +=" ";
							str_out += str_segment.slice(i,i+len_left);
							first_segment=0;
						}
						done=1;
					}
					else
					{
						if (!first_segment && first_iter)
							str_out +=" ";
						str_out += str_segment.slice(i,i+chunk_size) +"&#8203;";
						first_segment=0;
						i+=chunk_size;
						len_left-=chunk_size;
					}
					if (i>1000000) done=1;
					first_iter=0;
				}
			}

			/*
			else
			{
				// Only parse sections not in <>
				var array_sections = str_in.split("<");
				var array_subsections = new Array(array_sections.length);
				var k=0;
				var subsection = null;
				var m=0;
				var sections_len =array_sections.length;
				if (sections_len==0)
				{
					return str_in;
				}

				for (k=0; k<array_sections.length; k++)
				{
					if (k==0)
					{
						array_str_in =array_sections[0].split(" ");
					}
					else
					{
						str_out += "<";
						array_subsections[k] =array_sections[k].split(">");
						subsection = array_subsections[k];
						for (m=0; m<subsection.length; m++)
						{
							if (m!=0)
							{
								str_out += ">";
							}
							str_out += subsection[m];
						}
						array_str_in =(subsection[subsection.length-1]).split(" ");
					}

					for (j=0; j<array_str_in.length; j++)
					{
						done=0;
						str_segment =array_str_in[j];
						len =str_segment.length;
						len_left =len;
						i =0;
						first_iter=1;
						while (!done)
						{
							if (len_left<chunk_size)
							{
								if (len_left>0)
								{
									if (!first_segment && first_iter)
										str_out +=" ";
									str_out += str_segment.slice(i,i+len_left);
									first_segment=0;
								}
								done=1;
							}
							else
							{
								if (!first_segment && first_iter)
									str_out +=" ";
								str_out += str_segment.slice(i,i+chunk_size) +"&#8203;";
								first_segment=0;
								i+=chunk_size;
								len_left-=chunk_size;
							}
							if (i>1000000) done=1;
							first_iter=0;
						}
					}
				}
			}
			*/
		}
		catch(e)
		{
			return "";
		}
		if (!text_mode)
			str_out = fnText2HTML(str_out);

		return str_out;
	}
	else return str_in;
}

function fnEnforceMaxLen(obj, maxlen)
{
	return (obj.value.length <=maxlen);
}

function fnTruncateStr(str_in, max_char)
{
	if (!str_in)
		return str_in;
	if (str_in.length<=max_char)
		return str_in;
	var str_out = str_in.slice(0,max_char);
	str_out += "...";
	return str_out;
}

function fnTruncHTMLStr(str_in, max_char)
{
	if (!fnDoesStrHaveValue(str_in))
		return str_in;
	if (str_in.length<=max_char)
		return str_in;
	var str_out = str_in.slice(0,max_char);
	var array_test_lt = str_out.split("<");
	var test_lt = array_test_lt.length;
	if (test_lt==1 && array_test_lt[0]=="")
		test_lt=0;
	var array_test_gt = str_out.split(">");
	var test_gt = array_test_gt.length;
	if (test_gt==1 && array_test_gt[0]=="")
		test_gt=0;
	if (test_lt>test_gt)
	{
		var n_at =str_out.lastIndexOf("<");
		str_out =str_out.slice(0,n_at);
	}
	str_out += "...";
	return str_out;
}

function fnSetCapture(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.setCapture();
}

function fnReleaseCapture(str_elem)
{
	var elem = document.getElementById(str_elem);
	if (!elem)
		return;
	elem.releaseCapture();
}

//[
function QStr()
{
	this.buf = new Array();
	this.buf_len = 0;
}

function QStr_Reset()
{
	with (this)
	{
		buf =null;
		buf_len =0;
		buf =new Array();
	}
}
QStr.prototype.Reset = QStr_Reset;

function QStr_Length()
{
	with (this)
		return buf_len;
}
QStr.prototype.Length = QStr_Length;

function QStr_toString()
{
	with (this)
		return buf.join("");
}
QStr.prototype.toString = QStr_toString;

// Concatenate
function QStr_C(str_in)
{
	if (typeof(str_in)=="undefined")
		return;
	if (typeof(str_in)!="string")
		str_in=""+str_in;

	with (this)
	{
		buf_len +=str_in.length;
		buf.push(str_in);
	}
}
QStr.prototype.C = QStr_C;

// Destruct for mem cleanup
function QStr_Destruct()
{
	with (this)
		buf =null;
}
QStr.prototype.Destruct = QStr_Destruct;
//]
/*
function fnFormatVCalName(str_in)
{
	var last_name="";
	var first_name="";
	var addl_names="";
	var prefix="";
	var suffix="";
	var array_seg = str_in.split(" ");
	if (array_seg.length<2)
		return str_in;
	if (array_seg.length==2

	return (last_name+";"+first_name+";"+addl_names+";"+prefix+";"
}
*/
//////////////////// end of Utility Functions ////////////////////////

