//<![CDATA[
/*-------------- Find a course - Google map functions -------------------*/

// initialise default text for input fields
var DEFAULT_TEXT        = 'UK postcode or place';
var DEFAULT_SEARCH_TEXT = 'Search term';

// initialise default map settings
var DEFAULT_LAT         = 51.7;
var DEFAULT_LNG         = -0.6;
var DEFAULT_LATLNG;
var DEFAULT_ZOOM        = 7;

// initialise default limit on results
var RESULTS_PER_PAGE    = 5;

// image preload to help make image changes work smoothly
var gWork_Image     = new Image(40,26);
gWork_Image.src     = "/images/icons/work-shadow-combi.gif";
var gOther_Image    = new Image(40,26);
gOther_Image.src    = "/images/icons/other-shadow-combi.gif";
var gOther_set;
var gHome_set;

// initialise filters with their default settings
var gFilter_subject;
var gFilter_fd;
var gOrder_by;
var gHome_lat;
var gHome_lng;
var gOther_lat;
var gOther_lng;

var gMarkers_key;   // array for storing results/marker relationships
var gResults_ids;   // stores ids of results for one-to-many/many-to-one relationships between markers/results
var gAlert_on;      // stores whether an alert has been triggered on text input
var gKeyword_on;    // stores whether a search by keyword has happened recently
var gDouble_search; // stores whether a double-search is in progress (from keyword search)
var gSearch_type;   // stores which method of searching is in progress
var gKeyword_id;    // stores keyword id from keyword search
var gSearch_term;   // stores search term
var gResult_lock;   // stores whether a result has been clicked



function reset_globals()
{
    gOther_set      = 0;
    gHome_set       = 0;

    // initialise filters with their default settings
    gFilter_subject = 'all';
    gFilter_fd      = 0;
    gOrder_by       = 'inst_name, camp_name';
    gHome_lat       = null;
    gHome_lng       = null;
    gOther_lat      = null;
    gOther_lng      = null;

    gMarkers_key    = new Array();  // array for storing results/marker relationships
    gResults_ids    = new Array();  // stores ids of results for one-to-many/many-to-one relationships between markers/results
    gAlert_on       = false;        // stores whether an alert has been triggered on text input
    gKeyword_on     = false;        // stores whether a search by keyword has happened recently
    gDouble_search  = false;        // stores whether a double-search is in progress (from keyword search)
    gSearch_type    = '';           // stores which method of searching is in progress
    gKeyword_id     = '';           // stores keyword id from keyword search
    gSearch_term    = '';           // stores search term
    gResult_lock    = false;        // stores whether a result has been clicked
}

reset_globals();

// for storing which result has been selected
var gTop_lat_lng;
var gCurr_selected;
var gPrev_selected;
var gCurr_page;
var gPrev_page;

function reset_result_globals() {
    gTop_lat_lng    = null;
    gCurr_selected  = null;
    gPrev_selected  = null;
    gCurr_page      = 1;
    gPrev_page      = 1;
}
reset_result_globals(); // call to initiate result globals

// create sort order options for courses
var gCourse_order_options       = new Array();
gCourse_order_options['course'] = 'subjectarea_name, course_name, level_display_order';
gCourse_order_options['level']  = 'subjectarea_name, level_display_order, course_name';
var gCourse_order_by            = gCourse_order_options['course'];



/*
function get_html_translation_table(table, quote_style)
{
    // Returns the internal translation table used by htmlspecialchars and htmlentities  
    // 
    // version: 906.401
    // discuss at: http://phpjs.org/functions/get_html_translation_table
    // +   original by: Philip Peterson
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: noname
    // +   bugfixed by: Alex
    // +   bugfixed by: Marco
    // +   bugfixed by: madipta
    // +   improved by: KELAN
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
    // %          note: It has been decided that we're not going to add global
    // %          note: dependencies to php.js. Meaning the constants are not
    // %          note: real constants, but strings instead. integers are also supported if someone
    // %          note: chooses to create the constants themselves.
    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
    
    var entities = {}, histogram = {}, decimal = 0, symbol = '';
    var constMappingTable = {}, constMappingQuoteStyle = {};
    var useTable = {}, useQuoteStyle = {};
    
    // Translate arguments
    constMappingTable[0]      = 'HTML_SPECIALCHARS';
    constMappingTable[1]      = 'HTML_ENTITIES';
    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
    constMappingQuoteStyle[2] = 'ENT_COMPAT';
    constMappingQuoteStyle[3] = 'ENT_QUOTES';

    useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
    useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';

    if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
        throw new Error("Table: "+useTable+' not supported');
        // return false;
    }

    if (useTable === 'HTML_ENTITIES') {
        entities['160'] = '&nbsp;';
        entities['161'] = '&iexcl;';
        entities['162'] = '&cent;';
        entities['163'] = '&pound;';
        entities['164'] = '&curren;';
        entities['165'] = '&yen;';
        entities['166'] = '&brvbar;';
        entities['167'] = '&sect;';
        entities['168'] = '&uml;';
        entities['169'] = '&copy;';
        entities['170'] = '&ordf;';
        entities['171'] = '&laquo;';
        entities['172'] = '&not;';
        entities['173'] = '&shy;';
        entities['174'] = '&reg;';
        entities['175'] = '&macr;';
        entities['176'] = '&deg;';
        entities['177'] = '&plusmn;';
        entities['178'] = '&sup2;';
        entities['179'] = '&sup3;';
        entities['180'] = '&acute;';
        entities['181'] = '&micro;';
        entities['182'] = '&para;';
        entities['183'] = '&middot;';
        entities['184'] = '&cedil;';
        entities['185'] = '&sup1;';
        entities['186'] = '&ordm;';
        entities['187'] = '&raquo;';
        entities['188'] = '&frac14;';
        entities['189'] = '&frac12;';
        entities['190'] = '&frac34;';
        entities['191'] = '&iquest;';
        entities['192'] = '&Agrave;';
        entities['193'] = '&Aacute;';
        entities['194'] = '&Acirc;';
        entities['195'] = '&Atilde;';
        entities['196'] = '&Auml;';
        entities['197'] = '&Aring;';
        entities['198'] = '&AElig;';
        entities['199'] = '&Ccedil;';
        entities['200'] = '&Egrave;';
        entities['201'] = '&Eacute;';
        entities['202'] = '&Ecirc;';
        entities['203'] = '&Euml;';
        entities['204'] = '&Igrave;';
        entities['205'] = '&Iacute;';
        entities['206'] = '&Icirc;';
        entities['207'] = '&Iuml;';
        entities['208'] = '&ETH;';
        entities['209'] = '&Ntilde;';
        entities['210'] = '&Ograve;';
        entities['211'] = '&Oacute;';
        entities['212'] = '&Ocirc;';
        entities['213'] = '&Otilde;';
        entities['214'] = '&Ouml;';
        entities['215'] = '&times;';
        entities['216'] = '&Oslash;';
        entities['217'] = '&Ugrave;';
        entities['218'] = '&Uacute;';
        entities['219'] = '&Ucirc;';
        entities['220'] = '&Uuml;';
        entities['221'] = '&Yacute;';
        entities['222'] = '&THORN;';
        entities['223'] = '&szlig;';
        entities['224'] = '&agrave;';
        entities['225'] = '&aacute;';
        entities['226'] = '&acirc;';
        entities['227'] = '&atilde;';
        entities['228'] = '&auml;';
        entities['229'] = '&aring;';
        entities['230'] = '&aelig;';
        entities['231'] = '&ccedil;';
        entities['232'] = '&egrave;';
        entities['233'] = '&eacute;';
        entities['234'] = '&ecirc;';
        entities['235'] = '&euml;';
        entities['236'] = '&igrave;';
        entities['237'] = '&iacute;';
        entities['238'] = '&icirc;';
        entities['239'] = '&iuml;';
        entities['240'] = '&eth;';
        entities['241'] = '&ntilde;';
        entities['242'] = '&ograve;';
        entities['243'] = '&oacute;';
        entities['244'] = '&ocirc;';
        entities['245'] = '&otilde;';
        entities['246'] = '&ouml;';
        entities['247'] = '&divide;';
        entities['248'] = '&oslash;';
        entities['249'] = '&ugrave;';
        entities['250'] = '&uacute;';
        entities['251'] = '&ucirc;';
        entities['252'] = '&uuml;';
        entities['253'] = '&yacute;';
        entities['254'] = '&thorn;';
        entities['255'] = '&yuml;';
    }

    if (useQuoteStyle !== 'ENT_NOQUOTES') {
        entities['34'] = '&quot;';
    }
    if (useQuoteStyle === 'ENT_QUOTES') {
        entities['39'] = '&#39;';
    }
    entities['60'] = '&lt;';
    entities['62'] = '&gt;';

    // ascii decimals for better compatibility
    entities['38'] = '&amp;';

    // ascii decimals to real symbols
    for (decimal in entities) {
        symbol = String.fromCharCode(decimal);
        histogram[symbol] = entities[decimal];
    }
    
    return histogram;
}
*/



/*
function htmlentities (string, quote_style)
{
    // Convert all applicable characters to HTML entities  
    // 
    // version: 906.401
    // discuss at: http://phpjs.org/functions/htmlentities
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: nobbler
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
    // -    depends on: get_html_translation_table
    // *     example 1: htmlentities('Kevin & van Zonneveld');
    // *     returns 1: 'Kevin &amp; van Zonneveld'
    // *     example 2: htmlentities("foo'bar","ENT_QUOTES");
    // *     returns 2: 'foo&#039;bar'
    var histogram = {}, symbol = '', tmp_str = '', entity = '';
    tmp_str = string.toString();
    
    if (false === (histogram = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
        return false;
    }
    histogram["'"] = '&#039;';
    for (symbol in histogram) {
        entity = histogram[symbol];
        tmp_str = tmp_str.split(symbol).join(entity);
    }
    
    return tmp_str;
}
*/



function convert_to_ascii (s)
{
	var r = "";
	for (var i = 0; i < s.length; i++) {
		r += "&#" + s.charCodeAt(i) + ";";
	}
	return r;
}



function valid_postcode(pcode)
{
    var re  = new RegExp('^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$'); // create regular expression to test against
    var m   = re.exec(pcode); // execute test on string

    if (m == null) {	
        return 0; // if not found
	} else {	
        return 1; // if found
	} 	
}



function valid_email(email)
{
    // NOTE: var re uses regex syntax rather than the RegExp() constructor so that backslashes do not need to be escaped making it easier to read!
    var re  = /^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/; // create regular expression to test against
    var m   = re.exec(email); // execute test on string
    
    if (m == null) {
        return 0; // if not found
    } else {
        return 1; // if found
    }
}



function toggle_work_image()
{
    //alert("toggle_work_image");
    if ($('workplace').checked) {
        $('other_label').innerHTML  = 'Work';           // change label
        $('other_img').src          = gWork_Image.src;  // change image
        $('other_img').alt          = "Work icon";      // change alt tag
        
        //$('other_set').attributes['onclick'].value  = "set_location('work', $('otherbox').value)"; // change onclick javascript (original code)
        //$('other_set').onclick = function () {set_location('work', $('otherbox').value);} // change onclick javascript (has to be called as a function to work in IE)
        $('other_form').onsubmit = function () {set_location('work', $('otherbox').value); return false;} // change onclick javascript (has to be called as a function to work in IE)
        check_location_marker('work');
    
    } else {
        $('other_label').innerHTML  = 'Other';          // change label
        $('other_img').src          = gOther_Image.src; // change image
        $('other_img').alt          = "Other icon";     // change alt tag
        
        //$('other_set').attributes['onclick'].value  = "set_location('other', $('otherbox').value)"; // change onclick javascript (original code)
        //$('other_set').onclick = function () {set_location('other', $('otherbox').value);} // change onclick javascript (has to be called as a function to work in IE)
        $('other_form').onsubmit = function () {set_location('other', $('otherbox').value); return false;} // change onclick javascript (has to be called as a function to work in IE)
        check_location_marker('other');
    }
}



function reset_location_input(prefix) {
    $(prefix + 'box').style.color   = "#999999";    // reset text colour
    $(prefix + 'box').value         = DEFAULT_TEXT; // reset to default text
}



function reset_searchbox()
{
    $('course_searchbox').style.color   = "#999999";            // reset text colour
    $('course_searchbox').value         = DEFAULT_SEARCH_TEXT;  // reset to default text
}



function reset_subjectarea()
{
    $('filter_subject').selectedIndex = 0;
}



function reset_worktoggle()
{
    $('workplace').checked = 0;
}



function clear_search()
{
    reset_globals();
    reset_result_globals();
    reset_searchbox();
    reset_worktoggle();
    reset_subjectarea();
    remove_location_marker('home');
    remove_location_marker('other');
    remove_location_marker('work');
    toggle_work_image();
    remove_institution_markers();
    gCourse_Map.clearOverlays();
    gCourse_Map.setCenter(DEFAULT_LATLNG, DEFAULT_ZOOM);
    gCurrent_zoom = DEFAULT_ZOOM;
    hide_window('mp_courses');
    hide_window('mp_enquiry');
    hide_window('mp_keywords');
    clear_window('mp_courses');
    clear_window('mp_enquiry');
    clear_window('mp_keywords');
    $('mp_results').innerHTML = DEFAULT_INTRO;
}



function check_location_marker(prefix)
{
    // if the other/work location has been set then change it to prefix
    if (gOther_set) {
        var Lat_Lng = new GLatLng(gOther_lat, gOther_lng);
        add_location_marker(prefix, Lat_Lng, gCourse_Map.getZoom());
    }
}



function textbox_focus(prefix)
{
    //alert("textbox_focus");
    if ((DEFAULT_TEXT == $(prefix+'box').value) || (DEFAULT_SEARCH_TEXT == $(prefix+'box').value)) {
        $(prefix+'box').value = '';                // clear the prompt message ready for new input
    }
    $(prefix+'box').style.color = "#333333";       // change the input text colour
}


function textbox_blur(prefix)
{
    //alert("textbox_blur");
    if ('' == $(prefix+'box').value && !gAlert_on) {
        if (prefix == 'course_search') {
            reset_searchbox();
        } else {
            reset_location_input(prefix);
        }
    }
    gAlert_on = false;
}



function load_map()
{
    //alert("load_map");
    if (GBrowserIsCompatible()) {
        set_map();
    } else {
        alert("We're sorry. Your browser is not compatible with Google maps");
    }
}



function set_map()
{
    //alert('set_map');
    gCurrent_zoom   = DEFAULT_ZOOM;    // set current zoom
    
    gCourse_Map     = new GMap2($('course_map'));               // create map instance and attach it to containing div
    DEFAULT_LATLNG  = new GLatLng(DEFAULT_LAT, DEFAULT_LNG);    // store the default latlng
    gCourse_Map.setCenter(DEFAULT_LATLNG, DEFAULT_ZOOM);        // set the starting point for map
    gCourse_Map.addControl(new GLargeMapControl());             // add map zoom and position controls
    
    // create array for storing multiple institution icons
    // this gets populated in Cluster2_modified.js
    gMulti_inst_icon    = new Array();
    
    gLocation_markers   = new Array();  // create array for storing location markers (home, other, work)
    gInst_markers       = new Array();  // create array for storing institution markers
    
    // set up the clusters
    gInst_Clusterer = new Clusterer(gCourse_Map);
    gInst_Clusterer.SetMinMarkersPerCluster(2);
    gInst_Clusterer.SetGridSize(10);                // the default in Cluster2.js is 5
    gInst_Clusterer.SetMaxVisibleMarkers(1);
    gInst_Clusterer.SetMaxLinesPerInfoBox(5);
    
    gLocal_Search = new GlocalSearch();   // create ajax api local search instance
}



function create_icon(prefix)
{
    // create icon and its attributes
    var Icon               = new GIcon();
    Icon.image             = "/images/icons/course_map/" + prefix + ".png";
    Icon.shadow            = "/images/icons/course_map/" + prefix + "_shadow.png";
	Icon.iconSize          = new GSize(26, 26);
	Icon.shadowSize        = new GSize(46, 26);
	Icon.iconAnchor        = new GPoint(12, 26);
	Icon.infoWindowAnchor  = new GPoint(26, 0);
	Icon.imageMap          = [0,0, 26,0, 26,26, 0,26, 0,0];
	
	return Icon;
}



function focus_on_location(latLng, zoom)
{
    //alert(latLng);
    //alert(zoom);
    var Bounds = gCourse_Map.getBounds();       // get the current area covered by the map
    
    gCurrent_zoom = gCourse_Map.getZoom();      // get the current zoom level
    
    if ((gCurrent_zoom == DEFAULT_ZOOM) || (gCurrent_zoom > zoom)) {   // if we haven't changed zoom from the default or the current zoom is closer than the suggested zoom
        gCurrent_zoom = zoom;                   // use the suggested zoom
    }
    
    if (Bounds.containsLatLng(latLng)) {        // if the location we're going to is already on the map
        gCourse_Map.setZoom(gCurrent_zoom);     // set the zoom
        gCourse_Map.panTo(latLng);              // pan to the location
    } else {
        gCourse_Map.setCenter(latLng, gCurrent_zoom); // otherwise recenter the map and zoom
    }
}



function check_focus_on_location(latLng)
{
    var Bounds = gCourse_Map.getBounds();               // get the current map boundaries
    
    if (Bounds.containsLatLng(latLng)) {
        if (gCurrent_zoom == DEFAULT_ZOOM) {
            focus_on_location(DEFAULT_LATLNG, DEFAULT_ZOOM);    // if we're at the default zoom recentre at the default
        } else {
            focus_on_location(latLng, gCurrent_zoom);   // the location is on the map so focus on it
        }
    } else {
        if (gCurrent_zoom > DEFAULT_ZOOM) {             // if we're still zoomed in from the default
            gCurrent_zoom = gCourse_Map.getZoom() - 1;  // set the current zoom to the current zoom minus 1
            gCourse_Map.setZoom(gCurrent_zoom);         // reset the map zoom
            check_focus_on_location(latLng);            // check whether the location is on the map again
        } else {
            focus_on_location(DEFAULT_LATLNG, DEFAULT_ZOOM);    // go to the default zoom/location
        }
    }
}



function focus_on_cluster_location(lat, lng, zoom)
{
    gCurrent_zoom = gCourse_Map.getZoom();      // get the current zoom
    
    if (gCurrent_zoom < zoom) {                 // if the current zoom is less than the suggested zoom
        gCurrent_zoom = zoom;                   // use the suggested zoom
    } else {
        gCurrent_zoom = gCurrent_zoom + 2;      // else increase the zoom to zoom in further (and split cluster)
    }
    
    var Lat_Lng = new GLatLng(lat, lng);        // get the latlng
    focus_on_location(Lat_Lng, gCurrent_zoom);  // focus on the location
}



function set_location(prefix, loc)
{
    //alert('set_location - ' + prefix);
    
    // if the text input contains the default text (ie. unchanged)
    if (loc == DEFAULT_TEXT) {
        gAlert_on = true;
        alert('Please enter a UK postcode or place name');  // prompt the user to input an address
    
    // if the text input is empty
    } else if (loc == '') {
        if (prefix == 'home') {                             // if this is the home text input
            if (gHome_set) {                                // if a marker has been set
                remove_location_marker(prefix);             // remove the marker
            } else {                                        // or
                gAlert_on = true;
                alert('Please enter a UK postcode or place name');  // prompt the user to input an address
            }
        } else {                                            // if this is the other/work text input
            if (gOther_set) {                               // if a marker has been set
                remove_location_marker(prefix);             // remove the marker
            } else {                                        // or
                gAlert_on = true;
                alert('Please enter a UK postcode or place name');  // prompt the user to input an address
            }
        }
    
    // if the text input has a search value
    } else {
        // define the search function
        gLocal_Search.setSearchCompleteCallback(null, 
            function() {
            
                // a location has been found matching the search query
                if (gLocal_Search.results[0]) {        
                    var result_lat  = parseFloat(gLocal_Search.results[0].lat);
                    var result_lng  = parseFloat(gLocal_Search.results[0].lng);
                    var Lat_Lng     = new GLatLng(result_lat, result_lng);
                    
                    // set the global variables based on which text input prompted the search
                    if (prefix == 'home') {
                        gHome_lat   = result_lat;
                        gHome_lng   = result_lng;
                        gOrder_by   = 'home_dist';
                        gHome_set   = 1;
                    } else {
                        gOther_lat  = result_lat;
                        gOther_lng  = result_lng;
                        gOrder_by   = 'other_dist';
                        gOther_set  = 1;
                    }
                    
                    gCurrent_zoom = gCourse_Map.getZoom(); // find the current zoom
                    
                    if (gCurrent_zoom == DEFAULT_ZOOM) {
                        add_location_marker(prefix, Lat_Lng, 10);
                        gCurrent_zoom = 10;
                    } else {
                        add_location_marker(prefix, Lat_Lng, gCurrent_zoom);
                    }
                    
                    get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // get map data and set up markers
                
                // a location cannot be found matching the search query
                } else {
                    alert("Your location could not be found. \nPlease enter a new location.");
                }
            });
        gLocal_Search.execute(loc + ", UK"); // execute the search function
    }
}



function add_location_marker(prefix, latLng, zoom)
{
    //alert('add_location_marker');
    
    // clean up previous location markers
    if (gLocation_markers[prefix] != null) {
        gCourse_Map.removeOverlay(gLocation_markers[prefix]);
        gLocation_markers[prefix] = null;
    }
    
    // clean up previous location markers if work/other has changed
    if (prefix == 'work') {
        if (gLocation_markers['other'] != null) {
            gCourse_Map.removeOverlay(gLocation_markers['other']);
            gLocation_markers['other'] = null;
        }
    } else if (prefix == 'other') {
        if (gLocation_markers['work'] != null) {
            gCourse_Map.removeOverlay(gLocation_markers['work']);
            gLocation_markers['work'] = null;
        }
    }
    
    // MS: Temp - needs sorting out so window repops if open
    //var win = gCourse_Map.getInfoWindow();
    //gCourse_Map.closeInfoWindow(win);
    //gCourse_Map.closeInfoWindow();
    
    var icon = create_icon(prefix); // create the icon
    gLocation_markers[prefix] = new GMarker(latLng, { icon: icon, draggable: true, bouncy: true }); // create a new marker instance
    gCourse_Map.addOverlay(gLocation_markers[prefix]); // add the overlay to the map
    
    // set map view
    focus_on_location(latLng, zoom);
    
    // create listener for when the icon starts being dragged
    GEvent.addListener(gLocation_markers[prefix], "drag", function() {
        gCourse_Map.closeInfoWindow(); // close any open info windows so you can see where you're dragging!
    });
    
    // create listener for when the icon has stopped being dragged
    GEvent.addListener(gLocation_markers[prefix], "dragend", function() {
        var new_location = gLocation_markers[prefix].getLatLng() // get the new location
        
        // reset the location coordinates for the appropriate location
        if (prefix == 'home') {
            gHome_lat   = new_location.lat();
            gHome_lng   = new_location.lng();
            gOrder_by   = 'home_dist';
        } else {
            gOther_lat  = new_location.lat();
            gOther_lng  = new_location.lng();
            gOrder_by   = 'other_dist';
        }
        
        get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // get map data and set up markers
    });
}



function remove_location_marker(prefix)
{
    if (gLocation_markers[prefix]) {
        gCourse_Map.removeOverlay(gLocation_markers[prefix]);   // remove the marker
    }
    
    // reset the location lat/lng text input values
    if (prefix == 'home') {
        gHome_lat   = null;
        gHome_lng   = null;
        var pfx     = 'home';
        gHome_set   = 0;
    } else {
        gOther_lat  = null;
        gOther_lng  = null;
        var pfx     = 'other';
        gOther_set  = 0;
    }
    
    gOrder_by = 'inst_name, camp_name';
    
    reset_location_input(pfx);
    
    //get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // get map data and set up markers
}



function create_institution_marker(markerProperties)
{
    var icon = create_icon('institution');
    var Inst_Marker = new GMarker(markerProperties['latlng'], { icon: icon, draggable: false, bouncy: false });
    //var Inst_Marker = new GMarker(markerProperties['latlng'], { icon:markerProperties['icon'], draggable:false, bouncy:false });
    
    // get and store all the markerProperties
    /* this is shorthand for the list below but creates more properties that don't get used so doesn't execute so quickly
    for (var key in markerProperties) {
        Inst_Marker[key] = markerProperties[key];
    }
    */
    
    Inst_Marker.course_id           = markerProperties['course_id'];
    Inst_Marker.inst_id             = markerProperties['inst_id'];
    Inst_Marker.inst_name           = markerProperties['inst_name'];
    Inst_Marker.inst_address1       = markerProperties['inst_address1'];
    Inst_Marker.inst_address2       = markerProperties['inst_address2'];
    Inst_Marker.inst_address3       = markerProperties['inst_address3'];
    Inst_Marker.inst_city           = markerProperties['inst_city'];
    Inst_Marker.inst_county         = markerProperties['inst_county'];
    Inst_Marker.inst_postcode       = markerProperties['inst_postcode'];
    Inst_Marker.inst_contact_name   = markerProperties['inst_contact_name'];
    Inst_Marker.inst_contact_phone  = markerProperties['inst_contact_phone'];
    Inst_Marker.inst_contact_email  = markerProperties['inst_contact_email'];
    Inst_Marker.inst_website        = markerProperties['inst_website'];
    Inst_Marker.camp_id             = markerProperties['camp_id'];
    Inst_Marker.camp_name           = markerProperties['camp_name'];
    Inst_Marker.camp_address1       = markerProperties['camp_address1'];
    Inst_Marker.camp_address2       = markerProperties['camp_address2'];
    Inst_Marker.camp_address3       = markerProperties['camp_address3'];
    Inst_Marker.camp_city           = markerProperties['camp_city'];
    Inst_Marker.camp_county         = markerProperties['camp_county'];
    Inst_Marker.camp_postcode       = markerProperties['camp_postcode'];
    Inst_Marker.home_dist           = markerProperties['home_dist'];
    Inst_Marker.other_dist          = markerProperties['other_dist'];
    Inst_Marker.latlng              = markerProperties['latlng'];
    Inst_Marker.indexnum            = markerProperties['indexnum'];    
    
    // create click listener for each marker
    GEvent.addListener(Inst_Marker, "click", function(indexNum, courseId) {
        
        // if this is a free-text search make clicking on marker bring results for that inst/camp to the top
        if (gSearch_type == 'freetext' && !gResult_lock) {
            //alert('1'); // for route testing
            get_map_search_results(gKeyword_id, Inst_Marker.indexnum, Inst_Marker.course_id);
        
        // highlight that inst result on its current page
        } else {
            // if no args have been passed fromt the results entry
            if (indexNum == undefined || courseId == undefined) {
                //alert('2'); // for route testing
                Inst_Marker.select_result_entry(Inst_Marker.indexnum, Inst_Marker.course_id); // use this marker's info (normally top entry)
            } else {
                //alert('3'); // for route testing
                Inst_Marker.select_result_entry(indexNum, courseId); // use the args passed from the results entry
            }
        }
        
        // show the info box
        Inst_Marker.show_institution_info();
        gResult_lock = false;
    });
    
    gMarkers_key[Inst_Marker.indexnum] = Inst_Marker; // store each marker in array to link with results
    
    return Inst_Marker;
}



function remove_institution_markers()
{
    //alert(gInst_markers.length);
    // clear existing institution markers
    /* original code - OK to use if needing to revert
    for (var i = 0; i < gInst_markers.length; i++) {
        if (gInst_markers[i] != null) {
            gInst_Clusterer.RemoveMarker(gInst_markers[i]); // remove existing institution markers
        }
    }*/
    
    // clear existing institution markers
    for (var key in gInst_markers) {
        gInst_Clusterer.RemoveMarker(gInst_markers[key]); // remove existing institution markers
    }
}



function open_inst_marker_info(instId, campId) {
    // a bit clumsy but it works
    /* original code - OK to use if needing to revert
    for (var i = 0; i < gInst_markers.length; i++) {
        if (gInst_markers[i]) {
            if ((gInst_markers[i].inst_id == instId) && (gInst_markers[i].camp_id == campId)) {
                GEvent.trigger(gInst_markers[i], 'click');
                break;
            }
        }
    }*/
    for (var key in gInst_markers) {
        if ((gInst_markers[key].inst_id == instId) && (gInst_markers[key].camp_id == campId)) {
            GEvent.trigger(gInst_markers[key], 'click');
            break;
        }
    }
}



GMarker.prototype.show_institution_info = function () {
    var html = '';
    html += '<div class="mp_info_win">' + "\n";
    html += '<h4 onclick="view_courses(' + this.inst_id + ',' + (this.camp_id != '' ? this.camp_id : 0) + ',\'course\');">' + this.inst_name + '</h4>' + "\n";
    if (this.camp_name) {html += '<h5>' + this.camp_name + '</h5>' + "\n";}
    
    html += '<div class="mp_info_details">' + "\n";
    
    // if there's a campus address - use it
    if (this.camp_name && (this.camp_address1 || this.camp_address2 || this.camp_address3 || this.camp_city || this.camp_county || this.camp_postcode)) {
        html += '<p>' + "\n";
        if (this.camp_address1)   {html += this.camp_address1 + '<br />' + "\n";}
        if (this.camp_address2)   {html += this.camp_address2 + '<br />' + "\n";}
        if (this.camp_address3)   {html += this.camp_address3 + '<br />' + "\n";}
        if (this.camp_city)       {html += this.camp_city + '<br />' + "\n";}
        if (this.camp_county)     {html += this.camp_county + '<br />' + "\n";}
        if (this.camp_postcode)   {html += this.camp_postcode + "\n";}
        html += '</p>' + "\n";
    
    // else try using the institution address
    } else {
        html += '<p>' + "\n";
        if (this.inst_address1)   {html += this.inst_address1 + '<br />' + "\n";}
        if (this.inst_address2)   {html += this.inst_address2 + '<br />' + "\n";}
        if (this.inst_address3)   {html += this.inst_address3 + '<br />' + "\n";}
        if (this.inst_city)       {html += this.inst_city + '<br />' + "\n";}
        if (this.inst_county)     {html += this.inst_county + '<br />' + "\n";}
        if (this.inst_postcode)   {html += this.inst_postcode + "\n";}
        html += '</p>' + "\n";
    }
    
    // if there are contact details
    if (this.inst_contact_name || this.inst_contact_phone) {
        html += '<h6>Contact:</h6>' + "\n";
        html += '<p>';
        if (this.inst_contact_name)   {html += this.inst_contact_name + '<br />' + "\n";}
        if (this.inst_contact_phone)  {html += this.inst_contact_phone + "\n";}
        html += '</p>' + "\n";
    }
    
    // if there's a contact email or web address
    if (this.inst_contact_email || this.inst_website) {
        html += '<p>' + "\n";
        if (this.inst_contact_email)  {html += '<a href="' + convert_to_ascii('mailto:' + this.inst_contact_email) + '">email</a>&nbsp;&nbsp;|&nbsp;&nbsp;';}
        if (this.inst_website)        {html += '<a href="http://' + this.inst_website + '" target="_blank"  title="Opens ' + this.inst_name + ' web site in a new window">web site</a>' + "\n";}
        html += '</p>' + "\n";
    }
    
    html += '<p>' + "\n";
    html += '<a href="javascript:view_courses(' + this.inst_id + ',' + (this.camp_id != '' ? this.camp_id : 0) + ',\'course\');">View courses</a>';
    html += '</p>' + "\n";
    
    html += '</div>' + "\n";
    
    if (this.home_dist || this.other_dist) {
        html += '<div class="mp_info_location">' + "\n";
        html += '<h6>Distance from:</h6>' + "\n";
        
        if (this.home_dist) {
            html += '<div class="mp_dist">' + "\n";
            html += '<p>' + "\n";
            html += '<img src="images/icons/home-shadow-combi.gif" alt="Home icon" /><br />' + "\n";
            html += '<span class="home_heading">My Home</span><br />' + "\n";
            html += '<strong>' + this.home_dist + '</strong> mile' + (this.home_dist == 1 ? '' : 's') + '<br />' + "\n";
            html += '</p>' + "\n";
            html += '</div>' + "\n";
        }
        
        if (this.other_dist) {
            if ($('workplace').checked) {
                html += '<div class="mp_dist">' + "\n";
            html += '<p>' + "\n";
                html += '<img src="images/icons/work-shadow-combi.gif" alt="Work icon" /><br />' + "\n";
                html += '<span class="other_heading">Work</span><br />' + "\n";
                html += '<strong>' + this.other_dist + '</strong> mile' + (this.other_dist == 1 ? '' : 's') + '<br />' + "\n";
                html += '</p>' + "\n";
                html += '</div>' + "\n";
            } else {
                html += '<div class="mp_dist">' + "\n";
            html += '<p>' + "\n";
                html += '<img src="images/icons/other-shadow-combi.gif" alt="Other icon" /><br />' + "\n";
                html += '<span class="other_heading">Other</span><br />' + "\n";
                html += '<strong>' + this.other_dist + '</strong> mile' + (this.other_dist == 1 ? '' : 's') + '<br />' + "\n";
                html += '</p>' + "\n";
                html += '</div>' + "\n";
            }
        }
        
        html += '</div>' + "\n";
    }
    
    html += '<div class="clearboth"></div>' + "\n";
    html += '</div>';

    this.openInfoWindowHtml(html);
}



function create_results_entry(marker, resultProperties)
{
    //alert('create_results_entry');
    /*
    for (var key in resultProperties) {
        this[key] = resultProperties[key];
    }
    */
    
    this.result_num = resultProperties['indexnum'];
    this.course_id  = resultProperties['course_id'];
    this.inst_id    = resultProperties['inst_id'];
    this.inst_name  = resultProperties['inst_name'];
    this.camp_id    = resultProperties['camp_id'];
    this.camp_name  = resultProperties['camp_name'];
    this.home_dist  = resultProperties['home_dist'];
    this.other_dist = resultProperties['other_dist'];
    
    
    var latlng      = resultProperties['latlng'];
    //var result_id   = 'result_' + this.result_num;
    var result_id   = this.result_num;
    
    var html        = '';
    html            += '<div><h4>' + this.inst_name + '</h4>' + "\n";
    html            += '<h5>' + this.camp_name + '</h5>' + "\n";    
    html            += '<p>' + "\n";
    html            += '<a href="javascript:view_courses(' + this.inst_id + ',' + (this.camp_id != '' ? this.camp_id : 0) + ',\'course\');">View courses</a>' + "\n"; // NOTE: change js call to onclick if you can to hide values
    html            += '</p></div>' + "\n";
    
    var li          = document.createElement('li');
    li.innerHTML    = html; // set the html content
    
    //li.id           = result_id;
    li.id           = 'result_' + result_id + 'c' + this.course_id;
    li.className    = 'unselected';
    
    var index_num   = this.result_num;
    var course_id   = this.course_id;
    
    // add a listener for the result entry
    GEvent.addDomListener(li, 'click', function() {
        hide_window('mp_enquiry');
        clear_window('mp_enquiry');
        hide_window('mp_courses');
        clear_window('mp_courses');
        hide_window('mp_keywords');
        clear_window('mp_keywords');
        if (gCurr_selected != result_id) {
            if ('' != latlng) { // to filter out things like Open University that don't have location markers set
                var Current_Center  = gCourse_Map.getCenter();
                var difference_x    = Math.max(Current_Center.lat(), latlng.lat()) - Math.min(Current_Center.lat(), latlng.lat()); 
                var difference_y    = Math.max(Current_Center.lng(), latlng.lng()) - Math.min(Current_Center.lng(), latlng.lng());
                var distance        = (Math.sqrt(difference_x * difference_x) + (difference_y * difference_y));
    			
    			gResult_lock = true;
    			GEvent.trigger(marker, 'click', index_num, course_id);
    			
    			if (distance > 0.5) {
                    focus_on_location(latlng, 10);
    			}
			}
		}
    });
    
    GEvent.addDomListener(li, 'mouseover', function() {
        if (gCurr_selected == result_id) {
            li.style.cursor = 'default';
        } else {
            li.className    = 'selected';
            li.style.cursor = 'pointer';
        }
    });
    
    GEvent.addDomListener(li, 'mouseout', function() {
        if (gCurr_selected != result_id) {
            li.className    = 'unselected';
            li.style.cursor = 'default';
        }
    });
		
    return li; // return the entry for inclusion
}



function create_course_results_entry(marker, resultProperties)
{
    //alert('create_course_results_entry');
    
    this.result_num         = resultProperties['indexnum'];
    this.course_id          = resultProperties['course_id'];
    this.course_name        = resultProperties['course_name'];
    this.course_link        = resultProperties['course_link'];
    this.level_id           = resultProperties['level_id'];
    this.level_name         = resultProperties['level_name'];
    this.inst_id            = resultProperties['inst_id'];
    this.inst_name          = resultProperties['inst_name'];
    this.camp_id            = resultProperties['camp_id'];
    this.camp_name          = resultProperties['camp_name'];
    this.home_dist          = resultProperties['home_dist'];
    this.other_dist         = resultProperties['other_dist'];
    this.subjectarea_name   = resultProperties['subjectarea_name'];
    this.inst_contact_email = resultProperties['inst_contact_email'];
    this.inst_contact_name  = resultProperties['inst_contact_name'];
    
    
    var latlng      = resultProperties['latlng'];
    //var result_id   = 'result_' + this.result_num;
    var result_id   = this.result_num;
    
    var html        = '';
    html            += '<div><h4>' + this.course_name + '</h4>' + "\n";
    html            += '<h5>' + this.level_name + '</h5>' + "\n";
    html            += '<h6>' + this.inst_name + '</h6>' + "\n";
    html            += '<h6 class="camp_name">' + this.camp_name + '</h6>' + "\n";
    
    // add course web page link if it exists
    if ((this.course_link != undefined) && (this.course_link != '') && (this.course_link != 'http://') && (this.level_id == 5 || this.level_id == 22 || this.level_id == 23)) {
        html        += '<p>' + "\n";
        html        += '<a href="' + this.course_link + '" target="_blank" title="Opens course web page in a new window">Course web page</a>';
        html        += '</p>' + "\n";
    }
    
    // add course enquiry link if it exists
    if (this.inst_contact_email != '' && (this.level_id == 5 || this.level_id == 22 || this.level_id == 23)) { // if this is a Foundation Degree/HND/HNC and a contact email exists
        html        += '<p>' + "\n";
        html        += '<a href="javascript:make_enquiry({inst_name:\'' + escape(this.inst_name) + '\',camp_name:\'' + escape(this.camp_name) + '\',course_name:\'' + escape(this.course_name) + '\',subjectarea_name:\'' + escape(this.subjectarea_name) + '\',level_name:\'' + escape(this.level_name) + '\',inst_contact_email:\'' + this.inst_contact_email + '\',inst_contact_name:\'' + escape(this.inst_contact_name) + '\'}, true);">Enquire about this course</a>';
        html        += '</p>' + "\n";
    }
    
    html            += '</div>' + "\n";
    
    var li          = document.createElement('li');
    li.innerHTML    = html; // set the html content
    //li.id           = result_id;
    li.id           = 'result_' + result_id + 'c' + this.course_id;
    li.className    = 'unselected';
    
    var index_num   = this.result_num;
    var course_id   = this.course_id;
    
    // add a listener for the result entry
    GEvent.addDomListener(li, 'click', function() {
        hide_window('mp_enquiry');
        clear_window('mp_enquiry');
        hide_window('mp_courses');
        clear_window('mp_courses');
        hide_window('mp_keywords');
        clear_window('mp_keywords');
        if (gCurr_selected != result_id) {
            if ('' != latlng) { // to filter out things like Open University that don't have location markers set
                var Current_Center  = gCourse_Map.getCenter();
                var difference_x    = Math.max(Current_Center.lat(), latlng.lat()) - Math.min(Current_Center.lat(), latlng.lat()); 
                var difference_y    = Math.max(Current_Center.lng(), latlng.lng()) - Math.min(Current_Center.lng(), latlng.lng());
                var distance        = (Math.sqrt(difference_x * difference_x) + (difference_y * difference_y));
    			
    			gResult_lock = true;
    			GEvent.trigger(marker, 'click', index_num, course_id);
    			
    			if (distance > 0.5) {
                    focus_on_location(latlng, 10);
    			}
			}
		}
    });
    
    // add listener for mouseover
    GEvent.addDomListener(li, 'mouseover', function() {
        if (gCurr_selected == result_id) {
            li.style.cursor = 'default';
        } else {
            li.className    = 'selected';
            li.style.cursor = 'pointer';
        }
    });
    
    // add listener for mouseout
    GEvent.addDomListener(li, 'mouseout', function() {
        if (gCurr_selected != result_id) {
            li.className    = 'unselected';
            li.style.cursor = 'default';
        }
    });
		
    return li; // return the entry for inclusion
}



/* original code
GMarker.prototype.select_result_entry = function (id) {
    var which = "result_" + id;
    select_result(which);
}
*/



GMarker.prototype.select_result_entry = function (which, course_id) {
    select_result(which, course_id);
}



function select_result(which, courseId) {
    // code for displaying which result is currently selected
    
    if (gPrev_selected != undefined) {                  // if there's a previous selection
        for (var key in gResults_ids[gPrev_selected]) { // cycle through the related results
            var prev_li         = $('result_' + key);   // get the handle for each of the previously selected results
            prev_li.className   = 'unselected';         // set the result to unselected
        }
    }
    
    gCurr_selected = which; // set the currently selected result
    
    if (gCurr_selected != gPrev_selected) {             // if the current selection has changed
        for (var key in gResults_ids[gCurr_selected]) { // cycle through the related results
            var tmp_curr_li = $('result_' + key);       // get the handle for each result to select
            tmp_curr_li.className = 'selected';         // set result to selected
        }
        
        var curr_li = $('result_' + which + 'c' + courseId);   // set the id for the result sent through from the marker (should be the top result or current selection)
        gCurr_page = parseFloat(curr_li.parentNode.id.substring(11, curr_li.parentNode.id.length)); // get the corresponding page indexnum for top result (go_to_page() works with numbers)
    }
    
    gPrev_selected = gCurr_selected;    // store current selected result as the previously selected result for next time
    
    if (gPrev_page != gCurr_page) {                 // if we need to change results page
        go_to_page(gPrev_page, gCurr_page);         // change results page
    }
}



/* orginal code
function select_result(which) {
    // code for displaying which result is currently selected
    
    if (gPrev_selected) {                           // if there's a previous selection
        var prev_li         = $(gPrev_selected);    // get the handle for the previously selected result
        prev_li.className   = 'unselected';         // if the previous result exists then remove its highlight
    }
    gCurr_selected          = which;                // set the currently selected result
    
    var curr_li             = $(which);             // get the handle for the currently selected result
    if (curr_li) {
        curr_li.className   = 'selected';           // set its highlight
        gCurr_page          = parseFloat(curr_li.parentNode.id.substring(11, curr_li.parentNode.id.length)); // get the corresponding page indexnum (go_to_page() works with numbers)
        
    }
    gPrev_selected          = gCurr_selected;       // store it as the previously selected result for next time
    
    if (gPrev_page != gCurr_page) {                 // if we need to change results page
        go_to_page(gPrev_page, gCurr_page);         // change results page
    }
}
*/



function go_to_page(fromPage, toPage)
{
    //alert('go_to_page');
    $('mp_results_' + fromPage).style.display = 'none';     // hide the previous page
    $('mp_results_' + toPage).style.display   = 'block';    // show the current page
    gPrev_page  = toPage;                                   // update the previous page
    gCurr_page  = toPage;                                   // store the current page
}



function create_course_entry(courseProperties, rowSwitcher)
{
    // get and store courseProperties
    
    for (var key in courseProperties) {
        this[key] = courseProperties[key];
    }
    
    /* replaced by above although this version might offer slightly better performance
    //this.course_id              = courseProperties['course_id'];
    this.course_name            = courseProperties['course_name'];
    //this.subjectarea_id         = courseProperties['subjectarea_id'];
    this.subjectarea_name       = courseProperties['subjectarea_name'];
    this.level_id               = courseProperties['level_id'];
    this.level_name             = courseProperties['level_name'];
    //this.level_display_order    = courseProperties['level_display_order'];
    this.course_link            = courseProperties['course_link'];
    this.inst_contact_email     = courseProperties['inst_contact_email'];
    */
    
    // create the table rows and cells and populate them
    var tr      = document.createElement('tr');
    tr.vAlign   = 'top';
    if (rowSwitcher) {tr.className = 'row_alt';}
    
    var td1     = document.createElement('td');
    var td2     = document.createElement('td');
    var td3     = document.createElement('td');
    var td4     = document.createElement('td');
    var html    = '';
    
    // course name
    html            = this.course_name;
    td1.innerHTML   = html;
    td1.className   = 'course';
    tr.appendChild(td1);
    
    // level name
    html            = this.level_name;
    td2.innerHTML   = html;
    td2.className   = 'level';
    tr.appendChild(td2);
    
    // course enquiry link
    if (this.inst_contact_email != '' && (this.level_id == 5 || this.level_id == 22 || this.level_id == 23)) { // if this is a Foundation Degree/HND/HNC and a contact email exists
        html        = '<a href="javascript:make_enquiry({inst_name:\'' + escape(this.inst_name) + '\',camp_name:\'' + escape(this.camp_name) + '\',course_name:\'' + escape(this.course_name) + '\',subjectarea_name:\'' + escape(this.subjectarea_name) + '\',level_name:\'' + escape(this.level_name) + '\',inst_contact_email:\'' + this.inst_contact_email + '\',inst_contact_name:\'' + escape(this.inst_contact_name) + '\'});">Enquire about<br />this course</a>';
    } else {
        html        = '';
    }
    td3.innerHTML   = html;
    td3.className   = 'enquire';
    tr.appendChild(td3);
    
    // course web page link
    if ((this.course_link != undefined) && (this.course_link != '') && (this.course_link != 'http://')) {
        html        = '<a href="' + this.course_link + '" target="_blank" title="Opens course web page in a new window">Course web page</a>';
    } else {
        html        = '';
    }
    td4.className   = 'link';
    td4.innerHTML   = html;
    tr.appendChild(td4);
    
    return tr;
}



function make_enquiry(courseProperties, fromResult)
{
    // get and store courseProperties
    for (var key in courseProperties) {
        this[key] = courseProperties[key];
    }
    
    var enquiry_win = $('mp_enquiry'); // get the id handle for the enquiry window
    enquiry_win.innerHTML = ''; // clear previous content
    
    // create the window close button
    var a       = document.createElement('a');
    a.className = 'close_button';
    a.href      = "javascript:hide_window('mp_enquiry')" + (fromResult ? ';' : ", show_window('mp_courses');");
    var img     = document.createElement('img');
    img.src     = '/images/icons/course_map/close_button.gif';
    img.alt     = 'Close button';
    a.appendChild(img);
    enquiry_win.appendChild(a);
    
    var div  = document.createElement('div');
    div.id   = 'mp_enquiry_form';
    
    var html = '';
    html += '<h4>Enquire about this course</h4>' + "\n";
    html += '<p class="intro">To send an enquiry to <span class="institution">' + unescape(this.inst_name) + '</span> please complete the form below. They will then contact you direct.</p>' + "\n";
    html += '<p class="no_divide"><span class="required">&#42;</span> required fields</p>' + "\n";
    
    html += '<form action="/find-a-course" method="post" onsubmit="check_enquiry_form(this); return false;">' + "\n";
    html += '<input id="enq_inst_name" name="enq_inst_name" type="hidden" value="' + unescape(this.inst_name) + '" />' + "\n";
    html += '<input id="enq_camp_name" name="enq_camp_name" type="hidden" value="' + unescape(this.camp_name) + '" />' + "\n";
    html += '<input id="enq_inst_contact_name" name="enq_inst_contact_name" type="hidden" value="' + unescape(this.inst_contact_name) + '" />' + "\n";
    html += '<input id="enq_inst_contact_email" name="enq_inst_contact_email" type="hidden" value="' + this.inst_contact_email + '" />' + "\n";
    html += '<input id="enq_course_name" name="enq_course_name" type="hidden" value="' + unescape(this.course_name) + '" />' + "\n";
    html += '<input id="enq_level_name" name="enq_level_name" type="hidden" value="' + unescape(this.level_name) + '" />';
    html += '<div class="form_divide"><span class="faux_label">Course:</span><span class="faux_input course_name">' + unescape(this.course_name) + '</span></div>' + "\n";
    html += '<div class="form_divide"><span class="faux_label">Qualification:</span><span class="faux_input">' + unescape(this.level_name) + '</span></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_first_name">First name: <span class="required">&#42;</span></label><input class="text_input" id="enq_first_name" name="enq_first_name" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_surname">Surname: <span class="required">&#42;</span></label><input class="text_input" id="enq_surname" name="enq_surname" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_phone">Phone: <span class="required">&#42;</span></label><input class="text_input" id="enq_phone" name="enq_phone" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide select_row"><label for="enq_person_type">Are you&hellip;: <span class="required">&#42;</span></label>' + "\n";
    html += '<select id="enq_person_type" name="enq_person_type">' + "\n";
    html += '<option value="0" selected="selected">Please choose&hellip;</option>' + "\n";
    html += '<option value="A prospective student">a prospective student</option>' + "\n";
    html += '<option value="An employer">an employer</option>' + "\n";
    html += '<option value="Other">other</option>' + "\n";
    html += '</select></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_email">Email:</label><input class="text_input" id="enq_email" name="enq_email" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_address1">Address:</label><input class="text_input" id="enq_address1" name="enq_address1" type="text" value="" /></div>' + "\n";
    html += '<div class="no_divide address"><label for="enq_address2" class="hidden">Address2:</label><input class="text_input" id="enq_address2" name="enq_address2" type="text" value="" /></div>' + "\n";
    html += '<div class="no_divide address"><label for="enq_address3" class="hidden">Address3:</label><input class="text_input" id="enq_address3" name="enq_address3" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_city">City:</label><input class="text_input" id="enq_city" name="enq_city" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_county">County:</label><input class="text_input" id="enq_county" name="enq_county" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_postcode">Postcode:</label><input class="text_input" id="enq_postcode" name="enq_postcode" type="text" value="" /></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_query">What would you like to know?: <span class="required">&#42;</span></label><textarea id="enq_query" name="enq_query"></textarea></div>' + "\n";
    html += '<div class="form_divide select_row"><label for="enq_where">Where did you hear about this web site?</label>' + "\n";
    html += '<select id="enq_where" name="enq_where">' + "\n";
    html += '<option value="None selected" selected="selected">Please choose&hellip;</option>' + "\n";
    html += '<option value="Poster/flyer">Poster/flyer</option>' + "\n";
    html += '<option value="Magazine/paper">Magazine/paper</option>' + "\n";
    html += '<option value="Careers adviser">Careers adviser</option>' + "\n";
    html += '<option value="Colleague/business contact">Colleague/business contact</option>' + "\n";
    html += '<option value="Lecturer/teacher">Lecturer/teacher</option>' + "\n";
    html += '<option value="Search engine">Search engine</option>' + "\n";
    html += '<option value="Link from another web site">Link from another web site</option>' + "\n";
    html += '<option value="Family member/friend">Family member/friend</option>' + "\n";
    html += '<option value="Employer">Employer</option>' + "\n";
    html += '<option value="Union Learning Rep">Union Learning Rep</option>' + "\n";
    html += '<option value="Lifelong Learning Network">Lifelong Learning Network</option>' + "\n";
    html += '</select><div></div></div>' + "\n";
    html += '<div class="form_divide"><label for="enq_contact">Contact:</label><input class="checkbox" id="enq_contact" name="enq_contact" type="checkbox" /><label class="checkbox_para" for="enq_contact">Please tick this checkbox if you are happy for us to contact you for evaluation purposes. Thank you.</label></div>' + "\n";
    html += '<div class="form_submit"><input type="submit" value="Send your enquiry" />&nbsp;&nbsp;&nbsp;<a href="javascript:' + (fromResult ? '' : 'show_window(\'mp_courses\'),') + 'hide_window(\'mp_enquiry\');">Cancel</a></div>' + "\n";
    html += '</form>' + "\n";
    
    div.innerHTML = html;
    enquiry_win.appendChild(div);

    show_window('mp_enquiry');  // show the enquiry form window
    hide_window('mp_courses');  // hide the courses window
    hide_window('mp_keywords'); // hide the keywords window
}



function check_enquiry_form(f)
{
    // if first name is not supplied or is a space
    if (f.enq_first_name.value.length == 0 || f.enq_first_name.value == ' ') {
        alert('Please enter your first name.');
        return false;
    }
    
    // if surname is not supplied or is a space
    if (f.enq_surname.value.length == 0 || f.enq_surname.value == ' ') {
        alert('Please enter your surname.');
        return false;
    }
    
    // if phone number is not supplied or is a space
    if (f.enq_phone.value.length == 0 || f.enq_phone.value == ' ') {
        alert('Please enter a phone number we can contact you on.');
        return false;
    }
    
    // if person type is not selected
    if (f.enq_person_type.selectedIndex == 0) {
        alert('Please tell us what type of visitor you are.');
        return false;
    }
    
    // if query is not supplied or is a space
    if (f.enq_query.value.length == 0 || f.enq_query.value == ' ') {
        alert('Please tell us what you would like to know.');
        return false;
    }
    
    // if email is supplied - check for validity
    if (f.enq_email.value.length != 0) {
        var email_check = valid_email(f.enq_email.value); // check for validity
        
        // if it's not valid
        if (!email_check) {
            alert('Your email does not appear to be valid - please check it and try sending your enquiry again.');
            return false;
        }
    }
    
    // call the processing function passing the form info
	send_course_enquiry(f);
}



function send_course_enquiry(f)
{ 
    // send the form data
    new Ajax.Request(
        'send_course_enquiry/', // the url
        {
            method: 'post', // send via post
            postBody: Form.serialize(f), // serialise the form data into post format (Prototype function) 
            onSuccess: function(t) {
                //alert(t.responseText);
                update_enquiry_window(t.responseText); // when completed, send the result to the enquiry window
            },
            asynchronous:true
        }
    );
    return false; // make sure the window doesn't reload 
}



function update_enquiry_window(message)
{
    // update the html in the enquiry window
    var html = '<h4>Enquire about this course</h4>' + "\n";
    html     += message + "\n";
    
    $('mp_enquiry_form').innerHTML = html;
}



function filter_subjects()
{
    //alert(filter_subjects);
    var filter_subject = $('filter_subject'); // get input handle
    
    if (filter_subject != undefined) {                                          // if input exists
        var subject_index       = filter_subject.selectedIndex;                 // get the index of that value
        var subject_selected    = filter_subject.options[subject_index].value;  // get the value
        gFilter_subject         = subject_selected;                             // set the global to match the value
        
        // if we're not already ordering by distance
        if ((gOrder_by != 'home_dist') && (gOrder_by != 'other_dist')) {
            gOrder_by = 'inst_name, camp_name';
        } 
    }   
    
    get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // get map data and set up markers
}



function filter_fds()
{
    // NOTE: Not currently used as all results are limited to Foundation Degrees only
    //alert(filter_fds);
    if ($('filter_fd').checked) {
        gFilter_fd  = 1;
    } else {
        gFilter_fd  = 0;
    }
    
    // if we're not already ordering by distance
    if ((gOrder_by != 'home_dist') && (gOrder_by != 'other_dist')) {
        gOrder_by = 'inst_name, camp_name';
    }
    
    get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // get map data and set up markers
}



function do_map_search(tag_id)
{
    gSearch_type = 'freetext';
    gSearch_term = $('course_searchbox').value;
    
    // if this is not a keyword search - reset the gKeyword_id global
    if (tag_id == undefined) {
        gKeyword_id = '';
    }
    
    // if search is empty
    if ($('course_searchbox').value == '') {
        if ($('homebox').value == DEFAULT_TEXT && $('otherbox').value == DEFAULT_TEXT && $('filter_subject').selectedIndex == 0) {
            alert('Please enter a search term');    // prompt user to enter something
        } else {
            get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // use the non-free-text search
        }
        reset_searchbox();  // reset the default text etc
    
    // if search is the default text
    } else if ($('course_searchbox').value == DEFAULT_SEARCH_TEXT) {
        alert('Please enter a search term');    // prompt user to enter something
    
    // a search term has been entered
    } else {
        // set up the results column
        var results_wrapper         = $('mp_results');  // get the results wrapper id handle
        results_wrapper.innerHTML   = '<p id="results_p"><img src="/images/loading_small.gif" style="margin-right:4px;" />Searching&hellip;<br />&nbsp;</p>'; // load search indicator
        
        // clean up previous searches
        gCourse_Map.closeInfoWindow();  // close the info window if open
        hide_window('mp_courses');      // hide the course window
        clear_window('mp_courses');     // clear the contents of the course window
        hide_window('mp_enquiry');      // hide the course window
        clear_window('mp_enquiry');     // clear the contents of the course window
        hide_window('mp_keywords');     // hide the keywords window
        clear_window('mp_keywords');    // clear the contents of the keywords window
        reset_result_globals();         // reset result global variables
        
        // create the request function call and name/value pairs to be passed into php/sql
        var search_url = '/get_map_search_institutions/?subjectarea=' + gFilter_subject + '&fd=' + gFilter_fd + '&home_lat=' + gHome_lat + '&home_lng=' + gHome_lng + '&other_lat=' + gOther_lat + '&other_lng=' + gOther_lng + '&order_by=' + gOrder_by + '&course_searchbox=' + encodeURIComponent($('course_searchbox').value) + (tag_id != undefined ? '&tag_id=' + tag_id : '');
        
        GDownloadUrl(search_url, function(data) {
            remove_institution_markers();   // MS: moving this to here seems to improve performance and solves the "multiple search at once/multi Plumptons" bug
            
            var xml     = GXml.parse(data);
            var markers = xml.documentElement.getElementsByTagName('marker');
            
            // if there are any markers for results
            if (markers.length > 0) {// create the map markers and results
                for (var i = 0; i < markers.length; i++) {
                    
                    // if there's a location for the campus - use it
                    if ((markers[i].getAttribute('camp_lat') != '') && (markers[i].getAttribute('camp_lng') != '')) {
                        var Lat_Lng = new GLatLng(parseFloat(markers[i].getAttribute('camp_lat')), parseFloat(markers[i].getAttribute('camp_lng')));
                    
                    // else if there's a location for the institution - use it
                    } else if ((markers[i].getAttribute('inst_lat') != '') && (markers[i].getAttribute('inst_lng') != '')) {
                        var Lat_Lng = new GLatLng(parseFloat(markers[i].getAttribute('inst_lat')), parseFloat(markers[i].getAttribute('inst_lng')));
                    
                    // else Open University or other without location
                    } else {
                        //if (orderBy = 'home_dist') {
                        //    var Lat_Lng = new GLatLng(homeLat + 0.001, homeLng + 0.001);
                        //} else if (orderBy = 'other_dist') {
                        //    var Lat_Lng = new GLatLng(otherLat + 0.001, otherLng + 0.001);
                        //} else {
                            var Lat_Lng = '';
                        //}
                    }
                    
                    // if a location exists - create a marker
                    //if (Lat_Lng != '') {
                    
                        var marker_properties                    = new Array();
                        marker_properties['course_id']           = markers[i].getAttribute('course_id'); // used to create faux id to match with free-text search results
                        marker_properties['inst_id']             = markers[i].getAttribute('inst_id');
                        marker_properties['inst_name']           = markers[i].getAttribute('inst_name');
                        marker_properties['inst_address1']       = markers[i].getAttribute('inst_address1');
                        marker_properties['inst_address2']       = markers[i].getAttribute('inst_address2');
                        marker_properties['inst_address3']       = markers[i].getAttribute('inst_address3');
                        marker_properties['inst_city']           = markers[i].getAttribute('inst_city');
                        marker_properties['inst_county']         = markers[i].getAttribute('inst_county');
                        marker_properties['inst_postcode']       = markers[i].getAttribute('inst_postcode');
                        marker_properties['inst_contact_name']   = markers[i].getAttribute('inst_contact_name');
                        marker_properties['inst_contact_phone']  = markers[i].getAttribute('inst_contact_phone');
                        marker_properties['inst_contact_email']  = markers[i].getAttribute('inst_contact_email');
                        marker_properties['inst_website']        = markers[i].getAttribute('inst_website');
                        marker_properties['camp_id']             = markers[i].getAttribute('camp_id');
                        marker_properties['camp_name']           = markers[i].getAttribute('camp_name');
                        marker_properties['camp_address1']       = markers[i].getAttribute('camp_address1');
                        marker_properties['camp_address2']       = markers[i].getAttribute('camp_address2');
                        marker_properties['camp_address3']       = markers[i].getAttribute('camp_address3');
                        marker_properties['camp_city']           = markers[i].getAttribute('camp_city');
                        marker_properties['camp_county']         = markers[i].getAttribute('camp_county');
                        marker_properties['camp_postcode']       = markers[i].getAttribute('camp_postcode');
                        marker_properties['home_dist']           = markers[i].getAttribute('home_dist');
                        marker_properties['other_dist']          = markers[i].getAttribute('other_dist');
                        marker_properties['latlng']              = Lat_Lng;
                        marker_properties['indexnum']            = markers[i].getAttribute('id');
                        
                        gResults_ids[marker_properties['indexnum']] = new Object(); // NOTE: added as object not array or else it loads tons of array methods which cause problems later - not sure why
                    
                    if (Lat_Lng != '') {
                        gInst_markers[i] = create_institution_marker(marker_properties);
                        gInst_Clusterer.AddMarker(gInst_markers[i], marker_properties['inst_name'], marker_properties['camp_name']);
                        
                        if (gTop_lat_lng == undefined) {
                            gTop_lat_lng = Lat_Lng;
                            //focus_on_location(gTop_lat_lng, gCurrent_zoom);
                            check_focus_on_location(gTop_lat_lng);
                        }
                    }
                    //}
                }
                
                // if we've reverted to a standard search switch off keyword lock
                if (tag_id == undefined && gKeyword_on) {
                    gKeyword_on = false;
                }
                get_map_search_results(tag_id); // create results in results column
            } else {
                // if keyword is on and there are no results
                if (gKeyword_on) {
                    // revert to a standard search
                    gDouble_search = true;
                    get_map_data(gFilter_subject, gFilter_fd, gHome_lat, gHome_lng, gOther_lat, gOther_lng, gOrder_by); // use the non-free-text search
                } else {
                    // else get free text search display
                    get_map_search_results(tag_id); // create results in results column
                }
            }
        });
    }
}



function get_map_search_results(tagId, instcampId, courseId)
{
    // create the request function call and name/value pairs to be passed into php/sql
    var search_url = '/get_map_search_results/?subjectarea=' + gFilter_subject + '&fd=' + gFilter_fd + '&home_lat=' + gHome_lat + '&home_lng=' + gHome_lng + '&other_lat=' + gOther_lat + '&other_lng=' + gOther_lng + '&order_by=' + gOrder_by + '&course_searchbox='+ encodeURIComponent($('course_searchbox').value) + (tagId != undefined ? '&tag_id=' + tagId : '') + (instcampId != undefined ? '&instcamp_id=' + instcampId : '');
    
    GDownloadUrl(search_url, function(data) {
        //remove_institution_markers();   // MS: moving this to here seems to improve performance and solves the "multiple search at once/multi Plumptons" bug
        
        var xml     = GXml.parse(data);
        var results = xml.documentElement.getElementsByTagName('result');
        
        // set up the results column
        var results_wrapper         = $('mp_results');  // get the results wrapper id handle
        results_wrapper.innerHTML   = '';               // clear the previous results!
            
        // create the results paragraph
        var p       = document.createElement('p');
        p.id        = 'results_p';
        var html    = '';
        
        if (results.length > 0) {
            html += '<a href="javascript:;" onclick="clear_search();">Clear search</a><br /><br />There ' + (results.length == 1 ? 'is' : 'are') + ' <strong>' + results.length + ' result' + (results.length == 1 ? '' : 's') + '</strong> matching your search choices:';
        } else {
            html += '<a href="javascript:;" onclick="clear_search();">Clear search</a><br /><br />There are <strong>no results</strong> matching your search choices.<br /><br />Please narrow your search by <a href="javascript:;" onclick="view_keywords();">searching by keyword</a>.';
        }
        
        p.innerHTML = html;
        results_wrapper.appendChild(p);
        
        // if there are any results
        if (results.length > 0) {// create the results
            var num_results             = 0;                // for storing number of results
            var num_pages               = 0;                // for storing number of pages of results
            
            // create the results entries
            for (var i = 0; i < results.length; i++) {
                    
                // create the results lists
                // creates a new ul with controls each time we need a new page
                num_results++; // increment the number of results
                
                if (num_results > (RESULTS_PER_PAGE * num_pages)) {
                    ++num_pages;
                    var ul          = document.createElement('ul');
                    ul.id           = 'mp_results_' + num_pages;
                    ul.className    = 'mp_results_list';
                    if (num_pages > 1) {
                        ul.style.display = 'none';
                    }
                    
                    var li          = document.createElement('li');
                    li.className    = 'list_header';
                    html            = ''; // clear previous content
                    html            += '<div class="mp_results_control">&nbsp;';
                    
                    if (num_pages != 1) {
                        html += '<p class="mp_results_prev"><a href="javascript:go_to_page(' + num_pages + ',' + (num_pages - 1) + ');">&#171;&nbsp;previous</a></p>';
                    }
                    
                    if (num_pages != (Math.ceil(results.length / RESULTS_PER_PAGE))) {
                        html += '<p class="mp_results_next"><a href="javascript:go_to_page(' + num_pages + ',' + (num_pages + 1) + ');">next&nbsp;&#187;</a></p>';
                    }
                    
                    html            += '</div>';
                    li.innerHTML    = html;
                    ul.appendChild(li);
                    results_wrapper.appendChild(ul);
                }
                
                
                
                // if there's a location for the campus - use it
                if ((results[i].getAttribute('camp_lat') != '') && (results[i].getAttribute('camp_lng') != '')) {
                    var Lat_Lng = new GLatLng(parseFloat(results[i].getAttribute('camp_lat')), parseFloat(results[i].getAttribute('camp_lng')));
                
                // else if there's a location for the institution - use it
                } else if ((results[i].getAttribute('inst_lat') != '') && (results[i].getAttribute('inst_lng') != '')) {
                    var Lat_Lng = new GLatLng(parseFloat(results[i].getAttribute('inst_lat')), parseFloat(results[i].getAttribute('inst_lng')));
                
                // else Open University course or other without location
                } else {
                //    if (orderBy = 'home_dist') {
                //        var Lat_Lng = new GLatLng(homeLat + 0.001, homeLng + 0.001);
                //    } else if (orderBy = 'other_dist') {
                //        var Lat_Lng = new GLatLng(otherLat + 0.001, otherLng + 0.001);
                //   } else {
                        var Lat_Lng = '';
                //    }
                }
                
                
                // if this is a course
                if (results[i].getAttribute('type') == 'course') {
                    var results_properties                      = new Array();
                    results_properties['indexnum']              = results[i].getAttribute('id');
                    results_properties['course_id']             = results[i].getAttribute('course_id');
                    results_properties['course_name']           = results[i].getAttribute('course_name');
                    results_properties['course_link']           = results[i].getAttribute('course_link');
                    results_properties['level_id']              = results[i].getAttribute('level_id');
                    results_properties['level_name']            = results[i].getAttribute('level_name');
                    results_properties['inst_id']               = results[i].getAttribute('inst_id');
                    results_properties['inst_name']             = results[i].getAttribute('inst_name');
                    results_properties['inst_lat']              = results[i].getAttribute('inst_lat');
                    results_properties['inst_lng']              = results[i].getAttribute('inst_lng');
                    results_properties['camp_id']               = results[i].getAttribute('camp_id');
                    results_properties['camp_name']             = results[i].getAttribute('camp_name');
                    results_properties['camp_lat']              = results[i].getAttribute('camp_lat');
                    results_properties['camp_lng']              = results[i].getAttribute('camp_lng');
                    results_properties['home_dist']             = results[i].getAttribute('home_dist');
                    results_properties['other_dist']            = results[i].getAttribute('other_dist');
                    results_properties['subjectarea_name']      = results[i].getAttribute('subjectarea_name');
                    results_properties['inst_contact_email']    = results[i].getAttribute('inst_contact_email');
                    results_properties['inst_contact_name']     = results[i].getAttribute('inst_contact_name');
                    results_properties['latlng']                = Lat_Lng;
                    
                    var results_entry = create_course_results_entry(gMarkers_key[results_properties['indexnum']], results_properties);
                // else if this is an institution/campus
                } else {
                    var results_properties              = new Array();
                    results_properties['indexnum']      = results[i].getAttribute('id');
                    results_properties['course_id']     = results[i].getAttribute('course_id');
                    results_properties['inst_id']       = results[i].getAttribute('inst_id');
                    results_properties['inst_name']     = results[i].getAttribute('inst_name');
                    results_properties['camp_id']       = results[i].getAttribute('camp_id');
                    results_properties['camp_name']     = results[i].getAttribute('camp_name');
                    results_properties['home_dist']     = results[i].getAttribute('home_dist');
                    results_properties['other_dist']    = results[i].getAttribute('other_dist');
                    results_properties['latlng']        = Lat_Lng;
                
                    var results_entry = create_results_entry(gMarkers_key[results_properties['indexnum']], results_properties); // create the entry (so that it matches the marker indexnum)
                }
                
                // code for mapping one-to-many ids
                var result_entry_id = results_properties['indexnum'] + 'c' + results_properties['course_id'];
                gResults_ids[results_properties['indexnum']][result_entry_id] = result_entry_id;
                
                // add the result
                var results_list    = $('mp_results_' + num_pages);
                results_list.appendChild(results_entry); // add the entry
            }
        }
        if (courseId != undefined) {
            gMarkers_key[instcampId].select_result_entry(instcampId, courseId);
        }
    });
}



function get_map_data(subjectarea, fd, homeLat, homeLng, otherLat, otherLng, orderBy)
{
    //alert('Starting get_map_data');
    
    // last minute hack to combine free-text search when using other filters
    if ($('course_searchbox').value != '' && $('course_searchbox').value != DEFAULT_SEARCH_TEXT && !gDouble_search) { // if the search box is not blank or set to default and not a double search
        do_map_search(); // use the free-text search instead!
    } else {
        gSearch_type    = 'standard';
        gSearch_term    = '';
        gKeyword_id     = '';
        gKeyword_on     = false; // reset the gKeyword_on flag
        gDouble_search  = false; // reset double search flag
        
        // set up the results column
        var results_wrapper         = $('mp_results');  // get the results wrapper id handle
        results_wrapper.innerHTML   = '<p id="results_p"><img src="/images/loading_small.gif" style="margin-right:4px;" />Searching&hellip;<br />&nbsp;</p>'; // load search indicator
        // clean up previous searches
        //remove_institution_markers();   // clear existing institution markers
        gCourse_Map.closeInfoWindow();  // close the info window if open
        hide_window('mp_courses');      // hide the course window
        clear_window('mp_courses');     // clear the contents of the course window
        hide_window('mp_enquiry');      // hide the course window
        clear_window('mp_enquiry');     // clear the contents of the course window
        hide_window('mp_keywords');     // hide the keywords window
        clear_window('mp_keywords');    // clear the contents of the keywords window
        reset_result_globals();         // reset result global variables
        reset_searchbox();              // clear search terms
        
        // create the request function call and name/value pairs to be passed into php/sql
        var search_url = '/get_map_data/?subjectarea=' + subjectarea + '&fd=' + fd + '&home_lat=' + homeLat + '&home_lng=' + homeLng + '&other_lat=' + otherLat + '&other_lng=' + otherLng + '&order_by=' + orderBy;
        
        GDownloadUrl(search_url, function(data) {
            remove_institution_markers();   // MS: moving this to here seems to improve performance and solves the "multiple search at once/multi Plumptons" bug
            
            var xml     = GXml.parse(data);
            var markers = xml.documentElement.getElementsByTagName('marker');
            
            // if there are any results
            if (markers.length > 0) {
            
                // set up the results column
                var results_wrapper         = $('mp_results');  // get the results wrapper id handle
                results_wrapper.innerHTML   = '';               // clear the previous results!
                var num_markers             = 0;                // for storing number of markers
                var num_pages               = 0;                // for storing number of pages of results
                
                // create the results paragraph
                var p       = document.createElement('p');
                p.id        = 'results_p';
                var html    = '';
                
                if ((orderBy == 'home_dist') || (orderBy == 'other_dist')) {
                    html += '<a href="javascript:;" onclick="clear_search();">Clear search</a><br /><br />These are the nearest institutions that run courses matching your search choices:'
                } else {
                    html += '<a href="javascript:;" onclick="clear_search();">Clear search</a><br /><br />These institutions run courses matching your search choices:';
                }
                p.innerHTML = html;
                results_wrapper.appendChild(p);
                
                // create the map markers and results
                for (var i = 0; i < markers.length; i++) {
                    
                    // if there's a location for the campus - use it
                    if ((markers[i].getAttribute('camp_lat') != '') && (markers[i].getAttribute('camp_lng') != '')) {
                        var Lat_Lng = new GLatLng(parseFloat(markers[i].getAttribute('camp_lat')), parseFloat(markers[i].getAttribute('camp_lng')));
                    
                    // else if there's a location for the institution - use it
                    } else if ((markers[i].getAttribute('inst_lat') != '') && (markers[i].getAttribute('inst_lng') != '')) {
                        var Lat_Lng = new GLatLng(parseFloat(markers[i].getAttribute('inst_lat')), parseFloat(markers[i].getAttribute('inst_lng')));
                    
                    // else Open University or other without location
                    } else {
                        //if (orderBy = 'home_dist') {
                        //    var Lat_Lng = new GLatLng(homeLat + 0.001, homeLng + 0.001);
                        //} else if (orderBy = 'other_dist') {
                        //    var Lat_Lng = new GLatLng(otherLat + 0.001, otherLng + 0.001);
                        //} else {
                            var Lat_Lng = '';
                        //}
                    }
                    
                    // NOTE: Commented out if conditional - not ideal but now creates OU entry in results without marker and fails silently on link to marker
                    // if a location exists - create a marker
                    //if (Lat_Lng != '') {
                    
                        var marker_properties                    = new Array();
                        marker_properties['course_id']           = markers[i].getAttribute('course_id'); // used to create faux id to match with free-text search results
                        marker_properties['inst_id']             = markers[i].getAttribute('inst_id');
                        marker_properties['inst_name']           = markers[i].getAttribute('inst_name');
                        marker_properties['inst_address1']       = markers[i].getAttribute('inst_address1');
                        marker_properties['inst_address2']       = markers[i].getAttribute('inst_address2');
                        marker_properties['inst_address3']       = markers[i].getAttribute('inst_address3');
                        marker_properties['inst_city']           = markers[i].getAttribute('inst_city');
                        marker_properties['inst_county']         = markers[i].getAttribute('inst_county');
                        marker_properties['inst_postcode']       = markers[i].getAttribute('inst_postcode');
                        marker_properties['inst_contact_name']   = markers[i].getAttribute('inst_contact_name');
                        marker_properties['inst_contact_phone']  = markers[i].getAttribute('inst_contact_phone');
                        marker_properties['inst_contact_email']  = markers[i].getAttribute('inst_contact_email');
                        marker_properties['inst_website']        = markers[i].getAttribute('inst_website');
                        marker_properties['camp_id']             = markers[i].getAttribute('camp_id');
                        marker_properties['camp_name']           = markers[i].getAttribute('camp_name');
                        marker_properties['camp_address1']       = markers[i].getAttribute('camp_address1');
                        marker_properties['camp_address2']       = markers[i].getAttribute('camp_address2');
                        marker_properties['camp_address3']       = markers[i].getAttribute('camp_address3');
                        marker_properties['camp_city']           = markers[i].getAttribute('camp_city');
                        marker_properties['camp_county']         = markers[i].getAttribute('camp_county');
                        marker_properties['camp_postcode']       = markers[i].getAttribute('camp_postcode');
                        marker_properties['home_dist']           = markers[i].getAttribute('home_dist');
                        marker_properties['other_dist']          = markers[i].getAttribute('other_dist');
                        marker_properties['latlng']              = Lat_Lng;
                        //marker_properties['indexnum']            = i;
                        marker_properties['indexnum']            = markers[i].getAttribute('id');
                        
                        gResults_ids[marker_properties['indexnum']] = new Object(); // NOTE: added as object not array or else it loads tons of array methods which cause problems later - not sure why
                    
                    if (Lat_Lng != '') {
                        gInst_markers[i] = create_institution_marker(marker_properties);
                        //gInst_Clusterer.AddMarker(gInst_markers[i], marker_properties['inst_name'], marker_properties['camp_name'], marker_properties['inst_id'], marker_properties['camp_id']);
                        gInst_Clusterer.AddMarker(gInst_markers[i]);
                    }
                        
                        
                        // create the results lists
                        // creates a new ul with controls each time we need a new page
                        num_markers++; // increment the number of markers
                        
                        if (num_markers > (RESULTS_PER_PAGE * num_pages)) {
                            ++num_pages;
                            var ul          = document.createElement('ul');
                            ul.id           = 'mp_results_' + num_pages;
                            ul.className    = 'mp_results_list';
                            if (num_pages > 1) {
                                ul.style.display = 'none';
                            }
                            
                            var li          = document.createElement('li');
                            li.className    = 'list_header';
                            html            = ''; // clear previous content
                            html            += '<div class="mp_results_control">&nbsp;';
                            
                            if (num_pages != 1) {
                                html += '<p class="mp_results_prev"><a href="javascript:go_to_page(' + num_pages + ',' + (num_pages - 1) + ');">&#171;&nbsp;previous</a></p>';
                            }
                            
                            if (num_pages != (Math.ceil(markers.length / RESULTS_PER_PAGE))) {
                                html += '<p class="mp_results_next"><a href="javascript:go_to_page(' + num_pages + ',' + (num_pages + 1) + ');">next&nbsp;&#187;</a></p>';
                            }
                            
                            html            += '</div>';
                            li.innerHTML    = html;
                            ul.appendChild(li);
                            results_wrapper.appendChild(ul);
                        }
                        
                        // add the results
                        //var results_entry = create_results_entry(gInst_markers[i], marker_properties, num_markers); // create the entry
                        //var results_entry = create_results_entry(gInst_markers[i], marker_properties, marker_properties['indexnum']); // create the entry (so that it matches the marker 
                
                        // code for mapping one-to-many ids (not really necessary with this search but needed with free-text search)
                        var result_entry_id = marker_properties['indexnum'] + 'c' + marker_properties['course_id'];
                        gResults_ids[marker_properties['indexnum']][result_entry_id] = result_entry_id;
                        
                        // create results entry
                        var results_entry = create_results_entry(gMarkers_key[marker_properties['indexnum']], marker_properties); // create the entry (so that it matches the markerindexnum)
                        var results_list    = $('mp_results_' + num_pages);
                        results_list.appendChild(results_entry); // add the entry
                    //}
                }
            } else {
                // set up the results column
                var results_wrapper         = $('mp_results');  // get the results wrapper id handle
                results_wrapper.innerHTML   = '<a href="javascript:;" onclick="clear_search()">Clear search</a><br /><br /><p>There are no institutions running courses matching your search choices. Please change your choices to search again.</p>';
            }
        });
        //alert('Ending get_map_data');
    }
}



function view_courses(instId, campId, orderBy)
{
    clear_window('mp_courses');
    //alert("campId is " + campId + ".");
    gCourse_order_by = gCourse_order_options[orderBy];

    // create the request function call and name/value pairs to be passed into php/sql
    var search_url = '/get_map_course_data/?subjectarea=' + gFilter_subject + '&fd=' + gFilter_fd + '&home_lat=' + gHome_lat + '&home_lng=' + gHome_lng + '&other_lat=' + gOther_lat + '&other_lng=' + gOther_lng + '&course_order_by=' + gCourse_order_by + '&inst_id=' + instId + '&camp_id=' + campId + '&search_type=' + gSearch_type + (gSearch_term != '' ? '&course_searchbox=' + encodeURIComponent(gSearch_term) : '')  + (gKeyword_id != '' ? '&tag_id=' + gKeyword_id : '');
    
    // create the xml
    GDownloadUrl(search_url, function(data) {
        var xml         = GXml.parse(data);
        var institution = xml.documentElement.getElementsByTagName('institution');
        var courses     = xml.documentElement.getElementsByTagName('course');
        
        // if there are any courses
        if (courses.length > 0) {
            
            for (var j = 0; j < institution.length; j++) {
                // set up the institution details
                this.inst_id            = institution[j].getAttribute('inst_id');
                this.inst_name          = institution[j].getAttribute('inst_name');
                this.inst_address1      = institution[j].getAttribute('inst_address1');
                this.inst_address2      = institution[j].getAttribute('inst_address2');
                this.inst_address3      = institution[j].getAttribute('inst_address3');
                this.inst_city          = institution[j].getAttribute('inst_city');
                this.inst_county        = institution[j].getAttribute('inst_county');
                this.inst_postcode      = institution[j].getAttribute('inst_postcode');
                this.inst_contact_name  = institution[j].getAttribute('inst_contact_name');
                this.inst_contact_phone = institution[j].getAttribute('inst_contact_phone');
                this.inst_contact_email = institution[j].getAttribute('inst_contact_email');
                this.inst_website       = institution[j].getAttribute('inst_website');
                this.camp_id            = institution[j].getAttribute('camp_id');
                this.camp_name          = institution[j].getAttribute('camp_name');
                this.camp_address1      = institution[j].getAttribute('camp_address1');
                this.camp_address2      = institution[j].getAttribute('camp_address2');
                this.camp_address3      = institution[j].getAttribute('camp_address3');
                this.camp_city          = institution[j].getAttribute('camp_city');
                this.camp_county        = institution[j].getAttribute('camp_county');
                this.camp_postcode      = institution[j].getAttribute('camp_postcode');
                this.home_dist          = institution[j].getAttribute('home_dist');
                this.other_dist         = institution[j].getAttribute('other_dist');
                
                if (this.camp_name) { // if we find a campus name then break the loop and move on
                    break;
                }
            }
        
            // set up the view courses window
            var view_courses_wrapper    = $('mp_courses'); // get the courses wrapper id handle
            
            var html = '';
            html += '<div id="course_info_win" class="mp_info_win">' + "\n";
            html += '<h4>' + this.inst_name + '</h4>' + "\n";
            if (this.camp_name) {html += '<h5>' + this.camp_name + '</h5>' + "\n";}
            
            html += '<div class="mp_info_details">' + "\n";
            
            // if there's a campus address - use it
            if (this.camp_name && (this.camp_address1 || this.camp_address2 || this.camp_address3 || this.camp_city || this.camp_county || this.camp_postcode)) {
                html += '<p>' + "\n";
                if (this.camp_address1)   {html += this.camp_address1 + '<br />' + "\n";}
                if (this.camp_address2)   {html += this.camp_address2 + '<br />' + "\n";}
                if (this.camp_address3)   {html += this.camp_address3 + '<br />' + "\n";}
                if (this.camp_city)       {html += this.camp_city + '<br />' + "\n";}
                if (this.camp_county)     {html += this.camp_county + '<br />' + "\n";}
                if (this.camp_postcode)   {html += this.camp_postcode + "\n";}
                html += '</p>' + "\n";
            
            // else try using the institution address
            } else {
                html += '<p>' + "\n";
                if (this.inst_address1)   {html += this.inst_address1 + '<br />' + "\n";}
                if (this.inst_address2)   {html += this.inst_address2 + '<br />' + "\n";}
                if (this.inst_address3)   {html += this.inst_address3 + '<br />' + "\n";}
                if (this.inst_city)       {html += this.inst_city + '<br />' + "\n";}
                if (this.inst_county)     {html += this.inst_county + '<br />' + "\n";}
                if (this.inst_postcode)   {html += this.inst_postcode + "\n";}
                html += '</p>' + "\n";
            }
            
            html += '</div>' + "\n";
            
            // if there are contact details
            if (this.inst_contact_name || this.inst_contact_phone || this.inst_contact_email || this.inst_website) {
                html += '<div class="mp_info_details_2">' + "\n";
            
                // if there are contact details
                if (this.inst_contact_name || this.inst_contact_phone) {
                    html += '<h6>Contact:</h6>' + "\n";
                    html += '<p>';
                    if (this.inst_contact_name)   {html += this.inst_contact_name + '<br />' + "\n";}
                    if (this.inst_contact_phone)  {html += this.inst_contact_phone + "\n";}
                    html += '</p>' + "\n";
                }
                
                // if there's a contact email or web address
                if (this.inst_contact_email || this.inst_website) {
                    html += '<p>' + "\n";
                    if (this.inst_contact_email)  {html += '<a href="' + convert_to_ascii('mailto:' + this.inst_contact_email) + '">email</a>&nbsp;&nbsp;|&nbsp;&nbsp;';}
                    if (this.inst_website)        {html += '<a href="http://' + this.inst_website + '" target="_blank" title="Opens ' + this.inst_name + ' web site in a new window">web site</a>' + "\n";}
                    html += '</p>' + "\n";
                }
                
                html += '</div>' + "\n";
            }
            
            if (this.home_dist || this.other_dist) {
                html += '<div class="mp_info_location">' + "\n";
                html += '<h6>Distance from:</h6>' + "\n";
                
                if (this.home_dist) {
                    html += '<div class="mp_dist">' + "\n";
                    html += '<p>' + "\n";
                    html += '<img src="images/icons/home-shadow-combi.gif" alt="Home icon" /><br />' + "\n";
                    html += '<span class="home_heading">My Home</span><br />' + "\n";
                    html += '<strong>' + this.home_dist + '</strong> mile' + (this.home_dist == 1 ? '' : 's') + '<br />' + "\n";
                    html += '</p>' + "\n";
                    html += '</div>' + "\n";
                }
                
                if (this.other_dist) {
                    if ($('workplace').checked) {
                        html += '<div class="mp_dist">' + "\n";
                    html += '<p>' + "\n";
                        html += '<img src="images/icons/work-shadow-combi.gif" alt="Work icon" /><br />' + "\n";
                        html += '<span class="other_heading">Work</span><br />' + "\n";
                        html += '<strong>' + this.other_dist + '</strong> mile' + (this.other_dist == 1 ? '' : 's') + '<br />' + "\n";
                        html += '</p>' + "\n";
                        html += '</div>' + "\n";
                    } else {
                        html += '<div class="mp_dist">' + "\n";
                    html += '<p>' + "\n";
                        html += '<img src="images/icons/other-shadow-combi.gif" alt="Other icon" /><br />' + "\n";
                        html += '<span class="other_heading">Other</span><br />' + "\n";
                        html += '<strong>' + this.other_dist + '</strong> mile' + (this.other_dist == 1 ? '' : 's') + '<br />' + "\n";
                        html += '</p>' + "\n";
                        html += '</div>' + "\n";
                    }
                }
                
                html += '</div>' + "\n";
            }
            
            html += '<div class="clearboth"></div>' + "\n";
            html += '</div>' + "\n";
            
            view_courses_wrapper.innerHTML  = html;
            
            // add the close button
            var course_info_win     = $('course_info_win');
            var a                   = document.createElement('a');
            a.className             = 'close_button';
            a.href                  = 'javascript:hide_window(\'mp_courses\');';
            var img                 = document.createElement('img');
            img.src                 = '/images/icons/course_map/close_button.gif';
            img.alt                 = 'Close button';
            a.appendChild(img);
            course_info_win.appendChild(a);
            
            // set up the course html
            var table           = document.createElement('table');  // create the container table
            table.id            = 'mp_course_table';                // give it some properties
            table.cellSpacing   = 0;
            table.cellPadding   = 4;
            table.border        = 0;
            
            var tbody           = document.createElement('tbody');  // create the tbody node (IE needs this for DOM scripted HTML)
            tbody.id            = 'mp_course_tbody';                // give it an id
            table.appendChild(tbody);                               // add it to the container table
            view_courses_wrapper.appendChild(table);                // add the table to the course wrapper
            
            var course_tbody    = $('mp_course_tbody'); // get the course table id handle
            var current_subject;
            var row_switcher    = 0;
            
            // create the course list
            for (var i = 0; i < courses.length; i++) {
                var course_properties                       = new Array();
                course_properties['inst_name']              = courses[i].getAttribute('inst_name');
                course_properties['course_id']              = courses[i].getAttribute('course_id');
                course_properties['course_name']            = courses[i].getAttribute('course_name');
                course_properties['subjectarea_id']         = courses[i].getAttribute('subjectarea_id');
                course_properties['subjectarea_name']       = courses[i].getAttribute('subjectarea_name');
                course_properties['level_id']               = courses[i].getAttribute('level_id');
                course_properties['level_name']             = courses[i].getAttribute('level_name');
                course_properties['level_display_order']    = courses[i].getAttribute('level_display_order');
                course_properties['course_link']            = courses[i].getAttribute('course_link');
                course_properties['inst_contact_email']     = this.inst_contact_email;
                course_properties['inst_contact_name']      = this.inst_contact_name;
                
                // create subject area headings
                if (current_subject != course_properties['subjectarea_name']) {
                    var tr          = document.createElement('tr');
                    tr.className    = 'subject_heading';
                    var parnode     = course_tbody.appendChild(tr);
                    
                    var td          = document.createElement('td');
                    td.colSpan      = 4;
                    td.vAlign       = 'bottom';
                    
                    td.innerHTML    = course_properties['subjectarea_name'];
                    parnode.appendChild(td);
                    
                    current_subject = course_properties['subjectarea_name'];
                    
                    // switch to help alternate the row background colours
                    row_switcher = 0;
                }
                
                // add course entries for that subject area heading
                var course_entry = create_course_entry(course_properties, row_switcher);
                course_tbody.appendChild(course_entry);
                
                // switch to help alternate the row background colours
                if (row_switcher) {row_switcher--;}
                else {row_switcher++;}
            }
        }
    });
    show_window('mp_courses');  // show the course window
    hide_window('mp_enquiry');  // hide the enquiry window
    hide_window('mp_keywords'); // hide the keywords window
}



function view_keywords()
{
    // create the request function call and name/value pairs to be passed into php/sql
    var search_url = '/view_keywords/?subjectarea=' + gFilter_subject + '&fd=' + gFilter_fd + '&home_lat=' + gHome_lat + '&home_lng=' + gHome_lng + '&other_lat=' + gOther_lat + '&other_lng=' + gOther_lng;
    
    // create the xml
    GDownloadUrl(search_url, function(data) {
        var xml         = GXml.parse(data);
        var keywords    = xml.documentElement.getElementsByTagName('keyword');
        
        // prepare the window
        clear_window('mp_keywords');
        var keyword_win = $('mp_keywords');
            
        // add the close button
        var a       = document.createElement('a');
        a.className = 'close_button';
        a.href      = 'javascript:hide_window(\'mp_keywords\');';
        var img     = document.createElement('img');
        img.src     = '/images/icons/course_map/close_button.gif';
        img.alt     = 'Close button';
        a.appendChild(img);
        keyword_win.appendChild(a);
        
        // add heading
        h4              = document.createElement('h4');
        h4.innerHTML    = 'Keyword search';
        keyword_win.appendChild(h4);
        
        // add instructions text
        var p           = document.createElement('p');
        p.innerHTML     = 'Click on one of the keywords below to search for related courses:';
        keyword_win.appendChild(p);
        
        // if there are associated keywords
        if (keywords.length > 0) {
            var ul      = document.createElement('ul');
            ul.id       = 'keyword_list';
            var parnode = keyword_win.appendChild(ul);
        
            for (var i = 0; i < keywords.length; i++) {
                this.keyword_id     = keywords[i].getAttribute('keyword_id');
                this.keyword_name   = keywords[i].getAttribute('keyword_name');
                
                var li = document.createElement('li');
                li.innerHTML    = '<a href="javascript:;" onclick="keyword_search(\'' + this.keyword_name + '\',' + this.keyword_id + ')">' + this.keyword_name + '</a>';
                parnode.appendChild(li);
            }
        } else {
            // highly unlikely but just in case there a no keywords for this subject area
            var p       = document.createElement('p');
            p.innerHTML = 'There are no keywords associated with course in this subject area.';
            keyword_win.appendChild(p);
        }
    });
    show_window('mp_keywords');
    hide_window('mp_courses');
    hide_window('mp_enquiry');
}


function keyword_search(keyword, tag_id)
{
    gKeyword_on = true;
    $('course_searchbox').style.color   = "#333333";    // reset the text colour to live
    $('course_searchbox').value         = keyword;      // set the keyword as the search term
    do_map_search(tag_id);                              // do a free text search with a tag_id limiter
    gKeyword_id                         = tag_id;       // stores the keyword id in a global for reference elsewhere
}



function show_window(which)
{
    $(which).style.display  = 'block';  
}



function hide_window(which)
{
    $(which).style.display  = 'none';
}



function clear_window(which)
{
    $(which).innerHTML = '';
}
//]]>
