function getForm(){
    // Returns the html form element object
    // Common code procedure; treat like a constant variable 
    return document.frmLibrarian;
}  // getForm()

function showRegionMap(regionID){
	var w = self.open('map.aspx?id=' + regionID,'1','height=410,width=390,scrollbars,resizable');
	if(w.focus)
		w.focus();
	w = null;
} // showLevel()

function showLevel(){
	var w = self.open('level.html','1','height=175,width=390,scrollbars,resizable');
	if(w.focus)
		w.focus();
	w = null;
} // showLevel()

function showRating() {
	var w = self.open('rating.html','1','height=275,width=390,scrollbars,resizable');
	if(w.focus)
		w.focus();
	w = null;
}  // showRating()

function getSelectedRideId(){
    // Returns the selected ride id from the drop down list box
    var rides = getForm().lstRides.options;
    
    for(var i = rides.length - 1; i >= 0; i--) {
		if(rides[i].selected) 
			return rides[i].value; //rideID;
	} // for each ride	
}  // getSelectedRideId()

function getThisDocumentUrl(){
    var thisDocURL = document.URL;		// The URL of this web page
	
	// Locate the position of the query arguments and if any, 
	// then strip them away from the complete URL address
	var pos = thisDocURL.indexOf('?');  

	if(pos != -1)
		thisDocURL = thisDocURL.substring(0, pos);   
	
	return thisDocURL;
}  // getThisDocumentUrl()


function isBlank(s) {
	// A utility function that returns true if a string contains only 
    // whitespace characters.
	if((s == null) || (s == '') || (s.length == 0)) { return true; }    for(var i = s.length - 1; i >= 0; i--) {
        var c = s.charAt(i);
        if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
    }
    return true;
} // isBlank()


function getXmlElementValue(xmlDocument, id){
    var returnValue = null;
    var xmlElement  = xmlDocument.getElementsByTagName(id);
    
    if(xmlElement){
        if(xmlElement[0]){
            if(xmlElement[0].firstChild){
                if(xmlElement[0].firstChild.nodeValue){
                    returnValue = xmlElement[0].firstChild.nodeValue;
                }
            }
        }
    }
    
    return returnValue;
}  // getXmlElementValue()

function setValue(xmlDocument, id){
    var htmlElement = null;
    var xmlValue    = getXmlElementValue(xmlDocument, id);
    
    if(!isBlank(xmlValue)){
    
        htmlElement = document.getElementById(id);
        
        if(htmlElement){
            if(htmlElement.innerHTML){
                htmlElement.innerHTML = xmlValue;
            }
        }
    }
}  // setValue()


/************************************************************
*    strGetFileExtension()
*  Returns the parsed out filename extension.  Used as the 
*  inner text for cue sheet and map anchor tags.
*
*  P. O'Reilly, 25 November 2003
************************************************************/
function strGetFileExtension(strUrl)
{
	if(isBlank(strUrl)) { return ''; }

	var intPos = strUrl.lastIndexOf('.');

	if(intPos > 0)
		return strUrl.substring(intPos + 1);
	else
		return 'html';

}  // strGetFileExtension()

function createLink(parentElement, xmlDocument, id_prefix, i){
    // parentElement - the parent html element which the link will be appended to
    // xmlDocument   - xml document containing the element's value to be extracted
    // id_prefix     - the prefix for the xml document element name
    //  i            -  xml document element name increment value
    
    var url             = getXmlElementValue(xmlDocument, id_prefix + i);
    
    if(isBlank(url)) { return; }
    
    var fileSize        = getXmlElementValue(xmlDocument, id_prefix + '_size' + i);
    var fileExtension   = strGetFileExtension(url);
    var anchorTag       = document.createElement('a');
    	
	anchorTag.setAttribute('href', url);
	anchorTag.setAttribute('target', 'new');  
	anchorTag.innerHTML = fileExtension;

	parentElement.appendChild(anchorTag);
	
	if(!isBlank(fileSize))
	    parentElement.innerHTML += '&nbsp;(' + fileSize + ')&nbsp;';
	else
        parentElement.innerHTML += '&nbsp;';
        
    url = fileSize = fileExtension = anchorTag = null;      
}   // createLink()

function doCueSheetLinks(xmlDocument){
    // creates the cue sheet anchor tag link(s)
    var tdCueSheets = document.getElementById('cue_sheets');
    
    if(tdCueSheets){ 
        while(tdCueSheets.lastChild)
            tdCueSheets.removeChild(tdCueSheets.lastChild);
            
       tdCueSheets.innerHTML = '';
    
        for(var i = 1; i <= 3; i++)
            createLink(tdCueSheets, xmlDocument, 'cue', i);
    }
    tdCueSheets = null;
}  // doCueSheetLinks()

function doMapLinks(xmlDocument){
    // creates the map anchor tag link(s), if any
    var tdMaps = document.getElementById('maps');
    
    if(tdMaps){ 
        while(tdMaps.lastChild)
            tdMaps.removeChild(tdMaps.lastChild);

       tdMaps.innerHTML = '';
    
        for(var i = 1; i <= 3; i++)
            createLink(tdMaps, xmlDocument, 'map', i);
    }
    tdMaps = null;
}  // doMapLinks()


function handleResponseXML(xmlDocument){
    // Processes the HTTP Response returned from the AJAX call
    // Build out the ride details..
    setValue(xmlDocument, 'ride_title');
    setValue(xmlDocument, 'author');
    setValue(xmlDocument, 'way_points');
    setValue(xmlDocument, 'distance');
    setValue(xmlDocument, 'level');
    setValue(xmlDocument, 'rating');
    setValue(xmlDocument, 'comments');
    
    doCueSheetLinks(xmlDocument);
    doMapLinks(xmlDocument);
    
    xmlDocument = null;
}  // handleResponseXML()



function loadDocument(urlAjaxRequest, handler, urlClassicRequest){
    // Try retrieving the data first using a remote JavaScript HTTP Request (AJAX);
    // If that fails, then fall back on doing a full page request.
    // Note the former is likely to occur as some prescreening has occurred in
    // the procedure: useAjax()
    var xmlDocument = null;

	try{
	    if(document.implementation && document.implementation.createDocument){
		    xmlDocument = document.implementation.createDocument('','',null);
		    xmlDocument.onload = function(){ handler(xmlDocument); }
		    xmlDocument.load(urlAjaxRequest);
	    }
	    else if(window.ActiveXObject){
		    // Use Microsoft's proprietary API for Internet Explorer
		    var xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
    		
		    xmlDocument.onreadystatechange = function(){
			    if(xmlDocument.readyState == 4) { handler(xmlDocument, urlAjaxRequest); }
		    }		
		    xmlDocument.load(urlAjaxRequest);
	    }
	    else{
	        location.href = urlClassicRequest;	
	    }
	}
	catch(ignoreThisError){
	    // try the classic approach way - full page HTTP Request
	    location.href = urlClassicRequest;
	}
}  // loadDocument()

function useAjax(){
    // Returns true if the user agent/web browser has
    // pontential to make a remote HTTP request using JavaScript

    // Error object was introduced in
    // JavaScript 1.5/JScript 5.5/ECMAScript v3
    // and at the same time try/catch exception handling was introduced
    return (Error ? true : false);
}  // useAjax()

function doRequestRide() {
	// Reloads this page with new ride (route) selection
    var rideId              = getSelectedRideId();    	
    
    if(rideId == -1){
        // Ride not found, is oiffline or page improperly accessed
        // This logic should never be true
        location.href = 'errorRide.shtml';
        return;
    }
    
    var thisDocURL          = getThisDocumentUrl();
    var urlAjaxRequest      = 'rideXml.aspx?id=' + rideId;
    var urlClassicRequest   = thisDocURL + '?id=' + rideId;
	
	if (useAjax())
	    loadDocument(urlAjaxRequest, handleResponseXML, urlClassicRequest);	
	else
	    location.href = urlClassicRequest;
} // doRequestRide()


function getQueryArguments() {
    //  This function parses &-separated name=value argument pairs
    //  from the query string of the URL.  It stores the name=value pairs 
    //  in properties of an object and returns that object.		
	if(location.search == null || location.search.length < 2)
		return null;

	var query = location.search.substring(1);
	var nameValuePairs = query.split('&');
	var args = new Object();
	
	for(var i = 0; i < nameValuePairs.length; i++) {
		var pos = nameValuePairs[i].indexOf('=');
		if(pos == -1) { continue; }
		
		var argName = nameValuePairs[i].substring(0, pos);
		var value = nameValuePairs[i].substring(pos + 1);
		args[argName] = unescape(value);
	}

	return args;
}  // getQueryArguments()

function getRideID() {
    // Retrieves the Ride ID from the query string
	var rideID = 0;  // default return value
	var queryArgs = getQueryArguments();
	
	if(queryArgs) {
		if(queryArgs.id) {
			if(!isNaN(queryArgs.id))
				rideID = parseInt(queryArgs.id);
		}
	}
	
	return rideID;
}  // getRideID()

function preserverRideSelection(frm) {
    // If the user hits the browser back button, the rides list box selection
    // is that of the last page viewed.  We need to actively select the ride
    // in the list for the currently viewed page that has been accessed by 
    // hitting the back button.
	var rideID = getRideID();

	if(rideID == 0) { return; }

	var listRides = frm.lstRides;

	for(var i = 0; i < listRides.options.length; i++) {
		var opt = listRides.options[i];
		if(opt.value == rideID) {
			opt.selected = true;
			return;
		}
	} 
}  // preserverRideSelection()

function initializeWindow() {
	var frm = getForm();
	if(frm) {
		preserverRideSelection(frm);
		if(frm.lstRides.focus)
			frm.lstRides.focus(); 
	}
				
}  // initializeWindow()

window.onload                   = initializeWindow;
getForm().lstRides.onchange     = doRequestRide;