function JSDynTable() {
	this.myName = null;
	this.tBodyObj = null;
	this.renderFunc = null;
	this.renderDetailsFunc = null;
	this.rowsArr = null;
	this.pageSize = null;
	this.navObj = null;
	
	this.nacoDeArray = new Array();
	this.numRows = 0;
	this.currPage = 0;
	this.maxPages = 0;
	this.initted = false;
	this.cortaArray = jsdtCortaArray;
	this.MoveFirst = jsdtMoveFirst;
	this.MoveNext = jsdtMoveNext;
	this.MovePrevious = jsdtMovePrevious;
	this.MoveLast = jsdtMoveLast;
	this.MoveTo = jsdtMoveTo;
	this.init = jsdtInit;
	this.updateRows = jsdtUpdateRows;
	this.clearTbody = jsdtClearTBody;
	this.updateNav = jsdtUpdateNav;
	this.rowMensagem = jsdtRowMensagem;
	this.renderNavFunc = jsdtDefaultNav; // customize
	this.renderBC = jsdtDefaultBC; // customize
	this.bcCell = null;
	this.butFirst = null;
	this.butNext = null;
	this.butPrev = null;
	this.butLast = null;
	this.strCasoUm = null;
	this.strCasoVarios = null;
	this.strCasoNenhum = null;
	this.resObj = null;
}

function jsdtCortaArray() {
	prim = (this.currPage-1) * this.pageSize;
	ultimo = prim + this.pageSize;
	this.nacoDeArray = this.rowsArr.slice(prim, ultimo);
}

function jsdtMoveFirst() {
	if (!this.initted) { if (!this.init()) return; }
	this.currPage = 1;
	this.updateRows();
}

function jsdtMoveNext() {
	if (this.currPage + 1 <= this.maxPages) {
		this.currPage++;
		this.updateRows();
	}
}

function jsdtMovePrevious() {
	if (this.currPage - 1 >= 1) {
		this.currPage--;
		this.updateRows();
	}
}

function jsdtMoveLast() {
	this.currPage = this.maxPages;
	this.updateRows();
}

function jsdtMoveTo(num) {
	this.currPage = num;
	this.updateRows();
}

function jsdtUpdateNav() {
	if (this.butFirst) this.butFirst.disabled = (this.currPage==1);
	if (this.butNext) this.butNext.disabled = (this.currPage==this.maxPages);
	if (this.butPrev) this.butPrev.disabled = (this.currPage==1);
	if (this.butLast) this.butLast.disabled = (this.currPage==this.maxPages);
	if (this.renderBC) this.renderBC();
}

function jsdtDefaultNav() {
	s = "";
	if (this.maxPages <= 1) { this.navObj.innerHTML = s; return; }
	s = s + '<table class="navHmmTable" width="100%" cellpadding="0" cellspacing="0" border="0">';
	s = s + '<tr><td align="left" width="1%">';
	s = s + '<input id="'+this.myName+'btFirst" type="Button" value="&lt;&lt;" onclick="'+this.myName+'.MoveFirst();"/>';
	s = s + '</td><td align="left" width="1%">';
	s = s + '<input id="'+this.myName+'btPrev" type="Button" value="&nbsp;&lt;&nbsp;" onclick="'+this.myName+'.MovePrevious();"/>';
	s = s + '</td>';
	s = s + '<td class="texto9" align="center" id="'+this.myName+'bcCell">&nbsp;aaa</td>';
	s = s + '<td align="right" width="1%">';
	s = s + '<input id="'+this.myName+'btNext" type="Button" value="&nbsp;&gt;&nbsp;" onclick="'+this.myName+'.MoveNext();"/>';
	s = s + '</td><td align="right" width="1%">';
	s = s + '<input id="'+this.myName+'btLast" type="Button" value="&gt;&gt;" onclick="'+this.myName+'.MoveLast();"/>';
	s = s + '</td></tr>';
	s = s + '</table>';
	this.navObj.innerHTML = s;
	this.bcCell = document.getElementById(this.myName+'bcCell');
	this.butFirst = document.getElementById(this.myName+'btFirst');
	this.butNext  = document.getElementById(this.myName+'btNext');
	this.butPrev  = document.getElementById(this.myName+'btPrev');
	this.butLast  = document.getElementById(this.myName+'btLast');
}

function jsdtDefaultNavSemBotoes() {
	s = "";
	if (this.maxPages <= 1) { this.navObj.innerHTML = s; return; }
	s = s + '<table class="navHmmTable" width="100%" cellpadding="0" cellspacing="0" border="0">';
	s = s + '<tr>';
	s = s + '<td class="texto9" align="left" id="'+this.myName+'bcCell">&nbsp;aaa</td>';
	s = s + '</tr>';
	s = s + '</table>';
	this.navObj.innerHTML = s;
	this.bcCell = document.getElementById(this.myName+'bcCell');
	this.butFirst = null; this.butNext  = null;  this.butPrev  = null; this.butLast  = null;
}
	
function jsdtDefaultBC() {
	if (!this.bcCell) return;
	eachSide = 4; // this has to be an even number
	s = "";
	if (this.maxPages > (eachSide*2)) {
		antesAtual = this.currPage - (eachSide);
		depoisAtual = this.currPage + (eachSide);
		if (antesAtual < 1) { depoisAtual = depoisAtual + (Math.abs(antesAtual-1)); antesAtual = 1;}
		if (depoisAtual >= this.maxPages) { antesAtual = antesAtual - (depoisAtual - this.maxPages); depoisAtual = this.maxPages;};
		elipD=false; elipA=false; if (antesAtual > 1) {elipA = true;} if (depoisAtual < this.maxPages) {elipD = true;}
		if (elipA) { s = s + "...&nbsp;";} else {s = s + "&nbsp;&nbsp;&nbsp;&nbsp;";}
		for (i = antesAtual; i <= (depoisAtual); i++) {
			jsdtDefaultBCWritePageNum(this.myName, i, this.currPage, this.maxPages);
		}
		if (elipD) { s = s + "&nbsp;...";} else {s = s + "&nbsp;&nbsp;&nbsp;&nbsp;";}
	} else {
		for (i = 1; i <= this.maxPages; i++) {
			jsdtDefaultBCWritePageNum(this.myName, i, this.currPage, this.maxPages);
		}
	}
	this.bcCell.innerHTML = s;
}

function jsdtDefaultBCWritePageNum(nome, pagenum, atual, maxx) {
	mostraNum = i; if ((maxx > 9) & (pagenum < 10)) mostraNum = "0" + mostraNum;
	if (pagenum == atual) {
		s = s + "<b class=\"textobox_on\">&nbsp;" + mostraNum + "&nbsp;</b>&nbsp;";
	} else {
		s = s + '<a class="textobox" style="text-decoration: none;" href="javascript:'+nome+'.MoveTo('+pagenum+')">&nbsp;' + mostraNum + "&nbsp;</a>&nbsp;";
	}
}


function jsdtInit() {
	this.numRows = this.rowsArr.length;
	
	if (this.pageSize>0) {
		this.maxPages = Math.ceil(this.numRows / this.pageSize);
	} else {
		this.maxPages = 1;
		this.pageSize = this.numRows;
	}
	this.currPage = 1;
	this.renderNavFunc();
	if (this.resObj) {
		if (this.numRows < 1) {
			//this.resObj.innerHTML = this.strCasoNenhum;
			this.rowMensagem(this.strCasoNenhum);
			return false;
		} else if (this.numRows == 1) {
			this.resObj.innerHTML = this.strCasoUm;
		} else {
			variosStr = this.strCasoVarios.replace("%c", this.numRows);
			if (this.maxPages > 1) {variosStr = variosStr + "&nbsp;("+this.maxPages+" páginas)";}
			this.resObj.innerHTML = variosStr;
		}
	}
	this.initted = true;
	return true;
}

function jsdtClearTBody() {
	for (i = this.tBodyObj.rows.length-1; i >= 0 ; i--) {this.tBodyObj.deleteRow(i);}
}

function jsdtUpdateRows() {
	this.cortaArray();
	this.updateNav();
	this.clearTbody();
	for (i = 0; i < this.nacoDeArray.length; i++) {
		umrow = this.tBodyObj.insertRow(this.tBodyObj.rows.length);
		this.renderFunc(i, umrow, this.nacoDeArray[i]);
		if (this.renderDetailsFunc) {
			detailrow = this.tBodyObj.insertRow(this.tBodyObj.rows.length);
			this.renderDetailsFunc(i, detailrow, this.nacoDeArray[i]);
		}
	}
	window.scrollTo(0,0);
}

function jsdtRowMensagem(msg) {
	this.clearTbody();
	umrow = this.tBodyObj.insertRow(this.tBodyObj.rows.length);
	celMsg = umrow.insertCell(0);
	celMsg.colSpan = 50; celMsg.align = "center";
	celMsg.innerHTML = msg;
}

var jsdtfirMaxRecs = null;
var jsdtFirID = null;
var jsdtInterv = null;
function jsdtDefaultFirula(tipo, val) {
	doPercent = true; msg = "";
	if (tipo == 5) {
		// Inicializa a firula.
		s = '';
		s = s + '<table cellpadding="0" cellspacing="0" border="0"><tr><td width="50px"></td><td>';
		s = s + '<table width="300px" cellpadding="0" cellspacing="0" style="border: 1px solid gray;">';
		s = s + '<tr>';
		s = s + '<td height="15" id="JSDTpercentCounter" width="0%" bgcolor="#789CCE"></td>';
		s = s + '<td width="100%"></td>';
		s = s + '</tr>';
		s = s + '</table>';
		s = s + '</td><td class="texto9">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span id="JSDTfirMsg">Aguarde....</span></td></tr></table>';
		document.getElementById(jsdtFirID).innerHTML = s;
		if (jsdtfirMaxRecs < 1) {
			// nao sabemos o total de registros ainda. faz mais uma firula...
			jsdtDefaultFirula(3, 1);
			jsdtInterv = setInterval('jsdtFirDuringQuery()', 100);
		}
		return;
	} else if (tipo == 3) {
		// Este é chamado pelo timer.
		percent = Math.round(val);
		msg = "Consultando...";
		//doPercent = false;
	} else if (tipo == 4) {
		// Terminamos de fazer a(s) query(ies).
		clearInterval(jsdtInterv);
		msg = "Processando...";
		percent = 33;
	} else if (tipo == 6) {
		// Estamos populando a JSTable; podemos ou nao saber o número total de registros.
		if (jsdtfirMaxRecs>0) {
			percent = 33 + Math.round(val * 100 / jsdtfirMaxRecs /3);
			msg = "Processando... " + val + " de "  +jsdtfirMaxRecs + " registros";
		} else {
			percent = 45;
			msg = "Processando... registro N° " + val + "";
			doPercent = false;
		}
	} else if (tipo == 7) {
		// Terminamos de popular a JSTable! o val diz o número total de registros, just in case.
		percent = 66; jsdtfirMaxRecs = val;	msg = "Recebendo...";
	} else if (tipo == 8) {
		// Estamos mandando dados já. o val é o número do registro mandado.
		percent = 66 + Math.round(val * 100 / jsdtfirMaxRecs /3);
		msg = "Recebendo... " + val + " de " + jsdtfirMaxRecs + " registros";
	} else if (tipo == 9) {
		// Terminou de mandar dados. Vai chamar MoveFirst logo mais.
		percent = 100;
		msg = "Exibindo...";
	}
	if (doPercent) { msg = msg + " ("+percent+"%)";}
	try {document.getElementById('JSDTfirMsg').innerHTML = msg} catch (e) {}
	try {document.getElementById('JSDTpercentCounter').width = percent + "%";} catch (e) {}
}

var jsdtDQcount = 1;
var jsdtDQsubcount = 0;
function jsdtFirDuringQuery() {
	if (jsdtDQcount < 20) {
		jsdtDQcount++;
	} else if (jsdtDQcount < 27) {
		if (jsdtDQsubcount>4) {jsdtDQcount++;jsdtDQsubcount=-1;}jsdtDQsubcount++;
	} else if (jsdtDQcount < 33) {
		if (jsdtDQsubcount>24) {jsdtDQcount++;jsdtDQsubcount=-1;}jsdtDQsubcount++;
	} else {
		clearInterval(jsdtInterv);
	}
	jsdtDefaultFirula(3, jsdtDQcount);
}

function jsdtNewAjaxObject() {
	var A;
	try {
		A=new ActiveXObject('Msxml2.XMLHTTP');
	} catch (e) {
		try {
			A=new ActiveXObject('Microsoft.XMLHTTP');
		} catch (oc) {
			A=null;
		}
	}
	if(!A && typeof XMLHttpRequest != 'undefined') A = new XMLHttpRequest();
	return A;
}		

/* Sorters */

function jsdtSort_NumericSort(a, b, idx) {
    aa = parseFloat(a[idx]);
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(b[idx]); 
    if (isNaN(bb)) bb = 0;
    return aa-bb;
}

function jsdtSort_AlphaSortInsens(a,b, idx) {
    aa = ( (a[idx]) ? a[idx].toLowerCase() : '');
    bb = ( (b[idx]) ? b[idx].toLowerCase() : '');
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

function jsdtSort_DateSortDDMMYYHHMM(a,b, idx) {
    aa = ( (a[idx]) ? a[idx].toLowerCase() : '');
    bb = ( (b[idx]) ? b[idx].toLowerCase() : '');
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}