# Marijn's debug logging functionality
# Purely javascript based version (no css file and no html required)


#||define||_inline_css||foo||

function Debug(){

#	External interface	
	this.dbg=dbg;
	this.dbg_clr=dbg_clr;
	this.dbg_report=dbg_report;
	this.pop_inout=pop_inout;
	this.popout_cb=popout_cb;
	this.popin_cb=popin_cb;
	this.setFilter=setFilter;
	this.setHighlight=setHighlight;
	this.setBreak=setBreak;
    this.screenUpdates=screenUpdates;
    this.disable=disable;
    this.getDoc=function(){return doc}

# 	Private implementation
	var dbg_lines=[];
	var dbg_n=0;
    var disabled=false;
	var updateScreen=true;
	var doc=document;
	var last;
#	Allow debug window to be popped out into it's own window
	var mypop=null;
    var mydebugger=__mydebugger;

	docwrite_html();		

	init();

	function init(){
		dbg("Marijns javascript debugger init");
	
		var theHandle = doc.getElementById("dbg_handle");
		var theRoot   = doc.getElementById("dbg_root");
		if (typeof Drag=='undefined'){
			dbg("Window drag module is not available");
		}else{
#			Drag.init(theHandle, theRoot);		
            Drag.init(theHandle, theRoot, null,null,null,null, true, true);              
		}
		if (typeof Popout=='undefined'){
			dbg("Window popout module is not available");
			o=doc.getElementById("dbg_popout");
			o.style.display="none";
		}
		theHandle.onkeydown=stopBubble;
		theHandle.onkeyup=stopBubble;
	}

	function dbg(){
		var debug_break=false;
		var txt,type;

        if (disabled)
            return;

		var now=mtime();

		if (arguments.length>=2 && arguments[1]!=undefined){
			type=arguments[0];
			txt=arguments[1];
		}else if (arguments.length>=1 && arguments[0]!=undefined){
			txt=arguments[0];
		}else{
			return;
		}

		dbg_n++;

		o=doc.getElementById("dbg_search");
        if (o==null)
            return;     // Not sure if and why this is required. FIND OUT!!
		if (!_mymatch(o.value,txt,type))
			return;

		var op=[];

#		Count and time output
		if (dbg_n<10) 	
		op.push("&nbsp;");
		if (dbg_n<100)  
		op.push("&nbsp;");
		
		var ticks=Math.round((now%1000)/10);
		var time=(window.clock ? (clock(now)+'.'+prefix_time(ticks)) : ('('+ticks+')'))
		op.push( dbg_n+' '+time);

# 		Allow fixed width font header if we want
		op.unshift( '<span class="dbg_hdr">');
		op.push( '</span>');

#		Add code area
		if (type != undefined)
		op.push(' '+type);
		op.push(' '+txt);

# 		Highlight it if required				
		o=doc.getElementById("dbg_highlight");
		if (o.value.length>0 && _mymatch(o.value,txt,type)){
			op.unshift('<span class="dbg_highlight">');
			op.push('</span>');
		}
		if(last && now-last>3000){
			op.unshift('<span style="width:100%;border-bottom:1px solid #aaa;display:inline-block;">');
			op.push('</span>');
		}
		last=now;

		var full_line=op.join('');
		dbg_lines.unshift(full_line);

		if (dbg_lines.length>500)
			dbg_lines.pop();

		if(updateScreen==false)
			return;

		var o=doc.getElementById("dbg_text");
		o.innerHTML=dbg_lines.join("<br>");

		o=doc.getElementById("dbg_break_text");
		if (_mymatch(o.value,full_line,type)){
			o=doc.getElementById("dbg_break");
			if (o.checked){
				o.checked = !o.checked;
				debug_break=true;
			}
		}
		if (debug_break) 
            mydebugger();
#            debugger; // Keep this as very last line in function for easy debugger stepping
	}
	
	function setFilter(txt){
		doc.getElementById("dbg_search").value=txt;
	}

	function setHighlight(txt){
		doc.getElementById("dbg_highlight").value=txt;
	}
	
	function setBreak(txt){
		doc.getElementById("dbg_break_text").value=txt;
		doc.getElementById("dbg_break").checked=true;
	}

	function screenUpdates(val){
		if (val){
			updateScreen=true;
			dbg('screen updated reenabled');
		}else{
			updateScreen=false;
			dbg('screen updated disabled');
		}
	}
    function disable(val){
        disabled=val;
    }
	
	function _mymatch(o,type,str){
		if (o.length==0)
			return true;

		var srch=o.split(",");
		var txt=type + " " + str;

		// first search term defines default behaviour
		var overall_match = (srch[0].substr(0,1)=="!") ? true : false ;

		for (var i in srch){
			var term = srch[i];
			if (typeof(term) == 'function') continue;	// for those nitwits that globally overrride the array object
			var this_match=false;
			if (term.substr(0,1)=="!"){
				this_match=true;
				if (txt.indexOf(term.substring(1,term.length))!=-1)
					this_match=false;
				overall_match = overall_match && this_match;
			}else{
				if (txt.indexOf(term)!=-1)
					this_match=true;
				overall_match = overall_match || this_match;
			}
		}

		return overall_match;
	}

	function dbg_break(txt){
        mydebugger();
	}

	function dbg_clr(txt){
#		might need scope correction
		dbg_lines=[];
		var o=doc.getElementById("dbg_text");
		o.innerHTML="";
	}
	function dbg_report(){
		if(!Dbg.report_cb) 
			alert("Reporting not enabled")
		else
			Dbg.report_cb(dbg_lines.join('<br>'));
	}
		
	
	function docwrite_html(){
		||ifdef||_inline_css||
			doc.write('<style type="text/css">');
			doc.write('	#dbg_root {');
			doc.write('		position:absolute;z-index:1000;');
			doc.write('		width:500px;');
			doc.write('		background-color:#F4F4F4; border:1px solid #333;');
			doc.write('		font-family:verdana, sans-serif; font-size:10px;');
			doc.write('	}');
			doc.write('');
			doc.write('	.dbg_root_popout {');
			doc.write('		position:block;');
			doc.write('		width:100%;');
			doc.write('	}');
			doc.write('	#dbg_handle {');
			doc.write('		margin:2px; padding:2px;');
			doc.write('		white-space: nowrap; overflow:hidden;');
			doc.write('		color:white; background-color:navy; cursor:default');
			doc.write('	}');
			doc.write('');
			doc.write('	#dbg_search, #dbg_clear, #dbg_highlight, #dbg_break_text {');
			doc.write('		font-size:9px;');
			doc.write('	}');
			doc.write('	#dbg_text {');
			doc.write('		height:280px;');
			doc.write('		overflow: auto;');
			doc.write('	}');
			doc.write('	.dbg_highlight {');
			doc.write('		color:red;');
			doc.write('	}');
			doc.write('	.dbg_hdr {');
#			doc.write('		font-family:courier-new;font-size:8px;');
			doc.write('	}');
			doc.write('	.dbg_popout {');
			doc.write('		display:none;');
			doc.write('	}');
			doc.write('</style>');
			doc.write('');
		||endif||

		var events='onkeydown="return stopEvent(event);" onkeyup="return stopEvent(event);" onclick="return stopEvent(event);" onkeypress="return stopEvent(event);"';

||iftrue(dbg_leftalign)||
        doc.write('<div id="dbg_root" style="left:20px; bottom:20px;" '+events+'>');
||else||        
        doc.write('<div id="dbg_root" style="right:20px; bottom:20px;" '+events+'>');
||endif||       
        doc.write('  <div id="dbg_handle">Debug: ');
        doc.write('    <input type="button" id="dbg_report" onclick="Dbg.dbg_report();" value="report"/> ');
        doc.write('    <input type="button" id="dbg_clear" onclick="Dbg.dbg_clr();" value="clear"/> ');
        doc.write('      Filter <input id="dbg_search"  style="width:50px"/>');
        doc.write('      Highlight <input id="dbg_highlight"  style="width:50px"/>');
        doc.write('      Break <input type="checkbox" id="dbg_break" /><input id="dbg_break_text" style="width:50px"/>');
        doc.write('      <input id="dbg_popout" type="button" onclick="Dbg.pop_inout(\'dbg_root\');" value="P">');
        doc.write('    </div>');
        doc.write('    <div id="dbg_text"></div>');
        doc.write('</div>');
   	}

#	Optional support for popping windows in and out	
	function pop_inout(txt){
		if (typeof Popout=='undefined'){
			dbg("Window popout module is not available");
			return;
		}
		if (!mypop) {
			mypop=new Popout; 
			mypop.setCustomCb(Dbg.popout_cb, Dbg.popin_cb);			
		}
		mypop.pop_inout(txt);
	}
	function popout_cb(new_doc){		// function callback only
		dbg("fns popout_cb");
		doc=new_doc;
	}	
	function popin_cb(new_doc){			// function callback only
		dbg("fns popin_cb");
		doc=new_doc;
		var theHandle = doc.getElementById("dbg_handle");
		var theRoot   = doc.getElementById("dbg_root");        
        Drag.init(theHandle, theRoot, null,null,null,null, true, true);  
	}	
}

function __mydebugger(){    // Just to keep YUICompresser happy
    eval('debugger');   // note YUICompresser falls over just having "debugger;" statement and inline reduces compression
}

# Pollute the global namespace with easy access function
function dbg(a1,a2){ return Dbg.dbg(a1,a2); }
function dbg_emptyfn(){}

var Dbg=new Debug;


# Originally devt location: ..\dbg\dbg.js
dbg("module Debug source file loaded");

# Experimental code to reconnect popped out window from previous browsed page
function reconnect(w){
	w.reconnected("will this work?");
}