﻿/* **************************************************************
							--XJS--
Desenvolvedora: Rhianna Cantarelli
Versão: 2.0
Data: 17.10.2007
Email: r.rhianna@yahoo.com.br
************************************************************** */







/* **************************************************************
	-- OBJETO XHtmlGet
	
	- É esperado deste objeto que ele identifique dentro do seletor estilo CSS
	quais objetos devem ser retornados permitindo assim que sejam manipulados
	pelos demais métodos.

	- Abaixo Está uma Lista do tipo de Seletores que é Suportado por Esta Versão

		*								[Todos os Elementos]
		tag								[Elementos do Tipo TAG]
		.className						[Elementos com Classe = className]

		#idName							[Elemento com ID = idName]
		#idName.className				[Elemento com ID = idName e Classe = className]

		tag.className					[Elementos TAG com Classe = className]
		tag[att]						[Elementos TAG com Atributo 'att' definido]
		tag[att=value]					[Elementos TAG com Atributo att=value]

		tag/className:first-child		[Primeiro Elemento TAG]
		tag/className:last-child		[Ultimo Elemento TAG]

		ElementoPai>ElementoFilho		[Realiza busca de Todo(s) Elemento(s) Filho(s) Diretos do(s) Elemento(s) Pai(s)]


	- Não Há Suporte Para as Seguintes Seletores:

		Elem_1 ' + ' Elem_2				[Elemento 2 Irmão do Mesmo Pai de Elemento 1 e Escrito Imediatamente na Sequencia]




	Abaixo da Relação de Todas as Possibilidades de Retorno do Método
	this.ruleType(). A partir do Type Encontrado Executa Método Equivalente para
	Resgatar o Node Requerido

	- Métodos de ID			:		id - idWithClass | idWithAttribute
	- Métodos TAG			:		tag - tagWithClass | tagWithAttribute | tagFirstChild | tagLastChild
	- Métodos ClassName		:		class - classWithClass | classWithAttribute	
************************************************************** */
function XHtmlGet() {

	// Objeto(s) Selecionados
	this.Node = null; 

	/* ----------  ----------  ----------
		Método Público para Carregar Node(s) a Partir de Seletores CSS
	----------  ----------  ---------- */	
	this.get = function(cssSeletor) {
		// Separa o Parametro Passado em Quantos Seletores Houverem
		var arrSelectors = cssSeletor.split(',');

		// Para Cada Conjunto de Seletores passados...
		for(i=0; i<arrSelectors.length; i++) { 
			
			var nodeAtual = null;
			// Resgata Array de Seletores
			var arrRules = setSeletores(arrSelectors[i]);

			// Para Cada Regra do Seletor Atual Faz Get do(s) respectivo(s) Node(s)
			for(j=0; j<arrRules.length; j++) { 
				var strAtualRule = arrRules[j];
				var onlyDirectChild = false;
				var directFirstlastChild = false;
				var parentNodes = null;
				var typeRule = null;

				// Em caso de Seletor '>' Prepara Variaveis
				if(strAtualRule.indexOf('>') != -1) { 
					onlyDirectChild = true; 
					parentNodes = nodeAtual;
					strAtualRule = strAtualRule.substring(1, strAtualRule.length);
					if(strAtualRule.indexOf(':') != -1) { directFirstlastChild = true; }
				}

				// Retorna First/Last Childs Filhos Diretos do Node Pai
				if(directFirstlastChild == true) { nodeAtual = getDirectFirstLastChildsOd(nodeAtual, parentNodes, strAtualRule); }
				else {
					// Retorna Nodes em casos mais Simples
					typeRule = ruleType(strAtualRule);
					nodeAtual = executeRule(nodeAtual, typeRule, strAtualRule); 
					
					// Em caso de Request de Filhos Diretos, executa tal seleção
					if(onlyDirectChild == true) { nodeAtual = getDirectChildsOf(parentNodes, nodeAtual); }
				}
				
				// Após cada Get, Verifica se Há Possibilidade de Prosseguir Busca
				if(nodeAtual == null) { this.Node = null; break; }
				else if(nodeAtual[0] == undefined && nodeAtual.innerHTML == undefined) { this.Node = null; break; }
				else { this.Node = nodeAtual; }
			}

			return this.Node;
		}
	};



	// Retorna Array de Seletores corrijindo Sintaxe no caso de uso do seletor '>'
	var setSeletores = function(strSeletors) {
		seletores = strSeletors.split(' ');
		var nSeletores = new Array();
		cSelect = 0;
		for(r=0; r<seletores.length; r++) {
			if(seletores[r].indexOf('>') != -1) { 
				splita = seletores[r].split('>');
				for(s=0; s<splita.length; s++) {
					finalSelect = '';
					if(s>0) { finalSelect = '>'; } finalSelect += splita[s] + '';
					nSeletores[cSelect] = finalSelect;
					cSelect++;
				}
			}
			else { nSeletores[cSelect] = seletores[r]; cSelect++; }
		}
		return nSeletores;
		
	};


	// Retorna somente filhos diretos dos Nodes Pais
	var getDirectChildsOf = function(parentNodes, childNodes) {
		selectedNodes = new Array();

		// Seleciona apenas os Filhos Diretos
		if(parentNodes != null && childNodes != null) {
			pNodes = new Array();
			cNodes = new Array();

			if(parentNodes.length == undefined) { pNodes[0] = parentNodes; }
			else { pNodes = parentNodes; }
			if(childNodes.length == undefined) { cNodes[0] = childNodes; }
			else { cNodes = childNodes; }

			count = 0;
			for(r=0; r<pNodes.length; r++) {
				for(s=0; s<cNodes.length; s++) {
					if(pNodes[r] == cNodes[s].parentNode) { selectedNodes[count] = cNodes[s]; count++; }
				}						
			}
		}
		return selectedNodes;
	};



	var getDirectFirstLastChildsOd = function(nodeAtual, parentNodes, strAtualRule) {
		indexDot = strAtualRule.indexOf(':');
		strTempRule = strAtualRule.substring(0, indexDot);
		typeRule = ruleType(strTempRule);
		nodeAtual = executeRule(nodeAtual, typeRule, strTempRule); 
		nodeAtual = getDirectChildsOf(parentNodes, nodeAtual);

		typeRule = ruleType(strAtualRule);
		newNode = nodeAtual;
		if(newNode != null) {
			if(typeRule.indexOf('LastChild') != -1) { 
				if(nodeAtual.length != undefined) {	newNode = nodeAtual[nodeAtual.length-1]; }
			}
			if(typeRule.indexOf('FirstChild') != -1) { 
				if(nodeAtual.length != undefined) {	newNode = nodeAtual[0]; }
			}
		}
		return newNode;
	};




	/* ----------  ----------  ----------
		Retorna que tipo de Regra foi passada
	----------  ----------  ---------- */	
	var ruleType = function(strRule) {
		// Toda Busca é Originalmente uma Busca por Tag exceto se Encontrar Algum Seletor Abaixo
		strType = 'tag';
		tTypes = 0;
		strChar = strRule.substring(0, 1);

		switch (strChar) {
			case '*': strType = 'tag'; break;
			case '.': strType = 'class'; break;
			case '#': strType = 'id'; break;
		}

		strType += ruleTypeCompost(strRule);

		return strType;
	};



	/* ----------  ----------  ----------
		Em caso de Regra Composta, Adiciona Identificador
	----------  ----------  ---------- */	
	var ruleTypeCompost = function(strRule) {
		strType = '';
		var strTemp = strRule.substring(1, strRule.length);

		if(strRule.indexOf('.') != -1) { 
			cDot = strRule.split('.');
			if(strRule.indexOf('.') > 0) { strType = 'WithClass'; }
			if(cDot.length >= 3) { strType = 'WithClass'; }
		}
		if(strRule.indexOf('[') != -1) { strType = 'WithAttribute'; }
		if(strRule.indexOf(':') != -1) { 
			if(strRule.indexOf('first-child') != -1) { strType = 'FirstChild'; }
			if(strRule.indexOf('last-child') != -1) { strType = 'LastChild'; }
		}

		return strType;
	};



	/* ----------  ----------  ----------
		Responsável por Verificar qual Tipo de Get é Adequado para A Regra Atual
	----------  ----------  ---------- */	
	var executeRule = function(node, typeRule, strSearch) {
		var selectNode = null;

		switch (typeRule) {
			// Procura por ID
			case 'id': selectNode = getID(node, strSearch); break;
			case 'idWithClass': selectNode = getIdWithClass(node, strSearch); break;
			case 'idWithAttribute': selectNode = getIdWithAttribute(node, strSearch); break;

			// Procura por TAG
			case 'tag': selectNode = getTag(node, strSearch); break;
			case 'tagWithClass': selectNode = getTagWithClass(node, strSearch); break;
			case 'tagWithAttribute': selectNode = getTagsWithAttribute(node, strSearch); break;
			case 'tagFirstChild': selectNode = getTagFirstChild(node, strSearch); break;
			case 'tagLastChild': selectNode = getTagLastChild(node, strSearch); break;

			// Procura por Classes
			case 'class': selectNode = getClassName(node, strSearch); break;
			case 'classWithClass': selectNode = getClassWithClass(node, strSearch); break;
			case 'classWithAttribute': selectNode = getClassWithAttribute(node, strSearch); break;
		}
		
		return selectNode;
	};



	/* ----------  ----------  ----------
		MÉTODOS PARA RESGATE DE NODE A PARTIR DE SUA ID
		- getID();
		- getIdWithClass();
		- getIdWithAttribute();
	----------  ----------  ---------- */	
	var getID = function(node, idName) { 
		nodeReturn = null;
		idName = idName.substring(1, idName.length);

		if(node == null) { nodeReturn = document.getElementById(idName); }
		else {
			arrNodes = null;
			if(node.length == undefined) { 
				arrNodes = node.getElementsByTagName('*'); 
				for(r=0; r<arrNodes.length; r++) {
					if(arrNodes[r].id == idName) { nodeReturn = arrNodes[r]; break; }
			} }
			else {
				for(r=0; r<node.length; r++) {
					arrNodes = node[r].getElementsByTagName('*'); 
					
					for(s=0; s<arrNodes.length; s++) {
						if(arrNodes[s].id == idName) { nodeReturn = arrNodes[s]; break; }
			} }
		} }
		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Resgata Node Com Determinados ID e Classe
	----------  ----------  ---------- */
	var getIdWithClass = function(node, strRule) {
		nodeReturn = null;
		indexDot = strRule.indexOf('.');
		
		strID = strRule.substring(1, indexDot);
		strClass = strRule.substring(indexDot + 1, strRule.length);
		
		// Procura Em Todo Documento
		if(node == null) {
			nodeTemp = document.getElementById(strID);
			if(nodeTemp != null) { 
				if(nodeTemp.className.indexOf(strClass) != -1) { nodeReturn = nodeTemp; } 
		} }
		else {
			arrNodes = null;
			if(node.length == undefined) { 
				arrNodes = node.getElementsByTagName('*'); 
				for(r=0; r<arrNodes.length; r++) {
					if(arrNodes[r].id == strID && arrNodes[r].className.indexOf(strClass) != -1) { nodeReturn = arrNodes[r]; break; }
			} }
			else {
				for(r=0; r<node.length; r++) {
					arrNodes = node[r].getElementsByTagName('*'); 
					for(s=0; s<arrNodes.length; s++) {
						if(arrNodes[s].id == strID && arrNodes[r].className.indexOf(strClass) != -1) { nodeReturn = arrNodes[s]; break; }
			} }
		} }
		
		
		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Resgata Node Com Determinado ID e Atributo
	----------  ----------  ---------- */
	var getIdWithAttribute = function(node, strRule) {
		nodeReturn = null;
		indexIniAtt = strRule.indexOf('[');
		indexEndAtt = strRule.indexOf(']');
		
		strID = strRule.substring(1, indexIniAtt);
		strAtt = strRule.substring(indexIniAtt + 1, indexEndAtt);
		arrAttrib = strAtt.split('=');

		if(node == null) {
			nodeTemp = document.getElementById(strID);
			if(nodeTemp != null) {
				attValue = eval('nodeTemp.' + arrAttrib[0]);
				if(attValue == arrAttrib[1]) { nodeReturn = nodeTemp; }
		} }
		else {
			arrNodes = null;
			if(node.length == undefined) { 
				arrNodes = node.getElementsByTagName('*'); 
				for(r=0; r<arrNodes.length; r++) {
					if(arrNodes[r].id == strID) {
						attValue = eval('arrNodes[r].' + arrAttrib[0]);
						if(attValue == arrAttrib[1]) { nodeReturn = arrNodes[r]; break; }
					}					
			} }
			else {
				for(r=0; r<node.length; r++) {
					arrNodes = node[r].getElementsByTagName('*'); 
					for(s=0; s<arrNodes.length; s++) {
						if(arrNodes[s].id == strID) { 
							attValue = eval('arrNodes[s].' + arrAttrib[0]);
							if(attValue == arrAttrib[1]) { nodeReturn = arrNodes[s]; break; }
			} }	} 
		} }
		
		return nodeReturn;
	};



	/* ----------  ----------  ----------
		MÉTODOS PARA RESGATE DE NODE A PARTIR DO NOME DA TAG
		- getTag();
		- getTagWithClass();
		- getTagsWithAttribute();
		- getTagFirstChild();
		- getTagLastChild();
	----------  ----------  ---------- */	
	var getTag = function(node, tagName) {
		nodeReturn = null;

		if(node == null) { nodeReturn = document.getElementsByTagName(tagName); }
		else { 
			arrNodes = null;
			if(node.length == undefined) { nodeReturn = node.getElementsByTagName(tagName); }
			else { 
				nodeReturn = new Array();
				cNodes = 0;
				for(r=0; r<node.length; r++) {
					arrTempNodes = node[r].getElementsByTagName(tagName);
					for(s=0; s<arrTempNodes.length; s++) { 
						nodeReturn[cNodes] = arrTempNodes[s]; cNodes++; 
			} } 
		} }

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona todos os Nodes de Determinada Tag e Classe
	----------  ----------  ---------- */
	var getTagWithClass = function(node, strRule) {
		nodeReturn = null;
		indexDot = strRule.indexOf('.');

		strTAG = strRule.substring(0, indexDot);
		strClass = strRule.substring(indexDot + 1, strRule.length);

		if(node == null) {
			nodeReturn = new Array();
			nodeTemp = document.getElementsByTagName(strTAG);
			for(r=0,s=0; r<nodeTemp.length; r++) {
				if(nodeTemp[r].className.indexOf(strClass) != -1) { nodeReturn[s] = nodeTemp[r]; s++; }
		} }
		else {
			nodeReturn = new Array();
			if(node.length == undefined) {
				nodeTemp = node.getElementsByTagName(strTAG);
				for(r=0,s=0; r<nodeTemp.length; r++) {
					if(nodeTemp[r].className.indexOf(strClass) != -1) { nodeReturn[s] = nodeTemp[r]; s++; }
			} }
			else {
				for(r=0,s=0; r<node.length; r++) {
					nodeTemp = node[r].getElementsByTagName(strTAG);
					for(t=0;t<nodeTemp.length; t++) {
						if(nodeTemp[t].className.indexOf(strClass) != -1) { nodeReturn[s] = nodeTemp[t]; s++; }
			} }				
		} }

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona todos os Nodes de Determinada Tag e Atributo
	----------  ----------  ---------- */
	var getTagsWithAttribute = function(node, strRule) {
		nodeReturn = null;
		indexIniAtt = strRule.indexOf('[');
		indexEndAtt = strRule.indexOf(']');

		strTAG = strRule.substring(0, indexIniAtt);
		strAtt = strRule.substring(indexIniAtt + 1, indexEndAtt);
		arrAttrib = strAtt.split('=');

		if(node == null) {
			nodeReturn = new Array();
			nodeTemp = document.getElementsByTagName(strTAG);
			for(r=0,s=0; r<nodeTemp.length; r++) {
				attValue = eval('nodeTemp[r].' + arrAttrib[0]);
				if(attValue == arrAttrib[1]) { nodeReturn[s] = nodeTemp[r]; s++; }
		} }
		else {
			nodeReturn = new Array();
			if(node.length == undefined) {
				nodeTemp = node.getElementsByTagName(strTAG); 
				for(r=0, s=0; r<nodeTemp.length; r++) {
					attValue = eval('nodeTemp[r].' + arrAttrib[0]);
					if(attValue == arrAttrib[1]) { nodeReturn[s] = nodeTemp[r]; s++; }
			} }
			else { 
				for(r=0, s=0; r<node.length; r++) {
					nodeTemp = node[r].getElementsByTagName(strTAG);
					for(t=0; t<nodeTemp.length; t++) {
						attValue = eval('nodeTemp[t].' + arrAttrib[0]);
						if(attValue == arrAttrib[1]) { nodeReturn[s] = nodeTemp[t]; s++; }
			} }
		} }

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona a Primeira Tag Filha do(s) Node(s) Selecionados
	----------  ----------  ---------- */
	var getTagFirstChild = function(node, strRule) {
		nodeReturn = null;
		indexDots = strRule.indexOf(':');

		strTAG = strRule.substring(0, indexDots);

		if(node == null) { nodeReturn = document.getElementsByTagName(strTAG)[0]; }
		else {
			if(node.length == undefined) { nodeReturn = node.getElementsByTagName(strTAG)[0]; }
			else {
				nodeReturn = new Array();
				for(r=0, s=0; r<node.length; r++) {
					nodeTemp = node[r].getElementsByTagName(strTAG)[0];
					if(nodeTemp != null) { nodeReturn[s] = nodeTemp; s++; }
		} }	}

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona a Última Tag Filha do(s) Node(s) Selecionados
	----------  ----------  ---------- */
	var getTagLastChild = function(node, strRule) {
		nodeReturn = null;
		indexDots = strRule.indexOf(':');

		strTAG = strRule.substring(0, indexDots);

		if(node == null) { 
			nodeReturn = document.getElementsByTagName(strTAG); 
			nodeReturn = nodeReturn[nodeReturn.length-1];
		}
		else {
			if(node.length == undefined) { 
				nodeReturn = node.getElementsByTagName(strTAG); 
				nodeReturn = nodeReturn[nodeReturn.length-1];
			}
			else {
				nodeReturn = new Array();
				for(r=0, s=0; r<node.length; r++) {
					nodeTemp = node[r].getElementsByTagName(strTAG);
					nodeTemp = nodeTemp[nodeTemp.length-1];
					if(nodeTemp != null) { nodeReturn[s] = nodeTemp; s++; }
		} }	}

		return nodeReturn;
	};



	/* ----------  ----------  ----------
		MÉTODOS PARA RESGATE DE NODE A PARTIR DO NOME DA CLASSE
		- getClassName();
		- getClassWithClass();
		- getClassWithAttribute();
	----------  ----------  ---------- */	
	var getClassName = function(node, cssName) {
		nodeReturn = null;
		tempElem = null;
		cssName = cssName.substring(1, cssName.length);

		
		if(node == null) { tempElem = document.getElementsByTagName('*'); }
		else {
			// Verifica se é um array de Nodes
			if(node.length == undefined) { tempElem = node.getElementsByTagName('*'); }
			else {
				nodeReturn = new Array();
				for(r=0,t=0; r<node.length; r++) {
					tempElem = node[r].getElementsByTagName('*');
					for(s=0; s<tempElem.length; s++) {
						atualClass = ' ' + tempElem[s].className + ' ';
						if(atualClass.indexOf('' + cssName + '') != -1) { nodeReturn[t] = tempElem[s]; t++; }
		} } } }


		// Se Ainda não houve Captura dos Nodes Buscados, Busca Agora
		if(nodeReturn == null) {
			nodeReturn = new Array();
			for (r=0,s=0; r<tempElem.length; r++) {
				atualClass = ' ' + tempElem[r].className + ' ';
				if (atualClass.indexOf(cssName) != -1) { nodeReturn[s] = tempElem[r]; s++; }
		} }

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona Nodes com Duas Classes Definidas
	----------  ----------  ---------- */
	var getClassWithClass = function(node, strRule) {
		nodeReturn = null;
		strRuleNoDot = strRule.substring(1, strRule.length);
		indexDot = strRuleNoDot.indexOf('.');

		strClassP = strRule.substring(0, indexDot + 1);
		strClassF = strRule.substring(indexDot + 2, strRule.length);

		// Resgata Todo Node dentro da Atual Seleção que Contenha a Classe Primaria
		nodeClassP = getClassName(node, strClassP);

		nodeReturn = new Array();
		for(r=0, s=0; r<nodeClassP.length; r++) {
			allClassname = nodeClassP[r].className;
			if(allClassname.indexOf(strClassF) != -1) { nodeReturn[s] = nodeClassP[r]; s++; }
		}

		return nodeReturn;
	};

	/* ----------  ----------  ----------
		Seleciona Nodes com Determinadas Classe e Atributo
	----------  ----------  ---------- */
	var getClassWithAttribute = function(node, strRule) {
		nodeReturn = null;
		indexIniAtt = strRule.indexOf('[');
		indexEndAtt = strRule.indexOf(']');

		strClass = strRule.substring(0, indexIniAtt);
		strAtt = strRule.substring(indexIniAtt + 1, indexEndAtt);
		arrAttrib = strAtt.split('=');

		// Resgata Todo Node dentro da Atual Seleção que Contenha a Classe Primaria
		nodeClass = getClassName(node, strClass);

		nodeReturn = new Array();
		for(r=0, s=0; r<nodeClass.length; r++) {
			attValue = eval('nodeClass[r].' + arrAttrib[0]);
			if(attValue == arrAttrib[1]) { nodeReturn[s] = nodeClass[r]; s++; }
		}

		return nodeReturn;
	};










	/* ------------------------------------------------------------------------
				MÉTODOS DE ALTERAÇÃO DE ESTADO, ATRIBUTOS OU CLASSES
	 ------------------------------------------------------------------------ */






	/* ----------  ----------  ----------
		Seta Atributo Nos Objetos. 
		- Não funciona em Nodes de Table no IE.
	----------  ----------  ---------- */
	this.setAttribute = function(attrib, value) {
		if(this.Node != null) {
			if(this.Node.length == undefined) {	this.Node.setAttribute(attrib, value); }
			else { for(i=0; i<this.Node.length; i++) { this.Node[i].setAttribute(attrib, value); } } }
	};

	/* ----------  ----------  ----------
		Seta a Classe dos Nodes
	----------  ----------  ---------- */
	this.setClass = function(cssClass) {
		if(this.Node != null) {	if(this.Node.length == undefined) {	this.Node.className = cssClass;	}
		else { for(i=0; i<this.Node.length; i++) { this.Node[i].className = cssClass; } } }
	};

	/* ----------  ----------  ----------
		Adiciona um Evento aos Nodes.
		- "evType" não pode ter o prefixo 'on';
		- "evName" precisa ser definido no JS previamente e apenas seu nome deve ser passado
	----------  ----------  ---------- */
	this.setEvent = function(evType, evName){
		if(this.Node != null) {
			if(this.Node.length == undefined) { 
				if (document.attachEvent) {	this.Node.attachEvent('on'+ evType, eval(evName)); }
				else { nameEv = evName + '(this)'; this.Node.setAttribute('on'+ evType, nameEv); }
			} 
			else {
				for(i=0; i<this.Node.length; i++) {
					if (document.attachEvent) {	this.Node[i].attachEvent('on'+ evType, eval(evName)); }
					else { nameEv = evName + '(this)'; this.Node[i].setAttribute('on'+ evType, nameEv); }
			} } 
		}
	};

	/* ----------  ----------  ----------
		Altera ou Seta Propriedade CSS nos Nodes
	----------  ----------  ---------- */
	this.setCss = function(attrib, value) {
		if(this.Node != null) {
			if(this.Node.length == undefined) {	exec = 'this.Node.style.' + attrib + '="' + value + '";'; eval(exec); }
			else { for(i=0; i<this.Node.length; i++) { exec = 'this.Node[i].style.' + attrib + '="' + value + '";'; eval(exec); } }
	} };










	/* ------------------------------------------------------------------------
				MÉTODOS DE ATALHO À ALTERAÇÕES COMUNS ROTINEIRAMENTE
	 ------------------------------------------------------------------------ */




	/* ----------  ----------  ----------
		DIMENSÕES
	----------  ----------  ---------- */
	this.Dimension = function(w, h) { this.setCss('width', w + 'px'); this.setCss('height', h + 'px'); };
	this.Position = function(posType, top, right, bottom, left) { 
		if(posType != null) { this.setCss('position', posType); }
		if(top != null) { this.setCss('top', top + 'px'); }
		if(right != null) { this.setCss('right', right + 'px'); }
		if(bottom != null) { this.setCss('bottom', bottom + 'px'); }
		if(left != null) { this.setCss('left', left + 'px'); }
	};

	/* ----------  ----------  ----------
		DISPLAY
	----------  ----------  ---------- */
	this.DisplayBlock = function() { this.setCss('display', 'block'); };
	this.DisplayNone = function() { this.setCss('display', 'none'); };

	/* ----------  ----------  ----------
		VISIBILITY
	----------  ----------  ---------- */
	this.VisibilityVisible = function() { this.setCss('visibility', 'visible'); };
	this.VisibilityHidden = function() { this.setCss('visibility', 'hidden'); };

	/* ----------  ----------  ----------
		ZINDEX
	----------  ----------  ---------- */
	this.setZIndex = function(value) { this.setCss('zIndex', value); };
};










/* ----------  ----------  ----------
	OBJETOS DE EFEITOS ESPECIAIS
----------  ----------  ---------- */


/* ----------  ----------  ----------
	Efeito FADE In/Out
	objFade = new fadeEffect(nodeFade, timeFade, arg3, arg4);
	nodeFade    : Node Afetado pelo Fade
	timeFade    : Tempo em que o Efeito deve durar (cada 0.1 = 1 segundo)
	arg3        : [opcional] indica o Alpha Minimo (evitando que o node suma);
	arg4        : [opcional] indica o Alpha Maximo (deixando-o translucido);
----------  ----------  ---------- */
function fadeEffect(nodeFade, timeFade) {
    var node = nodeFade;
    var time = timeFade;
    var alpha = 0;



    var alphaLimitMin = 0;
    if(arguments.length >= 3) { alphaLimitMin = arguments[2]; }
    var alphaLimitMax = 100;
    if(arguments.length >= 4) { alphaLimitMax = arguments[3]; }



    // FadeIn [ Faz Node Surgir ]
    this.fadeIn = function() {
        alpha = alphaLimitMin;
        timer = (time*1000)/50;
        execOpenThis = setInterval(refreshFadeIn, timer);
    };
    var refreshFadeIn = function() { 
        if (alpha >= alphaLimitMax) { clearInterval(execOpenThis); }
        setAlpha();
        alpha += 2;
    };



    // FadeIn [ Faz Node Sumir ]
    this.fadeOut = function() {
        alpha = alphaLimitMax;
        timer = (time*1000)/50;
        execCloseThis = setInterval(refreshFadeOut, timer);
    };
    var refreshFadeOut = function() {
        if (alpha <= alphaLimitMin) { clearInterval(execCloseThis); }
        setAlpha();
        alpha -= 2;
    };



    // Faz Set de Propriedade Alpha
    var setAlpha = function() {
        node.style.filter = "alpha(opacity="+ alpha +")";
        node.style.opacity = alpha/100;
    };
};






/* ----------  ----------  ----------
	Efeito OPEN/CLOSE NODe
    objOpenClose = new openCloseEffect();
    
    - Primeiro é necessário Dizer quais Nodes são 'Botoes' e qual o Nome da Instancia
            objOpenClose.setButtons(xGet.get('#divTeste a'), 'objOpenClose');
    
    - Após é necessário enviar quais Nodes[em numero igual de Buttons] devem ser Alvo do Efeito
            objOpenClose.setTargets(xGet.get('#divTeste div'));
    
    - Pode-se dizer o quão rapido o movimento deve ser
            objOpenClose.setPixPMove(10);
----------  ----------  ---------- */
function openCloseEffect() {
    var buttons = null;
    var targets = null;
    var timeRef = 40;
    var pixPMov = 10;

    // Seta Atributo Identificador nos Buttons
    this.setButtons = function(arrButtons, objName) { 
        buttons = arrButtons; 
        for(i=0; i<buttons.length; i++) { buttons[i].setAttribute('name', i); }
        xGet.Node = buttons;
        xGet.setEvent('click', objName + '.openCloseNode');
    };
    // Armazena Array de Nodes Alvos
    this.setTargets = function(arrTargets) { targets = arrTargets; };
    // Seta Quantos Pixels Abrirá ou Fechará a cada Refresh
    this.setPixPMove = function(n) { pixPMov = n; };



    // Métodos de Ação
    var nodeAtual = null;
    var hAtual = null;
    var hMax = null;
    var isMoveOn = null;

    this.openCloseNode = function(obj) {
        if(document.attachEvent) { var obj = (obj.srcElement) ? obj.srcElement : obj.target; }
        if(isMoveOn == null) {
            index = obj.name;
            display = obj.style.display;
            
            nodeAtual = targets[index];
            hMax = getHMax(nodeAtual);

            isMoveOn = true;
            if(hMax == 0) { openNode(index); }
            else { closeNode(index); }
        }
    };

    // Método OPEN NODE
    var openNode = function(index) {
        hAtual = 1;
        nodeAtual.style.display = 'block';
        hMax = getHMax(nodeAtual);
        nodeAtual.style.height = hAtual + 'px';
        execThis = setInterval(refreshOpenNode, timeRef);
    };
    var refreshOpenNode = function() { 
        if (hAtual >= hMax) { isMoveOn = null; clearInterval(execThis); }
        nodeAtual.style.height = hAtual + 'px';
        hAtual += pixPMov;
    };

    // Método CLOSE NODE
    var closeNode = function(index) {
        hAtual = hMax;
        execThis = setInterval(refreshCloseNode, timeRef);
    };
    var refreshCloseNode = function() { 
        if (hAtual <= 0) { 
            isMoveOn = null; 
            nodeAtual.style.height = '';
            nodeAtual.style.display = 'none'; 
            clearInterval(execThis); 
        }
        nodeAtual.style.height = hAtual + 'px';
        hAtual -= pixPMov;
    };


    // Verifica a Altura Máxima do Node
    var getHMax = function(node) {
        h = node.clientHeight;
        return h;
    };
};
