var rowCache;
var pendingRequestCount;
function initJoinTable() {
	rowCache = new Array();
	pendingRequestCount = 0;	
}
addOnloadEvent(initJoinTable);

function changedJoinRow(keyFieldName, rowID, optionalRowParams) {
	pendingRequestCount++;

	/* Make sure optionalRowParams is not null so we can just always include it.
	 * optionalRowParams apply to specific row data, whereas optionalAJAXHandlerParams
	 * is a global JavaScript variable and applies to the join table as a whole
	 */
	if (optionalRowParams == null) { optionalRowParams = ""; }
	
	//Disable key field so only one AJAX request per row goes through at a time
	document.forms["mainForm"].elements[keyFieldName].disabled = true;
	
	//Disable buttons
	document.forms["mainForm"].elements["cmdSubmit"].disabled = true;
	try {
		customButtonEnableFunction(false);
	} catch (e) {}
	
	//Get input from key field
	var value = null;
	eval("value = document.forms['mainForm']." + keyFieldName + ".value;");
	
	//Get reference to that row's DIV
	var rowDiv = document.getElementById("join_row_" + rowID);
	var tempRowCache = new JoinTableRow(rowID, rowDiv);

	rowCache[rowID] = tempRowCache;
	
	//Determine CSS class of row by searching through all children until we find an element node
	var colorClass = "";
	try {
		colorClass = getChildElements(rowDiv)[0].getAttribute(getElementClassAttributeName());
	} catch (e) {}

	//Make AJAX request
	//alert(join_ajaxJoinTableHandlerURL + '?rowID=' + rowID + '&keyID=' + value + "&colorClass=" + join_colorClass + optionalAJAXHandlerParams + optionalRowParams);
	var sendSuccess = makeAJAXRequest(join_ajaxJoinTableHandlerURL + '?rowID=' + rowID + '&keyID=' + value + "&colorClass=" + join_colorClass + optionalAJAXHandlerParams + optionalRowParams, "populateJoinRow", "responseXML", "");
	
	if (sendSuccess) { //We sent the request
		//Determine how many rows we currently have
		var rows = getChildElements(document.getElementById("joinTable"));
		var rowNumber = getChildIndex(rowDiv);
		
		//If the current ID is one less than the number of rows, we need to add a new one
		if (rowNumber == join_numRows) {
			//Insert a new row
			insertBlankJoinRow();

			rowCache[rowID].startTimer();
			
			//If there are no additional form fields in this row, set the focus to the first field in the next row
			if (rowCache[rowID].getNumFields() > 1) {
				//TODO
			}
		}
	} else { //Request send failed
		//Reenable key field
		document.forms["mainForm"].elements[keyFieldName].disabled = false;
		pendingRequestCount--;
		if (pendingRequestCount < 1) {
			//Re-enable main submit button
			document.forms["mainForm"].elements["cmdSubmit"].disabled = false;
			
			//Call any custom enable/disable functions
			try {
				customButtonEnableFunction(true);
			} catch (e) {}
		}
	}
}

function deleteJoinRow(rowID) {
	//Get reference to existing join row
	var rowDiv = document.getElementById("join_row_" + rowID);
	try { //IE seems to think there's an error
		var parentDiv = rowDiv.parentNode;
	} catch (e) {}
		
	//Delete from DOM
	parentDiv.removeChild(rowDiv);
	
	//Restripe table
	restripeTable(parentDiv);
	
	//Call any custom functions
	try {
		deletedJoinRow(rowID);
	} catch (e) {}
	
	//Delete from cache
	rowCache[rowID] = null;
	
	//Update new row count variable
	join_numRows--;
	document.forms['mainForm'].elements['join_numRows'].value = join_numRows;
}

function populateJoinRow(responseXML) {
	//Get the row number
	var rowID;
	var deleteRowFlag = false;
	
	var metaList = responseXML.getElementsByTagName("metaAttribute");
	for (var i = 0; i < metaList.length; i++) {
		if (metaList[i].getAttribute("id") == "rowID") {
			rowID = Number(metaList[i].getAttribute("value"));
		} else if (metaList[i].getAttribute("id") == "join_deleteRowFlag") {
			deleteRowFlag = Boolean(metaList[i].getAttribute("value"));
		}
	}
	
	//If AJAX response has flagged an error, remove the row
	if (deleteRowFlag) {
		deleteJoinRow(rowID);
	} else if (rowCache[rowID] != null) { //Row did not time out
		//Get references to the old row
		var parentNode = document.getElementById("joinTable");
		var oldRowDiv = document.getElementById("join_row_" + rowID);
		
		if (oldRowDiv != null) { //Check to make sure it wasn't deleted in the meantime
			var newRow = responseXML.getElementsByTagName("renderHTML")[0].getElementsByTagName("div")[0];
			
			//Create new row div to hold data
			var newRowDiv = copyNode(newRow);
			
			rowCache[rowID].clearTimer();
			
			//Backup existing form field values
			if (join_persistFormValues) { rowCache[rowID].backupFormValues(); }
			
			//Repaint row
			parentNode.replaceChild(newRowDiv, oldRowDiv);
			
			//Restore optional form field values
			if (join_persistFormValues) { rowCache[rowID].restoreFormValues(); }
			
			//Restripe table
			restripeTable(parentNode);
		}
	}
	
	//Call any custom functions
	try {
		populatedJoinRow(rowID);
	} catch (e) {}
	
	pendingRequestCount--;
	if (pendingRequestCount < 1) {
		//Keep main submit button disabled
		document.forms["mainForm"].elements["cmdSubmit"].disabled = false;
		
		//Call any custom enable/disable functions
		try {
			customButtonEnableFunction(true);
		} catch (e) {}
	}
}

function insertBlankJoinRow() {
	//From now on, we need to use a higher blank row ID
	join_blankRowID++;
	
	//Determine CSS class of row by searching through all children until we find an element node
	var lastRowNumber = join_numRows - 1;
	var rowCollection = getChildElements(document.getElementById("joinTable"));
	var currentLastRowDiv = document.getElementById(rowCollection[rowCollection.length - 1].getAttribute("id"));
	
	var colorClass = "";
	try {
		colorClass = getChildElements(currentLastRowDiv)[0].getAttribute(getElementClassAttributeName());
	} catch (e) {}
	
	//Replace dummy ID with real ID and next color class
	var newBlankRow = join_blankJoinRowTemplate;
	newBlankRow = newBlankRow.replace(new RegExp("65534", "gi"), join_blankRowID);
	newBlankRow = newBlankRow.replace(new RegExp(colorClass, "gi"), getNextColorClass(colorClass));
	
	//Create new div
	var newRowDiv = document.createElement("div");
	newRowDiv.setAttribute(getElementClassAttributeName(), "tableRow");
	newRowDiv.setAttribute("id", "join_row_" + join_blankRowID);
	newRowDiv.innerHTML = newBlankRow;
	
	//Add it to the table
	document.getElementById("joinTable").appendChild(newRowDiv);
	
	//Update new row count variable
	join_numRows++;
	document.forms['mainForm'].elements['join_numRows'].value = join_numRows;
}

function JoinTableRow(ID, rowDiv) {
	//Instance variables
	this.ID = ID;
	this.oldRowDiv = rowDiv;
	this.childElements = null;
	this.fieldArray = null;
	this.fieldSourceArray = null;
	this.timerID = null;
	
	//Determine number of parameters in this join row
	var cont = true;
	this.numParams = 0;
	while (cont) {
		try {
			var tempParam = document.forms["mainForm"].elements["join_param_" + this.ID + "_" + this.numParams];
			if (tempParam == null) {
				cont = false;
			} else {
				this.numParams++;
			}
		} catch (e) { cont = false; }
	}
	
	//Instance functions
	this.setID = function(ID) { this.ID = ID; }
	this.getID = function() { return this.ID; }
	
	this.setOldRowDiv = function(rowDiv) {
		this.oldRowDiv = rowDiv;
		this.childElements = getChildElements(this.oldRowDiv);
	}
	this.getOldRowDiv = function() { return this.oldRowDiv; }
	
	this.getNumFields = function() { return this.numParams; }
	
	this.backupFormValues = function() {
		this.fieldArray = new Array();
		this.fieldSourceArray = new Array();
		var formElements = document.forms["mainForm"].elements;
		
		//Backup key
		this.fieldArray["join_floatingKey_" + this.ID] = formElements["join_floatingKey_" + this.ID].value;
		
		//Backup params
		for (var i = 0; i < this.numParams; i++) {
			//Backup form values only if needed
			var fieldName = "join_param_" + this.ID + "_" + i;
			
			if ((formElements[fieldName].value.length < 1) && (formElements[fieldName].innerHTML.length > 0)) {
				this.fieldArray[fieldName] = formElements[fieldName].innerHTML;
				this.fieldSourceArray[fieldName] = "innerHTML";
			} else {
				this.fieldArray[fieldName] = formElements[fieldName].value;
				this.fieldSourceArray [fieldName] = "value";
			}
			
		}
	}
	
	this.restoreFormValues = function() {
		var formElements = document.forms["mainForm"].elements;

		//Restore key
		formElements["join_floatingKey_" + this.ID].value = this.fieldArray["join_floatingKey_" + this.ID];
		
		//Restore params
		for (var i = 0; i < this.numParams; i++) {
			//Backup form values only if needed
			var fieldName = "join_param_" + this.ID + "_" + i;
			try { //Need to handle case when new row has less fields than old fields
				if (this.fieldSourceArray[fieldName] == "value") {
					formElements[fieldName].value = this.fieldArray[fieldName];
				} else if (this.fieldSourceArray[fieldName] == "innerHTML") {
					formElements[fieldName].innerHTML = this.fieldArray[fieldName];
				}
			} catch (e) {}
		}
	}
	
	//Set timer to make sure we handle non-returned join rows
	this.startTimer = function() {
		this.timerID = setTimeout('rowCache[' + this.ID + '].notifyTimer();', 8000);
	}
	
	this.clearTimer = function() {
		try {
			clearTimeout(this.timerID);
		} catch (e) {}
	}
	
	this.notifyTimer = function() {
		alert("ERROR: A problem was encountered looking up the requested information.  IROMS will remove the row from the table.  Please try again.");
		try {
			deleteJoinRow(this.ID);
		} catch (e) {}
	}
}
