/**
*	geolibFunctions.js
*
*	JavaScript methods to power GeolSoc library search via 
*	AJAX / Web 2.0 methods.
*
*	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_handleContextSwitch()	
*
* Manipulates the detail search form to display only 
* elements applicable to the search type selected.
*/
function geolib_handleContextSwitch() {        
	//Gather the selected option
    var selectedContextIndex = document.KeywordSearchForm.searchType.selectedIndex;            
    var newContext = document.KeywordSearchForm.searchType.options[selectedContextIndex].value;
    
    //TODO - this may change.
    // commented out for maintenance ticket 46, comment 8, issue 2
//    if (newContext == "map") {                             
//        if (confirm("You are about to be redirected to the GIS Map interface.\n\nDo you wish to continue?")) {
//            //Load the GIS interface   
//            window.location = geolib_gisPageUrl;
//        } else {
//            document.KeywordSearchForm.searchType.selectedIndex = 0;
//            geolib_handleContextSwitch();
//        }
//        return;    
//    }	    
    
  ///Enable the required fields for this context
    for (var fieldIndex = 0; fieldIndex < geolib_searchContextArray[newContext]["enabled"].length; fieldIndex++) {
        var labelContainer = document.getElementById("geolib_search"+
                                geolib_searchContextArray[newContext]["enabled"][fieldIndex]+"ContainerLabel");
                                
        var fieldContainer = document.getElementById("geolib_search"+
                                geolib_searchContextArray[newContext]["enabled"][fieldIndex]+"ContainerField");
                                
        
                              
        labelContainer.style.display = "";
		fieldContainer.style.display = "";
        
        var fieldFormElement = document.forms.DetailSearchForm.elements["geolib_"+
                                geolib_searchContextArray[newContext]["enabled"][fieldIndex]];
                
        fieldFormElement.disabled = false;
        fieldFormElement.value = "";
    }
    
  ///Disable the unneeded fields for this context
    for (var fieldIndex = 0; fieldIndex < geolib_searchContextArray[newContext]["disabled"].length; fieldIndex++) {
        var labelContainer = document.getElementById("geolib_search"+
                                geolib_searchContextArray[newContext]["disabled"][fieldIndex]+"ContainerLabel");
        
        var fieldContainer = document.getElementById("geolib_search"+
                                geolib_searchContextArray[newContext]["disabled"][fieldIndex]+"ContainerField");

        labelContainer.style.display = "none";		                                
        fieldContainer.style.display = "none";
        
        var fieldFormElement = document.forms.DetailSearchForm.elements["geolib_"+
                                geolib_searchContextArray[newContext]["disabled"][fieldIndex]];
        
        fieldFormElement.disabled = true;
        //Blank the field when it is hidden
        fieldFormElement.value = "";
    }
    
  ///Special Case
    //Handle Date: label display
    document.getElementById("geolib_searchDateContainerLabel").style.display = 
    	document.getElementById("geolib_searchDateFromContainerLabel").style.display
    	
    //Handle ISBN Labeling
    /**
    * The same field is used, but it must be labelled differently dependent on the context
    **/
    switch (newContext) {
    	case "book":
    		document.getElementById("geolib_searchIsbnIssnContainerLabelText").innerHTML = isbn_label;
    		break;
    	case "serial":
    		document.getElementById("geolib_searchIsbnIssnContainerLabelText").innerHTML = issn_label;
    		break;
    	case "audiovisual":    		
    	case "all":
    	Default:
    		document.getElementById("geolib_searchIsbnIssnContainerLabelText").innerHTML = issnisbn_label;
    		break;
    }	
    
    //Update the hidden form field with the new context
    document.forms.DetailSearchForm.geolib_searchType.value = newContext;	              
}

		
/** geolib_handleKeywordSearchByAjax()
* 
* Performs basic validation & initiates a keyword search
* using DWR calls
*/
function geolib_handleKeywordSearchByAjax() {
  ///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("librarySearchResultsContainer").innerHTML = "";		
	//Ensure pagination control is hidden
	document.geolib_pagingQuantity.style.display = "none";
	
	
  ///Housekeeping, get the values for the relevant fields
	var keywordTerm = document.KeywordSearchForm.keyword.value;
	var selectedContextIndex = document.KeywordSearchForm.searchType.selectedIndex;            
    var selectedContext = document.KeywordSearchForm.searchType.options[selectedContextIndex].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.keywordSearchAction(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_handleDetailSearchByAjax() {
   ///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("librarySearchResultsContainer").innerHTML = "";
	//Ensure pagination control is hidden
	document.geolib_pagingQuantity.style.display = "none";		
	
  ///Housekeeping, get the values for the relevant fields
  	var authorTerm = document.DetailSearchForm.geolib_Author.value;
  	var organisationTerm = document.DetailSearchForm.geolib_Organisation.value;
  	var titleTerm = document.DetailSearchForm.geolib_Title.value;
  	var publisherTerm = document.DetailSearchForm.geolib_Publisher.value;
  	var ISBNTerm = document.DetailSearchForm.geolib_IsbnIssn.value;
  	var subjectTerm = document.DetailSearchForm.geolib_Subject.value;
 	var languageTerm = document.DetailSearchForm.geolib_Language.value;
 	var dateFromTerm = document.DetailSearchForm.geolib_DateFrom.value;
 	var dateToTerm = document.DetailSearchForm.geolib_DateTo.value;
 	var seriesTitleTerm = document.DetailSearchForm.geolib_SeriesTitle.value;
 	var seriesNoTerm = document.DetailSearchForm.geolib_SeriesNo.value;
  	
  	//Get Context and "Join type"
  	var selectedContextIndex = document.KeywordSearchForm.searchType.selectedIndex;            
    var selectedContext = document.KeywordSearchForm.searchType.options[selectedContextIndex].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 (organisationTerm.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 (seriesTitleTerm.length > 0) {validSearch = true;}
    if (seriesNoTerm.length > 0) {validSearch = true;}
    
    //ISBN needs to be numeric only    
	ISBNTerm = ISBNTerm.replace(numericDataRegExp, "");
	document.DetailSearchForm.geolib_IsbnIssn.value = ISBNTerm;
	if (ISBNTerm.length > 0) {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.detailSearchAction(selectedContext, selectedJoin, 
    		authorTerm, organisationTerm, titleTerm, publisherTerm,
    		dateFromToSend, dateToToSend, ISBNTerm, subjectTerm, languageTerm,
    		seriesTitleTerm, seriesNoTerm, 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
	var pagingIndex = document.geolib_pagingQuantity.pagingQuantity.selectedIndex;            
    geolib_pagingPerPage = document.geolib_pagingQuantity.pagingQuantity.options[pagingIndex].value;
    var resultsContainer = document.getElementById("librarySearchResultsContainer");
    
    //Start Spinner
	geolib_beginAjaxActivity();		    
    //Blank the currently displayed page
    resultsContainer.innerHTML = "";
    
    //Remove any CMS content
    document.getElementById("geolib_contentFromJahia").style.display = "none";
    
    //Ensure the record paging control is shown
    document.geolib_pagingQuantity.style.display = "";
    
    //Reset the summary ordering array
    geolib_summaryPlacementOrder = new Array();
        	    
	//Calculate start and end points for this 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]);
  		return;
  	}		

  ///Generate page	
	//Display the top paging bar
	geolib_generatePagingControl("geolib_topPaging");		
	
	//For each result on the page, put in an asynchronous call to show summary data
	for (var currentRecord = geolib_pagingStartRecord; currentRecord < geolib_pagingEndRecord; currentRecord++) {
		//We need to make sure the summary is ordered correctly
		//Store the record number of this record into a mapping array
		geolib_summaryPlacementOrder[geolib_searchResults[currentRecord]] = currentRecord;		
		
		//Create a container element to hold the summary results.
		containerElement = document.createElement("div");
        containerElement.setAttribute("id", "geolib_summaryRecord_"+currentRecord);
        resultsContainer.appendChild(containerElement);
		
		//Finally dispatch the AJAX request
		LibraryActions.getSummaryAction(geolib_searchResults[currentRecord], geolib_getSummaryCallBack);
	}		
	
	//Display the bottom paging bar
	geolib_generatePagingControl("geolib_bottomPaging");
	
	//Display the bottom bilbiography
	var bottomBiblioSummaryLocation = document.getElementById("geolib_recordSummaryBottomBiblio");
	bottomBiblioSummaryLocation.style.visibility = "visible";

  ///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 columnGap = document.getElementById("geolib_columnGap");
		columnGap.style.display = "";	
						
		var searchPanel = document.getElementById("geolib_searchInterface");
		searchPanel.style.display = "";	
		
		var bottomBilbio = document.getElementById("geolib_recordSummaryBottomBiblio");
		bottomBilbio.style.visibility = "visible";
	
	}		
	
	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_processPagedResults(0);			
	} else {
		dwrErrorHandler("Keyword#Your search returned no 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_processPagedResults(0);			
	} else {
		dwrErrorHandler("Your search returned no results");
	}	
}


/** 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 selectedContextIndex = document.KeywordSearchForm.searchType.selectedIndex;            
    var context = document.KeywordSearchForm.searchType.options[selectedContextIndex].value;
    var resultsContainer = document.getElementById("geolib_summaryRecord_"+geolib_summaryPlacementOrder[Data.ID]);
    var titleHTML = "";
			
	//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>";
	}
	
	//EntryType only for 'all' context
	if (context == "all" && Data.entryType != "") {
		titleHTML += "&nbsp;[" + Data.entryType +  "]<br />";
	} else {
		titleHTML += "<br />";
	}
	resultsContainer.innerHTML += titleHTML;
	
	//Create a table and dynamically fill it with attributes
	var summaryTable = document.createElement("table");
	summaryTable.style.width = "100%";
	summaryTableRowsCounter = 0;
	
	//Author not for Serials
	if (context != "serial" && Data.author != "") {				
		var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
		var cellLabel = tableRow.insertCell(0);
		var cellField = tableRow.insertCell(1);		
		
		cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["author"] + "</strong>";
		cellLabel.style.verticalAlign = "top";
		cellLabel.style.width = "30%";
		cellField.innerHTML = geolib_processFieldData(Data.author);
		
		summaryTableRowsCounter++;	
	}
	
	//corpBody only for 'all' context
	if (context == "all" && Data.corpBody != "") {
		var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
		var cellLabel = tableRow.insertCell(0);
		var cellField = tableRow.insertCell(1);		
		
		cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["corpBody"] + "</strong>";
		cellLabel.style.verticalAlign = "top";
		cellLabel.style.width = "30%";
		cellField.innerHTML = geolib_processFieldData(Data.corpBody);
		
		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);
		
		summaryTableRowsCounter++;
	}
	
	//Author 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++;
		}
	}
	
	//ISSN only for Serials	
	if (context == "serial" && Data.ISSN != "") {
		var tableRow = summaryTable.insertRow(summaryTableRowsCounter);		
		var cellLabel = tableRow.insertCell(0);
		var cellField = tableRow.insertCell(1);		
		
		cellLabel.innerHTML = "<strong>" + geolib_langArray["details"]["issn"] + "</strong>";
		cellLabel.style.verticalAlign = "top";
		cellLabel.style.width = "30%";
		cellField.innerHTML = geolib_processFieldData(Data.ISSN);
		
		summaryTableRowsCounter++;
	}
	
	resultsContainer.appendChild(summaryTable);
	resultsContainer.innerHTML += "<hr />";
	
	//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 = new Number(0);	
	for (var arrayPlace = 0; arrayPlace < geolib_searchResults.length; arrayPlace++) {
		if (geolib_searchResults[arrayPlace] == geolib_currentRecordDetail) {
			recordPlace = arrayPlace + 1				
			break;				
		} else {
			continue;
		}
	}
	
	//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;
	
  ///Turn on & off the correct document elements
	//Hide the list results and search interface	
	var searchResults = document.getElementById("geolib_searchResults");
	searchResults.style.display = "none";		
	var searchPanel = document.getElementById("geolib_searchInterface");
	searchPanel.style.display = "none";
	var columnGap = document.getElementById("geolib_columnGap");
	columnGap.style.display = "none";		
	
	//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 topPagingLocation = document.getElementById("geolib_recordDetailTopPagingLinks");
	var bottomPagingLocation = document.getElementById("geolib_recordDetailBottomPagingLinks");
	topPagingLocation.innerHTML = pagingControlHTML;
	bottomPagingLocation.innerHTML = pagingControlHTML;
	
	//If the user is logged in, display the bibliography controls
	var topBiblioLocation = document.getElementById("geolib_recordDetailTopBiblio");
	var bottomBiblioLocation = document.getElementById("geolib_recordDetailBottomBiblio");
	var bottomBiblioSummaryLocation = document.getElementById("geolib_recordSummaryBottomBiblio");
	/* All users can now see the Bibliography links
	if (geolib_userLoggedIn == true) {
		topBiblioLocation.style.visibility = "visible";
		bottomBiblioLocation.style.visibility = "visible";	
	} else {
		topBiblioLocation.style.visibility = "hidden";
		bottomBiblioLocation.style.visibility = "hidden";
	}
	*/
	topBiblioLocation.style.visibility = "visible";
	bottomBiblioLocation.style.visibility = "visible";
	bottomBiblioSummaryLocation.style.visibility = "hidden";
		
	//Complete the header with the the record place, the type and title
	var recordPlacementContainer = document.getElementById("geolib_recordDetailContainerPlacement");
	recordPlacementContainer.innerHTML = "Displaying record " + recordPlace + " of " + geolib_searchResults.length;
	
	var recordEntryTypeContainer = document.getElementById("geolib_recordDetailContainerEntryType");
	recordEntryTypeContainer.innerHTML = "Record Type: <strong>" + Data.entryType + "</strong>";
			
	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();		
	switch (Data.entryType) {
		case "Book / Special Issue":
			if (Data.parallelTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelTitle"], geolib_processFieldData(Data.parallelTitle));}
			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.conference != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["conference"], geolib_processFieldData(Data.conference));}
			if (Data.edition != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["edition"], geolib_processFieldData(Data.edition));}
			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.seriesTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["seriesTitle"], geolib_processFieldData(Data.seriesTitle));}
			if (Data.seriesNo != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["seriesNumber"], geolib_processFieldData(Data.seriesNo));}
			
			//Handle Serial Links
			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.parallelSeriesTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelSeriesTitle"], geolib_processFieldData(Data.parallelSeriesTitle));}
			if (Data.parallelSeriesNo != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelSeriesNumber"], geolib_processFieldData(Data.parallelSeriesNo));}
			if (Data.physicalDescription != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["physicalDescription"], geolib_processFieldData(Data.physicalDescription));}
			if (Data.ISBN != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["isbn"], geolib_processFieldData(Data.ISBN));}
			if (Data.ISSN != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["issn"], geolib_processFieldData(Data.ISSN));}
			if (Data.languages != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["languages"], geolib_processFieldData(Data.languages));}
			if (Data.subjects != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["subject"], geolib_processFieldData(Data.subjects));}
			if (Data.noCopies != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["noOfCopies"], geolib_processFieldData(Data.noCopies));}
			if (Data.notes != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["notes"], geolib_processFieldData(Data.notes));}				
								
			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();">Click here to view Serial Location</span>');
			    } else {
			        recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location"], geolib_processFieldData(Data.location));
			    }
			}
						
			//Add Admin rows
			if (Data.v3 != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["v3"], geolib_processFieldData(Data.v3));}
			if (Data.recordID != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["recordId"], geolib_processFieldData(Data.recordID));}				
			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());}	
			
			break;
		case "Serial":
			if (Data.corpBody != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["corpBody"], geolib_processFieldData(Data.corpBody));}
			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.ISSN != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["issn"], geolib_processFieldData(Data.ISSN));}				
			if (Data.variantTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["variantTitle"], geolib_processFieldData(Data.variantTitle));}
			if (Data.holdings != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["holdings"], geolib_processFieldData(Data.holdings));}
			if (Data.notes != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["notes"], geolib_processFieldData(Data.notes));}				
			if (Data.location != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location1"], geolib_processFieldData(Data.location));}
			if (Data.bay1 != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["bay1"], geolib_processFieldData(Data.bay1));}
			if (Data.location2 != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location2"], geolib_processFieldData(Data.location2));}				
			if (Data.bay2 != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["bay2"], geolib_processFieldData(Data.bay2));}	
			
			if (Data.v38 != "") {				
				if (Data.v38.substring(0, 4) == "http") {
					//This is a URL
					//We need to replace __ with _
					var geolib_underscoreRegExp = /__/g;
					Data.v38 = Data.v38.replace(geolib_underscoreRegExp, "_");
					
					var	linkText = '<a href="'+Data.v38+'" target="_BLANK">' + Data.v38 + '</a>';					
					recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["v38"], linkText);
				} else {
					recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["v38"], geolib_processFieldData(Data.v38));
				}
			}				
			
			//Add Admin rows
			if (Data.shortTitle != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["shortTitle"], geolib_processFieldData(Data.shortTitle));}
			if (Data.recordID != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["recordId"], geolib_processFieldData(Data.recordID));}				
			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());}	
			
			break;
		case "Map":
			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();">Click here to view Serial Location</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());}	
			
			break;
		case "Audio - Visual":
			if (Data.parallelTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelTitle"], geolib_processFieldData(Data.parallelTitle));}				
			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.conference != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["conference"], geolib_processFieldData(Data.conference));}
			if (Data.edition != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["edition"], geolib_processFieldData(Data.edition));}
			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.seriesTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["seriesTitle"], geolib_processFieldData(Data.seriesTitle));}
			if (Data.seriesNo != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["seriesNo"], geolib_processFieldData(Data.seriesNo));}				
			if (Data.parallelSeriesTitle != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelSeriesTitle"], geolib_processFieldData(Data.parallelSeriesTitle));}
			if (Data.parallelSeriesNo != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["parallelSeriesNo"], geolib_processFieldData(Data.parallelSeriesNo));}
			if (Data.physicalDescription != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["physicalDescription"], geolib_processFieldData(Data.physicalDescription));}
			if (Data.ISBN != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["isbn"], geolib_processFieldData(Data.ISBN));}
			if (Data.ISSN != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["issn"], geolib_processFieldData(Data.ISSN));}
			if (Data.languages != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["languages"], geolib_processFieldData(Data.languages));}
			if (Data.subjects != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["subject"], geolib_processFieldData(Data.subjects));}
			if (Data.noCopies != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["noOfCopies"], geolib_processFieldData(Data.noCopies));}
			if (Data.notes != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["notes"], geolib_processFieldData(Data.notes));}				
			if (Data.location != "") {recordAttributes[recordAttributes.length] = new Array(geolib_langArray["details"]["location"], geolib_processFieldData(Data.location));}	
			
			//Add Admin rows
			if (Data.v3 != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["v3"], geolib_processFieldData(Data.v3));}
			if (Data.recordID != "") {adminAttributes[adminAttributes.length] = new Array(geolib_langArray["details"]["recordId"], geolib_processFieldData(Data.recordID));}				
			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());}				
			
			break;
	}
	
  ///Output the results!
	//Dynamically build up a table through DOM-esque methods
    //General data
	var geolib_recordAttributeTable = document.getElementById("geolib_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";
		newRowLabel.width = "30%";
		newRowData.innerHTML = recordAttributes[myNiceCounter][1];
	}
	
	//Insert a "View record in GIS link"
	if (Data.entryType == "Map") {
		var newRowReference = geolib_recordAttributeTable.insertRow(recordAttributes.length);
		
		var newRowCell = newRowReference.insertCell(0);
		
		newRowCell.colSpan = 2;		
		newRowCell.style.textAlign = "center";
		newRowCell.innerHTML = "<a href=\""+geolib_gisPageUrl+"#viewLibraryRecord=" 
		                            + Data.ID + "|" + Data.westDecCoord + "|" + Data.eastDecCoord + "|"
		                            + Data.northDecCoord + "|" + Data.southDecCoord + "|" + Data.recordID
		                            + "\">View this record in the Map GIS interface</a>";	
	}	
	
	//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];
		}
	}
	
	//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 = " Library Catalogue ";	
	bottomPaging.innerHTML = " Library Catalogue ";
	
	//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
			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("librarySearchErrorText").innerHTML = "";
	
	var errorList = document.createElement("ul");
	var errorItem = document.createElement("li");
	
	errorItem.appendChild(document.createTextNode(displayError));
	errorList.appendChild(errorItem);
	
	document.getElementById("librarySearchErrorText").appendChild(errorList);	
	document.getElementById("librarySearchErrorContainer").style.display = "";
	
	//document.getElementById("librarySearchErrorText").innerHTML = "<ul><li>" + displayError + "</ul></li>";
}


//Instruct DWR to use our bespoke error-handler
DWREngine.setErrorHandler(dwrErrorHandler);
	
		
/** 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>)
*/	
function geolib_processFieldData(dataString) {
	var geolib_fieldDataRegExp = /\|/g;
	return dataString.replace(geolib_fieldDataRegExp, "<br />");
}


/** geolib_clearFormErrors()
*
* Removes all error Messages and clears Error classes on form elements
*/
function geolib_clearFormErrors() {
	//Remove & Clear the central message display	
	document.getElementById("librarySearchErrorContainer").style.display = "none";
	document.getElementById("librarySearchErrorText").innerHTML = "";
	
	//Clear any error classes on individual fields
	document.KeywordSearchForm.keyword.parentNode.className = "";
	document.DetailSearchForm.geolib_Author.parentNode.className = "";
	document.DetailSearchForm.geolib_Organisation.parentNode.className = "";	
	document.DetailSearchForm.geolib_Title.parentNode.className = "";
	document.DetailSearchForm.geolib_Publisher.parentNode.className = "";
	document.DetailSearchForm.geolib_IsbnIssn.parentNode.className = "";
	document.DetailSearchForm.geolib_Subject.parentNode.className = "";
	document.DetailSearchForm.geolib_Language.parentNode.className = "";
	document.DetailSearchForm.geolib_DateFrom.parentNode.className = "";
	document.DetailSearchForm.geolib_DateTo.parentNode.className = "";
}


/** geolib_setTermsCookie()
*
* Stores the current values of the search files in a cookie!
*/
function geolib_setTermsCookie() {
	//Get all the variables & Compose the cookie Value String
	var cookieString = "";	
	cookieString += escape(document.KeywordSearchForm.keyword.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Author.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Organisation.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Title.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Publisher.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_IsbnIssn.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Subject.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_Language.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_DateFrom.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_DateTo.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_SeriesTitle.value) +  "|";
	cookieString += escape(document.DetailSearchForm.geolib_SeriesNo.value) +  "|";
	
	//Sort the Cookie Expiry
	var nowDate = new Date();
	nowDate.setMonth(nowDate.getMonth() + 6);

	//Set the Cookie
	document.cookie = "geolibSearchTerms=" + cookieString + ";expires=" + nowDate.toGMTString();
}


/** geolib_gettTermsCookie()
*
* Retrieves any previous terms held in a cookie and loads them into the form.
*/
function geolib_getTermsCookie() {
	
	//Load the full cookie for the docuement
	var documentCookieValue = document.cookie;
	
	//Attempt to find our geolib cookie somewhere in this string
	var geoCookieStartsAt = documentCookieValue.indexOf(" geolibSearchTerms=");
	
	if (geoCookieStartsAt == -1) {
		//Cookie not found, but it may be at the start?
		geoCookieStartsAt = documentCookieValue.indexOf("geolibSearchTerms=");
	}
	
	if (geoCookieStartsAt == -1) {
		//No cookie found!
		return false;
	} else {
		//We have a cookie!
		//Retrieve the full cookie
		//Get the starting position of the value component
		geoCookieStartsAt = documentCookieValue.indexOf("=", geoCookieStartsAt) + 1;
		
		//And get the end
		var geoCookieEndsAt = documentCookieValue.indexOf(";", geoCookieStartsAt);
		if (geoCookieEndsAt == -1) {
			//Our cookie runs to the end 
			geoCookieEndsAt = documentCookieValue.length;
		}
				
		//Get the cookie data!
		var geoCookieData = documentCookieValue.substring(geoCookieStartsAt, geoCookieEndsAt);
		
		//Explode this into component parts
		geoCookieData = geoCookieData.split("|");
		
		//Load things back into the form
		document.KeywordSearchForm.keyword.value = unescape(geoCookieData[0]);
		document.DetailSearchForm.geolib_Author.value = unescape(geoCookieData[1]);
		document.DetailSearchForm.geolib_Organisation.value = unescape(geoCookieData[2]);
		document.DetailSearchForm.geolib_Title.value = unescape(geoCookieData[3]);
		document.DetailSearchForm.geolib_Publisher.value = unescape(geoCookieData[4]);
		document.DetailSearchForm.geolib_IsbnIssn.value = unescape(geoCookieData[5]);
		document.DetailSearchForm.geolib_Subject.value = unescape(geoCookieData[6]);
		document.DetailSearchForm.geolib_Language.value = unescape(geoCookieData[7]);
		document.DetailSearchForm.geolib_DateFrom.value = unescape(geoCookieData[8]);
		document.DetailSearchForm.geolib_DateTo.value = unescape(geoCookieData[9]);
		document.DetailSearchForm.geolib_SeriesTitle.value = unescape(geoCookieData[10]);
		document.DetailSearchForm.geolib_SeriesNo.value = unescape(geoCookieData[11]);
		
		//And finish!
		return true;
	}
}


/** 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 pagingContainer = document.getElementById(pagingLocation);
	var	numPages = Math.ceil(geolib_searchResults.length / geolib_pagingPerPage);
	
  ///Output the basic X to Y of Z portion
	pagingContainer.innerHTML = "<span style=\"float: left;\">&nbsp;Results " + parseInt(geolib_pagingStartRecord+1) + " to " +
					geolib_pagingEndRecord +  " of " + geolib_searchResults.length + ".</span>";
	
	
  ///Generate the actual clickable links
  	var linksHtml = "<span style=\"float: right;\">";
	//Link to first page is always the same
	if (geolib_searchCurrentPage == 0) {
		//Show none-linking first page
		linksHtml += "<strong>1</strong>";
	} else {
		//show linking first page
		linksHtml += "<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults(0);\">1</span>";
	}
	
	if (numPages > 0) {
	//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) {
					linksHtml += "|<strong>" + parseInt(aPage+1) + "</strong>";
				} else {
					linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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) {
						linksHtml += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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
					linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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) {
						linksHtml += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults("+parseInt(numPages - 2)+");\">&hellip;</span>";						
					} else {
						linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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) {
						linksHtml += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage - 3) +");\">&hellip;</span>";
				
				//Add previous, currnt and next page links
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage - 1) +");\">"+ geolib_searchCurrentPage +"</span>";
				linksHtml += "|<strong>" + parseInt(geolib_searchCurrentPage+1) + "</strong>";
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults("+ parseInt(geolib_searchCurrentPage + 1) +");\">"+ parseInt(geolib_searchCurrentPage + 2) +"</span>";
				
				//Add the next 3 ellipsis link
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" 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
				linksHtml += "|<strong>" + numPages + "</strong>";
			} else {
				//show linking first page
				linksHtml += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_processPagedResults("+ parseInt(numPages-1) +");\">" + numPages + "</span>";				
			}
			
		}				
	}
	linksHtml += "</span>";
	pagingContainer.innerHTML += linksHtml;
	
	return true;
}


/** geolib_generateRecordPagingControl()
*
* Generates the paging control for the *Detail View*
*/	
function geolib_generateRecordPagingControl(currentRecord, totalRecords) {
	
	var pagingHTML = "";

  ///Generate the actual clickable links
	//Link to first page is always the same
	if (currentRecord == 0) {
		//Show none-linking first page
		pagingHTML += "<strong>1</strong>";
	} else {
		//show linking first page
		pagingHTML += "<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord(" + geolib_searchResults[0] + ");\">1</span>";
	}
	
	if (totalRecords > 1) {
	//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 (totalRecords < 8) {
			//1|2|3|4|5|6|7 (upto)
			for (var aPage = 1; aPage < totalRecords; aPage++) {
				//Don't link to a page if we are already on it
				if (aPage == currentRecord) {
					pagingHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
				} else {
					pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[aPage] +");\">" + parseInt(aPage+1) + "</span>";
				}		
			}
		} 
		else {
			if (currentRecord < 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 == currentRecord) {
						pagingHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[aPage] +");\">" + parseInt(aPage+1) + "</span>";
					}					
				}
				
				//Work out where the ellipsis link to "next 3" should send us
				if ((currentRecord + 3) < 5) {
					//Show page 6 anyway
					pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+geolib_searchResults[5]+");\">&hellip;</span>";
				} else {
					//If the link would send us to the last page or beyond, use (last -1)
					if ((currentRecord + 4) >= totalRecords) {
						pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+geolib_searchResults[(totalRecords - 2)]+");\">&hellip;</span>";						
					} else {
					
						pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+geolib_searchResults[(currentRecord + 3)]+");\">&hellip;</span>";
					}					
				}					
			}
			else if (currentRecord > (totalRecords - 4)) {
				//1|x-3 or 2|x|*y*|z|last
				
				//calulate the ellipsis link
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+geolib_searchResults[(totalRecords -7)]+");\">&hellip;</span>";
				
				//Iterate over the last pages					
				for (var aPage = totalRecords - 5; aPage < totalRecords-1; aPage++) {
					//Don't link to a page if we are already on it
					if (aPage == currentRecord) {
						pagingHTML += "|<strong>" + parseInt(aPage+1) + "</strong>";
					} else {
						pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[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
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord - 3)] +");\">&hellip;</span>";
				
				//Add previous, currnt and next page links
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord - 1)] +");\">"+ currentRecord +"</span>";
				pagingHTML += "|<strong>" + parseInt(currentRecord+1) + "</strong>";
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord + 1)] +");\">"+ parseInt(currentRecord + 2) +"</span>";
				
				//Add the next 3 ellipsis link
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(currentRecord + 3)] +");\">&hellip;</span>";
					
			}
			
			//Show the last page
			//Always the same :)
			if (currentRecord == (totalRecords-1)) {
				//Show none-linking first page
				pagingHTML += "|<strong>" + totalRecords + "</strong>";
			} else {
				//show linking first page
				pagingHTML += "|<span class=\"brownAjaxHeaderLinks\" onClick=\"geolib_showRecord("+ geolib_searchResults[(totalRecords-1)] +");\">" + totalRecords + "</span>";
			}
		}				
	}
	
	return pagingHTML;
}
