/* A definição do objecto */
function eowTree(treeName)
{
	this.node0i = "<table width=\"&treewidth;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"tabela\">";
	this.node1i = "<tr id=\"row&rowID;\" height=\"18\"><td class=\"row&nivel;\" onmouseover=\"javascript: this.className='row&nivel;Hover';\" onmouseout=\"javascript: this.className='row&nivel;';\">";
	this.imgStri  = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr width=\"11\"><td valign=\"top\"><img id=\"img&rowID;\" src=\"";
	this.imgStrf  = "\" width=\"11\" height=\"11\" align=\"left\" onClick=\"&treeName;.oc('&rowID;')\"/></td>";
	this.linkStr = "<td><a href=\"&url;\" class=\"txtNivel&nivel;\">";
	this.node1f = "</a></td></tr></table></td></tr>";
	this.separador = "<tr><td height=\"1\"><img src=\"imagens/horzLine.gif\" width=\"&treewidth;\" height=\"1\" /></td></tr>";
	this.node0f = "</table>";

	// Arrays for nodes and icons
	this.obj = treeName;
	this.nodes = new Array();
	this.openNodes = new Array();
	this.nodesHeight = new Array();
	this.selectedNode = 0;
	this.initScroll = 0;
	this.altura = 0;
	this.largura = "169px";
	this.maxHeight = 300;
	this.intervalo = null;
	this.icons = new Array(2);
		
		this.debug = false;
		this.keepOnlyOneLevelOpen=true; // Indica se, ao abrir um determinado nó, devemos fechar todos os outros nós ao mesmo nível
		
		this.intervalo; //Variável usada para o window.setTimeout de subir ou descer o espaço visivel
};

/* Carrega as imagens que vão ser usadas */
eowTree.prototype.preloadIcons = function() {
	this.icons[0] = new Image();
	this.icons[0].src = "../UI/imagens/btMaisSubmenu.gif";
	this.icons[1] = new Image();
	this.icons[1].src = "../UI/imagens/btMenosSubmenu.gif";
	this.icons[2] = new Image();
	this.icons[2].src = "../UI/imagens/btEmptySubmenu.gif";
};

/* Create the tree */
eowTree.prototype.createTree = function(startNode, openNode, treeWidth) {		
	if(treeWidth)
  	this.largura = treeWidth;        

	if (this.nodes.length > 0) {
		this.preloadIcons();
		
		this.clearOpenNodes();
		
		if (openNode != null){
			this.selectedNode = openNode;
			this.updateOpenNodes( this.selectedNode );
		}

		if (startNode == null) startNode = 0;
		//if (openNode != 0 || openNode != null) setOpenNodes(openNode);
		
		if (startNode !=0) {
			var nodeValues = this.nodes[this.getArrayId(startNode)].split("|");	
		}			

		document.write(this.node0i.replace("&treewidth;", this.largura));
		
		var recursedNodes = new Array();
		this.addNode(startNode, recursedNodes);
		
		document.write(this.node0f);		
	}
	
	this.updateOpenCloseStatus();	
};


/* Adds a new node to the tree */
eowTree.prototype.addNode = function(parentNode, recursedNodes) {	
	for (var i = 0; i < this.nodes.length; i++) {
		var nodeValues = this.nodes[i].split("|");
		if (nodeValues[1] == parentNode) {
			
			var hcn	= this.hasChildNode(nodeValues[0]);
			var ino = this.isOpen( nodeValues[0] );
			var nivel = recursedNodes.length;
			var selected = "";
			
			//alert( "nodeID="+nodeValues[0] );
			//alert( "nodeName="+nodeValues[2] );
			//alert("nivel="+nivel);
			
			recursedNodes.push(1);
			
			if ( nodeValues[0] == this.selectedNode ){
				selected = "_selected";
				this.initScroll = this.altura;
			}
			
			document.write( this.node1i.replace("&rowID;", nodeValues[0]+this.obj ).replace("&nivel;", nivel).replace("&nivel;", nivel).replace("&nivel;", nivel));			
			
			this.altura += 8;
			
			document.write( this.imgStri.replace( "&rowID;", nodeValues[0]+this.obj ) );
			if (hcn) {
				if (ino){
					document.write( this.icons[1].src );
				} else {
					document.write( this.icons[0].src );
				}
			} else {
				document.write( this.icons[2].src );
			}
			
			document.write( this.imgStrf.replace( "&rowID;", nodeValues[0] ).replace("&treeName;", this.obj) );
			
			document.write( this.linkStr.replace("&url;", nodeValues[3] ).replace("&nivel;", nivel+selected) + nodeValues[2] );
			document.write(this.node1f );
			
			if (nivel == 0){
				document.write( this.separador.replace("&treewidth;", this.largura) );
				this.altura += 1;
			}			

			if (hcn) {
				this.addNode(nodeValues[0], recursedNodes);
			}
			
			recursedNodes.pop();
		}
	}
};

eowTree.prototype.updateOpenCloseStatus = function(){
	//this.debugOpenNodes();
	this.nodesHeight = new Array(this.nodes.length);
	var altura = 0;
	
	for (var i=0; i<this.nodes.length; i++) {
		this.nodesHeight[i] = altura;
		
		var nodeValues = this.nodes[i].split("|");
		var theRow = this.findObj("row" + nodeValues[0] + this.obj);
		var theIcon = this.findObj("img" + nodeValues[0] + this.obj);
		
		if ( this.hasChildNode(nodeValues[0]) ){ // Se tiver filhos mostra o icon +
			if ( this.isOpen( nodeValues[0] ) )
				theIcon.src = this.icons[1].src;
			else
				theIcon.src = this.icons[0].src;
		}
		
		this.showMessage( nodeValues[0] + ":  isOpen(" + nodeValues[1] + ")=" + this.isOpen( nodeValues[1] ) + "    isFatherOpen(" + nodeValues[1] + ")" )
		
		if ( this.isOpen( nodeValues[1] ) && this.isFatherOpen( nodeValues[1] ) ){ // Se o pai está aberto mostra
			theRow.style.display = '';
			altura += 18;
		} else {
			theRow.style.display = 'none';
		}
	}
	
	this.showHideArrows();
}

// Esta função coloca todos os pais deste nó abertos (de forma a este nó aparecer aberto)
eowTree.prototype.updateOpenNodes = function( node ){
	if(this.debug) this.debugOpenNodes();
	
	var nodeValues = this.nodes[ this.getArrayId( node ) ].split("|");
	if ( (nodeValues[1] != 0) && (nodeValues[1] != null) ){ // Abre o pai
		this.setOpen( nodeValues[1] );
		this.updateOpenNodes( nodeValues[1] );
	}
};

// Coloca todos os nós fechados (apaga o vector de openNodes)
eowTree.prototype.clearOpenNodes = function ( openNode ){
	var i;
	for(i=0;i<this.openNodes.length;i++){
		this.openNodes[i] = null;
	}
	this.setOpen( 0 );
}

// Abre ou fecha um nó
eowTree.prototype.oc = function(node) {
	//alert( "oc(" + node + ")");
	if ( this.isOpen( node ) )
		this.setClose( node );
	else
		this.setOpen( node, true );
	
	//setArray( "openNodes", openNodes );
	this.updateOpenCloseStatus();
	
	//alert( "this.nodesHeight[ this.getArrayId( "+node+" )="+this.getArrayId( node )+" ]="+this.nodesHeight[ this.getArrayId( node ) ] );
	if(this.findObj(this.obj+'_divMenu'))
	    this.findObj(this.obj+'_divMenu').scrollTop = this.nodesHeight[ this.getArrayId( node ) ]-50;
};

eowTree.prototype.setOpen = function( node, closeAll ){
	this.showMessage("open(" + node + ", " + closeAll + ")");
	if (! this.isOpen(node) ){
		if( this.keepOnlyOneLevelOpen && closeAll){
			//Vamos agora fechar todos os outros items do mesmo nível
			//Vamos ser agressivos e fechamos todos os outros nós, excepto este
			this.clearOpenNodes();
			this.openNodes.push( node );
			this.updateOpenNodes( node );
		}	else {
			this.openNodes.push( node );
		}
	}
};

eowTree.prototype.setClose = function( node ){
	for (i=0;i<this.openNodes.length;i++){
		if ( this.openNodes[i] == node){
			this.openNodes[i] = null;
		}
	}
};

eowTree.prototype.isOpen = function( node ){
	//alert( "isOpen("+node+") openNodes.length=" + openNodes.length );
	for (i=0;i<this.openNodes.length;i++){
		//alert( "openNodes["+i+"]=" + openNodes[i] + " == " + node + "?" );
		if ( this.openNodes[i] == node)
			return true;
	}
	return false
};

eowTree.prototype.isFatherOpen = function( node ){
	var father = this.getFatherNode( node );
	
	this.showMessage("node=" + node + "  father=" + father + "  isOpen=" + this.isOpen( father ) )
	
	if ( father > 0 ){
		if ( this.isOpen( father ) ){
			// Esta aberto, mas vamos ver se os pais dele tb estão abertos
			return this.isFatherOpen( father );
		} else { // O pai está fechado
			return false;
		}
	} else { // Se não tem pai então está aberto
		return true;
	}

};

// Retorna a posição do nó no vesctor
eowTree.prototype.getArrayId = function(node) {
	var result = 0;
	for (i=0; i<this.nodes.length; i++) {
		var nodeValues = this.nodes[i].split("|");
		if (nodeValues[0]==node) result = i;
	}
	return result;
};

// Verifica se um nó tem filhos
eowTree.prototype.hasChildNode = function(parentNode) {
	for (i=0; i< this.nodes.length; i++) {
		var nodeValues = this.nodes[i].split("|");
		if (nodeValues[1] == parentNode) return true;
	}
	return false;
};

// Retorna o pai do nó (se não existir retorna 0)
eowTree.prototype.getFatherNode = function( node ) {
	var nodeId = this.getArrayId( node );
	var nodeValues = this.nodes[ nodeId ].split("|");
	return nodeValues[1];
};

//Retorna um vector com todos os filhos do nó
eowTree.prototype.getChilds = function(parentNode, recursivo) {
	//alert( "getChilds("+parentNode+")" );
	var result = new Array();
	if ( this.hasChildNode(parentNode) ){
		for (i=0; i< this.nodes.length; i++) {
			var nodeValues = this.nodes[i].split("|");
			if (nodeValues[1] == parentNode){
				if ( this.hasChildNode( nodeValues[0] ) && (nodeValues[0] != parentNode) ){
					var i, childs = this.getChilds( nodeValues[0], true );
					for (k=0;k<childs.length;k++){
						result.push( childs[k] );
					}
				}
				result.push(nodeValues[0]);	
			}
		}
	}
	
	var k, tmp = "";
	for (k=0;k<result.length;k++){
		tmp+="  result("+k+")="+result[k];
	}
	//alert( tmp );
	return result;
};

eowTree.prototype.findObj = function (theObj, theDoc){
  var p, i, foundObj;
  if(!theDoc) theDoc = document;
  if( (p = theObj.indexOf("?")) > 0 && parent.frames.length)
  {
    theDoc = parent.frames[theObj.substring(p+1)].document;
    theObj = theObj.substring(0,p);
  }
  if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj];
  for (i=0; !foundObj && i < theDoc.forms.length; i++) 
    foundObj = theDoc.forms[i][theObj];
  for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++) 
    foundObj = this.findObj(theObj,theDoc.layers[i].document);
  if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
  return foundObj;
}

eowTree.prototype.init = function(){
  this.showMessage( "initScroll="+initScroll + " menu.scrollHeight="+findObj( this.obj + '_divMenu').scrollHeight )
  findObj( this.obj + '_divMenu').scrollTop = initScroll;
	showHideArrows();
}

eowTree.prototype.showHideArrows = function (){
	try{
		var btUp = this.findObj( this.obj + '_btUp');
		var btDw = this.findObj( this.obj + '_btDw');
		var menu = this.findObj( this.obj + '_divMenu');
		if ( menu.scrollHeight > this.maxHeight ){
			btUp.style.display = "";
			btDw.style.display = "";
		} else {
			btUp.style.display = "none";
			btDw.style.display = "none";
		}
	} catch (e){
		txt="Ocorreu o seguinte erro: " + e.description + "\n\n";
  	//alert(txt)
	}
}

eowTree.prototype.goUp = function (){
	this.findObj( this.obj + '_divMenu').scrollTop += 10;
	this.intervalo = window.setTimeout( this.obj + ".goUp()", 50 );
}
eowTree.prototype.goDw = function ( ){
	this.findObj( this.obj + '_divMenu').scrollTop -= 10;
	this.intervalo = window.setTimeout( this.obj + ".goDw()", 50 );
}

eowTree.prototype.endUpDw = function (){
	window.clearTimeout( this.intervalo );
}

eowTree.prototype.showMessage = function( message ){
	if(this.debug)
		if(!confirm(message))
			this.debug=false;
}

eowTree.prototype.debugOpenNodes = function (){
	alert( "openNodes.length=" + this.openNodes.length );
	for (i=0;i<this.openNodes.length;i++){
		alert( "openNodes[" + i + "] = " + this.openNodes[i] );
	}
}


// Os metodos de Push e Pop não estão implementados no IE. Vamos fazê-lo...
if(!Array.prototype.push) {
	function array_push() {
		for(var i=0;i<arguments.length;i++)
			this[this.length]=arguments[i];
		return this.length;
	}
	Array.prototype.push = array_push;
}
if(!Array.prototype.pop) {
	function array_pop(){
		lastElement = this[this.length-1];
		this.length = Math.max(this.length-1,0);
		return lastElement;
	}
	Array.prototype.pop = array_pop;
}
