// jsdebugwin.js 
// jsDebugWin 
// Version: 1.1
// Author: Justin Khoo (5/9/2004)
// email: justin 'at' talkloud.com
//
// Copyright 2010.
// Licenced LGPLv3
// No guarantee is made in regards to this code.
//
// Currently tested and works with IE4+, NN4+, Opera 7+
// Will work on supporting other browsers if needs arise

var jsDebugOK = true;
var jsWin = false;
var jsHelp = false;
var jsWinInit = false;
var jsErrorTrap = false;


var jsDebugStr = "";
var jsHistoryArray = new Array();
var jsHistoryCount = 0;
var jsHistoryCache = "";

var jsMode = "cache"; //cache or nocache
var jsInputBoxSize = "small"; //default
var jsRowColor = "ffffff";
var jsRefreshTimer = 0;
var jsTmpInput = "";

//has "css issues"
var jsIsNN4 = false; 
//===============================================================
//"Public methods"
//===============================================================


function jsdebug(debug){
	if(!jsDebugOK)return;

	if(debug)
		jsAddToArray("out",debug);	
	jsRefresh();
}

//the default function is jsdebug() not jsDebug()
function jsDebug(debug){
	if(!jsDebugOK)return;
	
	jsAddToArray("*err","The proper method is jsdebug(), not jsDebug().");	
	jsRefresh();
}

function jsDelayedDebug(debug,intv){
	if(!jsDebugOK)return;
	
	jsAddToArray("out",debug);	
	var interval = intv?intv:1000; //1sec default
	if(jsRefreshTimer != 0) 
		return;
	else{
		jsRefreshTimer = setTimeout("jsRefresh()",interval);
	}
}


function jsTimedDebug(debug){
	if(!jsDebugOK)return;
	
	var myDate = new Date();
	var myOut = "["+myDate.getHours()+":"+myDate.getMinutes()+":"+myDate.getSeconds()+"]: "+debug;
	jsAddToArray("out",myOut);		
	jsRefresh();
}

//Error trapping routine
//add window.onerror = jsDebugError to your code if you want to turn this on by default
//Does not work in all environments, read the Help for details
function jsDebugError(msg, url, linenumber){
	if(!jsDebugOK)return;
	
	jsAddToArray("*err",msg+' (line: '+linenumber+')');	
	jsRefresh();
}


//Shortcut to call getElementById or document.all
//Only IE4+ or DOM enabled browsers, does not work with NN4
function jsGetElem(elemId){
	
	if(document.getElementById)
		return document.getElementById(elemId);
	if(document.all)
		return document.all[elemId];
		
	return;
}

//===============================================================
// End of "public functions"
// Functions below are internal to the script, you may use them at your discretion
//===============================================================

//Types: del(deleted), cmd(command), out(print) *err(error)
function jsDebugObj(jsType,jsMsg){
	this.type = jsType;
	this.msg= jsMsg;
}


function jsLaunchWin(){
	jsWinInit = false;
	if(document.layers)jsIsNN4 = true;
	
	jsWin = window.open("about:blank","jsDebugWin", "width=400,height=400,location=no,menubar=no,status=yes,toolbar=no,scrollbars=yes,resizable=yes");
	jsRefresh();
}

function jsRefresh(){
	jsRefreshTimer = 0;
	
	if(!jsWin || jsWin.closed){
			jsLaunchWin();
	}else{
		if(jsWinInit)
			jsTmpInput = jsWin.document.forms.jsdbform.evalfield.value;
		
		var winHtml = "";
		winHtml += "<HTML><HEAD><TITLE>jsDebugWin</TITLE></HEAD><BODY onload='window.focus();opener.jsFocusInput()' >";
		
		//Write style
		if(!jsIsNN4){
			winHtml += "<STYLE>BODY {	FONT-SIZE: 9pt; COLOR: #000000; FONT-FAMILY: Arial,Helvetica, sans-serif; BACKGROUND-COLOR: #ffffff	}</STYLE>";
			winHtml += "<STYLE>TD {	FONT-SIZE: 9pt; COLOR: #000000; FONT-FAMILY: Arial,Helvetica, sans-serif; }</STYLE>";
			winHtml += "<STYLE>A {COLOR: blue;}</STYLE>";
		}
		
		winHtml += jsGenInputForm();
		winHtml += jsGenOptions();
				
		if(jsMode == "nocache"){
			winHtml += "<table width=360 cellspacing=0 cellpadding=0 border=0>";
			winHtml += jsArrayToRows();
			winHtml += "</table>";
		}
		else{
			winHtml += "<table width=360 cellspacing=0 cellpadding=0 border=0>";
			winHtml += jsHistoryCache;
			winHtml += "</table>";
		}
		winHtml += "</BODY></HTML>";
		jsWin.document.open();		
		jsWin.document.write(winHtml);
		jsWin.document.close();
		if(jsWinInit)
			jsWin.document.forms.jsdbform.evalfield.value = jsTmpInput;
		jsWinInit = true;
	}
}


function jsGenInputForm(){
	var formHtml = "";
	formHtml += "<FORM name='jsdbform' onsubmit='opener.jsEvalDebug();return false;'>";	
	
	if(jsInputBoxSize == "small"){
		formHtml += "<div style='font-size:8pt'>";
		formHtml += "<a href='javascript:opener.jsResizeInput(\"large\")'>Expand Input</a>";
		formHtml += "&nbsp; <a href='javascript:' title='functions:\n - jsdebug,\n - jsDelayedDebug,\n - jsTimedDebug,\n - jsGetElem'>[?]</a>";
		formHtml += "</div>";
		formHtml += "<input type=text size=45 name=evalfield >";
	}else{
		formHtml += "<div style='font-size:8pt'>";
		formHtml += "<a href='javascript:opener.jsResizeInput(\"small\")'>Minimize Input</a>";
		formHtml += "&nbsp; <a href='javascript:' title='functions:\n - jsdebug,\n - jsDelayedDebug,\n - jsTimedDebug,\n - jsGetElem'>[?]</a>";
		formHtml += "</div>";
		formHtml += "<textarea name=evalfield rows=5 cols=42></textarea><br>";
	}
	formHtml += "<input type=button value=' Run ' onclick='opener.jsEvalDebug()'></FORM>";	
	return formHtml;
}

function jsGenOptions(){
	var oHtml = "";
	oHtml += "<a href='javascript:opener.jsClearDebug()'>Clear All</a> | ";
	if(!jsErrorTrap){
		oHtml += "<a href='javascript:opener.jsTrapErrors(true)'>Trap errors</a>";
	}else{
		oHtml += "<a href='javascript:opener.jsTrapErrors(false)'>UnTrap errors</a>";
	}
	oHtml += " | <a href='javascript:opener.jsOpenHelp()'>Help</a>";
	
	oHtml += "<br>";
	return oHtml;
}

function jsTrapErrors(flag){
	if(flag){
		window.onerror = jsDebugError;
		jsAddToArray("out","* Error trapping may not work in all browsers. Read the Help page *");	
		jsErrorTrap = true;
	}else{
		window.onerror = null;
		jsErrorTrap = false;
	}
	
	jsRefresh();
}

function jsResizeInput(size){
	jsInputBoxSize = size;
	jsRefresh();
}

function jsFocusInput(){
	jsWin.document.forms.jsdbform.evalfield.focus();
}



function jsArrayToRows(){
	var rows = "";
	for(var i=0;i<jsHistoryArray.length;i++){
		jsObj = jsHistoryArray[i];
		rows = jsGenRow(jsObj,i) + rows;
	}
	return rows;
}


function jsGenRow(jsObj,rowNum){
	var rowHtml = "";
	var myMsg = jsObj.msg;
	myMsg = ""+myMsg;

	if(myMsg.match(/[\n&<>]/)){
		//must be in this order
		myMsg = myMsg.replace(/&/g,"&amp;");
		myMsg = myMsg.replace(/</g,"&lt;");
		myMsg = myMsg.replace(/>/g,"&gt;");
		myMsg = myMsg.replace(/\n/g,"<br>");
		
	}
	
	if(jsObj.type != "del"){
		if(jsRowColor == "ffffff")
			jsRowColor = "eaeaea";
		else
			jsRowColor = "ffffff";			
		rowHtml += "<tr bgcolor="+jsRowColor+">";
		rowHtml += "<td width=20 valign=top><b>"+jsObj.type+":&nbsp;</b></td><td>"+myMsg+"</td><td align=right width=80>";
		if(jsObj.type == "cmd"){
			rowHtml += " <a href='javascript:opener.jsCmdReuse("+rowNum+")'>[reuse]</a> ";
			rowHtml += "<a href='javascript:opener.jsCmdRerun("+rowNum+")'>[run]</a> ";
		}
		rowHtml += "<a href='javascript:opener.jsCmdDel("+rowNum+")'>[x]</a> </td>";
		rowHtml += "</tr>";
	}
	return rowHtml;
}


function jsCmdReuse(idx){
	var evalObj = jsHistoryArray[idx];
	if((evalObj.msg.match(/\n/))&&(jsInputBoxSize == "small")){
		jsInputBoxSize = "big";
		jsRefresh();
	}
	jsWin.document.forms.jsdbform.evalfield.value = evalObj.msg;
}

function jsCmdRerun(idx){
	var evalObj = jsHistoryArray[idx];
	jsEval(evalObj.msg);
}

function jsCmdDel(idx){
	var evalObj = jsHistoryArray[idx];
	evalObj.type = "del";
	//refresh Cache
	jsHistoryCache = jsArrayToRows();
	jsRefresh();
}

function jsClearDebug(){
	jsHistoryCache = "";
	jsHistoryArray = new Array();
	jsHistoryCount = 0;
	jsRefresh();
}

function jsEvalDebug(){
	var mcmd = jsWin.document.forms.jsdbform.evalfield.value; 
	jsWin.document.forms.jsdbform.evalfield.value = "";
	jsEval(mcmd);
}

function jsEval(mcmd){
	jsAddToArray("cmd",mcmd);
	jsRefresh();
	eval(mcmd); 	
}

function jsAddToArray(jsType,jsMsg){
	
	jsObj = new jsDebugObj(jsType,jsMsg);	
	jsHistoryArray[jsHistoryCount] = jsObj;
	
	//add to cache so the page does not need to be generated from the array each time
	jsHistoryCache = jsGenRow(jsObj,jsHistoryCount) + jsHistoryCache;
	
	jsHistoryCount++;		
}

function jsOpenHelp(){
	var helpUrl = "http://www.talkloud.com/jsdebugwin/";
	
	if(jsHelp && !jsHelp.closed){
		jsHelp.location = helpUrl;
		jsHelp.focus();
	}else{
		jsHelp = window.open(helpUrl,"jsHelp", "width=700,height=500,menubar=yes,status=yes,toolbar=yes,scrollbars=yes,resizable=yes");
	}
}


function jsinspect(obj) {
  var msg = "";
   for (var i in obj) {
      msg += i + ":" + obj[i]+"\n";
   }
   jsdebug(msg);
}
