/**
* Construtor da classe que representa cada item do conteiner
*
* @param id - identificador do elemento
* @param nodePai - Node pai do elemento
* @param strConteudo - Conteudo do elemento
* @param bolAberto - indica se o elemento esta aberto ou fechado
* @param espacamento - espacamento do elemento
* @param espacamentoDefault - espacamento default do node
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node = function(id,nodePai,strConteudo,bolAberto,espacamento,espacamentoDefault)
{
	this.id = id; // id do conteiner
	this.nodePai = nodePai; // referencia ao node pai do elemento
	this.strConteudo = strConteudo;//+ " ("+id+")"; // conteudo do node
	this.bolAberto = bolAberto; // variavel que indica se o node esta aberto ou fechado
	this.espacamentoDefault = espacamentoDefault; // espacamento default
	// verificando se o node é o raiz
	if(this.nodePai==null)
	{
		this.espacamento = 0;
		this.nivel = 0;
	}
	else
	{
		// verificando se o espacanemento foi definido
		if(espacamento < 0)
		{
			this.bolEspacamendoDefinido = false;
			this.espacamento = parseInt(nodePai.getEspacamento())+ parseInt(espacamentoDefault);
			this.nivel = parseInt(nodePai.getNivel())+1;
		}
		else
		{
			this.bolEspacamendoDefinido = true;
			this.espacamento = espacamento;
		}
	}
	// criando lista de itens
	this.listItens = new ListNode();
	// variavel que controla a posicao de navegacao do nodos filhos
	this.posCorrente = 0;
}
/**
* Metodo que verifica se o espacamento foi definido
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getEspacamentoDefinido = function()
{
	return this.bolEspacamendoDefinido;
}

/**
* Metodo para adicionar o nodo na listas de nodos filhos
*
* @param node - elemento adicionado
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.addItem = function(node)
{	
	this.listItens.add(node);		
}

/**
* Metodo para remover o nodo na listas de nodos filhos
*
* @param node - elemento removido
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.removeItem = function(node)
{
	this.listItens.remove(node);	
}


/**
* Metodo para retornar o id do nodo
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getId= function()
{
	return this.id;
}

/**
* Metodo para retornar o node pai
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getNodePai= function()
{
	return this.nodePai;
}

/**
* Metodo para retornar se o nodo esta aberto

* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getAberto= function()
{
	return this.bolAberto;
}

/**
* Metodo para a lista de itens filhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getItensFilhos= function()
{
	return this.listItens;
}

/**
* Metodo para retornar o espacamento do elemento no conteiner
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getEspacamento= function()
{
	return this.espacamento;
}

/**
* Metodo para retornar o nodo filho pelo id
* Caso nao for encontrato é retornado false
*
* @param id - Identificador do elemento buscado
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getNodeFilhoPorId = function(id)
{
	return this.listItens.find(id);
}

/**
* Metodo para retornar conteudo do nodo	
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getConteudo = function()
{
	return this.strConteudo;
}

/**
* Metodo para retornar conteudo do nodo	
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getNivel = function()
{
	return this.nivel;
}

/**
* Metodo para retornar se o nodo esta aberto
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getAberto = function()
{
	return this.bolAberto;
}

/**
* Metodo para verificar se possui filhos
* Poderia ser hasFilhos, na verdade seria hasChildNodes ou então temFilhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.isFilhos = function()
{	
	return (this.listItens.count() > 0)
}

/**
* Metodo para verificar se o node é descendente
*
* @since 27/07/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.isDescendente = function(objNode)
{
	return this.listItens.isDescendente(objNode);
}

/**
* Metodo para atualizar o conteudo do node
*
* @param strConteudo - Conteudo que o node ira receber
* @since 14/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setConteudo = function(strConteudo)
{
	this.strConteudo = strConteudo;
}

/**
* Metodo para atualizar o espacamento
*
* @param espacamento - espacamento do elemento em relacao no conteiner
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setEspacamento = function(espacamento)
{
	this.espacamento = espacamento;
}


/**
* Metodo para atualizar o node pai
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setNodePai = function(objNodoPai)
{
	this.nodePai = objNodoPai;
}

/**
* Metodo para atualizar o nivel
*
* @param nivel - Nivel do elemento no conteiner
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setNivel = function(nivel)
{
	this.nivel = nivel
}

/**
* Metodo para atualizar o id
*
* @param id - Identificador do elemento
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setId = function(id)
{
	this.id = id;
}

/**
* Metodo para atualizar o status do nodo
*
* @param bolAberto - indica se o elemento esta aberto ou fechado
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setAberto= function(bolAberto)
{
	this.bolAberto = bolAberto;
}

/**
* Metodo para incluir o elemento antes ou depois do nodo de referencia
* os nodos restantes sao reajustados
*
* @param node - Node que esta sendo incluido
* @param nodeRef - node que serve como referencia
* @param bolAntes - Indica se o elemento vai ser colocado antes ou depois
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.insert= function(node, nodeRef, bolAntes)
{
	this.listItens.insert(node,nodeRef, bolAntes);
}

/**
* retorna os itens no formato de array
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getArray= function()
{
	return this.listItens.getArray();
}

/**
* retorna o proximo elemento da lista de nodes filhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.proximo= function()
{
	if(this.posCorrente>this.listItens.count())
	{
		return false;	
	}
	if(this.isFilhos())
	{
		var objNode =  this.listItens.getNode(this.posCorrente);
		this.posCorrente++;
		return objNode;
	}
	return false;
}


/**
* retorna o elemento anterior da lista de nodes filhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.anterior= function()
{
	if(this.posCorrente<0)
	{
		return false;	
	}
	if(this.isFilhos())
	{
		var objNode =  this.listItens.getNode(this.posCorrente);
		this.posCorrente--;
		return objNode;
	}
	return false;
}

/**
* retorna o primeiro elemento da lista de nodes filhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.primeiro= function()
{
	this.posCorrente = 0;
	if(this.isFilhos())
	{
		var objNode =  this.listItens.getNode(this.posCorrente);
		return objNode;
	}
	return false;
}
/**
* retorna o ultimo elemento da lista de nodes filhos
*
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.ultimo= function()
{
	this.posCorrente = (this.listItens.count()-1);
	if(this.isFilhos())
	{
		var objNode =  this.listItens.getNode(this.posCorrente);
		return objNode;
	}
	return false;
}
/**
* Metodo para alterar o node por outro
*
* @param objNode1 - Node que esta sendo trocado por 2
* @param objNode2 - Node que esta sendo trocado por 1
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.trocaFilhos= function(objNode1,objNode2)
{
	var intPosicao1 = this.listItens.findPosicao(objNode1.getId());
	var intPosicao2 = this.listItens.findPosicao(objNode2.getId());
	if(intPosicao1 >-1 && intPosicao2>-1)
	{
		this.listItens.setNode(objNode1,intPosicao2);
		this.listItens.setNode(objNode2,intPosicao1);
		return true;
	}
	return false;
}

/**
* Metodo para alterar o node por outro
*
* @param objNodeAntigo - Node que esta alterado por objNodeNovo
* @param objNodeNovo - Node que esta alterando o objNodeAntigo
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.setNode= function(objNodeAntigo,objNodeNovo)
{
	var intPosicao = this.listItens.findPosicao(objNodeAntigo.getId());
	if(intPosicao >-1)
	{
		this.listItens.setNode(objNodeNovo,intPosicao);
		return true;
	}
	return false;
}

/**
* Metodo retornar a posicao de um node
*
* @param objNode - Node que esta sendo buscado
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getPosicao= function(objNode)
{
	var intPosicao = this.listItens.findPosicao(objNode.getId());
	if(intPosicao >-1)
	{
		return intPosicao;
	}
	return false;
}

/**
* Metodo o node pela posicao
*
* @param objNode - Node que esta sendo buscado
* @since 13/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.getNode= function(posicao)
{
	return this.listItens.getNode(posicao);
}

/**
* Metodo para clonar um objeto
*
* @return Objeto clonado
* @since 14/06/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.clone = function()
{
  if(this.bolEspacamendoDefinido)
  {
  	var newObject = new Node(this.id,this.nodePai,this.strConteudo,this.bolAberto,this.espacamento,this.espacamentoDefault);
  }
  else
  {
  	var newObject = new Node(this.id,this.nodePai,this.strConteudo,this.bolAberto,-1,this.espacamentoDefault);
  }
  var objNewNode = this.primeiro();
  while(objNewNode = this.proximo())
  {
  	newObject.addItem(objNewNode.clone());
  }
  return newObject;
}

/**
* Metodo para contar numero de descendentes
*
* @return numero de descendentes
* @since 27/07/2006
* @author Erix Henrique Morato <emorato@unibh.br>
* @access public
*/
Node.prototype.countDescendentes = function()
{
	return this.listItens.countDescendentes();
}
