/** DOMCacher 1.1 - gestore ottimizzato del DOM **/
/** requires: eventregister.js **/

/** Quest'oggetto gestisce il DOM con accesso indicizzato in modo da ottenere
rapidamente gli oggetti dei tag necessari **/

if(typeof DOM=="undefined")
{
	function DOMcacher()
	{
		var self=this;
		var _objs_array=new Array();
		var _objs_hash=new Array();
		
		// "fa la foto" del DOM, aggiornando la lista 
		// di tutti gli obj in cache
		self.DOMshot=function(){
			_emptyObjects();
			_inspectDOM(document.body);
		};
		
		// ritorna l'handle del tag con indice richiesto
		self.getFromIndex=function(index){
			if(index<_objs_array.length)
				return _objs_array[index];
			return null;
		};
		
		// ritorna l'handle del con id richiesto
		this.getFromId=function(id){
			return _objs_hash[id] || document.getElementById(id);
		};
		
		// ritorna un array con tutti i figli di un tag
		this.getChildren=function(id){
			var parent=this.getFromId(id);
			var child=_firstChild(parent);
			var children=new Array();
			while(child)
			{
				children.push(child);
				child=_nextSibling(child);
			}
			return children;
		};
		
		/// PRIVATES
		// svuota la lista degli oggetti
		function _emptyObjects(){
			for(var i=0;i<_objs_array.length;i++)
				_objs_array.pop();
			for(var o in _objs_hash)
				_objs_hash.pop(o);
		};
		
		// scorre ricorsivamente il DOM alla ricerca degli id
		// e riempie l'array _objs con i rispettivi oggetti
		function _inspectDOM(obj){
			if(!obj)
				return;
			if(!_isEmpty(obj.id))
			{
				_objs_array.push(obj);
				_objs_hash[obj.id]=obj;
			}
			if(_hasChildren(obj))
				_inspectDOM(_firstChild(obj));
			_inspectDOM(_nextSibling(obj));
		};
		
		// dice se una stringa è vuota (eliminando gli spazi)
		function _isEmpty(str){
			str=str.replace(/\s+$|^\s+/g,"");
			if(str=="")
				return true;
			else
				return false;
		};
		
		this.nextSibling=function(obj){ return _nextSibling(obj); }
		// ritorna il prossimo nodo
		function _nextSibling(obj){
			if(obj=obj.nextSibling)
			{
				if(obj.nodeType!=1)
					obj=_nextSibling(obj);
			}
			return obj;
		};
		
		// ritorna il primo figlio
		function _firstChild(obj){
			if(obj=obj.firstChild)
			{
				if(obj.nodeType!=1)
					obj=_nextSibling(obj);
			}
			return obj;
		};
		
		// controlla se ha dei figli
		function _hasChildren(obj){
			if(obj.childNodes.length>0)
				return true;
			else
				return false;
		};
	}
	
	DOM=new DOMcacher();
	EVENT_REGISTER.register("onload",DOM.DOMshot);
}

