// Utilities for JavaScript investigations

var welem=null;
var wdoc=document;
var waccum="";

function wtodoc(doc) {
	wdoc=doc;
	welem=null;
}
function wtoelem(elem) {
	wdoc=null;
	welem=elem;
	waccum="";
	if (welem != null) {
		welem.innerHTML="";
	}
}
function wflush() {
	if (welem != null) {
		welem.innerHTML+=waccum;
		waccum="";
	}
}
wtodoc(window.document);
function w(s) { 
	if (wdoc != null) {
		wdoc.write(s); 
	}
	else if (welem != null) {
		waccum+=s;
	}
}
function wln(s) { 
	if (wdoc != null) {
		wdoc.writeln((s?s:'')); 
	}
	else if (welem != null) {
		waccum+=(s?s:'')+"\r\n";
	}
}
function wlb(s) { 
	wln((s?s:'')+"<br>"); 
}
function pre() { 
	wln("<pre>");  
}
function slashpre() { 
	wln("</pre>"); 
}

function plural(n,s1,sN) {
	if (n == 1) {
		return n.toString()+" "+s1;
	}
	else if (arguments.length >= 3) {
		return n.toString()+" "+sN;
	}
	else {
		return n.toString()+" "+s1+"s";
	}
}

function stringDissect(s) {
	var sx='';
	for (var i=0 ; i < s.length ; i++) {
		var cc=s.charCodeAt(i);
		if (33 <= cc && cc <= 126) {
			sx+="'"+String.fromCharCode(cc)+"' ";
		}
		else {
			sx+=cc.toString()+' ';
		}
	}
	return sx;
}

function presentableString(stg) {
	return stg.replace(/\r/g,"\\r")
	          .replace(/\n/g,"\\n")
	          .replace(/\t/g,"\\t");
}

function objectDissect(o, excludablemembers) {  // e.g. objectDissect(document, ["implementation","writeln"]))
	if (excludablemembers == null) {
		excludablemembers = new Array();
	}
	var retval=typeof(o);
	switch (typeof(o)) {
	case "unknown":
	case "undefined":
		return retval;

	case "string":
	case "number":
	case "boolean":
		retval=retval+" "+o.toString();
		break;

	case "function":
	case "object":
	default:
		var a=new Array();
		for (var p in o) {
			includable=true;
			for (var i in excludablemembers) {
				if (p == excludablemembers[i]) {
					includable=false;
					break;
				}
			}
			if (includable) {
				if (is_exceptions) {
					eval(
						"try {"+
							"var t=typeof(o[p]);"+
							"a[a.length]=p+'('+t.charAt(0)+')';"+
						"}"+
						"catch(e) {"+
							"var msg=e.message ? e.message : e.description;"+
							"a[a.length]=p+'[[[typeof() exception: '+msg+']]]';"+
						"}"
					);
				}
				else {
					var t=typeof(o[p]);
					a[a.length]=p+"("+t.charAt(0)+")";
				}
			}

			//try {
			//	var t=typeof(o[p]);
			//	a[a.length]=p+"("+t.charAt(0)+")";
			//}
			//catch (e) {
			//	var msg=e.message ? e.message : e.description;
			//	a[a.length]=p+"[[[typeof() exception: "+msg+"]]]";
			//}
		}
		a.sort();
		retval=retval+" "+a.join(" ");
		break;
	}
	return retval;
}


	function element(id) {									// universal way to get element by id
	     if (document.getElementById != null) {				// 1st choice
	          return document.getElementById(id);			// no N4,IE4
	     }
	     if (document.all != null) {                        // 2nd choice
	          return document.all[id];             			// IE only
	     }
	     if (document.layers != null) {         			// 3rd choice
	          return document.layers[id];     				// N4 only
	     }
	     return null;                                       // give up
	}
