var xmlhttp;
var retfunc;
var doDebug;
var use_qaq								= false;
var TIMEOUT_MS_SERVER_RSP	= 30000;

//Columns of data elements passed back from php
var col_type 						=	0;
var col_program					=	1;
var col_level						=	2;
var col_stream					=	3;
var col_module					=	4;
var col_place						=	5;
var col_country					=	6;
var col_format					=	7;
var col_sdate						=	8;
var col_edate						=	9;
var col_status					=	10;
var col_code   					=	11;
var col_id							=	12;

if (window.XMLHttpRequest) {
	// code for IE7+, Firefox, Chrome, Opera, Safari
	xmlhttp=new XMLHttpRequest();
	//alert( 'loaded IE7 xmlhttp' );
}
else{
	// code for IE6, IE5
	xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	//alert( 'loaded IE xmlhttp' );
}

//--------------------------------------------------------------------------------------------------
//Loads URI into a javascript GET var
(function(){ // Import GET Vars
   document.$_GET = [];
   var urlHalves = String(document.location).split('?');
   if(urlHalves[1]){
      var urlVars = urlHalves[1].split('&');
      for(var i=0; i<=(urlVars.length); i++){
         if(urlVars[i]){
            var urlVarPair = urlVars[i].split('=');
            document.$_GET[urlVarPair[0]] = urlVarPair[1];
         }
      }
   }
})();


//--------------------------------------------------------------------------------------------------
//Ensures debugging statements dont error if firebug not installed or other browser
try { console.debug('init console... done'); } catch(e) { console = { debug: function() {} } }

//--------------------------------------------------------------------------------------------------
function mconsole( txt ){
	if( doDebug == true ) {
		console.debug(txt);
	}
}

//--------------------------------------------------------------------------------------------------
(function(){ // Import GET Vars
   document.$_GET = [];
   var urlHalves = String(document.location).split('?');
   if(urlHalves[1]){
      var urlVars = urlHalves[1].split('&');
      for(var i=0; i<=(urlVars.length); i++){
         if(urlVars[i]){
            var urlVarPair = urlVars[i].split('=');
            document.$_GET[urlVarPair[0]] = urlVarPair[1];
         }
      }
   }
})();

//--------------------------------------------------------------------------------------------------
function getEvent(event) 		{ return (event ? event : window.event); }
function getEventElement(e) { return (e.srcElement ? e.srcElement : (e.target ? e.target : e.currentTarget)); }

function myint(a) {
	return parseInt(a,10);
}

//--------------------------------------------------------------------------------------------------
function attachOnloadFunction( loadFunc ) {
	//Attach loadFunc() to onLoad
	if ( typeof window.addEventListener != "undefined" )
		window.addEventListener( "load", loadFunc, false );
	else if ( typeof window.attachEvent != "undefined" ) {
		window.attachEvent( "onload", loadFunc );
	}
	else {
		if ( window.onload != null ) {
			var oldOnload = window.onload;
			window.onload = function ( e ) {
				oldOnload( e );
				loadFunc();
			}
		}
		else  {
			window.onload = loadFunc();
		}
	}
}

//--------------------------------------------------------------------------------------------------
function gtrack( category, action, option_label, opt_value ) {
	return;
	if( use_qaq ) {
		_gaq.push(['_trackEvent', category, action, option_label, opt_value ]);
	}
	else {
		pageTracker._trackEvent( category	, action, option_label, opt_value );
	}
}
//--------------------------------------------------------------------------------------------------
function json_setTypes(key, value) {
	var type;
	if (value && typeof value === 'object') {
		type = value.type;
	  if (typeof type === 'string' && typeof window[type] === 'function') {
	  	return new (window[type])(value);
		}
	}
	return value;
}

//------------------------------------------------------------------------------------------------------------------
function getCRMEvents( returnFunc, waiting_msg )
{
	if (window.XMLHttpRequest) {		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp=new XMLHttpRequest();
	}	else {												// code for IE6, IE5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}

	if (xmlhttp==null) {
	  alert ("Your browser does not support XMLHTTP!");
	  return;
	}

	//document.getElementById("status_msg").innerHTML= waiting_msg + " <img src='/custom/ajax_lib/ajax-loader.gif'/>";
	var url="/custom/ajax_lib/geteventsdata.php?";
	url=url+"sid="+Math.random();

	//var args = Array( "test call" );
	//returnFunc.apply(this, args);
	retfunc = returnFunc;
	xmlhttp.onreadystatechange=stateChanged;
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}


//------------------------------------------------------------------------------------------------------------------
function createQuery(form, allow_blanks )
{
	var elements = form.elements;
  var pairs = new Array();

  for (var i = 0; i < elements.length; i++) {

		if ( elements[i].name.indexOf('[]') != -1 ) { //multiselect

			var ob = elements[i];
			//alert( 'multi=' + ob.name + ' #opt=' + ob.options.length  );
			for (var j = 0; j < ob.options.length; j++) {
				//alert( 'multi=' + ob.name + ' op['+j+']=' + ob.options[j].selected  );
      	if (ob.options[j].selected || allow_blanks ) {

      		//pairs.push(ob.name  + "=" + encodeURIComponent(ob.options[j].value));
      		pairs.push(ob.name  + "=" + totalEncode(ob.options[j].value));

      		//alert( 'added' );
      	}
			}
		}
		else {

	  	if ( elements[i].type == 'radio' ) { //radio
	  		//alert( 'radio: '+ elements[i].name + '  checked=' + elements[i].checked  );
  			if ( elements[i].checked == false )
  				continue;		//dont process unchecked radio
  		}

			name  = elements[i].name;
			value = elements[i].value;
    	if ( (name && value) || allow_blanks )
    		if ( value ) {
      		pairs.push(name + "=" + encodeURIComponent(value));
      	}
      	else {
      		pairs.push(name + "=" );
      	}
    }
	}

	return pairs.join("&");
}

//------------------------------------------------------------------------------------------------------------------
function postAJAX(url, query, handler)
{
    var status = false;
    var contentType = "application/x-www-form-urlencoded; charset=UTF-8";

    // Native XMLHttpRequest object
    if (window.XMLHttpRequest) {
	    xmlhttp = new XMLHttpRequest();
	    xmlhttp.onreadystatechange = handler;
	    xmlhttp.open("post", url, true);
	    xmlhttp.setRequestHeader("Content-Type", contentType);
	    xmlhttp.send(query);
	    status = true;

    // ActiveX XMLHttpRequest object
    } else if (window.ActiveXObject) {
	    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	    if (xmlhttp) {
	      xmlhttp.onreadystatechange = handler;
	      xmlhttp.open("post", url, true);
	      xmlhttp.setRequestHeader("Content-Type", contentType);
	      xmlhttp.send(query);
	      status = true;
	    }
    }

    return status;
}

//------------------------------------------------------------------------------------------------------------------
function ajaxRequest_get( req_url, returnFunc )
{
	if (window.XMLHttpRequest) {		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp=new XMLHttpRequest();
	}	else {												// code for IE6, IE5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}

	if (xmlhttp==null) {
	  alert ("Your browser does not support XMLHTTP!");
	  return;
	}
	var url="http://maps.google.com/maps/api/geocode/json?sensor=false&address=1600+Amphitheatre+Parkway,+Mountain+View,+CA";
	retfunc = returnFunc;
	xmlhttp.onreadystatechange=stateChanged2;
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}

//------------------------------------------------------------------------------------------------------------------
function fuckreq2( returnFunc )
{
	if (window.XMLHttpRequest) {		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp=new XMLHttpRequest();
	}	else {												// code for IE6, IE5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}

	if (xmlhttp==null) {
	  alert ("Your browser does not support XMLHTTP!");
	  return;
	}

	var url="http://maps.google.com/maps/api/geocode/json?sensor=false&address=1600+Amphitheatre+Parkway,+Mountain+View,+CA";
	//url=url+"sid="+Math.random();

	//var args = Array( "test call" );
	//returnFunc.apply(this, args);
	retfunc = returnFunc;
	xmlhttp.onreadystatechange=stateChanged;
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
}


//------------------------------------------------------------------------------------------------------------------
//function getCRMClasses2( returnFunc )
//{
//	if (window.XMLHttpRequest) {		// code for IE7+, Firefox, Chrome, Opera, Safari
//		xmlhttp=new XMLHttpRequest();
//	}	else {												// code for IE6, IE5
//		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
//	}
//
//	if (xmlhttp==null) {
//	  alert ("Your browser does not support XMLHTTP!");
//	  return;
//	}
//
//	var url="/custom/ajax_lib/getclassesdata.php?fetch_type=teacher&";
//	url=url+"sid="+Math.random();
//
//	//var args = Array( "test call" );
//	//returnFunc.apply(this, args);
//	retfunc = returnFunc;
//	xmlhttp.onreadystatechange=stateChanged;
//	xmlhttp.open("GET",url,true);
//	xmlhttp.send(null);
//}


//------------------------------------------------------------------------------------------------------------------
function notifyAdminError( err_text ) {
	var frm		= document.createElement('form');
	var act 	= document.createElement('input');
	var msg	  = document.createElement('input');
	var usr	  = document.createElement('input');

	var nname = document.getElementById('notif_name');
	var uname = (nname != undefined && nname != '')? nname.value : 'unknown';

	//Set values
	act.name 	= 'action';		act.value = 'jserror';
	msg.name 	= 'err_msg';	msg.value = err_text;
	usr.name  = 'user';			usr.value = uname;

	frm.appendChild( act );
	frm.appendChild( msg );
	frm.appendChild( usr );

	sendEmailNotif( frm  );	//Send ajax request
}

//------------------------------------------------------------------------------------------------------------------
function sendEmailNotif( cform, returnFunc )
{
	var purl		=	"/custom/ajax_lib/emailnotif.php";
	var params	= createQuery(cform);
	retfunc 		= returnFunc;
	postAJAX(purl, params, stateChanged );
}

//------------------------------------------------------------------------------------------------------------------
function setCRMClasses( cform, returnFunc )
{
	var purl		=	"/custom/ajax_lib/setclassesdata.php";
	var params	= createQuery(cform);
	//alert( '[setCRMClasses] submitting: ' + params );
	retfunc 		= returnFunc;
	//postAJAX(purl, totalEncode(params), stateChanged );		//TODO, more generically implement encoding
	postAJAX(purl, params, stateChanged );		//TODO, more generically implement encoding
}

//------------------------------------------------------------------------------------------------------------------
function getCRMCourses( cform, returnFunc )
{
	var purl		=	"http://www.chiball.com/?option=com_cbcrm&template=raw";
	var params	= createQuery(cform);
	//alert( '[setCRMClasses] submitting: ' + params );
	retfunc 		= returnFunc;
	//postAJAX(purl, totalEncode(params), stateChanged );		//TODO, more generically implement encoding
	postAJAX(purl, params, stateChanged );		//TODO, more generically implement encoding
}

//------------------------------------------------------------------------------------------------------------------
function lookupClasses2( cform, returnFunc )
{
	var purl		=	"/custom/ajax_lib/getclassesdata.php";
	var params	= createQuery(cform, true);	//allow blanks
	//alert( '[lookupClasses] submitting: ' + params );
	retfunc 		= returnFunc;
	postAJAX(purl, params, stateChanged );
}

//------------------------------------------------------------------------------------------------------------------
function stateChanged2() {
	alert ( 'stateChanged2 - readyState=['+xmlhttp.readyState+"]");
	if (xmlhttp.readyState==4) {
		alert ( 'stateChanged2 - responseText='+ xmlhttp.responseText + "\n responseXml=" + xmlhttp.responseXml );

		if ( xmlhttp.responseText != '' ) {
			retfunc();
		}
	}
}
//------------------------------------------------------------------------------------------------------------------
function stateChanged()
{
	if (xmlhttp.readyState==4) {
		//alert ( 'statechanged='+xmlhttp.readyState+'\nresponseText='+ xmlhttp.responseText);
		mconsole( 'stateChanged');
		if ( xmlhttp.responseText != '' ) {
			//document.getElementById("status_msg").innerHTML="";
			//alert( "xmlhttp=" +  xmlhttp.responseText );
			//var args = Array( String(xmlhttp.responseText) );
			mconsole( 'stateChanged - calling retfunc' );
  		retfunc();
  	}
  	else {
  		//document.getElementById("status_msg").innerHTML="Server error - please try again later";
  		//TODO: create email notif to admin
  		//alert( 'response=[' + xmlhttp.responseText +']' );
  	}
  }
}

//------------------------------------------------------------------------------------------------------------
function deleteChildren( el ) {
	if ( el.hasChildNodes() )	{
    while ( el.childNodes.length >= 1 ) {
    		//alert( 'removing: ' + el.firstChild.id );
        el.removeChild( el.firstChild );
    }
	}
}

//------------------------------------------------------------------------------------------------------------
function addLoadingEvents( el, txt, use_img, replace_el, colspan ) {
	var tr = document.createElement("tr");
	tr.setAttribute("id" , "tr_status");

	var td = document.createElement("td");
	td.setAttribute("id" 			, "td_status" 		);
	if ( colspan != undefined && colspan != null ) {
		//Use parameter
		td.setAttribute("colSpan"	, colspan				);
	}
	td.setAttribute("valign"	, "middle" 				);
	td.setAttribute("style"		, "height: 32px;  vertical-align:middle;"	);

	var td_span = document.createElement("span");
	td_span.setAttribute("id" 	, "status_msg" );

	var td_tspan = document.createElement("span");
	td_tspan.setAttribute("style", "height: 16px; vertical-align:middle;" );		//to match height of gif
	//td_tspan.appendChild(document.createTextNode( txt + "  " ));
	td_tspan.innerHTML = txt + "  ";
	td_span.appendChild(td_tspan);

	if ( use_img ) {
		var td_img = document.createElement("img");
		td_img.setAttribute("src" 	, "/custom/ajax_lib/ajax-loader_trans.gif" );
		td_img.setAttribute("style" , "vertical-align:middle;" );
		td_span.appendChild(td_img);
	}

	if ( replace_el ) {
		el.replaceChild( td_span, el.firstChild );
	}
	else {
		td.appendChild(td_span);
		tr.appendChild(td);
		el.appendChild(tr);
	}
}

//------------------------------------------------------------------------------------------------------------
function createDropdown( dropdownName, dropdownOptions, selectedOption, useOptionValue ) {

	td_class = (selectedOption == '')? 'drop' : 'drop_sel';

	var drop_td = document.createElement("td");
	drop_td.setAttribute( "id" , "th_"+dropdownName );
	drop_td.className = td_class;

	var drop_sel = document.createElement("select");
	drop_sel.setAttribute( "id"				, dropdownName+"_list" );
	drop_sel.setAttribute( "name"			, dropdownName+"_list" );
	//drop_sel.setAttribute( "onchange"	, "filterResults(\'"+dropdownName+"\');" );
	drop_sel.onchange = handleFilterResults;

	//Blank
	drop_opt = document.createElement("option");
	drop_opt.setAttribute("value", "" );
	drop_opt.appendChild(document.createTextNode( "- All -" ));
	drop_sel.appendChild(drop_opt);

	//Items
	for( val in dropdownOptions ) {
		mconsole('createDropdown - val=' + val);
		opttxt = (useOptionValue)? dropdownOptions[val] : val;
		drop_opt = document.createElement("option");
		drop_opt.setAttribute("value", val );												//Val is always the array key
		drop_opt.appendChild(document.createTextNode( opttxt ));		//opttxt is the text displayed
		if ( val == selectedOption )	{
			drop_opt.setAttribute("selected", "selected");
		}

		drop_sel.appendChild(drop_opt);
	}

	drop_td.appendChild(drop_sel);
	return drop_td;
}


//--------------------------------------------------------------------------------------------------
//TODO - make these functions into a common lib for myclasses and classfinder
function status_setInlineMsg( el_id, txt ) {
	var sp_msg = document.createTextNode( txt  );
	var cur_msg = document.getElementById("status_msg");
	td_msg = document.getElementById("td_status");
	if( td_msg != null ) {
		td_msg.replaceChild( sp_msg, cur_msg );
	}
}

//--------------------------------------------------------------------------------------------------
function status_setServerTimeout() {
	timerid_server_rsp = setTimeout( "status_handleServerTimeout()", TIMEOUT_MS_SERVER_RSP );
}

function status_clearServerTimeout() {
	clearTimeout(timerid_server_rsp);
}

function status_handleServerTimeout() {
	fetching = false;
	status_setInlineMsg( "td_status", "The server took too long to respond, please refresh the page to try again. If this problem persists, please contact support@chiball.com" );
	//status_showSave( "The server took too long to respond, please try again. If this problem persists, please contact support@chiball.com" );
	//setTimeout( "status_hideMsg()", TIMEOUT_MS_STATUS );
}



//------------------------------------------------------------------------------------------------------------
function getCoord(obj, offsetLeft, offsetTop){
	var orig = obj;
	var left = 0;
	var top = 0;
	if(offsetLeft) left = offsetLeft;
	if(offsetTop) top = offsetTop;
	if(obj != undefined && obj != null && obj.offsetParent){
		left += obj.offsetLeft;
		top += obj.offsetTop;
		while (obj = obj.offsetParent) {
			//left += (obj.offsetLeft-obj.scrollLeft+obj.clientLeft);
			//top += (obj.offsetTop-obj.scrollTop+obj.clientTop);
			left += (obj.offsetLeft+obj.clientLeft);
			top += (obj.offsetTop+obj.clientTop);
		}
	}
	return {left:left, top:top, width: orig.offsetWidth, height: orig.offsetHeight};
}

//------------------------------------------------------------------------------------------------------------
function strcmp ( str1, str2 ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Waldo Malqui Silva
    // +      input by: Steve Hilder
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    revised by: gorthaur
    // *     example 1: strcmp( 'waldo', 'owald' );
    // *     returns 1: 1
    // *     example 2: strcmp( 'owald', 'waldo' );
    // *     returns 2: -1

    return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
}

//------------------------------------------------------------------------------------------------------------
function trim( str ) {
	if( str != undefined && str != null && str != '' ) {
		str = str.replace(/^\s+/, '');
		for (var i = str.length - 1; i >= 0; i--) {
			if (/\S/.test(str.charAt(i))) {
				str = str.substring(0, i + 1);
				break;
			}
		}
	}
	return str;
}

//------------------------------------------------------------------------------------------------------------
function totalEncode(str){
	var s=escape(trim(str));
	s=s.replace(/\+/g,"+");
	s=s.replace(/@/g,"@");
	s=s.replace(/\//g,"/");
	s=s.replace(/\*/g,"*");
	return(s);
}
//------------------------------------------------------------------------------------------------------------
function addslashes(str) {
str=str.replace(/\\/g,'\\\\');
str=str.replace(/\'/g,'\\\'');
str=str.replace(/\"/g,'\\"');
str=str.replace(/\0/g,'\\0');
return str;
}
//------------------------------------------------------------------------------------------------------------
function stripslashes(str) {
str=str.replace(/\\'/g,'\'');
str=str.replace(/\\"/g,'"');
str=str.replace(/\\0/g,'\0');
str=str.replace(/\\\\/g,'\\');
return str;
}

//--------------------------------------------------------------------------------------------------
function html_entity_decode(str) {
  var ta=document.createElement("textarea");
  ta.innerHTML=str.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&amp;/g,"&");;
  return ta.value;
}



//--------------------------------------------------------------------------------------------------
function cleanData( rdata ) {

	for( var ci=0; ci < rdata.length; ci++ ) {
		var cl = rdata[ci];
		//for( var fi=0; fi < cl.length; fi++ ) {
		for( var fi in cl ) {
			var pre = cl[fi];
			if (typeof( pre ) === String ) {
				//cl[fi] = stripslashes( html_entity_decode( cl[fi] ) );
				cl[fi] = html_entity_decode( stripslashes(pre) );
				//cl[fi] = stripslashes( pre );
			}
			alert( 'decoding:  pre=['+pre+']  post=['+cl[fi]+']' );
		}
	}
}

// Class: Dump
// Author: Shuns (www.netgrow.com.au/files)
// Last Updated: 10/10/06
// Version: 1.1

dump = function(object, showTypes) {
  var dump = '';
  var st = typeof showTypes == 'undefined' ? true : showTypes;
  var winName = 'dumpWin';
  var browser = _dumpIdentifyBrowser();
  var w = 760;
  var h = 500;
  var leftPos = screen.width ? (screen.width - w) / 2 : 0;
  var topPos = screen.height ? (screen.height - h) / 2 : 0;
  var settings = 'height=' + h + ',width=' + w + ',top=' + topPos + ',left=' + leftPos + ',scrollbars=yes,menubar=yes,status=yes,resizable=yes';
  var title = 'Dump';
  var script = 'function tRow(s) {t = s.parentNode.lastChild;tTarget(t, tSource(s)) ;}function tTable(s) {var switchToState = tSource(s) ;var table = s.parentNode.parentNode;for (var i = 1; i < table.childNodes.length; i++) {t = table.childNodes[i] ;if (t.style) {tTarget(t, switchToState);}}}function tSource(s) {if (s.style.fontStyle == "italic" || s.style.fontStyle == null) {s.style.fontStyle = "normal";s.title = "click to collapse";return "open";} else {s.style.fontStyle = "italic";s.title = "click to expand";return "closed" ;}}function tTarget (t, switchToState) {if (switchToState == "open") {t.style.display = "";} else {t.style.display = "none";}}';
dump += (/String|number|undefined|boolean/.test(typeof(object)) || object == null) ? object : recurse(object, typeof object);
  winName = window.open('', winName, settings);
  if (browser.indexOf('ie') != -1 || browser == 'opera' || browser == 'ie5mac' || browser == 'safari') {
	winName.document.write('<html><head><title> ' + title + ' </title><script type="text/javascript">' + script + '</script><head>');
	winName.document.write('<body>' + dump + '</body></html>');
  } else {
	winName.document.body.innerHTML = dump;
	winName.document.title = title;
	var ffs = winName.document.createElement('script');
	ffs.setAttribute('type', 'text/javascript');
	ffs.appendChild(document.createTextNode(script));
	winName.document.getElementsByTagName('head')[0].appendChild(ffs);
  }
  winName.focus();
  function recurse(o, type) {
    var i;
	var j = 0;
	var r = '';
	type = _dumpType(o);
	switch (type) {
	  case 'regexp':
	    var t = type;
	    r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
	    r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>RegExp: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';
	    j++;
	    break;
	  case 'date':
	    var t = type;
	    r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
	    r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>Date: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';
	    j++;
	    break;
	  case 'nofunction':	//EC
	  	j = -1;
	  	break;

	  case 'function':
	    var t = type;
	    var a = o.toString().match(/^.*function.*?\((.*?)\)/im);
	    var args = (a == null || typeof a[1] == 'undefined' || a[1] == '') ? 'none' : a[1];
	    r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
	    r += '<tr><td colspan="2"' + _dumpStyles(t,'td-value') + '><table' + _dumpStyles('arguments','table') + '><tr><td' + _dumpStyles('arguments','td-key') + '><i>Arguments: </i></td><td' + _dumpStyles(type,'td-value') + '>' + args + '</td></tr><tr><td' + _dumpStyles('arguments','td-key') + '><i>Function: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o + '</td></tr></table>';
	    j++;
	    break;
	  case 'domelement':
	    var t = type;
	    r += '<table' + _dumpStyles(t,'table') + '><tr><th colspan="2"' + _dumpStyles(t,'th') + '>' + t + '</th></tr>';
	    r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Name: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeName.toLowerCase() + '</td></tr>';
		r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Type: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeType + '</td></tr>';
		r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>Node Value: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.nodeValue + '</td></tr>';
		r += '<tr><td' + _dumpStyles(t,'td-key') + '><i>innerHTML: </i></td><td' + _dumpStyles(type,'td-value') + '>' + o.innerHTML + '</td></tr>';
	    j++;
	    break;
	}
	if (/object|array/.test(type)) {
      for (i in o) {
	    var t = _dumpType(o[i]);
	    if (j < 1) {
	      r += '<table' + _dumpStyles(type,'table') + '><tr><th colspan="2"' + _dumpStyles(type,'th') + '>' + type + '</th></tr>';
		  j++;
	    }
	    if (typeof o[i] == 'object' && o[i] != null) {
		  r += '<tr><td' + _dumpStyles(type,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + recurse(o[i], t) + '</td></tr>';
	    } else if (typeof o[i] == 'function') {
		  r += '<tr><td' + _dumpStyles(type ,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + recurse(o[i], t) + '</td></tr>';
		} else {
		  r += '<tr><td' + _dumpStyles(type,'td-key') + '>' + i + (st ? ' [' + t + ']' : '') + '</td><td' + _dumpStyles(type,'td-value') + '>' + o[i] + '</td></tr>';
	    }
	  }
	}
	if (j == 0) {
	  r += '<table' + _dumpStyles(type,'table') + '><tr><th colspan="2"' + _dumpStyles(type,'th') + '>' + type + ' [empty]</th></tr>';
	}
	if (j >= 0)
		r += '</table>';
	return r;
  };
};
_dumpStyles = function(type, use) {
  var r = '';
  var table = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;cell-spacing:2px;';
  var th = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;text-align:left;color: white;padding: 5px;vertical-align :top;cursor:hand;cursor:pointer;';
  var td = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;vertical-align:top;padding:3px;';
  var thScript = 'onClick="tTable(this);" title="click to collapse"';
  var tdScript = 'onClick="tRow(this);" title="click to collapse"';
  switch (type) {
	case 'string':
	case 'number':
	case 'boolean':
	case 'undefined':
	case 'object':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#0000cc;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#4444cc;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + td + 'background-color:#ccddff;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
	case 'array':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#006600;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#009900;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + td + 'background-color:#ccffcc;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
	case 'function':
		return; //EC - dont display functions
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#aa4400;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#cc6600;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + td + 'background-color:#fff;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
	case 'arguments':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#dddddd;cell-spacing:3;"';
		  break;
		case 'td-key':
		  r = ' style="' + th + 'background-color:#eeeeee;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
	  }
	  break;
	case 'regexp':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#CC0000;cell-spacing:3;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#FF0000;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + th + 'background-color:#FF5757;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
	case 'date':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#663399;cell-spacing:3;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#9966CC;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + th + 'background-color:#B266FF;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
	case 'domelement':
	  switch (use) {
		case 'table':
		  r = ' style="' + table + 'background-color:#FFCC33;cell-spacing:3;"';
		  break;
		case 'th':
		  r = ' style="' + th + 'background-color:#FFD966;"' + thScript;
		  break;
		case 'td-key':
		  r = ' style="' + th + 'background-color:#FFF2CC;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
		  break;
		case 'td-value':
		  r = ' style="' + td + 'background-color:#fff;"';
		  break;
	  }
	  break;
  }
  return r;
};
_dumpIdentifyBrowser = function() {
  var agent = navigator.userAgent.toLowerCase();
  if (typeof window.opera != 'undefined') {
    return 'opera';
  } else if (typeof document.all != 'undefined') {
    if (typeof document.getElementById != 'undefined') {
      var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, '$1').replace(/ /, '');
      if (typeof document.uniqueID != 'undefined') {
        if (browser.indexOf('5.5') != -1) {
          return browser.replace(/(.*5\.5).*/, '$1');
        } else {
          return browser.replace(/(.*)\..*/, '$1');
        }
      } else {
        return 'ie5mac';
      }
    }
  } else if (typeof document.getElementById != 'undefined') {
    if (navigator.vendor.indexOf('Apple Computer, Inc.') != -1) {
      return 'safari';
    } else if (agent.indexOf('gecko') != -1) {
      return 'mozilla';
    }
  }
  return false;
};
_dumpType = function (obj) {
  var t = typeof(obj);
  if (t == 'function') {
  	return 'nofunction'; //EC - dont display functions

    var f = obj.toString();
    if ( ( /^\/.*\/[gi]??[gi]??$/ ).test(f)) {
      return 'regexp';
    } else if ((/^\[object.*\]$/i ).test(f)) {
      t = 'object'
    }
  }
  if (t != 'object') {
    return t;
  }
  switch (obj) {
    case null:
      return 'null';
    case window:
      return 'window';
	case document:
	  return document;
    case window.event:
      return 'event';
  }
  if (window.event && (event.type == obj.type)) {
    return 'event';
  }
  var c = obj.constructor;
  if (c != null) {
    switch(c) {
      case Array:
        t = 'array';
        break;
      case Date:
        return 'date';
      case RegExp:
        return 'regexp';
      case Object:
        t = 'object';
      break;
      case ReferenceError:
        return 'error';
      default:
        var sc = c.toString();
        var m = sc.match(/\s*function (.*)\(/);
        if(m != null) {
          return 'object';
        }
    }
  }
  var nt = obj.nodeType;
  if (nt != null) {
    switch(nt) {
      case 1:
        if(obj.item == null) {
          return 'domelement';
        }
        break;
      case 3:
        return 'string';
    }
  }
  if (obj.toString != null) {
    var ex = obj.toString();
    var am = ex.match(/^\[object (.*)\]$/i);
    if(am != null) {
      var am = am[1];
      switch(am.toLowerCase()) {
        case 'event':
          return 'event';
        case 'nodelist':
        case 'htmlcollection':
        case 'elementarray':
          return 'array';
        case 'htmldocument':
          return 'htmldocument';
      }
    }
  }
  return t;
};
