/*----------------------------------------------------------------------------\
|                                Table Sort                                   |
|-----------------------------------------------------------------------------|
|                         Created by Erik Arvidsson                           |
|                  (http://webfx.eae.net/contact.html#erik)                   |
|                      For WebFX (http://webfx.eae.net/)                      |
|-----------------------------------------------------------------------------|
| A DOM 1 based script that allows an ordinary HTML table to be sortable.     |
|-----------------------------------------------------------------------------|
|                  Copyright (c) 1998 - 2002 Erik Arvidsson                   |
|-----------------------------------------------------------------------------|
| This software is provided "as is", without warranty of any kind, express or |
| implied, including  but not limited  to the warranties of  merchantability, |
| fitness for a particular purpose and noninfringement. In no event shall the |
| authors or  copyright  holders be  liable for any claim,  damages or  other |
| liability, whether  in an  action of  contract, tort  or otherwise, arising |
| from,  out of  or in  connection with  the software or  the  use  or  other |
| dealings in the software.                                                   |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| This  software is  available under the  three different licenses  mentioned |
| below.  To use this software you must chose, and qualify, for one of those. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
| Permits  anyone the right to use the  software in a  non-commercial context |
| free of charge.                                                             |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Commercial license           http://webfx.eae.net/commercial.html |
| Permits the  license holder the right to use  the software in a  commercial |
| context. Such license must be specifically obtained, however it's valid for |
| any number of  implementations of the licensed software.                    |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
| Permits anyone the right to use and modify the software without limitations |
| as long as proper  credits are given  and the original  and modified source |
| code are included. Requires  that the final product, software derivate from |
| the original  source or any  software  utilizing a GPL  component, such  as |
| this, is also licensed under the GPL license.                               |
|-----------------------------------------------------------------------------|
| 1998-??-?? | First version                                                  |
|-----------------------------------------------------------------------------|
| Created 1998-??-?? | All changes are in the log above. | Updated 2001-??-?? |
\----------------------------------------------------------------------------*/


var dom = (document.getElementsByTagName) ? true : false;
var ie5 = (document.getElementsByTagName && document.all) ? true : false;
var arrowUp, arrowDown;

if (ie5 || dom)
	initSortTable();

function initSortTable() {
	arrowUp = document.createElement("SPAN");
	var tn = document.createTextNode("");
	arrowUp.appendChild(tn);

	arrowDown = document.createElement("SPAN");
	var tn = document.createTextNode("");
	arrowDown.appendChild(tn);
}



function sortTable(tableNode, nCol, bDesc, sType) {
	var tBody = tableNode.tBodies[0];
	var trs = tBody.rows;
	var trl= trs.length;
	var a = new Array();
	
	for (var i = 0; i < trl; i++) {
		a[i] = trs[i];
	}
	
	var start = new Date;
	window.status = "Classificando...";
	a.sort(compareByColumn(nCol,bDesc,sType));
	window.status = "Classificação de dados concluida";
	
	for (var i = 0; i < trl; i++) {
		tBody.appendChild(a[i]);
		window.status = "Atualizando linha  " + (i + 1) + " de " + trl +
						" (Tempo Estimado: " + (new Date - start) + "ms)";
	}
	
	// check for onsort
	if (typeof tableNode.onsort == "string")
		tableNode.onsort = new Function("", tableNode.onsort);
	if (typeof tableNode.onsort == "function")
		tableNode.onsort();
}

function CaseInsensitiveString(s) {
	return String(s).toUpperCase();
}

function nao_ordenar(s) {
	return 1;
}

i = 0;
function Hora(s) {	
	v_dias = 0;
	v_horas = 0;

	if (s.indexOf('/') != -1) {
	   v_dias = s.substr(0,2)*86400;
	   v_horas = s.substr(s.indexOf('/')+1,2)*3600
	}
	else {
	   v_dias = 0;
	   v_horas = s.substr(0,s.indexOf(':'))*3600	
	}
	
	if (s.length < 3) 
	   valor = -1;
	else   
	   valor =  v_dias + v_horas + s.substr(s.indexOf(':')+2)*60;
	return Number(valor);
}

function KM(s) {
	valor = s.split('(M)');

	valor[0] = valor[0].replace('.','');
	
	if (isNaN(Number(valor[0]))) {
		valor[0] = -30000;
	}
	return Number(valor[0]);
}


function parseDate( s )
	{ 
		Date.prototype.fromString = function( str )
	  {
		 var pt = str.split( String.fromCharCode( 32 ) );
		 var dt = pt[0].split( "/" );
		 
			 this.setFullYear( dt[ 2 ] , dt[ 1 ] - 1 , dt[ 0 ] );
			 
		 return( this );
		 
	  }
		
	  return Number(String(s).getDateTime());
			
	}



/* alternative to number function
 * This one is slower but can handle non numerical characters in
 * the string allow strings like the follow (as well as a lot more)
 * to be used:
 *    "1,000,000"
 *    "1 000 000"
 *    "100cm"
 */

function toNumber(s) {
	s = s.replace('R$', '');
	if (s.indexOf(',') != -1 && s.indexOf('.') != -1) {
		s = s.replace('.', '');
	}
	s = s.replace(',','.');
	if (s.indexOf(':') == -1) 
		return Number(s.replace(/[^:0-9,-\.]/g, ""));
	else 
		return Number(parseInt(s.slice(0,s.indexOf(':'))) + parseInt(s.substr(s.indexOf(':')))) ;	
		
}

function compareByColumn(nCol, bDescending, sType) {
	var c = nCol;
	var d = bDescending;
	var fTypeCast = String;
	sType = sType.toUpperCase();
	if (sType == "NUMBER")
		fTypeCast = toNumber;
	else if (sType == "KM")
		fTypeCast = KM;
	else if (sType == "DATE")
		fTypeCast = parseDate;
	else if (sType == "CASEINSENSITIVESTRING")
		fTypeCast = CaseInsensitiveString;
	else if (sType == "HORA") 
		fTypeCast = Hora;
	else if (sType == "NAO_ORDENAR") 
		fTypeCast = nao_ordenar;

	return function (n1, n2) {
		if (fTypeCast(getInnerText(n1.cells[c])) < fTypeCast(getInnerText(n2.cells[c])))
			return d ? -1 : +1;
		if (fTypeCast(getInnerText(n1.cells[c])) > fTypeCast(getInnerText(n2.cells[c])))
			return d ? +1 : -1;
		return 0;
	};
}

function sortColumnWithHold(e) {
	// find table element
	var el = ie5 ? e.srcElement : e.target;
	var table = getParent(el, "TABLE");
	
	// backup old cursor and onclick
	var oldCursor = table.style.cursor;
	var oldClick = table.onclick;
	
	// change cursor and onclick	
	table.style.cursor = "Aguarde um segundo..";
	table.onclick = null;
	
	// the event object is destroyed after this thread but we only need
	// the srcElement and/or the target
	var fakeEvent = {srcElement : e.srcElement, target : e.target};
	
	// call sortColumn in a new thread to allow the ui thread to be updated
	// with the cursor/onclick
	window.setTimeout(function () {
		sortColumn(fakeEvent);
		// once done resore cursor and onclick
		table.style.cursor = oldCursor;
		table.onclick = oldClick;
	}, 100);
}

var el_anterior = null;

function sortColumn(e) {
	var tmp = e.target ? e.target : e.srcElement;
	var tHeadParent = getParent(tmp, "THEAD");
	var el = getParent(tmp, "TD");
  
	if (el_anterior == null) 
	   el_anterior = el;
	else {
	   el_anterior.className = "";		
       el_anterior = el;
	}
		
	if (tHeadParent == null)
		return;
		
	if (el != null) {
		var p = el.parentNode;
		var i;

		// typecast to Boolean
		el._descending = !Boolean(el._descending);
		
		if (el.type != "nao_ordenar") {
			if (tHeadParent.arrow != null) {
				if (tHeadParent.arrow.parentNode != el) {
					tHeadParent.arrow.parentNode._descending = null;	//reset sort order		
				}
				tHeadParent.arrow.parentNode.removeChild(tHeadParent.arrow);			
			}
	
			if (el._descending) {
				tHeadParent.arrow = arrowUp.cloneNode(true);
				el.className = "arrowUp";
			}
			else {
				tHeadParent.arrow = arrowDown.cloneNode(true);
				el.className = "arrowDown";
			}
	
			el.appendChild(tHeadParent.arrow);
	
				
	
			// get the index of the td
			var cells = p.cells;
			var l = cells.length;
			for (i = 0; i < l; i++) {
				if (cells[i] == el) break;
			}
	
			var table = getParent(el, "TABLE");
			// can't fail
			
			sortTable(table,i,el._descending, el.getAttribute("type"));
		}
	}
}


function getInnerText(el) {
	if (ie5) return el.innerText;	//Not needed but it is faster
	
	var str = "";
	
	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
		
	}
	
	return str;
}

function getParent(el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
		return el;
	else
		return getParent(el.parentNode, pTagName);
}
