/**
* 25.03.08@FC	1.1.0	ADD w3gDOM.JavaScript debug functionality
* 05.03.08@FC	1.0.0	First release.
*/

var w3gDOM = function(){return;};

//Inspector utility for DOM Objects
w3gDOM.Inspector = function (node){

	var start = node ? node : document; 
	var current = start;
	
	//search for all the tag with name match and return on array
	this.searchIn= function(nodeName){
   	 nodeName = nodeName ? nodeName.toUpperCase():nodeName;	 
	 if(isIgnorable(current))return new Array();
	 return traverseDown(start,new Array(),nodeName)
	 
	}
	//PRIVATE@ recursive traverse down DOM 
	function traverseDown(current,stack,nodeName){
	 var done= false;
	 var cnod =firstChild(current);
	 if(!cnod)return stack;	 
	 if((cnod.nodeName==nodeName || !nodeName) && !isIgnorable(cnod)){
		 stack.push(cnod);		 
		 	
	 }
	 if(!isIgnorable(cnod))stack = traverseDown(cnod,stack,nodeName);	
	 while(cnod = nodeAfter(cnod)){
	    if(!isIgnorable(cnod)){
				if(cnod.nodeName==nodeName)stack.push(cnod);		
				stack = traverseDown(cnod,stack,nodeName);	 
			}
	 }
     return stack;	 
	}	
	//PRIVATE@ tell if a node content is  blank chars
	function isWhiteSpaces(nod) { return !(/[^\t\n\r ]/.test(nod.data)); }
	
	//PRIVATE@ tell if a node isn't a tag or is an empty tag
	function isIgnorable(nod) { return (nod.nodeType == 8) || ((nod.nodeType == 3) && isWhiteSpaces(nod)); }

    //retrive the previous node's "brother"
    this.nodeBefore = function(sib){
		var ret = nodeBefore(sib ? sib : current);
		if(ret!=null)current=ret;
		return ret;
	}
	function nodeBefore(sib) {
		while ((sib = sib.previousSibling)) {
			if (!isIgnorable(sib)) return sib;
		}
		return null;
	}
	//retrive the next node's "brother"
	this.nodeAfter = function(sib){	  
		var ret = nodeAfter(sib ? sib : current);
		if(ret!=null)current=ret;
		return ret;
	}
	function nodeAfter(sib) {
		while ((sib = sib.nextSibling)) {
			if (!isIgnorable(sib)) return sib;
		}
		return null;
	}
	//retrive node's first child node 
	this.firstChild = function(par){
		var ret = firstChild(par ? par : current);
		if(ret!=null)current=ret;
		return ret;
	}
	function firstChild(par) {
		var res = par.firstChild;
		while(res) {
			if(!isIgnorable(res)) return res;
			res = res.nextSibling;
		}
		return null;
	}
	//retrive the last node of the node's childs
	this.lastChild = function(par){
		var ret = lastChild(par ? par : current);
		if(ret!=null)current=ret;
		return ret;
	}
	function lastChild(par) {
		var res = par.lastChild;
		while(res) {
			if(!isIgnorable(res)) return res;
			res = res.previousSibling;
		}
		return null;
	}

}
w3gDOM.Console = function(){

	this.id = 'w3gDOMConsole';
	this.console;
	this.controls;
	this.content;
	
	this.create = function(){
		if(!this.console){
			this.console = document.createElement('DIV');
			this.console.setAttribute('id', this.id );
			this.console.setAttribute('name', this.id );
			this.console.setAttribute('width', '350px' );
			this.console.setAttribute('height', '350px' );
			this.console.style.height='350px';
			this.console.style.width='350px';			
			this.console.style.position="absolute";
			this.console.style.display="none";
			this.console.style.border="5px double #666666";
			this.console.style.backgroundColor="#cccccc";
			this.console.setAttribute('ondblclick', 'this.hide()' );
			this.console.style.right='50px';	
			this.console.style.top='80px';	
			document.getElementsByTagName('BODY')[0].appendChild(this.console);		
			this.controls =  document.createElement('DIV');
			this.controls.setAttribute('id', this.id+'Ctrl' );
			this.controls.setAttribute('name', this.id+'Ctrl' );
			this.controls.setAttribute('width', '100%' );
			this.controls.setAttribute('height', '30px' );			
			this.controls.setAttribute('align', 'right' );	
			this.controls.style.height='20px';
			this.controls.style.width='100%';
			this.controls.style.position="relative";
			this.controls.style.display="block";
			this.controls.style.top="0px";
			this.controls.style.borderBottom="1px dashed #666666";
			this.controls.style.backgroundColor="transparent";
			this.console.appendChild(this.controls);
			this.controls.innerHTML=(
				'<a href="javascript:void(0);" style="cursor:move;" id="'+ this.id+'Ctrl-Move' +'">[M]</a> '+
				'<a href="javascript:void(0);" onclick="javascript:w3gDOM.Console().clear();">[C]</a> '+
				'<a href="javascript:void(0);" onclick="javascript:w3gDOM.Console().hide();">[X]</a> '
				
				);				
			this.content =  document.createElement('DIV');
			this.content.setAttribute('id', this.id+'Cntn' );
			this.content.setAttribute('name', this.id+'Cntn' );
			this.content.setAttribute('width', '100%' );
			this.console.setAttribute('height', '330px' );
			this.content.setAttribute('align', 'left' );
			this.content.style.overflow='auto';
			this.content.style.width='100%';
			this.content.style.height='330px';
			this.content.style.paddin='7px';
			this.content.style.margin='0px';
			this.content.style.display="block";
			this.content.style.backgroundColor="#ffffff";
			this.console.appendChild(this.content);	
			new Draggable(this.console,{
				handle:this.id+'Ctrl-Move',
				onStart: function(){w3gDOM.Console().console.showOverlappedSelect();},
				onEnd: function(){w3gDOM.Console().show();}
				});				
					
		}
		return this;	
	}	

	this.show = function(){
	 this.console.show();
	 setTimeout(this.console.hideOverlappedSelect.bind(this.console), 50);	 
	 return this;	 
	}
	
	this.clear = function(){
	 this.content.innerHTML="";
	 return this;
	}
	
	this.info = function(myHTML){
		return this.print('<div style="color:black;padding:2px;margin:2px;font-size:8pt;">@ '+myHTML+'</div>')
	}
	this.error = function(myHTML){
		return this.print('<div style="color:darkred;padding:2px;margin:2px;font-size:8pt;">@ '+myHTML+'</div>')
	}
	this.warning = function(myHTML){
		return this.print('<div style="color:orange;padding:2px;margin:2px;font-size:8pt;">@ '+myHTML+'</div>')
	}	
	
	this.hide= function(){
	 this.console.hide();
	 return this;
	}
	
	this.println = function(myHTML){
		return this.print('<div style="padding:2px;margin:2px;font-size:8pt;">@ '+myHTML+'</div>');
	}
	
	this.print = function(myHTML){
		this.content.innerHTML=(this.content.innerHTML+myHTML);
		return this;		
	}
	
	this.create();
	
	return this;
}
function $NOCONSOLE(what){
	w3gDOM.Console().hide();
}
function $CONSOLE(what){
	w3gDOM.Console().show();
}
function $CLEAR(what){
	w3gDOM.Console().clear();
}
function $LOG(what){
	w3gDOM.Console().show().info(what);
}
function $ERR(what){
	w3gDOM.Console().show().error(what);
}
function $WARN(what){
	w3gDOM.Console().show().warning(what);
}
//retrive the versione of this js
w3gDOM.Version= function(){
	var release ='1';
	var major='1';
	var minor='0';		
	this.release=release;this.major=major;this.minor=minor;	
	function fullVersion(){	return release+'.'+major+'.'+minor; }
	return fullVersion();
}

w3gDOM.JavaScript= function(obj){
  	this.object = obj;
	this.BR;
	this.SP;
	this.time;
	this.limit = 2500;
	this.timeout = false;
	this.ignore;
	
	this.printTree= function(deep,parameter){
		if(!deep)deep=100;
		if(!parameter)parameter={};
		this.SP = parameter['space'] || '-';
		this.BR = parameter['newLine'] || '\n';
		this.limit = parameter['timeLimit'] || 2500;
		this.ignore = (parameter['ignore'] || 'bind,bindAsEventListener,prototype')+',';
		
		this.printDeep =  true;
		this.time = new Date().getTime();
		this.timeout = false;
		var tree =this.buildTree(this.object,'','',0,deep);
		return (this.timeout==true) ? tree + this.BR + '... [[ TIMEOUT@'+this.limit+'ms ]]' : tree;

	}
	
	this.buildTree= function(obj,string,offset,currentDeep,deep){
	    if(currentDeep>=deep)return string;	
			if(new Date().getTime() - this.time > this.limit) {this.timeout=true;return string;}
			for (var property in obj) { 			  
				if(new Date().getTime() - this.time > this.limit) {this.timeout=true;return string;}
			
				if(this.ignore.indexOf(property+',')<0){					
					if(typeof obj[property] == 'object' || typeof obj[property]== 'function'){
						if(typeof obj[property]!= 'function')
							string += this.BR+offset+property+': '+obj[property] + ' ['+ typeof obj[property]+']';
						else
							string += this.BR+offset+property +' ['+ typeof obj[property]+']'					
						string = this.buildTree(obj[property],string,offset+this.SP,++currentDeep,deep)
					}else
						string += this.BR+offset+property+': '+obj[property] + ' ['+ typeof obj[property]+']';
				}
  		}
  		return string ;
	}
}


/*	NODE TYPES REFERENCE
	--------------------------------
	n	 |	NodeType.[Constatant]
	--------------------------------
	1  |	ELEMENT_NODE
	2  |	ATTRIBUTE_NODE
	3  |	TEXT_NODE
	4  |	CDATA_SECTION_NODE
	5  |	ENTITY_REFERENCE_NODE
	6  |	ENTITY_NODE
	7  |	PROCESSING_INSTRUCTION_NODE
	8  |	COMMENT_NODE
	9  |	DOCUMENT_NODE
	10 |	DOCUMENT_TYPE_NODE
	11 |	DOCUMENT_FRAGMENT_NODE
	12`|	NOTATION_NODE
	--------------------------------*/

