/* Inicio de variables globales */
	//Separador de miles
	var separator = ",";
	//Separador de decimales
	var decimalSeparator = ".";
	//Selda actualmente seleccionada.
	var currentCell = null;

	// Stores the last used object during sort
	var objLastClick = -1;

	// Stores the text being edited
	//var txtOld = "";

	// Stores the flag used by capturemouse
	var blnMouseOver = false;	

	// Stores the div being moved
	var objDivToMove = null;

	// Stores the number of coloumns; initialized in init ()
	var intColCount = 0;

	// Stores the row table currently selected
	var objRowSelected = null;

	//THE table which holds the table... 
	var table = null;
	var tHead = null;
	var tBody = null;
	var tFoot = null;

	//Número de columnas
	var numCols = 0;

	//Indica si el navegador es internet Explorer.
	isIE = (navigator.appVersion.indexOf ("MSIE") != -1);
	isNS4 = (document.layers) ? true : false;
	isNS6 = (!document.layers) && (navigator.userAgent.indexOf ('Netscape')!=-1) && (navigator.userAgent.indexOf ('Mozilla')!=-1);
/* Fin de variables globales */

function handleError (err, url, line) {
	alert ('Error text: ' + err + '\n' +
		   'Location  : ' + url + '\n' +
		   'Line no   : ' + line + '\n');
	 return true; // let the browser handle the error */
}

/*\
|*| The entry point. This will 
|*|		Attache all the appropriate functions to the table
|*|		Call function to create the IMG elems used during the sorting
|*|		call function to init the DIV elems that are used for moving
\*/
function init (tableName, tHeadName, tBodyName,  tFootName, _numCols) {
	//Handle all javascript errors
	window.onerror = handleError;

	if ((isNS4) && (!isNS6)) alert ("Currently only supports NN 6 and above");
	
	numCols = _numCols;
	
	if ((isNS4) && (!isNS6)) alert ("Currently only supports NN 6 and above");

	if (document.getElementById)
		table = document.getElementById (tableName);
	else	//TODO: Need to test this piece of code still. Happens only in NN4 so far 
		eval (table = "document." + tableName);

	if (table == null)
		return alert ("Error: Not able to get table element ");

	if (table.tagName != 'TABLE')
		return alert ("Error: Not able to control element " + table.tagName);

	tHead = document.getElementById(tHeadName);
	tBody = document.getElementById(tBodyName);
	tFoot = document.getElementById(tFootName);

	if(!isIE) {
		initNNFunctions ();
	}
	//document.attachEvent ('onkeydown' , captureDelKey);

	table.focus ();
	initDiv ();
}

/*\
|*| This function removes the textnodes from the table rows.
|*| This cleanup work is needed to get rid of the EXTRA textnodes that NN gives
\*/

function removeTextNodes (t) {
	for (var i = 0; t.childNodes[i] ; i++) {
		if (!t.childNodes[i].tagName) {
			 t.childNodes[i].parentNode.removeChild (t.childNodes[i]);
		}
		else {
			for (var j = 0; t.childNodes[i].childNodes[j] ; j++) {
				if (!t.childNodes[i].childNodes[j].tagName)
					t.childNodes[i].childNodes[j].parentNode.removeChild (t.childNodes[i].childNodes[j]);
			}
		}
	}
}

/*\
|*| This will only be called once during initIALIZATION
|*| This will create the DIV elems at the end of each col and
|*| attach all the functions needed to resize the coloumns
\*/
function initDiv () {
	var objLast = table, objDiv;
	removeTextNodes (table.tBodies[0]);

	for (var i = 1; i <= intColCount; i++) {	
		objDiv = document.createElement ("DIV");
		objDiv.setAttribute ('id', "DragMark" + (i - 1));
		objDiv.setAttribute ('name',  i);		//Used to track the TDs that have to be moved
		objDiv.style.position = "absolute";
		objDiv.style.top = 0; 

		var objTD = table.tHead.childNodes[0].childNodes[i - 1];
		if (!objTD || objTD.tagName != "TD") return;

		objDiv.style.width = 6 + parseInt(table.border);
		objDiv.style.height = (table.tBodies[0].childNodes.length + 1) * objTD.offsetHeight;
		
		//To make it more beautiful in IE 6	
		if (isIE)
			objDiv.style.cursor = "col-resize";
		else
			objDiv.style.cursor = "crosshair";

		objDiv.attachEvent ('onmouseover', flagTrue);
		objDiv.attachEvent ('onmousedown', captureMouse);
		objDiv.attachEvent ('onmouseup', releaseMouse);
		objDiv.attachEvent ('onmouseout', flagFalse);

		objLast.insertAdjacentElement ("afterEnd", objDiv);
		objLast = objDiv;
	}
}

/*\
|*| This function will be fired onmouseover of the DIVs
|*| Set the flag to true indicating that the mouse is over the DIV
\*/
function flagTrue () {
	blnMouseOver = true;
}

/*\
|*| This function will be fired onmousedown on the DIVs
|*| Capture all the mosue events if mousedown is fired inside the DIV
\*/
function captureMouse () {
	if (blnMouseOver) {
		objDivToMove = window.event.srcElement;
		objDivToMove.setCapture ();
	}
}

/*\
|*| This function will be fired onmouseup
|*| Release all the mouse events of the DIV
\*/
function releaseMouse () {
	objDivToMove.releaseCapture ();
	objDivToMove = null;
}

/*\
|*| This function will be fired onmouseout of the DIV
|*| Set the flag indicating that the mouse is NOT over the DIV
\*/
function flagFalse () {
	blnMouseOver = false;
}

/* Función activa el evento de selección de celdas. */
function selectRow () {
	var srcElem = getEventRow ();
	table.focus ();
}

/* Función que captura la tecla de borrado. */
function captureDelKey () {
	var keyPressed = event.keyCode;
	
	var srcElem = window.event.srcElement;
	if ((keyPressed == 46) && (srcElem.tagName != "INPUT") && (objRowSelected)) {
		deleteRow (objRowSelected.rowIndex - 1);
		objRowSelected = null;
	}
}

/* Adiciona una fila en blanco al final de la tabla. */
function addLastRow ()	{
	createNewRow();
}

/* Retorna un elemento con los datos de la fila. */
function createNewRow() {
	var objTR = document.createElement ("TR");
	var objTD = document.createElement ("TD");

	for (var i = 0; i < numCols; i++) {
		objTD = document.createElement ("TD");
		objTD.appendChild (document.createTextNode(""));
		objTR.insertAdjacentElement ("beforeEnd", objTD);
	}
	tBody.insertAdjacentElement ("beforeEnd", objTR);
}

function createInput() { 
	var objInput = document.createElement ("INPUT");
	objInput.style.border = 0;
	objInput.type = "text";
	objInput.value = " ";
	return objInput;
}

/* Borra todos los datos de la tabla. */
function deleteAll () {
	while(this.deleteLastRow()){ }
}

/* Borra última la fila. */
function deleteLastRow () {
	if(table.tBodies[0].childNodes.length <= 0){
		return false;
	}
	this.removeTextNodes (table.tBodies[0]);
	this.deleteRow (table.tBodies[0].childNodes.length - 1);
	return true;
}

/* Borra la fila número rowNum. */
function deleteRow (rowNum)	{
	if (!tBody || rowNum < 0) return;

	removeTextNodes (tBody);
	tBody.childNodes[rowNum].removeNode (true);
}

/* Obtiene la fila donde sucede el evento. */
function getEventRow () {
	var srcElem = window.event.srcElement;
	while (srcElem.tagName != "TR" && srcElem.tagName != "TABLE") {
		srcElem = srcElem.parentNode;
	}
	return srcElem;
}

/* Obtiene la celda donde sucede el evento. */
function getEventCell () {
	var srcElem = window.event.srcElement;
	while (srcElem.tagName != "TD" && srcElem.tagName != "TABLE") {
		srcElem = srcElem.parentNode;
	}
	return srcElem;
}

function cleanCell(cell) {
	for (var i = 0; i < cell.childNodes.length ; i++) {
		cell.removeChild(cell.childNodes[i]);
	}
}

function validateNumber() {
	var srcKeyCode = eval(event.keyCode);
	if ( !((srcKeyCode >= 48 && srcKeyCode <= 57) || (srcKeyCode >= 96 && srcKeyCode <= 105)) ) {
		var srcElement = event.srcElement;
		srcElement.value = srcElement.value.substring(0, srcElement.value.length-1);
	}
}

function initNNFunctions () {
	if ((self.Node) && (self.Node.prototype)) {
		Node.prototype.removeNode = NNRemoveNode;

		Element.prototype.insertAdjacentText = NNInsertAdjacentText;
		Element.prototype.insertAdjacentElement = NNInsertAdjacentElement;
		Element.prototype.insert__Adj = NNInsertAdj;
		Element.prototype.attachEvent = NNAttachEvent;
		Element.prototype.detachEvent = NNDetachEvent;
		Element.prototype.setCapture = NNSetCapture;
		Element.prototype.releaseCapture = NNReleaseCapture;
		Element.prototype.__defineGetter__('document', NNDocumentGetter);

		HTMLElement.prototype.focus = NNNullFunction;
		HTMLElement.prototype.attachEvent = NNAttachEvent;
		HTMLElement.prototype.detachEvent = NNDetachEvent;
		HTMLElement.prototype.__defineGetter__('innerText', NNInnerTextGetter);
		HTMLElement.prototype.__defineSetter__('innerText', NNInnerTextSetter);

		HTMLDocument.prototype.attachEvent = NNAttachEvent;
		HTMLDocument.prototype.detachEvent = NNDetachEvent;

		Event.prototype.__defineGetter__('keyCode', NNKeyCodeGetter);
	}
}

function NNRemoveNode (a1) {
	var p = this.parentNode;
	if (p&&!a1) {
		var df = document.createDocumentFragment ();
		for (var a = 0; a < this.childNodes.length; a++) {
			df.appendChild (this.childNodes[a])
		}
		p.insertBefore (df , this)
	}
	return p?p.removeChild (this):this;
}

function NNInsertAdjacentText (a1 , a2) {
	var t = document.createTextNode (a2||"")
	this.insert__Adj (a1 , t);
}

function NNInsertAdjacentElement (a1 , a2) {
	this.insert__Adj (a1 , a2);
	return a2;
}

function NNInsertAdj (a1 , a2) {
	var p = this.parentNode;
	var s = a1.toLowerCase ();
	if (s == "beforebegin"){p.insertBefore (a2 , this)}
	if (s == "afterend"){p.insertBefore (a2 , this.nextSibling)}
	if (s == "afterbegin"){this.insertBefore (a2 , this.childNodes[0])}
	if (s == "beforeend"){this.appendChild (a2)}
}

/* Simula la adición de eventos para Netscape */
function NNAttachEvent (strEvent, funcHandle) {
	var shortTypeName = strEvent.replace (/on/, "");
	funcHandle._ieEmuEventHandler = function (e) {
		window.event = e;
		window.event.srcElement = e.target;
		return funcHandle ();
	};
	this.addEventListener (shortTypeName, funcHandle._ieEmuEventHandler, false);
}

/* Simula la adición de eventos para Netscape */
function NNAttachEvent (strEvent, funcHandle, element) {
	var shortTypeName = strEvent.replace (/on/, "");
	funcHandle._ieEmuEventHandler = function (e) {
		window.event = e;
		window.event.srcElement = e.target;
		return funcHandle (element);
	};
	this.addEventListener (shortTypeName, funcHandle._ieEmuEventHandler, false);
}

/* Simula la obtención de tecla para Netscape */
function NNDetachEvent (strEvent, funcHandle) {
	var shortTypeName = strEvent.replace (/on/, "");
	if (typeof funcHandle._ieEmuEventHandler == "function")
		this.removeEventListener (shortTypeName, funcHandle._ieEmuEventHandler, false);
	else 
		this.removeEventListener (shortTypeName, funcHandle, true);
}

/* Simula el evento de capturar para Netscape */
function NNSetCapture () {
	document.attachEvent ('onmouseup', releaseMouse);
}

/* Simula el evento release para Netscape */
function NNReleaseCapture () {
	document.detachEvent ('onmouseup', releaseMouse);
}

/* Simula null para Netscape */
function NNNullFunction () { /*Nothing here*/ }

/* Simula la obtención de innerHTML para Netscape */
function NNInnerTextGetter () {
	return this.innerHTML.replace (/<[^>]+>/g,"");
}

/* Simula la inclusión de InnerHTML para Netscape */
function NNInnerTextSetter (txtStr) {
	var parsedText = document.createTextNode (txtStr);
	this.innerHTML = "";
	this.appendChild (parsedText);
}

/* Simula la obtención de tecla para Netscape */
function NNKeyCodeGetter () {
	return this.which;
}

/* Simula la obtención de documento para Netscape */
function NNDocumentGetter () {
	return this.ownerDocument;
}

/* Realiza el formato de un número con una cantidad de posiciones decimales deseadas. */
function formatNumber(number, decimalPositions) {
	if( isNaN(parseFloat(number)) ){
		return 0;
	}
	var newInteger = "";
	number = number + "";
	if(number.search(separator) != -1){ return; }
	var integer = Math.round(parseInt(number)) + "";
	var decimal = number - integer;
	decimalMultiplicator = Math.pow(10, decimalPositions);
	
	decimal = (Math.round(decimal * decimalMultiplicator) / decimalMultiplicator) + "";

	//Poner los separadores.
	for(var i=0; i<integer.length; i++) {
		newInteger += integer.charAt(integer.length-i-1);
		if( (i+1) % 3 == 0 && i != (integer.length-1) ){
			newInteger += separator;
		}
	}
	
	newInteger = reverseString(newInteger);
	if(decimal == 0){
		return newInteger;
	}
	return newInteger.concat(decimalSeparator + decimal.substring(2, decimal.length));
}

/* Limpia el formato de número realizado. */
function clearNumberFormat(number) {
	if( isNaN(parseFloat(number)) ){
		return 0;
	}
	while(number.search(",") != -1){
		number = number.replace(/,/, "");
	}
	return parseFloat(number);
}


function reverseString(string){
	var reverseStr = "";
	for(var i=0; i<string.length; i++) {
		reverseStr += string.charAt(string.length-i-1);
	}
	return reverseStr;
}

function round(number, decimals){
	var mult = Math.pow(10, decimals);
	return Math.round(number * mult) / mult;
}
