/**
*	gisMapFunctions.js
*
*	This file contains JavaScript methods to power the GIS integrated library search.
*   The core methods found herein have been taken from the primary libryar search system, 
*  (geolibFunctions.js) and extended / altered to meet the specific needs of the GIS interface
*
*	AJAX functions built around the DWR libraries
*
*	@author ian.stapleton
*/

///BEGIN LIBRARY CORE FUNCTIONS
/*
* These functions are the core methods that handle events / actions
* in the application.
*/

		
/** geolib_handleGISKeywordSearchByAjax()
* 
* Performs basic validation & initiates a keyword search
* using DWR calls
*/
function geolib_handleGISKeywordSearchByAjax() {
  ///Warmup Tasks: show the ticker, disable the form submit control, hide any previous results or errors
	
	//Start Spinner
	geolib_beginAjaxActivity();
	
	//Disable Search Controls
	var keywordSubmitControl = document.KeywordSearchForm.geolib_keywordSubmit;
	keywordSubmitControl.disabled = true;
	var detailSubmitControl = document.DetailSearchForm.geolib_detailSubmit;
	detailSubmitControl.disabled = true;
	
	//Remove Form Errors display
	geolib_clearFormErrors();
	
	//Clear old results display
	document.getElementById("ResultsBody").innerHTML = "";		
	
  ///Housekeeping, get the values for the relevant fields
	var keywordTerm = document.KeywordSearchForm.keyword.value;
	var selectedContext = document.KeywordSearchForm.geolib_searchType.value;
    
  ///Processing
    if (keywordTerm.length > 0) {
    	//Good to go - remaining validation occurs server-side
    	//Store the terms in a cookie!
    	//geolib_setTermsCookie();
    	
    	//Server side failures are caught by DWR Exceptions	    	
    	LibraryActions.keywordSearchActionWithCoordData(keywordTerm, selectedContext, geolib_keywordCallBack);			
   	} else {
   		//Throw this off to our error handler!		
   		dwrErrorHandler("Keyword#"+geolib_langArray["errors"]["noFields"]);
   	}
    	    
  ///Cooldown Tasks: enable the form submit control, hide the ticker
	//Enable submit control
	keywordSubmitControl.disabled = false;		
	detailSubmitControl.disabled = false;		
	
	//Set Timer method to remove ticker ("fake" delay)
	geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);	  
    
  //Return
	//Return false to cancel the form submit we've stolen    	    
    return false; 	    
}


/** geolib_handleDetailSearchByAjax()
* 
* Performs basic validation & initiates a detail search
* using DWR calls
*/ 	
function geolib_handleGISDetailSearchByAjax() {
   ///Warmup Tasks: show the ticker, disable the form submit control, hide any previous results or errors
	//Start Spinner
	geolib_beginAjaxActivity();
	
	//Disable Search Controls
	var keywordSubmitControl = document.KeywordSearchForm.geolib_keywordSubmit;
	keywordSubmitControl.disabled = true;
	var detailSubmitControl = document.DetailSearchForm.geolib_detailSubmit;
	detailSubmitControl.disabled = true;
	
	//Remove Form Errors display
	geolib_clearFormErrors();
	
	//Clear old results display
	document.getElementById("ResultsBody").innerHTML = "";		
	
  ///Housekeeping, get the values for the relevant fields
  	var authorTerm = document.DetailSearchForm.geolib_Author.value;
  	var titleTerm = document.DetailSearchForm.geolib_Title.value;
  	var scaleFromTerm = document.DetailSearchForm.geolib_ScaleFrom.value;
  	var scaleToTerm = document.DetailSearchForm.geolib_ScaleTo.value;
  	
  	var latDegTerm = document.DetailSearchForm.geolib_LatCoordDeg.value;
  	var latMinTerm = document.DetailSearchForm.geolib_LatCoordMin.value;
  	var latDirIndex = document.DetailSearchForm.geolib_LatCoordDir.selectedIndex;            
    var latDirTerm = document.DetailSearchForm.geolib_LatCoordDir.options[latDirIndex].value;   	
  	
  	var lonDegTerm = document.DetailSearchForm.geolib_LonCoordDeg.value;
  	var lonMinTerm = document.DetailSearchForm.geolib_LonCoordMin.value;
  	var lonDirIndex = document.DetailSearchForm.geolib_LonCoordDir.selectedIndex;            
    var lonDirTerm = document.DetailSearchForm.geolib_LonCoordDir.options[lonDirIndex].value;
  	  	 	
  	var publisherTerm = document.DetailSearchForm.geolib_Publisher.value;
  	var dateFromTerm = document.DetailSearchForm.geolib_DateFrom.value;
 	var dateToTerm = document.DetailSearchForm.geolib_DateTo.value;
  	var subjectTerm = document.DetailSearchForm.geolib_Subject.value;
 	var languageTerm = document.DetailSearchForm.geolib_Language.value;
  	var geogAreaTerm = document.DetailSearchForm.geolib_geographicArea.value;
  	
  	//Get Context and "Join type"
  	var selectedContext = document.DetailSearchForm.geolib_searchType.value;
    var selectedJoinIndex = document.DetailSearchForm.geolib_SearchOn.selectedIndex;            
    var selectedJoin = document.DetailSearchForm.geolib_SearchOn.options[selectedJoinIndex].value;
    
  ///Processing
    var validSearch = false;
    var errorMsg = "";
    var numericDataRegExp = /[^\d]/g;	
    
    //The following fields just need to be validated as having content.
    if (authorTerm.length > 0) {validSearch = true;}
    if (titleTerm.length > 0) {validSearch = true;}
    if (publisherTerm.length > 0) {validSearch = true;}
    if (subjectTerm.length > 0) {validSearch = true;}
    if (languageTerm.length > 0) {validSearch = true;}
    if (geogAreaTerm.length > 0) {validSearch = true;}
        
    //Scales need to treated as Ints
    scaleFromTerm = scaleFromTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_ScaleFrom.value = scaleFromTerm;
    scaleFromTerm = parseInt(scaleFromTerm);
    scaleToTerm = scaleToTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_ScaleTo.value = scaleToTerm;
    scaleToTerm = parseInt(scaleToTerm);
    
    
    if (isNaN(scaleFromTerm) || scaleFromTerm == 0) {scaleFromTerm  = 0;} else {validSearch = true;}    
    if (isNaN(scaleToTerm) || scaleToTerm == 0) {scaleToTerm  = 0;} else {validSearch = true;}
    
    if (scaleFromTerm > 0 && scaleToTerm > 0) {
    	//Male sure they are different    	
    	if (scaleFromTerm > scaleToTerm) {
    		//From is bigger that to!
			//Make sure we cancel the search!
			validSearch = false;			
						
			//Turn the error highlighting on
			dwrErrorHandler("ScaleFrom#");
			dwrErrorHandler("ScaleTo#");

			//Set the correct error msg
			errorMsg = geolib_langArray["errors"]["scaleRange"];    	
    	} else {
    		validSearch = true;
    	}    	
    }
    
    //Coordinates need to be sanitised
    latDegTerm = latDegTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_LatCoordDeg.value = latDegTerm;
    latDegTerm = parseInt(latDegTerm);
    latMinTerm = latMinTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_LatCoordMin.value = latMinTerm; 
    latMinTerm = parseInt(latMinTerm);   
    lonDegTerm = lonDegTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_LonCoordDeg.value = lonDegTerm;
    lonDegTerm = parseInt(lonDegTerm);
    lonMinTerm = lonMinTerm.replace(numericDataRegExp, "");
    document.DetailSearchForm.geolib_LonCoordMin.value = lonMinTerm;
    lonMinTerm = parseInt(lonMinTerm);
        
    //Convert the coordinates into decimal
    var lonDecimal = 0;
    var latDecimal = 0;	
    if (!isNaN(latDegTerm)) {
    	if (latDegTerm > 90) {
    		//Out of bounds!
    		validSearch = false;
    		dwrErrorHandler("LatCoordDeg#");
    		errorMsg = geolib_langArray["errors"]["latDegRange"];    		
    	} else {
   			latDecimal = latDegTerm;
   		}
    }
    if (!isNaN(latMinTerm)) {
    	if (latMinTerm > 60) {
    		//Out of bounds!
    		validSearch = false;
    		dwrErrorHandler("LatCoordMin#");
    		errorMsg = geolib_langArray["errors"]["latMinRange"];    		
    	} else {
   			latDecimal += (latMinTerm / 60);
   		}
    }
    if (latDirTerm == "S") {
    	latDecimal = (latDecimal * -1);
    }
    if (isNaN(latDegTerm) && isNaN(latMinTerm)) {
    	latDecimal = null;
    } else {
    	validSearch = true;
    }
    
    if (!isNaN(lonDegTerm)) {
    	if (lonDegTerm > 180) {
    		//Out of bounds!
    		validSearch = false;
    		dwrErrorHandler("LonCoordDeg#");
    		errorMsg = geolib_langArray["errors"]["lonDegRange"];    		
    	} else {
   			lonDecimal = lonDegTerm;
   		}   
    }
    if (!isNaN(lonMinTerm)) {
    	if (lonMinTerm > 60) {
    		//Out of bounds!
    		validSearch = false;
    		dwrErrorHandler("LonCoordMin#");
    		errorMsg = geolib_langArray["errors"]["lonMinRange"];    		
    	} else {
   			lonDecimal += (lonMinTerm / 60);
   		}
    }
    if (lonDirTerm == "W") {
		lonDecimal = (lonDecimal * -1);
	}
    if (isNaN(lonDegTerm) && isNaN(lonMinTerm)) {
    	lonDecimal = null;
    } else {
    	validSearch = true;
    }
    
    //Dates need to be valid dates
    dateFromTerm = dateFromTerm.replace(numericDataRegExp, "");
	document.DetailSearchForm.geolib_DateFrom.value = dateFromTerm;
	if (dateFromTerm.length > 0) {
		//Create a date object!
		dateFromToSend = new Date();
		dateFromToSend.setYear(dateFromTerm);
		validSearch = true;
	} else {
		dateFromToSend = null;		
	}
    
    dateToTerm = dateToTerm.replace(numericDataRegExp, "");
	document.DetailSearchForm.geolib_DateTo.value = dateToTerm;
	if (dateToTerm.length > 0) {
		//Create a date object!
		dateToToSend = new Date();
		dateToToSend.setYear(dateToTerm);
		validSearch = true;
	} else {
		dateToToSend = null;		
	}
	
	//Validate Date fields to be logical
	if (dateFromToSend != null && dateToToSend != null) {
		if (dateFromToSend.getFullYear() > dateToToSend.getFullYear()) {
			//From is bigger that to!
			//Make sure we cancel the search!
			validSearch = false;			
						
			//Turn the error highlighting on
			dwrErrorHandler("DateFrom#");
			dwrErrorHandler("DateTo#");

			//Set the correct error msg
			errorMsg = geolib_langArray["errors"]["dateRange"];
		}	
	}
	      
    if (validSearch == true) {
    	//Good to go - remaining validation occurs server-side
    	//Store the terms in a cookie!
    	//geolib_setTermsCookie();
    	
    	//Server side failures are caught by DWR Exceptions	    	
    	LibraryActions.detailGisSearchAction(selectedJoin, 
    		authorTerm, titleTerm, publisherTerm, dateFromToSend, dateToToSend, 
    		scaleFromTerm, scaleToTerm, subjectTerm, languageTerm, geogAreaTerm,
			latDecimal,	lonDecimal, geolib_detailCallBack);	
   	} else {
   		//Throw this off to our error handler!
		if (errorMsg == "") {
			dwrErrorHandler(geolib_langArray["errors"]["noFields"]);
		} else {
			dwrErrorHandler(errorMsg);
		}
   	}
    	    
  ///Cooldown Tasks: enable the form submit control, hide the ticker
	//Enable submit control
	keywordSubmitControl.disabled = false;		
	detailSubmitControl.disabled = false;		
	
	//Set Timer method to remove ticker ("fake" delay)
	geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);	  
    
  //Return
	//Return false to cancel the form submit we've stolen    	    
    return false; 	    
}
	
			
/** geolib_processPagedResults()
*
* Shows a particular subset of the the search results
* Called when new results are loaded, when changing page 
* or when altering paging size
*/
function geolib_processPagedResults(pageNumber) { 
  ///Setup
  	//Gather page elements for the results
  	//Pagination is hard-coded for the GIS search
	geolib_pagingPerPage = 5;
	var resultsContainer = document.getElementById("ResultsBody");
   	var pagedRecords = new Array();
   	var gisRequestArray = new Array();
    
    //Switch the display focus to show the results pan
    geolib_enableTab("Results");
    geolib_switchTab("Results", false);
    
    //Start Spinner
	geolib_beginAjaxActivity();		    
    //Blank the currently displayed page
    resultsContainer.innerHTML = "";
    
    //Clear any errors messages that may be present
	geolib_clearGeneralErrors();	
	
	 //Reset the summary ordering array
    geolib_summaryPlacementOrder = new Array();
        	    
	//Calculate start and end points for t his page
    geolib_pagingStartRecord = (geolib_pagingPerPage * pageNumber);
    geolib_pagingEndRecord = geolib_pagingStartRecord + parseInt(geolib_pagingPerPage);
    
    //Check to prevent out-of-range issues
    if (geolib_pagingEndRecord > geolib_searchResults.length) {
	    geolib_pagingEndRecord = geolib_searchResults.length;
	}		
	
	//Store the current page for use by the Paging Control
	geolib_searchCurrentPage = pageNumber;
	
  ///Escape Task!!	
	//If there is only 1 result in the set, jump straight to it!
  	if (geolib_searchResults.length == 1) {
  		geolib_showRecord(geolib_searchResults[0].id);
  		return;
  	}		

  ///Generate page	
	//Display the top paging bar
	geolib_generatePagingControl("ResultsHeader");		
	
	//For each result on the page, put in an asynchronous call to show summary data
	for (var currentRecordKey = geolib_pagingStartRecord; currentRecordKey < geolib_pagingEndRecord; currentRecordKey++) {
		//Get the current record we are looking at
		var currentRecord = geolib_searchResults[currentRecordKey];
		
		//Store the record number of this record into a mapping array
		geolib_summaryPlacementOrder[currentRecord.id] = currentRecordKey;		
		
		//Create a container element to hold the summary results.
		containerElement = document.createElement("div");
        containerElement.setAttribute("id", "geolib_summaryRecord_"+currentRecordKey);
        resultsContainer.appendChild(containerElement);		
		
		//Send a DWR Request show the summary information for this record
		LibraryActions.getSummaryAction(currentRecord.id, geolib_getSummaryCallBack);

		//Store this record as an aspect of this page
		pagedRecords[pagedRecords.length] = parseInt(currentRecord.id);
		
		//Examine if this record has coordinates, and if so, add it to the GIS request array
		if ((currentRecord.minX != currentRecord.maxX) && (currentRecord.minY != currentRecord.maxY)) {
			gisRequestArray[gisRequestArray.length] = currentRecord.id;
			gisRequestArray[gisRequestArray.length] = currentRecord.minX;
			gisRequestArray[gisRequestArray.length] = currentRecord.minY;
			gisRequestArray[gisRequestArray.length] = currentRecord.maxX;
			gisRequestArray[gisRequestArray.length] = currentRecord.maxY;
		}
	}	
		
	//Send a request to the GIS application to highlight these sheets
	if (gisRequestArray.length > 0) {
		window.frames.gisInterface.soukgslOutlineAndPanCommand(gisRequestArray);	
	}
	
	//Display the bottom paging bar
	geolib_generatePagingControl("ResultsFooter");

  ///Finalise	
	//Set Timer method to remove ticker ("fake" delay)
	geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);
	
	//Returning false should kill browser history issues
	return false;	
}


/** geolib_handlePagingQuantity()
*
* Handles change in number of records shown per page.
*/
function geolib_handlePagingQuantity() {		
	//Only do something if we are currently showing results
	//The paging is automatically refreshed from the input when
	//performing a search
	if (geolib_searchResults.length > 0 ) {
	
		//Start Spinner
		geolib_beginAjaxActivity();
		
		//Change the paging, going back to page1		
		geolib_processPagedResults(0);
		
		//Set Timer method to remove ticker ("fake" delay)
		geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);			
	}	
	
	//Return false to abort the form!
	return false;
}


/** geolib_showRecord()
*
* Invokes a DWR request to load & disply a full record.
*/
function geolib_showRecord(recordID) {
	
	//Store the record we are viewing in a global variable
	geolib_currentRecordDetail = recordID;
	
	//Invoke the DWR request
	LibraryActions.getRecordAction(recordID, geolib_getRecordCallBack);
	
	return false;	
}


/** geolib_returnToResults()
* 
* Redisplays the previous page of results following a 
* record detail view
*/	
function geolib_returnToResults() {
	//Simply turn the required document elements off / on
	//Only perform this task if we have results to go back to!
	if (geolib_searchResults.length > 1) {
		
		var detailPanel = document.getElementById("geolib_recordDetail");
		detailPanel.style.display = "none";
		
		var searchResults = document.getElementById("geolib_searchResults");
		searchResults.style.display = "";
						
		var searchPanel = document.getElementById("geolib_searchInterface");
		searchPanel.style.display = "";	
	
	}		
	
	return false;			
}	


///BEGIN DWR CALLBACK FUNCTIONS
/*
* These functions are called by the DWR framework following a
* completed xmlhttp request to a remote method.
*/

/** geolib_keywordCallBack()
*
* Method called by DWR following a sucessful keyword search
* Handles storing results into application variables & fires display routines
*/	
var geolib_keywordCallBack = function(Data) {		
	if (Data.length > 0) {
		//Store the returned results and process the first page
		geolib_searchResults = Data;
		
		geolib_enableTab("Results");
		
		geolib_generateResultPlaceArray();
		
		geolib_processPagedResults(0);			
	} else {
		dwrErrorHandler("Keyword#Your search returned no results");
		geolib_disableTab("Results");
	}		
}


/** geolib_detailCallBack()
*
* Method called by DWR following a sucessful detail search
* Handles storing results into application variables & fires display routines
*/
var geolib_detailCallBack = function(Data) {	
	if (Data.length > 0) {
		//Store the returned results and process the first page
		geolib_searchResults = Data;
		
		geolib_enableTab("Results");
		
		geolib_generateResultPlaceArray();
		
		geolib_processPagedResults(0);				
	} else {
		dwrErrorHandler("Your search returned no results");
	}	
}


/** geolib_coordinateCallBack()
*
* Method called by DWR following a sucessful coordinaate based search
* Handles storing results into application variables & fires display routines
*/
var geolib_coordinateCallBack = function(Data) {	
	if (Data.length > 0) {
		//Store the returned results and process the first page
		geolib_searchResults = Data;
		
		geolib_enableTab("Results");
		
		geolib_generateResultPlaceArray();
		
		geolib_processPagedResults(0);				
	} else {
		dwrErrorHandler("No records could be found in this region of the map");
		isFirstGisRedraw = true;
	}	
}


/** geolib_getSummaryCallBack()
*
* Method called by DWR following a call to get the record summary
* Used to display a summary of the record in the results list.
*/	
	
var geolib_getSummaryCallBack = function(Data) {

	//Display of elements depends on the type of result returned
    var context = "Map";
    var resultsContainer = document.getElementById("geolib_summaryRecord_"+geolib_summaryPlacementOrder[Data.ID]);
    var recordPlace = geolib_searchResultsPlacementArray[Data.ID];
    var titleHTML = "<div>";
   		
	//Start Spinner
	geolib_beginAjaxActivity();	
		
	//Title globally shown
	if (Data.title != "")  {	
		titleHTML += "<span class=\"brownAjaxLinks\" onClick=\"geolib_showRecord("+ parseInt(Data.ID) +");\">" + geolib_processFieldData(Data.title) +"</span><br />";
	}
	
	resultsContainer.innerHTML += titleHTML;
	//Create a table and dynamically fill it with attributes
	var summaryTable = document.createElement("table");
	summaryTable.style.width = "100%";
	summaryTableRowsCounter = 0;
	
	//Scale shown
	if (Data.scale != "") {		
		var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
		var cellLabel = tableRow.insertCell(0);
		var cellField = tableRow.insertCell(1);		
		
		cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["scale"] + "</strong>";
		cellLabel.style.verticalAlign = "top";
		cellLabel.style.width = "30%";
		cellField.innerHTML = geolib_processFieldData(Data.scale);
		cellField.style.verticalAlign = "top";
		
		summaryTableRowsCounter++;			
	}		
		
	//Publisher globally shown
	if (Data.publisher != "") {
		var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
		var cellLabel = tableRow.insertCell(0);
		var cellField = tableRow.insertCell(1);		
		
		cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["publisher"] + "</strong>";
		cellLabel.style.verticalAlign = "top";
		cellLabel.style.width = "30%";
		cellField.innerHTML = geolib_processFieldData(Data.publisher);
		cellField.style.verticalAlign = "top";
		
		summaryTableRowsCounter++;	
	}
	
	//Pubdate not for Serials
	if (context != "serial") {
		var insertPubDateRow = false;
		var pubDateRowHtml = "";
		if (Data.pubDate != null) {
			pubDateRowHtml = Data.pubDate.getFullYear();
			insertPubDateRow = true;
		} else if (Data.pubDateDisplay != "") {
			pubDateRowHtml = Data.pubDateDisplay;
			insertPubDateRow = true;
		}
		
		if (insertPubDateRow == true) {
			var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
			var cellLabel = tableRow.insertCell(0);
			var cellField = tableRow.insertCell(1);		
			
			cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["pubDate"] + "</strong>";
			cellLabel.style.verticalAlign = "top";
			cellLabel.style.width = "30%";
			cellField.innerHTML = pubDateRowHtml;
			
			summaryTableRowsCounter++;
		}
	}
	
	resultsContainer.appendChild(summaryTable);
	
	var closingHTML = "<br />";
	if ((Data.westDecCoord != Data.eastDecCoord) && (Data.northDecCoord != Data.southDecCoord)) {
		//This record has been outlined, so show a Highlight Command
		closingHTML += "<span id=\"highlightLinkContainer_"+ parseInt(recordPlace) +"\" class=\"brownAjaxLinks\" onClick=\"geolib_highlightIndexSheet("+ parseInt(recordPlace) +", true);\">Highlight</span><br />";		
	} else {
		//This record has no coordindates, so won't be drawn (thus cannot be highlighted)
		closingHTML += "<em>Not Shown</em><br />";
	}
	
	closingHTML += "</div><hr />";	
	
	resultsContainer.innerHTML += closingHTML;
	
	//Set Timer method to remove ticker ("fake" delay)
	geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);	
}

/** geolib_getRecordCallBack()
*
* Method called by DWR following a call to get the full record
* Switches the application to a "detail view" of the individual record
* Generates new paging controls 
* Contextually shows different information based on the record type being shown 
*/
var geolib_getRecordCallBack = function(Data) {
  ///Startup
	//A bit of jiggery-pokery here
	//Get the "place" of this record in the full result list.	
	var recordPlace = geolib_searchResultsPlacementArray[Data.ID] + 1;		
	
	//Store the current Record ID in the global variable
	geolib_currentRecordDetailID = Data.ID;
	
	//Spoof an anchor to allow this page to be bookmarked
	window.location.hash = "viewLibraryRecord=" + Data.ID+ "|" 
							+ Data.westDecCoord + "|" + Data.eastDecCoord + "|"
		                    + Data.northDecCoord + "|" + Data.southDecCoord + "|" + Data.recordID
	
	//Reload the GIS interface to show the sheets (clear any errors prior to this)
	geolib_clearGeneralErrors();
	geolib_showMapSheets(geolib_searchResultsPlacementArray[Data.ID], Data.ID);	
	
  ///Turn on & off the correct document elements
	//Hide the list results and search interface	
    geolib_enableTab("Record");
    geolib_switchTab("Record");	
	
	//Display the results page
	var detailPanel = document.getElementById("geolib_recordDetail");
	detailPanel.style.display = "";	

  ///Begin the output process	
	//Generate and render the Paging controls	
	pagingControlHTML = geolib_generateRecordPagingControl(recordPlace-1, geolib_searchResults.length);
	var bottomPagingLocation = document.getElementById("RecordFooter");	
	bottomPagingLocation.innerHTML = pagingControlHTML;
	
	//If the user is logged in, display the bibliography controls
	/*
	if (geolib_userLoggedIn == true) {
		document.getElementById("RecordBibliography").style.visibility = "visible";
	} else {
		document.getElementById("RecordBibliography").style.visibility = "hidden";
	}	
	*/
	
	//Complete the header with the the record place, the type and title	
	var recordPlacementContainer = document.getElementById("recordDetailContainerPlacement");
	recordPlacementContainer.innerHTML = "Displaying record " + recordPlace + " of " + geolib_searchResults.length;
	
	var recordTitleContainer = document.getElementById("geolib_recordDetailContainerTitle");
	recordTitleContainer.innerHTML = "Title: " + Data.title ;
			
	//Output the attributes of the record
	//This is dependant on the entryType.
	//Different types have both different fields displayed, and a different order of fields.
	//The ordering of the fields in explicit!!!		
	var recordAttributes = new Array();		
	var adminAttributes = new Array();	
	
	//There can only be one EntryType - Maps!
	if (Data.parallelTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelTitle"], geolib_processFieldData(Data.parallelTitle));}				
	if (Data.edition != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["edition"], geolib_processFieldData(Data.edition));}
	if (Data.author != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["author"], geolib_processFieldData(Data.author));}	
	if (Data.corpBody != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["corpBody"], geolib_processFieldData(Data.corpBody));}				
	if (Data.scale != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["scale"], geolib_processFieldData(Data.scale));}
	if (Data.dateOfSituation != null) {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["dateOfSituation"], Data.dateOfSituation.getFullYear());}
	if (Data.westCoord != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["westCoord"], geolib_processFieldData(Data.westCoord));}			
	if (Data.eastCoord != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["eastCoord"], geolib_processFieldData(Data.eastCoord));}
	if (Data.northCoord != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["northCoord"], geolib_processFieldData(Data.northCoord));}
	if (Data.southCoord != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["southCoord"], geolib_processFieldData(Data.southCoord));}
	if (Data.placeOfPub != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["placeOfPub"], geolib_processFieldData(Data.placeOfPub));}
	if (Data.publisher != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["publisher"], geolib_processFieldData(Data.publisher));}
	if (Data.pubDate != null) {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["pubDate"], Data.pubDate.getFullYear());}
	else if (Data.pubDateDisplay != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["pubDate"], geolib_processFieldData(Data.pubDateDisplay));}
	if (Data.physicalDescription != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["physicalDescription"], geolib_processFieldData(Data.physicalDescription));}							
	if (Data.seriesTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["seriesTitle"], geolib_processFieldData(Data.seriesTitle));}				
	if (Data.explainText != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["explanatoryText"], geolib_processFieldData(Data.explainText));}				
	if (Data.index1 != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["index"], geolib_processFieldData(Data.index1));}
	if (Data.holdings != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["holdings"], geolib_processFieldData(Data.holdings));}
	if (Data.noCopies != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["noOfCopies"], geolib_processFieldData(Data.noCopies));}			
			
	if (Data.serialLink != "") {
		geolib_currentRecordSerialLinkID = Data.linkedSerialRecord;				
		recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["serialLink"], '<span class=\"brownAjaxLinks\" onClick="geolib_viewSerial();">'+Data.serialLink+'</span>');
	}
	
	if (Data.notes != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["notes"], geolib_processFieldData(Data.notes));}				
	if (Data.subjects != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["subject"], geolib_processFieldData(Data.subjects));}				
	if (Data.geogArea != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["geogArea"], geolib_processFieldData(Data.geogArea));}
	if (Data.languages != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["languages"], geolib_processFieldData(Data.languages));}
	
	if (Data.location != "") {
	    if (Data.location == "[Serial]" && Data.serialLink != "") {
	         //Legacy fallback, show a link to serial popup
	         recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location"], '<span class=\"brownAjaxLinks\" onClick="geolib_viewSerial();">'+Data.serialLink+'</span>');
	    } else {
	        recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location"], geolib_processFieldData(Data.location));
	    }
	}
	if (Data.recordID != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["recordId"], geolib_processFieldData(Data.recordID));}
				
	//Add Admin rows
	if (Data.dateEntered != null) {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["dateOfInput"], 
												weekday[Data.dateEntered.getDay()] + ", " + Data.dateEntered.getDate() + " " + month[Data.dateEntered.getMonth()] +
												" " + Data.dateEntered.getFullYear());}
			
	
  ///Output the results!
	//Dynamically build up a table through DOM-esque methods
    //General data
	var geolib_recordAttributeTable = document.getElementById("recordDetailAttributesContainer");
	
	//Remove old rows	
	for (var oldRow = geolib_recordAttributeTable.rows.length; oldRow > 0; oldRow--){
		geolib_recordAttributeTable.deleteRow(oldRow-1);			
	}
			
	//Insert new rows	
	//Thankyou Mr.Sean
	for (var myNiceCounter = 0; myNiceCounter < recordAttributes.length; myNiceCounter++) {

		var newRowReference = geolib_recordAttributeTable.insertRow(myNiceCounter);
		
		var newRowLabel = newRowReference.insertCell(0);
		var newRowData = newRowReference.insertCell(1);
		
		newRowLabel.innerHTML = "<strong>" + recordAttributes[myNiceCounter][0] + "</strong>";
		newRowLabel.style.verticalAlign = "top";
		newRowData.innerHTML = recordAttributes[myNiceCounter][1];
		newRowData.style.verticalAlign = "top";		
	}			
	
	//Admin only data	
	var geolib_recordAdminAttributeTable = document.getElementById("geolib_recordDetailAdminAttributesData");		
	//Remove old rows
	for (var oldRow = geolib_recordAdminAttributeTable.rows.length; oldRow > 0; oldRow--){
		geolib_recordAdminAttributeTable.deleteRow(oldRow-1);			
	}
		
	//Insert new rows
	if (geolib_userIsAdmin == true) {
		for (var myNiceAdminCounter = 0; myNiceAdminCounter < adminAttributes.length; myNiceAdminCounter++) {		
			var newRowReference = geolib_recordAdminAttributeTable.insertRow(myNiceAdminCounter);
			
			var newRowLabel = newRowReference.insertCell(0);
			var newRowData = newRowReference.insertCell(1);
			
			newRowLabel.innerHTML = "<strong>" + adminAttributes[myNiceAdminCounter][0] + "</strong>";
			newRowLabel.style.verticalAlign = "top";
			newRowData.innerHTML = adminAttributes[myNiceAdminCounter][1];
			newRowData.style.verticalAlign = "top";
		}
	}	
	
	//Set Timer method to remove ticker ("fake" delay)
	geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);		
}

		
///BEGIN UTILITY FUNCTIONS
/**
* Helper functions to provide common functions / methods etc.
*/	
	
/** dwrErrorHandler()
*
* Method to handle errors inside DWR related functions.
* Due to nesting, this catches virtually all JS errors in the application.
*/			
function dwrErrorHandler(msg) {
	//Blank the pagnation bars to default
	//var topPaging = document.getElementById("geolib_topPaging");					
	//var bottomPaging = document.getElementById("geolib_bottomPaging");
	var displayError = "";
	//topPaging.innerHTML = "GeolSoc Library";	
	//bottomPaging.innerHTML = "GeolSoc Library";
	
	//The error may be the result of a validation falure, 
	//if so the msg will be of the format "field#message"
	if (msg.indexOf("#") > -1) {
		//We have a field & a message
		var msgComponents = msg.split("#");
		
		if (msgComponents[0] == "Keyword") {
			//Keyword Error!
			document.KeywordSearchForm.keyword.parentNode.className = "errorField";	   		
		} else {
			//Detail error
			//alert(msgComponents[0]);
			document.DetailSearchForm.elements["geolib_"+msgComponents[0]].parentNode.className = "errorField";
		}
		
		//Set the text for the error	
		displayError = msgComponents[1];	
	} else {
		//Use the raw error message
		displayError = msg;
	}			
	
	//Output the error message
	document.getElementById("errorContainer").style.display = "";
	document.getElementById("errorContainerText").innerHTML = displayError;
}


//Instruct DWR to use our bespoke error-handler
DWREngine.setErrorHandler(dwrErrorHandler);


/** geolib_switchTab()
*
* Attempts to make visible a particular tab.
* It must be enabled via geolib_enableTab() before calling this method.<b> 
*
*/	
function geolib_switchTab(tabElement, performTask) {

	//Iterate over the tabs
	for (var tabsCounter = 0; tabsCounter < geolib_gisSearchTabs.length; tabsCounter++) {	
		
		var tabName = tmpTab = geolib_gisSearchTabs[tabsCounter]["tab"];
		var tabEnabled = geolib_gisSearchTabs[tabsCounter]["enabled"];
		var tabActive = geolib_gisSearchTabs[tabsCounter]["active"];
		var activationTask = geolib_gisSearchTabs[tabsCounter]["task"];
		
		var tabControl = document.getElementById("tabControl"+tabName);
		var tabContainer = document.getElementById(tabName+"Container");
		
		if (tabEnabled == true) {
			//The this tab is enabled so we can potentially do things to it
			//Ensure that the tab control has function
			tabControl.style.cursor = "";
			tabControl.href = "javascript:geolib_switchTab('"+tabName+"', true)";
			
			//Check if this is the tab we are supposed to be showing
			if (tabName == tabElement) {
				//Declare the tab as active
				geolib_gisSearchTabs[tabsCounter]["active"] = true;
				
				//Make the control highlighted
				tabControl.style.textDecoration = "underline";
				tabControl.style.color = "#FFF";
				
				//Show the tab's container
				tabContainer.style.display = "";
				
				//Do we want to perform activation tasks?				
				if (performTask == true) {
					//Do the correct activation task!
					switch (activationTask) {
						case "regenCurrentPage":
							//Regenerate the current page
							//Disable the Record and Sheet tabs
							//processPagedResult recalls this function (without the task) to regen tabs
							geolib_disableTab("Record");
							geolib_disableTab("Sheets");
							geolib_processPagedResults(geolib_searchCurrentPage);
							break;
						case "regenCurrentRecord":
							geolib_showRecord(geolib_currentRecordDetail);
							break;							
						case "regenSheetPage":
							//Regenerate a page of sheet data
							geolib_processPagedSheetData(geolib_sheetCurrentPage);
							document.getElementById("SheetsContainer").style.display = "";
							document.getElementById("SheetDetailContainer").style.display = "none";
							window.frames.gisInterface.soukgslHighlightSingleSheetCommand("-1");	
							break;
					}
				}
			} else {
				//Mark the tab as inactive
				geolib_gisSearchTabs[tabsCounter]["active"] = false;
				
				//Remove any highlighting
				tabControl.style.textDecoration = "none";
				
				//Hide the related container
				tabContainer.style.display = "none";
				
				if (tabName == "Sheets") {
					//Ensure that the Sheet detail is also hidden
					document.getElementById("SheetDetailContainer").style.display = "none";
				}			
			}
		} else {
			//The tab is not available, so turn off it's control and hide its container
			//Declare it inactive
			geolib_gisSearchTabs[tabsCounter]["active"] = false;
			
			//Ensure the control has no function
			tabControl.style.cursor = "not-allowed";		
			tabControl.href = "javascript:void(0)";
			tabControl.style.textDecoration = "none";
			
			//Ensure the tab's container is hidden
			tabContainer.style.display = "none";
		}		
	}	
}


/** dwrErrorHandler()
*
* Method to handle errors inside DWR related functions.
* Due to nesting, this catches virtually all JS errors in the application.
*/	
function geolib_enableTab(tabElement) {
	for (var tabsCounter = 0; tabsCounter < geolib_gisSearchTabs.length; tabsCounter++) {	
		var temp = geolib_gisSearchTabs[tabsCounter]["tab"];
		if (geolib_gisSearchTabs[tabsCounter]["tab"] == tabElement) {
			geolib_gisSearchTabs[tabsCounter]["enabled"] = true;
		}
	}
}

function geolib_disableTab(tabElement) {
	for (var tabsCounter = 0; tabsCounter < geolib_gisSearchTabs.length; tabsCounter++) {	
		var temp = geolib_gisSearchTabs[tabsCounter]["tab"];
		if (geolib_gisSearchTabs[tabsCounter]["tab"] == tabElement) {
			geolib_gisSearchTabs[tabsCounter]["enabled"] = false;
		}
	}
}
		
/** geolib_beginAjaxActivity()
*
* Clears any existing timer methods to remove the ajax activity display
* and ensures it is visible
*/
function geolib_beginAjaxActivity() {	
	//Remove any timeouts pending
	clearTimeout(geolib_ajaxActivityTimer);
	
	//Enable the spinner
	var ajaxSpinnner = document.getElementById("ajaxActivity");
	ajaxSpinnner.style.visibility = 'visible';		
}


/** geolib_endAjaxActivity()
*
* Removes AJAX Activity indicator
*/
function geolib_endAjaxActivity() {	
	//Disable (hide) the spinner
	var ajaxSpinnner = document.getElementById("ajaxActivity");
	ajaxSpinnner.style.visibility = 'hidden';		
}


/** geolib_processFieldData()
*
* Replaces | characters in the input with html line-breaks (<br>)
*/	
var geolib_fieldDataRegExp = /\|/g;
var geolib_fieldDataSpacesRegExp = /&nbsp;/g;
function geolib_processFieldData(dataString) {
	var toReturn = dataString;
	
	toReturn = toReturn.replace(geolib_fieldDataRegExp, "<br />");
	toReturn = toReturn.replace(geolib_fieldDataSpacesRegExp, " ");
	
	return toReturn;
}

function geolib_generateResultPlaceArray() {
	
	var holdingArray = new Array();	
	
	for (var arrayPlace = 0; arrayPlace < geolib_searchResults.length; arrayPlace++) {			
		holdingArray[geolib_searchResults[arrayPlace].id] = arrayPlace;				
	}
	
	geolib_searchResultsPlacementArray = holdingArray;
}


/** geolib_clearFormErrors()
*
* Removes all error Messages and clears Error classes on form elements
*/
function geolib_clearFormErrors() {
	//Remove & Clear the central message display	
	document.getElementById("errorContainer").style.display = "none";
	document.getElementById("errorContainerText").innerHTML = "";
	
	//Clear any error classes on individual fields
	document.KeywordSearchForm.keyword.parentNode.className = "";

	document.DetailSearchForm.geolib_Author.parentNode.className = "";	
	document.DetailSearchForm.geolib_Title.parentNode.className = "";
	document.DetailSearchForm.geolib_ScaleFrom.parentNode.className = "";
	document.DetailSearchForm.geolib_ScaleTo.parentNode.className = "";
	document.DetailSearchForm.geolib_LatCoordDeg.parentNode.className = "";
	document.DetailSearchForm.geolib_LatCoordMin.parentNode.className = "";
	document.DetailSearchForm.geolib_LonCoordDeg.parentNode.className = "";
	document.DetailSearchForm.geolib_LonCoordMin.parentNode.className = "";
	document.DetailSearchForm.geolib_Publisher.parentNode.className = "";
	document.DetailSearchForm.geolib_DateFrom.parentNode.className = "";
	document.DetailSearchForm.geolib_DateTo.parentNode.className = "";
	document.DetailSearchForm.geolib_Subject.parentNode.className = "";
	document.DetailSearchForm.geolib_Language.parentNode.className = "";
	document.DetailSearchForm.geolib_geographicArea.parentNode.className = "";
}


/** geolib_clearFormErrors()
*
* Removes all error Messages
*/
function geolib_clearGeneralErrors() {
	//Remove & Clear the central message display	
	document.getElementById("errorContainer").style.display = "none";
	document.getElementById("errorContainerText").innerHTML = "";
}
	

/** geolib_viewSerial()
*
* Opens a popup window to show a linked Serial Record
*/
function geolib_viewSerial() {
	//Open the window
	serialWindow  = window.open(geolib_serialLinkView+"?record="+geolib_currentRecordSerialLinkID, "GeoLibSerial", "toolbar=no,menubar=no,scrollbars=yes,resizable=yes,alwaysRaised=yes,width=789");
	//Ensure it has focus
	if (window.focus) {serialWindow.focus();}
}


/** geolib_viewBibliography()
*
* Opens a popup window to show a users' bibliography
*/
function geolib_viewBibliography() {	
	//Open the window
	biblioWindow  = window.open(geolib_biblioLinkView, "GeoLibBibliography", "toolbar=no,menubar=no,scrollbars=yes,resizable=yes,alwaysRaised=yes,width=789");		
	//Ensure it has focus
	if (window.focus) {biblioWindow.focus();}		
}


/** geolib_addToBibliography()
*
* Opens a popup window to add an entry to a users' bibliography
*/
function geolib_addToBibliography() {	
	//Open the window
	biblioWindow  = window.open(geolib_biblioLinkAdd.replace("#recordHolder#", geolib_currentRecordDetailID), "GeoLibBibliography", "toolbar=no,menubar=no,scrollbars=yes,resizable=yes,alwaysRaised=yes,width=789");
	//Ensure it has focus
	if (window.focus) {biblioWindow.focus();}
}


/* DO NOT ATTEMPT TO ALTER THE 2 METHODS BELOW UNLESS YOU KNOW WHAT YOU ARE DOING OR ARE SOME SORT OF WIZARD */
/** geolib_generatePagingControl()
*
* Generates the paging control for the *Results List*
*/	
function geolib_generatePagingControl(pagingLocation) {	
	//Get the document element to receive this paging control
	var	numPages = Math.ceil(geolib_searchResults.length / geolib_pagingPerPage);
	var pagingContainer = document.getElementById(pagingLocation);
	pagingContainer.innerHTML = "";
	
  ///Output the basic X to Y of Z portion (header only)
  	if (pagingLocation == "ResultsHeader") {
		pagingContainer.innerHTML = "&nbsp;<strong>Results " + parseInt(geolib_pagingStartRecord+1) + " to " +
					geolib_pagingEndRecord +  " of " + geolib_searchResults.length + ".</strong>&nbsp;&nbsp;<br /><br />";
	}
	
  	///Generate the actual clickable links
	if (numPages > 1) {
		//Link to first page is always the same
		if (geolib_searchCurrentPage == 0) {
			//Show none-linking first page
			pagingContainer.innerHTML += "<strong>1</strong>";
		} else {
			//show linking first page
			pagingContainer.innerHTML += "<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults(0);\">1</span>";
		}	
		
		//We have more than one page of results, so here starts the leg work!			
		//If we have 7 or fewer pages, then display is fixed
		if (numPages < 8) {
			//1|2|3|4|5|6|7 (upto)
			for (var aPage = 1; aPage < numPages; aPage++) {
				//Don't link to a page if we are already on it
				if (aPage == geolib_searchCurrentPage) {
					pagingContainer.innerHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
				} else {
					pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ aPage +");\">" + parseInt(aPage+1) + "</span>";
				}		
			}
		} 
		else {
			if (geolib_searchCurrentPage < 4) {
				//1|2|3|4|5|5+3 or last-1|last
				
				//Iterate over the first pages
				for (var aPage = 1; aPage < 5; aPage++) {
					//Don't link to a page if we are already on it
					if (aPage == geolib_searchCurrentPage) {
						pagingContainer.innerHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ aPage +");\">" + parseInt(aPage+1) + "</span>";
					}					
				}
				
				//Work out where the ellipsis link to "next 3" should send us
				if ((geolib_searchCurrentPage + 3) < 5) {
					//Show page 6 anyway
					pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults(5);\">&hellip;</span>";
				} else {
					//If the link would send us to the last page or beyond, use (last -1)
					if ((geolib_searchCurrentPage + 4) >= numPages) {
						pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+parseInt(numPages - 2)+");\">&hellip;</span>";						
					} else {
						pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+parseInt(geolib_searchCurrentPage + 3)+");\">&hellip;</span>";
					}					
				}					
			}
			else if (geolib_searchCurrentPage > (numPages - 4)) {
				//1|x-3 or 2|x|*y*|z|last
				
				//calulate the ellipsis link
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+parseInt(numPages -7)+");\">&hellip;</span>";
				
				//Iterate over the last pages					
				for (var aPage = numPages - 5; aPage < numPages-1; aPage++) {
					//Don't link to a page if we are already on it
					if (aPage == geolib_searchCurrentPage) {
						pagingContainer.innerHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ aPage +");\">" + parseInt(aPage+1) + "</span>";
					}					
				}				
			} 
			else {
				//1|x-3 or 2|x|*y*|z|z+3 or last-1|last
				
				//calulate the previous 3 ellipsis link
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage - 3) +");\">&hellip;</span>";
				
				//Add previous, currnt and next page links
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage - 1) +");\">"+ geolib_searchCurrentPage +"</span>";
				pagingContainer.innerHTML += "|<strong>" + parseInt(geolib_searchCurrentPage+1) + "</strong>";
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage + 1) +");\">"+ parseInt(geolib_searchCurrentPage + 2) +"</span>";
				
				//Add the next 3 ellipsis link
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+parseInt(geolib_searchCurrentPage + 3)+");\">&hellip;</span>";
					
			}
			
			//Show the last page
			//Always the same :)
			if (geolib_searchCurrentPage == (numPages-1)) {
				//Show none-linking first page
				pagingContainer.innerHTML += "|<strong>" + numPages + "</strong>";
			} else {
				//show linking first page
				pagingContainer.innerHTML += "|<span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedResults("+ parseInt(numPages-1) +");\">" + numPages + "</span>";				
			}		
		}
	}
	
	if (pagingLocation == "ResultsHeader") {
		pagingContainer.innerHTML += "<hr />";
	}
		
	return true;
}


/** geolib_generateRecordPagingControl()
*
* Generates the paging control for the *Detail View*
*/	
function geolib_generateRecordPagingControl(currentRecord, totalRecords) {
	
	var pagingHTML = "";
	
	//Generate a simplified pagination control
	if (currentRecord > 0) {
		//Show a "Previous" link!
		pagingHTML += "<div style=\"float: left;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord - 1)].id +");\">&laquo; Previous</span></div>";
	}
	
	if (currentRecord < (totalRecords-1)) {
		//Show a "Next" Link
		pagingHTML += "<div style=\"float: right;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord+1)].id +");\">Next &raquo;</span></div>";		
	}
	
	return pagingHTML;
}


/** geolib_generateSheetPagingControl()
*
* Generates the paging control for the *Sheet Listing*
*/	
function geolib_generateSheetPagingControl() {
	
	var pagingHTML = "";		
	
	//Generate a simplified pagination control
	if (geolib_sheetCurrentPage > 0) {
		//Show a "Previous" link!
		pagingHTML += "<div style=\"float: left;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedSheetData("+ (geolib_sheetCurrentPage -1) +");\">&laquo; Previous</span></div>";
	}
	
	if (geolib_sheetPagingEndRecord < geolib_sheetResults.length) {
		//Show a "Next" Link
		pagingHTML += "<div style=\"float: right;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_processPagedSheetData("+ (geolib_sheetCurrentPage + 1) +");\">Next &raquo;</span></div>";		
	}
	
	return pagingHTML;
}


/** geolib_generateSheetDetailPagingControl()
*
* Generates the paging control for the *Sheet Detail*
*/	
function geolib_generateSheetDetailPagingControl() {
	
	var pagingHTML = "";		
	
	//Generate a simplified pagination control
	if (geolib_sheetCurrentRecord > 0) {
		//Show a "Previous" link!
		pagingHTML += "<div style=\"float: left;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_showSheetDetail("+ (geolib_sheetCurrentRecord - 1) +");\">&laquo; Previous</span></div>";
	}
	
	if ((geolib_sheetCurrentRecord + 1) < geolib_sheetResults.length) {
		//Show a "Next" Link
		pagingHTML += "<div style=\"float: right;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_showSheetDetail("+ (geolib_sheetCurrentRecord + 1) +");\">Next &raquo;</span></div>";		
	}
	
	return pagingHTML;
}




///BEGIN GIS Proxy Methods
/**
* Functions that call GIS application methods
*/	

/** geolib_highlightIndexSheet()
*
* Controls the highlighting of index sheet outlines. Ensures only 1 sheets is highlighted,
* and that the proper rendering occurs in the left hand list of records.
*/	
function geolib_highlightIndexSheet(recordPlace, gisRender) {
	
	//If we currently have a highlighted sheeet
	indexIdentifier = geolib_searchResults[recordPlace].id;
	
	if (currentlyHighlightedSheet != null) {
		//A sheet has been highlighted.
		//This will be removed so renable to the link
		var currentlyHighlightedSheetControl = document.getElementById("highlightLinkContainer_"+currentlyHighlightedSheet);
		
		if (currentlyHighlightedSheetControl) {
			currentlyHighlightedSheetControl.innerHTML = "Highlight";
			currentlyHighlightedSheetControl.onclick = function (e) {geolib_highlightIndexSheet(currentlyHighlightedSheet, true); };
			currentlyHighlightedSheetControl.parentNode.className = "clearedMapItem"; //setAttribute("class", "clearedMapItem");
		} else {
			currentlyHighlightedSheet = null;
		}
	}
	
	if (gisRender == true) {
		//Highlight this sheet
		window.frames.gisInterface.soukgslHighlightSingleMapCommand(indexIdentifier);
	}
		
	//Store this sheet as the one currently highlighted	
	currentlyHighlightedSheet = recordPlace;
	
	//Update the page control for this sheet	
	var newHighlightedSheetControl = document.getElementById("highlightLinkContainer_"+recordPlace);	
	newHighlightedSheetControl.innerHTML = "Deselect";
	newHighlightedSheetControl.style.color = "#000000";
	newHighlightedSheetControl.onclick = function (e) {geolib_clearHighlightIndexSheet(); };	
	newHighlightedSheetControl.parentNode.className = "highlightedMapItem"; //setAttribute("class", "highlightedMapItem");
	
	
	
	//Make the record tab available for this record!
	geolib_currentRecordDetail = geolib_searchResults[recordPlace].id;
	
	geolib_enableTab("Record");	
	document.getElementById("tabControlRecord").style.cursor = "";
	document.getElementById("tabControlRecord").href = "javascript:geolib_switchTab('Record', true)";	
}


/** geolib_clearHighlightIndexSheet()
*
* Removes the any currently highlighted index sheet.  Ensures the left-hand
* link is reset before calling a GIS method to highlight a "fake" index sheet
*/	
function geolib_clearHighlightIndexSheet() {
	
	if (currentlyHighlightedSheet != null) {
		//A sheet has been highlighted.
		//This will be removed so renable to the link
		var currentlyHighlightedSheetControl = document.getElementById("highlightLinkContainer_"+currentlyHighlightedSheet);
		
		if (currentlyHighlightedSheetControl) {
			currentlyHighlightedSheetControl.innerHTML = "Highlight";
			currentlyHighlightedSheetControl.onclick = function (e) {geolib_highlightIndexSheet(currentlyHighlightedSheet, true); };
			currentlyHighlightedSheetControl.parentNode.className = "clearedMapItem"; //etAttribute("class", "clearedMapItem");
		} else {
			currentlyHighlightedSheet = null;
		}
	}

	window.frames.gisInterface.soukgslHighlightSingleMapCommand("-1");
	
	//Prevent switching to an empty Record tab
	geolib_currentRecordDetail = 0;
	geolib_disableTab("Record");

	document.getElementById("tabControlRecord").style.cursor = "not-allowed";
	document.getElementById("tabControlRecord").href = "javascript:void(0)";
}


/** geolib_highlightSingleMapSheet()
*
* Method that highlights a single sheet that forms part of a record.
* Ensures the correct rendering of highlight links occurs before calling a GIS method
*/	
function geolib_highlightSingleMapSheet(sheetId, gisRender) {
	
	if (currentlyHighlightedSingleMapSheet != null) {
		//A sheet has been highlighted.
		//This will be removed so renable to the link
		var currentlyHighlightedSingleMapSheetControl = document.getElementById("singleSheetLinkContainer_"+currentlyHighlightedSingleMapSheet);
		
		if (currentlyHighlightedSingleMapSheetControl) {
			currentlyHighlightedSingleMapSheetControl.innerHTML = "Highlight";
			currentlyHighlightedSingleMapSheetControl.onclick = function (e) {geolib_highlightSingleMapSheet(currentlyHighlightedSingleMapSheet, true); };
			currentlyHighlightedSingleMapSheetControl.parentNode.className = "clearedMapItem"; //setAttribute("class", "clearedMapItem");
		} else {
			currentlyHighlightedSingleMapSheet = null;
		}
	}
	
	if (gisRender == true) {
		//Highlight this sheet
		window.frames.gisInterface.soukgslHighlightSingleSheetCommand(sheetId);
	}
	
	//Store this sheet as the one currently highlighted	
	currentlyHighlightedSingleMapSheet = sheetId;
	
	//Update the page control for this sheet
	var newHighlightedSheetControl = document.getElementById("singleSheetLinkContainer_"+sheetId);	
	newHighlightedSheetControl.innerHTML = "Deselect";
	newHighlightedSheetControl.style.color = "#000000"
	newHighlightedSheetControl.onclick = function (e) {geolib_clearHighlightSingleMapSheet(); };
	newHighlightedSheetControl.parentNode.className = "highlightedMapItem"; //setAttribute("class", "highlightedMapItem");
}


/** geolib_clearHighlightSingleMapSheet()
*
* Clears any currently highlighted single map sheet by calling a GIS method.
* Ensures that the left-hand list remains properly rendered and in synch with the display.
*/	
function geolib_clearHighlightSingleMapSheet() {
	if (currentlyHighlightedSingleMapSheet != "") {
		//A sheet has been highlighted.
		//This will be removed so renable to the link
		var currentlyHighlightedSingleMapSheetControl = document.getElementById("singleSheetLinkContainer_"+currentlyHighlightedSingleMapSheet);
		
		if (currentlyHighlightedSingleMapSheetControl) {
			currentlyHighlightedSingleMapSheetControl.innerHTML = "Highlight";
			currentlyHighlightedSingleMapSheetControl.onclick = function (e) {geolib_highlightSingleMapSheet(currentlyHighlightedSingleMapSheet, true); };
			currentlyHighlightedSingleMapSheetControl.parentNode.className = "clearedMapItem"; //setAttribute("class", "clearedMapItem");
		} else {
			currentlyHighlightedSingleMapSheetControl = null;
		}
	}

	window.frames.gisInterface.soukgslHighlightSingleSheetCommand("-1");
}


/** geolib_showMapSheets()
*
* Method to display all the single map sheets that comprise a library catalouge record
*/	
function geolib_showMapSheets(recordPlace, recordId) {

	//We're not sure what data we're supposed to be querying at this point
	//Perform a sanity check here
	var Data = geolib_searchResults[recordPlace];
	
	if (Data.id == recordId) {
		//Things match up
		window.frames.gisInterface.soukgslOutlineSheetsCommand(Data.recordId,
													Data.minX, Data.minY,
													Data.maxX, Data.maxY);		
	} else {
		//Eeek
		alert("Data issue");
		return false;	
	}
}


function geolib_showSheetDetail(sheetRecord) {	
	//Indicate to the callback we want to view the Sheet Detail
	geolib_querySheetDetail = true;
	
	//Get the ID for this sheet, & ensure we know which sheet we are on
	sheetID = geolib_sheetResults[sheetRecord]["sheetID"];	
	geolib_sheetCurrentRecord = sheetRecord;
	
	//Request a highlight of the sheet, including a GIS redraw
	geolib_highlightSingleMapSheet(sheetID, true);
}


///BEGIN GIS CALLBACK FUNCTIONS
/*
* Methods that may be triggered following a GIS AJAX call
*/
/** geolib_gisHandlerProcessRedraw()
*
* This method is called by the GIS application whenever the extents of the
* current view changes (pan or zoom)
*
* The first instance of this is ignored (occurs on map load).
* If the view is changed and a search has yet to be performed, then an
* "auto search" is called to locate all the records in the new viewport.
*/
function geolib_gisHandlerProcessRedraw(xml) {
	
	if (isFirstGisRedraw == true) {
		//do nothing
		isFirstGisRedraw = false;
	} else {
		if (geolib_searchResults.length == 0) {
			//Start Spinner
			geolib_beginAjaxActivity();
			
			var minX = xml.getElementsByTagName("minX").item(0).firstChild.data;
			var minY = xml.getElementsByTagName("minY").item(0).firstChild.data;;
			var maxX = xml.getElementsByTagName("maxX").item(0).firstChild.data;;
			var maxY = xml.getElementsByTagName("maxY").item(0).firstChild.data;;
												
			LibraryActions.searchByCoordinatesAction(minX, minY, maxX, maxY, geolib_coordinateCallBack);			
			
			//Set a timeout for the spinner
			geolib_ajaxActivityTimer = setTimeout("geolib_endAjaxActivity()", ajaxFakeDelay);
		}
	}
}


/** geolib_gisHandlerProcessSheetList()
*
* This method is called by the GIS application whenever the sheets for
* a particular map are shown on the GIS display.
*
* If sheets have been found, then they are outputted to a display container, and the sheets
* tab is activated (but not given focus)
*/
function geolib_gisHandlerProcessSheetList(xml) {
	
	//Get the sheets from the returned XML
	var sheetElements = xml.getElementsByTagName("sheet");
	geolib_sheetResults = new Array();

	if (sheetElements.length > 0) {
		//We have some sheets!
		//Enable the tab!
		geolib_enableTab("Sheets");
		geolib_enableTab("Record");
		geolib_switchTab("Record");
		
		//Process each sheet
		for (var i=0;i<sheetElements.length;i++) {
			var currentSheet = sheetElements[i];
			var sheetSummary = new Array();
			
			//SheetID should always be herfe						
			sheetSummary["sheetID"] = currentSheet.getElementsByTagName("objectId").item(0).firstChild.data;//firstChild.nodeValue;//.getAttribute("textContent");			
			
			//sheetName, sheetNum and sheetHeld are all optional
			if (nodeElement = currentSheet.getElementsByTagName("sheetName").item(0).firstChild) {
				sheetSummary["sheetName"] = nodeElement.data;
			} else {
				sheetSummary["sheetName"] = null;
			}
			
			if (nodeElement = currentSheet.getElementsByTagName("sheetNum").item(0).firstChild) {
				sheetSummary["sheetNum"] = nodeElement.data;
			} else {
				sheetSummary["sheetNum"] = null;
			}
			
			if (nodeElement = currentSheet.getElementsByTagName("held").item(0).firstChild) {
				if (nodeElement.data == "Y") {
					sheetSummary["sheetHeld"] = "Yes";
				} else {
					sheetSummary["sheetHeld"] = "No";
				}
			} else {
				sheetSummary["sheetHeld"] = "No";
			}
											
			geolib_sheetResults[geolib_sheetResults.length] = sheetSummary;
		}
	} else {
		dwrErrorHandler("No Sheet Data is available for this Map.");
		geolib_disableTab("Sheets");
		geolib_switchTab("Record");	
	}
}


/** geolib_gisHandlerProcessSheetDetail()
*
* This method is called by the GIS application whenever a single sheet
* has been highligthed
*
*/
function geolib_gisHandlerProcessSheetDetail(xml) {
	if (geolib_querySheetDetail == true) {
		//We have invoked a request for sheet details		
		//Show the Details Panel
		document.getElementById("SheetsContainer").style.display = "none";
		document.getElementById("SheetDetailContainer").style.display = "";		
		
		
		//Set the Header
		document.getElementById("SheetDetailHeader").innerHTML = 
			"&nbsp;<strong>Displaying Sheet " + parseInt(geolib_sheetCurrentRecord+1) 
					+  " of " + geolib_sheetResults.length + ".</strong>&nbsp;&nbsp;<br /><br />";
		
		var sheetId = xml.getElementsByTagName("objectId").item(0).firstChild.data;
		
		if (nodeElement = xml.getElementsByTagName("sheetNum").item(0).firstChild) {
			sheetNum = nodeElement.data;
		} else {
			sheetNum = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("sheetName").item(0).firstChild) {
			sheetName = nodeElement.data;
		} else {
			sheetName = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("held").item(0).firstChild) {
			if (nodeElement.data == "Y") {
				held = "Yes";
			} else {
				held = "No";
			}
		} else {
			held = "No";
		}
		
		if (nodeElement = xml.getElementsByTagName("theme").item(0).firstChild) {
			theme = nodeElement.data;
		} else {
			theme = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("location").item(0).firstChild) {
			sheetLocation = nodeElement.data;
		} else {
			sheetLocation = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("yearPub").item(0).firstChild) {
			yearPub = nodeElement.data;
		} else {
			yearPub = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("textNotes").item(0).firstChild) {
			textNotes = nodeElement.data;
		} else {
			textNotes = null;
		}
		
		if (nodeElement = xml.getElementsByTagName("notes").item(0).firstChild) {
			notes = nodeElement.data;
		} else {
			notes = null;
		}
		
		//Remove old rows
		var sheetDetailTable = document.getElementById("SheetDetailTable");
		for (var oldRow = sheetDetailTable.rows.length; oldRow > 0; oldRow--){
			sheetDetailTable.deleteRow(oldRow-1);			
		}
		
		if (sheetNum != null && sheetNum.length > 0 && sheetNum != " ") {insertSheetDetailRow("Sheet Number:", sheetNum);}
		if (sheetName != null && sheetName.length > 0 && sheetName != " ") {insertSheetDetailRow("Sheet Name:", sheetName);}
		insertSheetDetailRow("Held?:", held);
		if (theme != null && theme.length > 0 && theme != " ") {insertSheetDetailRow("Theme:", theme);}
		if (sheetLocation != null && sheetLocation.length > 0 && sheetLocation != " ") {insertSheetDetailRow("Location:", sheetLocation);}
		if (yearPub != null && yearPub.length > 0 && yearPub != " ") {insertSheetDetailRow("Year Published:", yearPub);}
		if (textNotes != null && textNotes.length > 0 && textNotes != " ") {insertSheetDetailRow("Text Notes:", textNotes);}
		if (notes != null && notes.length > 0 && notes != " ") {insertSheetDetailRow("Notes:", notes);}
		
		//Set the Footer (Pagination)
		document.getElementById("SheetDetailFooter").innerHTML = geolib_generateSheetDetailPagingControl();
		
	} 
	
	//Reset the Detail Handler trigger
	geolib_querySheetDetail = false;
}


function insertSheetDetailRow(label, value) {
	var sheetDetailTable = document.getElementById("SheetDetailTable");	
	var newRowReference = sheetDetailTable.insertRow(sheetDetailTable.rows.length);		
	var newRowLabel = newRowReference.insertCell(0);
	var newRowData = newRowReference.insertCell(1);		
	
	newRowLabel.innerHTML = "<strong>" + label + "</strong>";
	newRowLabel.style.verticalAlign = "top";
	newRowData.innerHTML = value;
}


function geolib_processPagedSheetData(pageNumber) {
	//Pagination is hard-coded for the GIS search	
	geolib_sheetPagingPerPage = 10;
	var sheetsContainer = document.getElementById("SheetsBody");
   	var pagedRecords = new Array();
   
    //Switch the display focus to show the results pan
    geolib_enableTab("Sheets");
    geolib_switchTab("Sheets", false);
    
    //Blank the currently displayed page
    sheetsContainer.innerHTML = "";
        	    
	//Calculate start and end points for t his page
    geolib_sheetPagingStartRecord = (geolib_sheetPagingPerPage * pageNumber);
    geolib_sheetPagingEndRecord = geolib_sheetPagingStartRecord + parseInt(geolib_sheetPagingPerPage);
    
    //Check to prevent out-of-range issues
    if (geolib_sheetPagingEndRecord > geolib_sheetResults.length) {
	    geolib_sheetPagingEndRecord = geolib_sheetResults.length;
	}		
	
	//Store the current page for use by the Paging Control
	geolib_sheetCurrentPage = pageNumber;
	
  ///Generate page	
	//Display the top paging bar
	document.getElementById("SheetsHeader").innerHTML = 
			"&nbsp;<strong>Sheets " + parseInt(geolib_sheetPagingStartRecord+1) + " to " +
					geolib_sheetPagingEndRecord +  " of " + geolib_sheetResults.length + ".</strong>&nbsp;&nbsp;<br /><br />";
	
	geolib_generateSheetPagingControl("SheetsHeader");		
	
	//For each result on the page, put in an asynchronous call to show summary data
	for (var currentSheetKey = geolib_sheetPagingStartRecord; currentSheetKey < geolib_sheetPagingEndRecord; currentSheetKey++) {
		//Get the current record we are looking at
		var currentSheet = geolib_sheetResults[currentSheetKey];
		var containerDiv = document.createElement("div");
		
		
		var summaryTable = document.createElement("table");
		summaryTable.style.width = "100%";
		summaryTableRowsCounter = 0;
		
		//Scale shown
		if (currentSheet["sheetNum"] != null && currentSheet["sheetNum"].length > 0) {		
			var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
			var cellLabel = tableRow.insertCell(0);
			var cellField = tableRow.insertCell(1);		
			
			cellLabel.innerHTML = "<strong>Sheet Number:</strong>";
			cellLabel.style.verticalAlign = "top";
			cellLabel.style.width = "30%";
			cellField.innerHTML = currentSheet["sheetNum"];
			cellField.style.verticalAlign = "top";
			
			summaryTableRowsCounter++;			
		}
		
		if (currentSheet["sheetName"] != null && currentSheet["sheetName"].length > 0 && currentSheet["sheetName"] != " ") {		
			var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
			var cellLabel = tableRow.insertCell(0);
			var cellField = tableRow.insertCell(1);		
			
			cellLabel.innerHTML = "<strong>Sheet Name:</strong>";
			cellLabel.style.verticalAlign = "top";
			cellLabel.style.width = "45%";
			cellField.innerHTML = currentSheet["sheetName"];
			cellField.style.verticalAlign = "top";
			
			summaryTableRowsCounter++;			
		}
		
		if (summaryTableRowsCounter == 0) {
			//INsert a "no data" row
			var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
			var cellLabel = tableRow.insertCell(0);
			
			cellLabel.innerHTML = "<em>No data available</em>";
			cellLabel.style.verticalAlign = "top";
			cellLabel.setAttribute("colspan", "2");
			
			summaryTableRowsCounter++;			
		}
				
		if (currentSheet["sheetHeld"] != null && currentSheet["sheetHeld"].length > 0) {		
			var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
			var cellLabel = tableRow.insertCell(0);
			var cellField = tableRow.insertCell(1);		
			
			cellLabel.innerHTML = "<strong>Held?:</strong>";
			cellLabel.style.verticalAlign = "top";
			cellLabel.style.width = "45%";
			cellField.innerHTML = currentSheet["sheetHeld"];
			cellField.style.verticalAlign = "top";
			
			summaryTableRowsCounter++;			
		}		
		
		containerDiv.appendChild(summaryTable);
		
		var outputString = "";
		
		/*//Handle displaying the summary data
		if (currentSheet["sheetNum"] != null && currentSheet["sheetNum"].length > 0) {outputString += currentSheet["sheetNum"] + ".&nbsp;";	}		
		if (currentSheet["sheetName"] != null && currentSheet["sheetName"].length > 0 && currentSheet["sheetName"] != " ") {outputString += currentSheet["sheetName"] + ";&nbsp;";}				
		//If we have nothing so far, insert a placeholder
		if (outputString.length == 5) {outputString += "<em>No data available</em>&nbsp;";}		
		
		if (currentSheet["sheetHeld"] != null && currentSheet["sheetHeld"].length > 0) {outputString += currentSheet["sheetHeld"] + "<br />";}
		*/
		//Add Highlight controls
		outputString = "<span id=\"singleSheetLinkContainer_" + currentSheet["sheetID"] 
								+ "\" class=\"brownAjaxLinks\" style=\"float: left;\" onClick=\"geolib_highlightSingleMapSheet('" + currentSheet["sheetID"] + "', true)\">Highlight</span>";
								
		outputString += "<span class=\"brownAjaxLinks\" style=\"float: right;\" onClick=\"geolib_showSheetDetail(" + parseInt(currentSheetKey) + ");\">Details</span><br /><br /></div>";
										
		containerDiv.innerHTML += outputString;
		sheetsContainer.appendChild(containerDiv);
	}	
	
	//Display the bottom paging bar
	document.getElementById("SheetsFooter").innerHTML = geolib_generateSheetPagingControl() + "<div id=\"SheetsBack\" style=\"text-align: center; clear: both;\"><span class=\"brownAjaxLinks\" onClick=\"geolib_switchTab('Record', true);\" >Back</span></div>";
  
	//Returning false should kill browser history issues
	return false;	
}


function geolib_gisHandlerProcessSheetHighlight(data) {
	//Determine which sheet "number" this is
	var sheetNumber = null;
	var gisSelectedSheet = data.firstChild.nodeValue;
	
	for (var i = 0; i < geolib_sheetResults.length; i++) {
		if (geolib_sheetResults[i]["sheetID"] == gisSelectedSheet) {
			//Sheet found - store it and drop out
			sheetNumber = i;
			break;
		}	
	}
	
	//If we have found a sheet, we need to highlight it in the list!
	if (sheetNumber != null) {
		//Determine what page we should be on		
		var requiredPage = Math.floor((parseInt(sheetNumber) / parseInt(geolib_sheetPagingPerPage)));	
		
		//Ensure the correct page (or any page) is rendered
		if (requiredPage != geolib_sheetCurrentPage || 
				document.getElementById("SheetsBody").innerHTML.length == 0) {
			//Switch to that page
			geolib_processPagedSheetData(requiredPage);
		}
		
		//ensure we're on the correct tab
		geolib_enableTab("Sheets");
   		geolib_switchTab("Sheets", false);
   		
		//Have to do this manually
		document.getElementById("SheetsContainer").style.display = "";
		document.getElementById("SheetDetailContainer").style.display = "none";
		
		//Highlight that record
		geolib_highlightSingleMapSheet(gisSelectedSheet, false);
	} else {
		//Something wrong occured - clear whatever it was we managed to highlight!
		window.frames.gisInterface.soukgslHighlightSingleSheetCommand("-1");
	}
}

function geolib_gisHandlerProcessMapHighlight(data) {
	var recordPlace = null;
	recordPlace = geolib_searchResultsPlacementArray[data.firstChild.nodeValue];
	
	if (recordPlace != null) {
		geolib_highlightIndexSheet(recordPlace, false);	
	} else {
		//Dunno what we've got, but clear it!
		window.frames.gisInterface.soukgslHighlightSingleMapCommand("-1");	
	}
}

function geolib_processPassedMapHash() {
	var hashString = window.location.hash;
   	if (hashString.length > 0) {
   		//We have a possible hash string.  		
   		if (hashString.substring(1, 18) == "viewLibraryRecord") {
 			//We need to fake this single record being queried!
 			var recordProperties = hashString.substring(19, hashString.length).split("|");
 			/** 
 			0 -> ID
 			1 -> WestDecCoord
 			2 -> EastDecCoord
 			3 -> NorthDecCoord
 			4 -> SouthDecCoord
 			*/
 			
 			var Data = new Array();
 			Data[0] = {}
 			
 			//Load & Convert parameters   			
 			Data[0].id = parseInt(recordProperties[0]);
 			Data[0].minX = parseFloat(recordProperties[1]);
 			Data[0].maxX = parseFloat(recordProperties[2]);
 			Data[0].minY = parseFloat(recordProperties[4]);
 			Data[0].maxY = parseFloat(recordProperties[3]);
 			Data[0].recordId = recordProperties[5];
 			
 			//Perform some fairly agressive validation
 			if (isNaN(Data[0].id) || isNaN(Data[0].minX) || isNaN(Data[0].maxX) ||
 					isNaN(Data[0].minY) || isNaN(Data[0].maxY)) {
 					//Failed - clear the hash
 					window.location.hash = "";
 					return false;
 			} else {
 				//Good to go!
 				//Stop pan and zoom crazyness
 				isFirstGisRedraw = false;
 				
 				//Trigger the loading of the map
 				geolib_keywordCallBack(Data);
 				
 				return true;
 			}
 		} else {
 			return false;
 		}
 	} else {
	 	return false;
	}
}
 				
