	//função que redireciona a ordenação dependendo do tipo de grid 
	function sortGrid(doc, obj, id){
		var grid = getGrid(obj);
		var tpGrid = getTipoGrid(grid);
		if(tpGrid == 'List'){
			sortGridList(doc,obj,Number(id));
		} else if(tpGrid == 'Grid'){
			sortGridGrid(doc,obj,Number(id));
		} else if(tpGrid == 'Search'){
			sortGridSearch(doc,obj,Number(id));
		}
	}

	function SG_getInputValue(input, item, tc){
		if(tc != ''){
			tc = input.getAttribute('formatType');
			if(tc == null){
				tc = 'TEXT';
			}
		}
		item.d = item.d + input.value;
		item.t = tc;
		return tc
	}
	
	function SG_getSelectValue(select, item, tc){
		if(tc != ''){
			tc = 'TEXT';
		}
		item.d = item.d + select.value;
		item.t = tc;
		return tc;
	}
	
	function SG_getTextValue(text, item, tc){
		if(tc != ''){
			tc = 'TEXT';
		}
		item.d = item.d + text.nodeValue;
		item.t = tc;
		return tc;
	}
	
	function SG_getSpanText(span, item, tc){
		if(tc != ''){
			tc = 'TEXT';
		}
		var nodes = span.childNodes;
		var length = nodes.length;
		for(var i = 0; i < length; i++){
			if(nodes[i].nodeName == '#text'){
				item.d = item.d + nodes[i].nodeValue;
			}				
		}
		item.t = tc;
		return tc;
	}

	function SG_getComponentId(nomeGrid, nLinha, propertyName){
		nomeGrid = nomeGrid.charAt(0).toLowerCase() + nomeGrid.substr(1);
		return nomeGrid + '[' + nLinha + '].' + propertyName + '_' + nLinha;
	}
	
	function SG_coletaDadoDaColuna(componentes, j, item, tipoColuna, sortedBy, nomeGrid, nLinha){
		if(sortedBy != null){
			if(componentes[j].id == sortedBy || componentes[j].name == sortedBy || 
					componentes[j].id == SG_getComponentId(nomeGrid, nLinha, sortedBy)){
				if(componentes[j].tagName == 'INPUT'){
					return SG_getInputValue(componentes[j], item, tipoColuna);
				}else if(componentes[j].tagName == 'SELECT'){
					return SG_getSelectValue(componentes[j], item, tipoColuna);
				}else if(componentes[j].tagName == 'SPAN'){
					return SG_getSpanText(componentes[j], item, tipoColuna);
				}
			}
		}else{
			if(componentes[j].tagName == 'INPUT'){
				if(componentes[j].getAttribute('type') != 'hidden'){
					return SG_getInputValue(componentes[j], item, tipoColuna);
				}
			}else if(componentes[j].tagName == 'SELECT'){ 
				return SG_getSelectValue(componentes[j], item, tipoColuna);
			}else if(trim(componentes[j].nodeValue)!= '' && componentes[j].nodeName == '#text' ){
				return SG_getTextValue(componentes[j], item, tipoColuna);
			}
		}
		return tipoColuna;
	}

	// first td is number 0
	function SG_getTdNumber(tr, tdNumber){
		trChilds = tr.childNodes;
		var y = 0;
		var length = trChilds.length;
		for(var m = 0; m < length; m++){
			if(trChilds[m].tagName == 'TD'){
				if(y++ == tdNumber){
					return trChilds[m];
				}
			}				
		}
		return null;
	}

	// first td is number 0
	function SG_getChildNodesOfTDNumber(tr, tdNumber){
		var td = SG_getTdNumber(tr, tdNumber);
		if(td != null){
			return td.childNodes;
		}else{
			return null;
		}
	}
	
	function SG_getSortedBy(tr, tdNumber){
		var td = SG_getTdNumber(tr, tdNumber);
		var sortedBy = td.getAttribute('sortedBy');
		if(sortedBy != null && sortedBy == ''){
			return null;
		}else{
			return sortedBy;
		}
	}

	//função de ordenação da grid tipo GRID
	function sortGridGrid(doc, obj, id){
		var grid = getGrid(obj);
		var nomeGrid = getNomeGrid(grid);
		var nuLinhas = getNuLinhas(doc,nomeGrid);
		var itens = new Array();
		var comps = new Array();
		var z = 0;
		var tipoColuna = null;
		var trIdPrefix = 'linha' + nomeGrid + '_';
		// deve somar + 1 ao id porque a htmlgrid:grid possui sempre um <td> inicial (o status)
		var tdNumber = id + 1;
		var sortedBy = SG_getSortedBy(doc.getElementById(trIdPrefix + '-1'), tdNumber);

		//percorre as linhas capturando os componentes da coluna selecionada
		for(var i = 0; i < nuLinhas; i++){
			var tr = doc.getElementById(trIdPrefix + i);
			// deve somar + 1 ao id porque a htmlgrid:grid possui sempre um <td> inicial (o status)
			var componentes = SG_getChildNodesOfTDNumber(tr, tdNumber);
			var item = new ItemCol('',i,'TEXT');
			//pega os inputs, desprezando os hidden
			var componentesLength = componentes.length;
			for(var j = 0; j < componentesLength; j++){
				tipoColuna = SG_coletaDadoDaColuna(componentes, j, item, tipoColuna, sortedBy, nomeGrid, i);
			}
			itens[z] = item;
			z++;
		}
		//da refresh nas outras colunas e pega o sentido da ordenação
		var ordenacao = refreshStatusCols(obj,id);
		//pega a função de ordenação
		var fnSort = getFuncaoSort(ordenacao);		
		//pega a função de formatação dos dados
		var fnConvert = getFuncaoFormatacao(tipoColuna);
		
		if(tipoColuna != null){
			//formata e ordena os dados
			itens = formataOrdenaDados(fnConvert, fnSort, itens);
			
			//troca de posição as linhas da tabela, colocando de forma ordenada
			var itensLength = itens.length;
			for(var i = 0; i < itensLength; i++){
				trocaPosicaoLinhas(nomeGrid, itens[i].s, doc, getTipoGrid(grid));
			}
		}
	}

	//função de ordenação da grid tipo LIST
	function sortGridList(doc, obj, id){
		var grid = getGrid(obj);
		var nomeGrid = getNomeGrid(grid);
		var nuLinhas = getNuLinhas(doc,nomeGrid);
		var itens = new Array();
		var comps = new Array();
		var z = 0;
		var tipoColuna;
		// a htmlgrid:list não possui um <td> inicial adicional, 
		// então a posição do td é igual ao valor do id
		var tdNumber = id;
		var sortedBy = null;
		for(var i = 0; i < nuLinhas; i++){
			var tr = doc.getElementById('linha'+ nomeGrid+'_'+i);
			if(i == 0){
				sortedBy = SG_getSortedBy(tr, tdNumber);
			}
			var componentes = SG_getChildNodesOfTDNumber(tr, tdNumber);
			var item = new ItemCol('',i,'TEXT');
			//pega os inputs, desprezando os hidden
			var componentesLength = componentes.length;
			for(var j = 0; j < componentesLength; j++){
				tipoColuna = SG_coletaDadoDaColuna(componentes, j, item, tipoColuna, sortedBy, nomeGrid, i);
			}
			itens[z] = item;
			z++;
		}
		//da refresh nas outras colunas e pega o sentido da ordenação
		var ordenacao = refreshStatusCols(obj,id);
		//pega a função de ordenação
		var fnSort = getFuncaoSort(ordenacao);		
		//pega a função de formatação dos dados
		var fnConvert = getFuncaoFormatacao(tipoColuna);

		if(tipoColuna != null){
			//formata e ordena os dados
			itens = formataOrdenaDados(fnConvert, fnSort, itens);
			
			//troca de posição as linhas da tabela, colocando de forma ordenada
			var itensLength = itens.length;
			for(var i = itensLength - 1; i >= 0; i--){
				trocaPosicaoLinhas(nomeGrid, itens[i].s, doc, getTipoGrid(grid));
			}
		}
	}
	
	//função de ordenação da grid tipo SEARCH
	function sortGridSearch(doc,obj,id){
		var grid = getGrid(obj);
		var nomeGrid = getNomeGrid(grid);
		var nuLinhas = getNuLinhas(doc,nomeGrid);
		var itens = new Array();
		var comps = new Array();
		var z = 0;
		var tipoColuna;
		var sortedBy = null;
		// deve somar + 1 ao id porque a htmlgrid:search possui sempre um 
		// <td> inicial (o checkbox ou radio de seleção)
		var tdNumber = id + 1;
		for(var i = 0; i < nuLinhas; i++){
			var tr = doc.getElementById('linha_'+i);
			if(i == 0){
				sortedBy = SG_getSortedBy(tr, tdNumber);
			}
			var componentes = SG_getChildNodesOfTDNumber(tr, tdNumber);
			var item = new ItemCol('',i,'TEXT');
			tipoColuna = '';
			var componentesLength = componentes.length;
			for(var j = 0; j < componentesLength; j++){
				if(tipoColuna == ''){
					tipoColuna = componentes[j].parentNode.getAttribute("formatType");
					var checked = tr.getElementsByTagName('INPUT')[0].checked;
					item.t = tipoColuna;
					item.c = checked;
				}
				SG_coletaDadoDaColuna(componentes, j, item, tipoColuna, sortedBy, nomeGrid, i);
			}
			itens[z++] = item;
//			for(var j = 0; j < componentes.length; j++){
//				if(componentes[j].nodeValue != null){
//					if(tipoColuna != ''){
//						tipoColuna = componentes[j].parentNode.getAttribute("formatType");
//					}
//					checked = tr.getElementsByTagName('INPUT')[0].checked;
//					itens[z] = new ItemCol(componentes[j].nodeValue,i,tipoColuna);
//					itens[z].c = checked;
//					z++;
//				}
//			}
		}
		//da refresh nas outras colunas e pega o sentido da ordenação
		var ordenacao = refreshStatusCols(obj,id);
		//pega a função de ordenação
		var fnSort = getFuncaoSort(ordenacao);		
		//pega a função de formatação dos dados
		var fnConvert = getFuncaoFormatacao(tipoColuna);
		if(tipoColuna != null){
			//formata e ordena os dados
			itens = formataOrdenaDados(fnConvert, fnSort, itens);
			
			//troca de posição as linhas da tabela, colocando de forma ordenada
			var itensLength = itens.length;
			for(var i = itensLength - 1; i >= 0; i--){
				trocaPosicaoLinhas(nomeGrid, itens[i].s, doc, getTipoGrid(grid));
				doc.getElementById('linha_'+itens[i].s).getElementsByTagName('INPUT')[0].checked = itens[i].c;
			}
			
			//eh necessário selecionar novamente a linha que estava selecionada
			//antes da ordenação pois o IE não estava guardando este estado...
			idSelected = grid.getAttribute('selected');
			mudarSelecaoRegistroAtual(doc.getElementById(idSelected));
		}
	}
	
	//objeto que encapsula o valor do campo, posição original e tipo de dado
	function ItemCol(dado,seq,tipo){
		this.d = dado;
		this.s = seq;
		this.t = tipo;
	}
	
	//funcao que realiza a troca de posição entre as linhas da table
	function trocaPosicaoLinhas(nomeGrid, nuOrdemTR, doc, tipoGrid){
		nomeLinha = 'linha'+ (tipoGrid != 'Search'? nomeGrid : '') + '_' + nuOrdemTR;
		var objTR = doc.getElementById(nomeLinha);
		var table = objTR;
		while(table.nodeName != 'TABLE'){
			table = table.parentNode;
		}
		arrayTR = table.getElementsByTagName('TR');
		var objRowUltimo;
		
		//se for list ou search, a ordenação é do ultimo para o primeiro
		if(tipoGrid == 'List' || tipoGrid == 'Search'){
			objRowUltimo = arrayTR[0];
		}else if(tipoGrid == 'Grid'){
			objRowUltimo = arrayTR[arrayTR.length - 1];
		}
		table.lastChild.insertBefore(objTR, objRowUltimo);
	}
	
	function getFuncaoFormatacao(tpColuna){
		var fnConvert;
		if(tpColuna == 'DATE'){
			fnConvert = function(a){
				return a.d ? a.d : '00/00/0000';
			};
		}else if(tpColuna == 'NUMBER'){
			fnConvert = function(a){
				return a.d ? parseStrToFloat(a.d) : 0;
			};
		}else{
			fnConvert = function(a){
				return a.d ? a.d.toLowerCase(): '';
			};
		}
		return fnConvert;
	}
	
	function getFuncaoSort(ordem){
		var fnSort;
		if(ordem == 'asc'){
			fnSort = function(a,b) {
				if(a.t == 'DATE'){
					anoA = a.d.substring(6,10);
					anoB = b.d.substring(6,10);
					if(anoA > anoB) return 1;
					if(anoA < anoB) return -1;
					mesA = a.d.substring(3,5);
					mesB = b.d.substring(3,5);
					if(mesA > mesB) return 1;
					if(mesA < mesB) return -1;					
					diaA = a.d.substring(0,2);
					diaB = b.d.substring(0,2);				
					if(diaA > diaB) return 1;
					if(diaA < diaB) return -1;					
					return 0;
				}else{
					if (a.d<b.d) return -1;
					if (a.d>b.d) return 1;
					return 0;				
				}
			};
		} else {
			fnSort = function(a,b) {
				if(a.t == 'DATE'){
					anoA = a.d.substring(6,10);
					anoB = b.d.substring(6,10);
					if(anoA < anoB) return 1;
					if(anoA > anoB) return -1;
					mesA = a.d.substring(3,5);
					mesB = b.d.substring(3,5);
					if(mesA < mesB) return 1;
					if(mesA > mesB) return -1;					
					diaA = a.d.substring(0,2);
					diaB = b.d.substring(0,2);				
					if(diaA < diaB) return 1;
					if(diaA > diaB) return -1;					
					return 0;
				}else{
					if (a.d<b.d) return 1;
					if (a.d>b.d) return -1;
					return 0;				
				}
			};
		}
		return fnSort;
	}
	
	function formataOrdenaDados(funcaoForm, funcaoOrd, dados){
		var dadosLength = dados.length;
		for(var i = 0; i < dadosLength; i++){
			dados[i].d = funcaoForm(dados[i]);
		}				
		dados.sort(funcaoOrd);	
		return dados;
	}
	
	function refreshStatusCols(objClicado, idObjClicado){
		ordenacao = objClicado.getAttribute('ord');
		parNode = objClicado;
		while(parNode.nodeName != 'TR'){
			parNode = parNode.parentNode;
		}
		tds = parNode.getElementsByTagName('TD');
		var tdsLength = tds.length;
		for(var i = 0; i < tdsLength; i++){
			var estilo = tds[i].className;
			if(tds[i].className.indexOf('spwCabecalhoDesc') != -1){ 
				tds[i].className = estilo.substring(0,estilo.indexOf('spwCabecalhoDesc')) + estilo.substring(estilo.indexOf('spwCabecalhoDesc')+16,estilo.length);
			} else if(tds[i].className.indexOf('spwCabecalhoAsc') != -1 ){
				tds[i].className = estilo.substring(0,estilo.indexOf('spwCabecalhoAsc')) + estilo.substring(estilo.indexOf('spwCabecalhoAsc')+16,estilo.length);
			} 			
			tds[i].setAttribute('ord', null);
		}
		if(ordenacao == 'des' || ordenacao == null || ordenacao == ''){
			objClicado.setAttribute('ord', 'asc');
			objClicado.className = objClicado.className.substring(0,(objClicado.className.indexOf(' spwCabecalhoDesc')==-1?objClicado.className.length:objClicado.className.indexOf(' spwCabecalhoDesc'))) + ' spwCabecalhoAsc';
			return 'asc';
		} else {
			objClicado.setAttribute('ord', 'des');
			objClicado.className = objClicado.className.substring(0,(objClicado.className.indexOf(' spwCabecalhoAsc')==-1?objClicado.className.length:objClicado.className.indexOf(' spwCabecalhoAsc'))) + ' spwCabecalhoDesc';
			return 'des';
		}
	}
	
	function SG_sortCheckBoxColumn(checkColumn){
		var form = document.forms[0];
		var nuChecks = form.rowSelect.length;
		var checksMarcados = new Array();
		var count = 0;
		for(var i = 0; i < nuChecks; i++){
			if(form.rowSelect[i].checked == true){
				checksMarcados[count++] = form.rowSelect[i].getAttribute('value');				
			}
		}
		var nuMarcados = checksMarcados.length;
		if(nuMarcados != nuChecks){
			var table = document.getElementById('tabelaResultado');
			var arrayTR = table.getElementsByTagName('TR');
			var objRowUltimo;
			if(checkColumn.getAttribute('order') != 'firstChecked'){
				objRowUltimo = arrayTR[0];
			}else{
				objRowUltimo = arrayTR[arrayTR.length - 1];
			}

			for(var i = nuMarcados-1; i >= 0; i--){
				var nomeLinha = 'linha_' + checksMarcados[i];
				var objTR = document.getElementById(nomeLinha);
				if(checkColumn.getAttribute('order') != 'firstChecked'){
					table.lastChild.insertBefore(objTR, objRowUltimo);
				}else{
					table.lastChild.insertBefore(objTR, objRowUltimo);
					table.lastChild.insertBefore(objRowUltimo,objTR);
				}
				objTR.getElementsByTagName('INPUT')[0].checked = true;				
			}
		}
		if(nuMarcados != 0){	
			if(checkColumn.getAttribute('order') == 'firstChecked'){
				checkColumn.setAttribute('order','firstUnchecked');
			} else {
				checkColumn.setAttribute('order','firstChecked');
			}
		}
	}
