var XMLHTTPRequestForTable;
// a pointer to the table that trigerred the last XML/HTTP request.
var triggeringTable;

function XMLTable(tableID, oddRowStyle, evenRowStyle,arrowSelectedCol,arrowSelectedType,requestUrl)
{
	this.tableData = new Array();
	this.currentRow	= 0;
	this.tableID = tableID;
	this.nbRows = document.getElementById(this.tableID).rows.length - 1;
	this.isFullyLoaded = false;
	this.oddRowStyle = oddRowStyle;
	this.evenRowStyle = evenRowStyle;
	// number of the column where the arrow is activated
	this.arrowSelectedCol = arrowSelectedCol;
	// 1 for UpArrow, 2 for DownArrow
	this.arrowSelectedType = arrowSelectedType;
	// URL to ask when calling the XML/HTTP request
	this.requestUrl = requestUrl;
	// XML/HTTP Request
	//this.req = null;
}

XMLTable.prototype.displayRow = function(row)
{
	for (j=0; j < Math.min(this.tableData.length-row, this.nbRows); j++)
	{
		for (i=0; i<this.tableData[j].length; i++)
		{
			document.getElementById(this.tableID).rows[j+1].cells[i].innerHTML = this.tableData[j+row][i];
		}
	}
}

/**
	Add rows from the XML object passed in argument.
	The view of the table is not refreshed.
*/
XMLTable.prototype.addRowsFromXML = function(xmlObject)
{
	// First let's check if this is the last XML we will ever receive (end of the resulset).
	var mainNode = xmlObject.getElementsByTagName("data");
	var isEnd = mainNode[0].getAttribute("isEnd");
	
	if (isEnd == "true")
	{
		this.isFullyLoaded = true;
	}

	// Now, let's have a look at the columns.
	var myRows = xmlObject.getElementsByTagName('row');
	var lastNbRow = this.tableData.length;
	for (j=0;j<myRows.length;j++)
	{
		//alert("initTableFromXMLStringCoucou0");
		var myCols = myRows[j].getElementsByTagName('col');
		//alert("initTableFromXMLStringCoucou1");
		for (i=0;i<myCols.length;i++)
		{
			//alert("initTableFromXMLStringCoucouLaBoucleDebut"+i);
			/*if (this.tableData[50] == null)
				this.tableData[50] = new Array(0);
			this.tableData[50][60] = "toto";
			alert("initTableFromXMLStringCoucouLaBoucleTest"+i);*/
			if (this.tableData[j+lastNbRow] == null)
				this.tableData[j+lastNbRow] = new Array(0);
			this.tableData[j+lastNbRow][i] = myCols[i].firstChild.nodeValue;
			//alert("this.tableData["+j+"+"+lastNbRow+"]["+i+"] = "+this.tableData[j+lastNbRow][i]);
		}
	}
	//alert("initTableFromXMLStringEnd");
}


XMLTable.prototype.initTableFromXMLString = function(xmlString)
{
	var myXMLObject;

	// safari hack
	if (typeof window.DOMParser == "undefined" && navigator.appName != "Microsoft Internet Explorer")
	{
		if (this.requestUrl.indexOf("?") == -1)
			this.loadXMLDoc(this.requestUrl+"?row=0&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
		else
			this.loadXMLDoc(this.requestUrl+"&row=0&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
	}
	else if (document.implementation.createDocument)
	{
		// Mozilla, create a new DOMParser
		var parser = new DOMParser();
		myXMLObject = parser.parseFromString(xmlString, "text/xml");
	}
	else if (window.ActiveXObject)
	{
		// IE, create a new XML document using ActiveX
		// and use loadXML as a DOM parser.
		myXMLObject = new ActiveXObject("Microsoft.XMLDOM")
		myXMLObject.async="false";
		myXMLObject.loadXML(xmlString);      
	}
	else
	{
  		alert("Cannot display data using this browser");
  		return;
 	}

	this.addRowsFromXML(myXMLObject);
	// remove rows if there are too many....
	
	
	this.displayRow(0);
	
	this.initRemoveRows();
	
	//alert("initTableFromXMLStringEnd");
}

/**
	Returns true of the table is fully loaded and we can't go down anymore.
*/
XMLTable.prototype.initRemoveRows = function()
{
	if (this.isFullyLoaded && this.nbRows > this.tableData.length)
	{
		var i;
		for (i=this.tableData.length; i<this.nbRows; i++)
		{
			var myTable = document.getElementById(this.tableID);
			myTable.deleteRow(this.tableData.length+1);
		}
	}
}

/**
	Returns true of the table is fully loaded and we can't go down anymore.
*/
XMLTable.prototype.isGlobalBottom = function()
{
	if (this.isFullyLoaded && this.nbRows + this.currentRow >= this.tableData.length)
		return true;
	else
		return false;
}

/**
	Returns true of the table is at the top
*/
XMLTable.prototype.isGlobalTop = function()
{
	if (this.currentRow == 0)
		return true;
	else
		return false;
}

/**
	Returns true of the table is not fully loaded BUT we have to request more data from the server to go down again.
*/
XMLTable.prototype.isTempBottom = function()
{
	if (!this.isFullyLoaded && this.nbRows + this.currentRow >= this.tableData.length)
		return true;
	else
		return false;
}

XMLTable.prototype.arrowDown = function()
{
	// First, are we at the bottom of the table with all rows loaded.
	// if yes, don't do anything
	if (this.isGlobalBottom())
	{
		return;
	}
	// Second, have we got to do a request to go down some more?
	if (this.isTempBottom())
	{
		// if a request is currently done, don't do anything.
		if (XMLHTTPRequestForTable != null)
			return;
			
		// DO SOMETHING HERE!!!!!
		//alert("TODO!!!");
		var rowAsked = this.currentRow + this.nbRows;
		//alert("XMLUserRequest.php?row="+rowAsked+"&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
		if (this.requestUrl.indexOf("?") == -1)
			this.loadXMLDoc(this.requestUrl+"?row="+rowAsked+"&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
		else
			this.loadXMLDoc(this.requestUrl+"&row="+rowAsked+"&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
		//alert("coucou");
	}
	// Now, let's go down one step!
	this.currentRow++;
	this.displayRow(this.currentRow);
	this.setAllColors();
}

XMLTable.prototype.arrowUp = function()
{
	// First, are we at the top of the table?
	// if yes, don't do anything
	if (this.isGlobalTop())
	{
		return;
	}
	// Now, let's go up one step!
	this.currentRow--;
	this.displayRow(this.currentRow);
	this.setAllColors();
}

/**
	Takes in argument the row number from the top of the screen (not the real row number)
*/
XMLTable.prototype.isEvenRow = function(rowNumber)
{
	if ((rowNumber + this.currentRow) % 2 == 0)
		return true;
	else
		return false;
}

/**
	Takes in argument the row number from the top of the screen (not the real row number)
*/
XMLTable.prototype.getRowStyle = function(rowNumber)
{
	if (this.isEvenRow(rowNumber) == true)
	{
		return this.evenRowStyle;
	}
	else
	{
		return this.oddRowStyle;
	}
}

/**
	Sets all the colors of the table
*/
XMLTable.prototype.setAllColors = function()
{
	for (j=0; j < this.nbRows; j++)
	{
		document.getElementById(this.tableID).rows[j+1].className = this.getRowStyle(j);
	}
}

/**
	Returns imgSelected if the arrow is indeed selected, imgNotSelected otherwise
*/
XMLTable.prototype.isArrowSelected = function(arrowCol, arrowType, imgSelected, imgNotSelected)
{
	if (this.arrowSelectedCol == arrowCol && this.arrowSelectedType == arrowType)
		return imgSelected;
	else
		return imgNotSelected;
}

/**
	A click has been done on an arrow of the table
*/
XMLTable.prototype.onArrowClick = function(arrowCol, arrowType)
{
	// If the click has been done on the arrow already selected, let's do nothing.
	if (this.arrowSelectedCol == arrowCol && this.arrowSelectedType == arrowType)
	{
		return;
	}
	// Second, let's "unselect" the last arrowSelected
	if (this.arrowSelectedType == 1)
		document.getElementById(this.tableID+'arrow'+this.arrowSelectedCol+'dir'+this.arrowSelectedType).src = '/JSTable/images/SmallArrowUpStd.png';
	else
		document.getElementById(this.tableID+'arrow'+this.arrowSelectedCol+'dir'+this.arrowSelectedType).src = '/JSTable/images/SmallArrowDownStd.png';
	
	this.arrowSelectedCol = arrowCol;
	this.arrowSelectedType = arrowType;
	// Then, let's select the arrow clicked.
	if (arrowType == 1)
		document.getElementById(this.tableID+'arrow'+this.arrowSelectedCol+'dir'+this.arrowSelectedType).src = '/JSTable/images/SmallArrowUpSelected.png';
	else
		document.getElementById(this.tableID+'arrow'+this.arrowSelectedCol+'dir'+this.arrowSelectedType).src = '/JSTable/images/SmallArrowDownSelected.png';
		
	// Ok, now let's do the serious stuff...
	// Let's clean the table and make a real request
	this.tableData = new Array();
	this.currentRow = 0;
	this.isFullyLoaded = false;
	
	if (this.requestUrl.indexOf("?") == -1)
		this.loadXMLDoc(this.requestUrl+"?row=0&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);
	else
		this.loadXMLDoc(this.requestUrl+"&row=0&arrowCol="+this.arrowSelectedCol+"&arrowType="+this.arrowSelectedType);

}

XMLTable.prototype.loadXMLDoc = function(url)
{
	// branch for native XMLHttpRequest object
	if (window.XMLHttpRequest)
	{
		XMLHTTPRequestForTable = new XMLHttpRequest();
		XMLHTTPRequestForTable.onreadystatechange = processReqChange;
		XMLHTTPRequestForTable.open("GET", url, true);
		XMLHTTPRequestForTable.send(null);
		triggeringTable = this;
	}
	// branch for IE/Windows ActiveX version
	else if (window.ActiveXObject)
	{
		//isIE = true;
		XMLHTTPRequestForTable = new ActiveXObject("Microsoft.XMLHTTP");
		if (XMLHTTPRequestForTable)
		{
			// ICI on peut mettre un truc du style
			//this.req.onreadystatechange = function () { du code ici }
			// Bon, il faut arriver à remonter à l'objet en passant par exemple par un objet global.
			// Qui pourrait être défini éventuellement dans ce script?
			// Ok, mais je ne peux plus intégrer 2 fois le fichier js au fichier HTML alors...
			// A moins de mettre en plus un mécanisme comme le #define en C....
			
			// OU ALORS... on ne met qu'une seule requête par page.... pas con ça.
			// En global. Avec un pointeur sur l'objet qui a appelé la requête aussi tant qu'on y est.
			// En global aussi.
			XMLHTTPRequestForTable.onreadystatechange = processReqChange;
			XMLHTTPRequestForTable.open("GET", url, true);
			XMLHTTPRequestForTable.send();
			triggeringTable = this;
		}
	}
}

// handle onreadystatechange event of XMLHTTPRequestForTable object
function processReqChange()
{
	/////////ARRRGHHHH! Y a pas de THIS!
	// only if XMLHTTPRequestForTable shows "loaded"
	if (XMLHTTPRequestForTable.readyState == 4)
	{
		// only if "OK"
        	if (XMLHTTPRequestForTable.status == 200)
		{
			var myXML = XMLHTTPRequestForTable.responseXML;
			//alert(XMLHTTPRequestForTable.responseText);
			triggeringTable.addRowsFromXML(myXML);
			triggeringTable.displayRow(triggeringTable.currentRow);
			XMLHTTPRequestForTable = null;
		}
		else
		{
			alert("There was a problem retrieving the XML data:\n" + XMLHTTPRequestForTable.statusText);
			XMLHTTPRequestForTable = null;
		}
	}
	
}
