// ==========================
//  :: Default setting 
// currently disabling map data reference except for specific demos
// window.MM_MAPQUADS = 'readonly_reference.ttw_mapquads9';

// :: mapviewer
var show_mapviewer = true; 
var mapviewer_id = 'mapviewer';
var start_position = new MMLocation ( new MMLatLon( 51.518235, -0.111258 ), 15 );
var mapviewer_units = 'miles'; // or 'km' 
var widget_types = {
    pan_zoom : 'panzoom',
    small_pan_zoom : 'smallpanzoom',
    small_zoom : 'smallzoom',
    map_type_ : 'maptype',
    location : 'location',
    overview : 'overview',
    tools : 'tools',
    local_info : 'localinfo'
}
var mapviewer_widgets = { 
    pan_zoom_widget : { type : widget_types.pan_zoom, position : undefined, class_name : undefined, slider : undefined },
    map_type_widget : { type : widget_types.map_type, types : undefined, position : undefined, class_name : undefined }
}; 
var mapviewer_events = {
    //event_handler : { event_name: 'event_name', function_name: func_name },
}; 

// :: geocoder
var show_geocoder = true;
var geocoder_id = 'geocoder';
 
// :: search
var show_search = true;
var search_id = 'searchMap'; 
var perform_initial_search = false;

// :: search results display
var show_total_results_found = false
var move_pagination = false;

var search_params = {
    count : 10,
    start_index: undefined,
    order_by_fields : undefined,
    order_by_order : undefined,
    min_distance : undefined,
    max_distance : undefined,
    distance_units : 'miles',  
    return_fields : undefined     
}

// :: search result icon
var search_result_icon = MM_DEFAULT_ICON.copy(); 
search_result_icon.groupName = 'search_results';

// :: search/geocoder results list
var show_results_list = true; 
var results_list_id = 'resultslist';
var results_list_text_field = 'name';

// :: search result zoom in, will show in info box if info_box_text != ''
var search_result_zoom_in = {
    info_box_text : 'Zoom in to this location',
    zoom_factor : 18  
}
// :: route 
var route_id = 'routesteps';
var route_params = {
    optimize_for : 'distance', // or 'time' 
    mode : 'driving', // or 'walking' 
    exclude : '',
    lang : 'en',
    distance_units : 'miles' // or 'km'  
}
// :: route steps
var show_route_steps = true; 

// :: errors
var errors_id = 'errors'; 
var show_error_code = false; 

// :: error messages
var err_search_failed = '<p>Your request failed.</p>';
var err_search_no_results = '<p>No results found.</p>';
var err_search_ambiguous_location = '<p>Your search returned more than one result, please select the correct location from the drop-down box.</p>'; 
var err_geocoder_failed = '<p>Your request failed.</p>'; 
var err_geocoder_no_matches = '<p>Could not find any matches for your location search.</p>'; 
var err_routing_failed = '<p>Your request failed.</p>'; 

// :: ambiguous results
var ambiguous_id = 'ambiguous'; 

// :: pois
var show_poi = true;
var poi_id = 'poi';
var poi_type_url = '/clients/browse.cgi?client=julian_revgeo_poi&poi_default_radius=50&poi_howmany=100&rt=browse.json';
var poi_type_callback = 'poiCallback';
var poi_type_checkbox_first = true; // label or checkbox  
var poi_overlays = {};              


//  :: /Default setting 

// ====================================================
// ====================================================
var mapviewer = false;
var mapviewer_zoom_in_on_marker_click = false;

var poi_el = false;
var script_tag, timeout;
var last_request_num = 0;
var old_script_tags = [];

var geocoder_el = false; 
var geocoder_form = false; 
var geocoder;

var search_el = false; 
var search_form = false; 
var search_new = true;
var search, seacher, search_start_location;

var route_el = false; 
var route_finder, route;
var route_overlays = [];

var errors_el = false;  
var ambiguous_el = false; 
var results_list_el = false; 

// ====================================================
// ====================================================
function initMapviewer () {
    if ( !document.getElementById ( mapviewer_id ) ) return false; 
    if ( !show_mapviewer) {
         document.getElementById ( mapviewer_id ).style.display = 'none';
         return false;
    }
    // Add the map
    mapviewer = new MultimapViewer ( document.getElementById ( mapviewer_id ) );
    mapviewer.setOption ( 'units', mapviewer_units ); 

   mapviewer.drawAndPositionMap ( start_position );
    
    // Add widgets
    for( var key in mapviewer_widgets ) {
        addWidget ( mapviewer_widgets [ key ] )
    } 

    // Add events handlers
    for( var key in mapviewer_events ) {
        addEventHandler ( mapviewer_events [ key ] )
    } 

    // Add marker onclick zoom in if required
    if (mapviewer_zoom_in_on_marker_click) {
        mapviewer.addEventHandler( 'openInfoBox', function( eventType, eventTarget, marker ) {
            var location = marker.getPosition();
            location.zoom_factor = search_result_zoom_in.zoom_factor;
            mapviewer.goToPosition(location);
        });
    }

    return true; 
}

// ====================================================
// ====================================================
function initPOIs() {
    if (!document.getElementById(poi_id)) return false; 
    if (!show_poi) {
        document.getElementById(poi_id).style.display = 'none';
        return false;
    }
    // Populate POI types 
    poi_el = document.getElementById(poi_id); 
    for( var key in poi_overlays ) {
        if (!ul) {
            var ul = document.createElement('ul');
            ul.className = 'poiTypes';  
            poi_el.appendChild(ul);
        }    
        var li = document.createElement('li'); 
        if (poi_type_checkbox_first) {
            li.innerHTML = '<' + 'input type="checkbox" id ="show_' + key + '" name="" onclick="displayCheckedPois()"/>' + '<' + 'label for="show_' + key + '" >' + poi_overlays[key].label + '</label>';
        } else {
            li.innerHTML = '<' + 'label for="show_' + key + '" >' + poi_overlays[key].label + '</label>' + '<' + 'input type="checkbox" id ="show_' + key + '" name="" onclick="displayCheckedPois()"/>';
        }
        ul.appendChild(li);
    }  
    // Add event handlers to update POIs 
    mapviewer.addEventHandler( 'endPan', mapChanged );
    mapviewer.addEventHandler( 'changeZoom', mapChanged );
    return true; 
}  
// ==========================
// Called on pans/zooms to re-search POIs
function mapChanged(first, second, third, fourth, reason) {
    // If the map moved because an infobox popped up, don't re-search
    if (reason == 'infobox') {
        return;
    }
    displayCheckedPois();
}
// ==========================
function displayCheckedPois() {
    for( var key in poi_overlays ) {
        var el = document.getElementById( 'show_'+key );
        if( el ) {
            if( el.checked ) {
                displayPoiType( key );
            } else {
                hidePoiType( key );
            }
        }
    }
}
// ==========================
function hidePoiType ( key ) {
    var results = poi_overlays[key].results;

    // Remove all the markers from this type of POI from the map
    if( results ) {
        var result_count = results.length;
        for( var i = 0; i < result_count; i++ ) {
            if( results[i].infoBoxOpened() ) results[i].closeInfoBox();
            mapviewer.removeOverlay( results[i] );
        }
    }
}
// ==========================
function displayPoiType( key ) {
    var centre = mapviewer.getCurrentPosition();
    var url = poi_type_url;
    url += '&lon='+centre.lon+'&lat='+centre.lat;
    url += '&poi_types='+escape(poi_overlays[key].filter);
    url += '&callback=poiCallback&identifier='+key;

    // Create JSON script tag
    if( poi_overlays[key].script_tag )
        old_script_tags.push( poi_overlays[key].script_tag );
    var st = document.createElement( 'script' );
    st.type = 'text/javascript';
    st.src = url;
    poi_overlays[key].script_tag = st;
    loadingStatus(poi_el, true);
    document.getElementsByTagName( 'head' )[0].appendChild( st ); 
}
// ==========================
function poiCallback( key, results ) {
    // Don't display anything if check-box unchecked for this POI type
    if( ! document.getElementById( 'show_'+key ).checked ) return;

    // Remove old icons for POI type
    var old_results = poi_overlays[key].results;
    if( old_results ) {
        var result_count = old_results.length;
        for( var i = 0; i < result_count; i++ ) {
            if( old_results[i].infoBoxOpened() ) old_results[i].closeInfoBox();
            mapviewer.removeOverlay( old_results[i] );
        }
    }
    poi_overlays[key].results = null;
    // Turn off POI loading spinner
    loadingStatus(poi_el, false);

    var poi_markers = [];
    
    // Loop round JSON results from browse.cgi
    for( var i = 0; i < results.locationData.length - 1; i++ ) {
        var poi_results = results.locationData[i];

        var point = new MMLatLon( Number(poi_results.lat), Number(poi_results.lon) );

        // Grab the icon and icon size for this POI type
        var icon = undefined;
        if ( poi_overlays[key].image ) {
            var icon = new MMIcon ();
            icon.image = poi_overlays[key].image;
            icon.iconSize  = poi_overlays[key].size;
            icon.iconAnchor  = new MMPoint( Math.floor( icon.iconSize.width / 2 ), Math.floor( icon.iconSize.height / 2 ) );
            icon.infoBoxAnchor  = new MMPoint( Math.floor( icon.iconSize.width / 2 ), 0 );
        }

        // Create POI marker
        var marker = mapviewer.createMarker( point, { label: poi_results.name, icon: icon} );

        // Create info box HTML
        var html = "<h1>"+poi_results.name+"</h1>";
        var addr = '';
        if (poi_results.street && poi_results.street != '') {addr += poi_results.street + '<br/>'; }
        if (poi_results.town && poi_results.town != '') {addr += poi_results.town + '<br/>'; }
        if (poi_results.pc && poi_results.pc != '') {addr += poi_results.pc; }
        if (addr != '') html += '<p class="address" >'+addr+'</p>';
        if( poi_results.telephone && poi_results.telephone != '' )
          html += '<p class="phone">Telephone:&nbsp;'+poi_results.telephone.replace( / /g, "&nbsp;" )+'</p>';

        if( poi_results.url && poi_results.url != '' ) {
            if( poi_results.url.substring( 0, 7 ) != 'http://' ) {
                poi_results.url = 'http://'+poi_results.url;
            }
            html += '<p class="website"><a href="'+poi_results.url+'" target=\'_blank\'>Visit Website</a></p>';
        }
        marker.setInfoBoxContent ( html );
        poi_markers.push( marker );
    }
    
    poi_overlays[key].results = poi_markers;
}
// ====================================================
// ====================================================
function addWidget ( widget ) {
    //Add widget
    switch ( widget.type ) {
        case widget_types.pan_zoom : 
            var obj = new MMPanZoomWidget(widget.position, widget.class_name, widget.slider);
            break;    
        case widget_types.small_pan_zoom :  
            var obj = new MMSmallPanZoomWidget(widget.position, widget.class_name, widget.slider);
            break;    
        case widget_types.small_zoom :  
            var obj = new MMSmallZoomWidget(widget.position, widget.class_name, widget.slider );
            break;    
        case widget_types.map_type :  
            var obj = new MMMapTypeWidget(widget.types, widget.position, widget.class_name);
            break;    
        case widget_types.location :  
            var obj = new MMLocationWidget(widget.options, widget.position, widget.class_name);
            break;    
        case widget_types.overview :  
            var obj = new MMOverviewWidget(widget.delta, widget.dimensions, widget.position, widget.class_name);
            break;    
        case widget_types.tools :  
            var obj = new MMToolsWidget(widget.label, widget.position, widget.class_name);
            break; 
        case widget_types.local_info :
            var obj = new MMLocalInfoWidget(widget.label, widget.position, widget.class_name);
            break;
   }
    mapviewer.addWidget( obj );  
}

// ==========================
function addEventHandler ( event_handler ) {
    //Add event handler
    mapviewer.addEventHandler ( event_handler.event_name, event_handler.function_name );
}

// ====================================================
// ====================================================
function initGeocoder () {
    if ( !document.getElementById ( geocoder_id ) || !document.getElementById ( geocoder_id ).getElementsByTagName ( 'form' )[0]) return false;
    if ( !show_geocoder ) {
        document.getElementById ( geocoder_id ).style.display = 'none';
        if ( document.getElementById ( errors_id ) ) { document.getElementById ( errors_id ).style.display = 'none'; }
        if ( document.getElementById ( results_list_id ) ) { document.getElementById( results_list_id ).style.display = 'none'; }
        return false;
    }
    geocoder_el = document.getElementById(geocoder_id); 
    geocoder_form = geocoder_el.getElementsByTagName('form')[0];
    if (document.getElementById(errors_id)) errors_el = document.getElementById(errors_id);   
    if (show_results_list && document.getElementById(results_list_id)) results_list_el = document.getElementById(results_list_id); 
    
    // Use standard geocoder for location search    
    geocoder = new MMGeocoder( processGeocoderResults );
    geocoder_form.onsubmit = function () {return doGeocoder () };
    return true; 
}
// ==========================
function doGeocoder () {
    // clear any existing items from previous geocoding requests
    cleanUp ();
   
    // Add dynamic geocoder params:
    // format for address param input filed name is 'a_/param_name' 
    var address = new MMAddress();
    var form_elements = geocoder_form.elements;
    
    for (i = 0; i < form_elements.length; i++) {
        var el = form_elements[i];
        if ( el.name ) {
            var name_parts = el.name.split('/');
            var tag_name = el.tagName.toLowerCase();
            var value = undefined;

            if ( ( tag_name == 'input' && el.type && ((el.type == 'checkbox' || el.type == 'radio' ) && el.checked) || el.type == 'text' || el.type == 'hidden'  ) ||
                tag_name == 'select' ||
                tag_name == 'textarea' ) {
                value = el.value;
            } 
 
            if ( value && name_parts.length == 2 && name_parts[0] == 'a_') {
                address [ name_parts[1] ] = value;
            }
         }
    }    
    
    // perform the geocode
    loadingStatus ( geocoder_el, true ) 
    geocoder.geocode ( address );
    return false;
}
// ==========================
function processGeocoderResults() {
    // callback function registered with the Geocoder to handle geocoding results
    // Error - no results
    if (geocoder.error_code && geocoder.error_code != 'MM_GEOCODE_MULTIPLE_MATCHES') {
        var msg = err_geocoder_failed;
        if ( geocoder.error_code == 'MM_GEOCODE_NO_MATCHES' ) {
            msg = err_geocoder_no_matches;
        } 
        displayError( true, msg );          
        loadingStatus( geocoder_el, false );
        return false;
    }
   
    // Process results 
    var results = geocoder.result_set;
    var oBounds = new MMBounds();
    if (results.length > 0) {
        for( var i = 0; i < results.length; i++ ) {
            // Add a marker for each result
            var marker = createGeocoderResultMarker ( results[i], i );
            markers.push(marker);
            oBounds.extend( marker.point );
            // Create list DOM elements
            if (results_list_el)  {
                if (!list) {
                    var list = document.createElement( 'ol' );
                    results_list_el.appendChild(list); 
                } 
                var li = createGeocoderResultListItem (results[i], i, marker );
                list.appendChild( li );
           }
        }                    
        //display all the results
        mapviewer.goToPosition( mapviewer.getAutoScaleLocation( oBounds ) );
        loadingStatus( geocoder_el, false );
        return false;
    }
} 
// ==========================
function createGeocoderResultMarker ( record, num ) {
    // Add a marker for each result
    var marker = mapviewer.createMarker( record, { 'label' : record.address.display_name, 'text' : num + 1 });
    // Add an infobox for each result
    marker.setInfoBoxContent('<p>' + record.address.display_name + '<' + '/p>');
    return marker; 
}

// ==========================
function createGeocoderResultListItem ( record, num, marker ) {
    var li = document.createElement( 'li' );
    var a = document.createElement( 'a' );
    a.href = '#';
    a.onclick = onClickResult ( marker );
    var a_text = record.address.display_name;
    a.appendChild( document.createTextNode( a_text ) );
    li.appendChild( a );
    return li; 
}

// ====================================================
// ====================================================
function initSearch() {
    if (!document.getElementById(search_id) || !document.getElementById(search_id).getElementsByTagName('form')[0]) return false;
    if (!show_search) {
        document.getElementById(search_id).style.display = 'none';
        if (document.getElementById(errors_id)) {document.getElementById(errors_id).style.display = 'none';}
        if (document.getElementById(ambiguous_id)) {document.getElementById(ambiguous_id).style.display = 'none';}
        if (document.getElementById(results_list_id)) {document.getElementById(results_list_id).style.display = 'none';}
        return false;
    }
    search_el = document.getElementById(search_id); 
    search_form = search_el.getElementsByTagName('form')[0];
    search_form.onsubmit = function () { return doSearch() };
    
    if (document.getElementById(errors_id)) errors_el = document.getElementById(errors_id);   
    if (document.getElementById(ambiguous_id)) ambiguous_el = document.getElementById(ambiguous_id);
    if (show_results_list && document.getElementById(results_list_id)) results_list_el = document.getElementById(results_list_id); 
    
    // Set up new search and searcher objects
    search = new MMSearch(); 
    searcher = new MMSearchRequester( processSearchResults );
    
    loadingStatus( search_el, false );

    if (perform_initial_search) {
        initialSearch();
    }

    return true; 
}

// ==========================
function doSearch(lat, lon) {
    search_new = true;
    // Clear any existing items from previous search requests
    cleanUp();

    // Search from new location
    if ( search_new ) {
        search = new MMSearch(); 
       
        if (lat && lon) {
           var point = new MMLatLon(lat, lon);
           search.point = point;
        }

        while ( ambiguous_el && ambiguous_el.firstChild) {
            ambiguous_el.removeChild(ambiguous_el.firstChild);
        } 
        ambiguous_el.style.display = 'none';
    }
    
    // Add configuration search params
    for( var key in search_params ) {
        search [ key ] = search_params [key]; 
    } 
    
    // Add dynamic search params and filters:
    // format for address param input filed name is 'a_/param_name' 
    // format for search param input filed name is 'p_/param_name' 
    // format for filter input filed name is 'f_/field_name/operator'  
    
    search.filters = getFilters();
    search.logic = 'AND';
    var form_elements = search_form.elements;
    var address = new MMAddress();
    
    for (i = 0; i < form_elements.length; i++) {
        var el = form_elements[i];
        if ( el.name ) {
            var name_parts = el.name.split('/');
            var tag_name = el.tagName.toLowerCase();
            var value = undefined;

            if ( ( tag_name == 'input' && el.type && ((el.type == 'checkbox' || el.type == 'radio' ) && el.checked) || el.type == 'text' || el.type == 'hidden'  ) ||
                tag_name == 'select' ||
                tag_name == 'textarea' ) {
                value = el.value;
            } 
 
            if ( value && name_parts.length == 2 && name_parts[0] == 'a_') {
                address [ name_parts[1] ] = value;
                el.onchange =  function () {
                    search_new = true; 
                } 
            }

            if ( value && name_parts.length > 2 && name_parts[0] == 'f_' ) {
                search.filters.push( new MMSearchFilter( name_parts[1], name_parts[2], value ) );
            }

            if ( value && name_parts.length == 2 && name_parts[0] == 'p_') {
                search [ name_parts[1] ] = value;
            }
         }
    } 

    if ( search_new ) {
        search.address = address;
        search_new = false;
    }    
    loadingStatus( search_el, true );
    searcher.search ( search );
    return false;
}
// ==========================
function processSearchResults() {
    loadingStatus( search_el, false ); 
   
    // Error - geocode had no matches
    if ( searcher.error_code && searcher.error_code == 'MM_GEOCODE_NO_MATCHES' ) {
        var msg = err_geocoder_no_matches;
        search_new = true;
        displayError ( true,  msg );
        loadingStatus ( search_el, false );
        return false;
    }
 
    // Error - request failed
    if ( searcher.error_code && searcher.error_code != 'MM_GEOCODE_MULTIPLE_MATCHES' ) {
        var msg = err_search_failed;
        if ( show_error_code ) {
            msg += '<p><em>' + ( (searcher.error_explanation) ? searcher.error_explanation : '') + ' (' + searcher.error_code + ') <' + '/em><' + '/p>';
        }
        search_new = true;
        displayError ( true,  msg );
        loadingStatus ( search_el, false );
        return false;
    }
    
    // Error - multiple results
    if ( searcher.error_code && searcher.error_code == 'MM_GEOCODE_MULTIPLE_MATCHES' ) {
        results = searcher.result_set;
        var choicessel = false;
        // Find out if choices select is available
        var  sels = ambiguous_el.getElementsByTagName('select');
        for (i = 0; i < sels.length; i++) {
            if (sels[i].name == 'choices') { 
                choicessel = sels[i];
                break;
            }
        }
        // Clear if exists or create a new 
        if (choicessel) {
            while( choicessel.childNodes.length > 0 ) {
                choicessel.removeChild( choicessel.childNodes[0] );
            }
        } else {
            choicessel = document.createElement( 'select' );
            choicessel.setAttribute('name', 'choices'); 
            choicessel.setAttribute('id', 'choicessel'); 
            choicessel.onchange = function () {
                if (this.value != '' ) {
                    var coords = this.value.split(',');
                    search.address = new MMAddress();
                    search.point = new MMLocation(new MMLatLon(coords[0], coords[1]));
                    loadingStatus( search_el, true );
                    searcher.search ( search );
                    return false;
                }   
            };   
            ambiguous_el.appendChild(choicessel); 
        }
        // Create <option> elements for place name drop down
        var option = document.createElement( 'option' );
        option.value = '';
        option.appendChild( document.createTextNode( ' --- ' ) );
        choicessel.appendChild( option );

        for( var i = 0; i < results.length; i++ ) {
            var address = results[i].address;
            var coords = results[i].coords;
            var option = document.createElement( 'option' );
            option.value = coords.lat + ',' + coords.lon;
            option.appendChild( document.createTextNode( address.display_name ) );
            choicessel.appendChild( option );
        }
        ambiguous_el.style.display = 'block';
        displayError ( true, err_search_ambiguous_location ) ;
        loadingStatus( search_el, false );
        return false;
     }

    // No results
    if ( ! searcher.record_sets[0].records ) {
        loadingStatus( search_el, false );
        displayError(true, err_search_no_results );
        return false;
    }

    // Search results
    // Remove all the current markers as we will be display a new set
    mapviewer.removeAllOverlays();

    // Clean up prev results
    while (results_list_el && results_list_el.firstChild) {
        results_list_el.removeChild(results_list_el.firstChild);
    }   
    displayError (false);
    
    // Get search starting location
    search_start_location = false; 
    if ( search.point ) {
        search_start_location = search.point;
    } else {
        search_start_location = new MMLocation ( search.address.copy () ) ;
    }

    // Handle all records
    var markers = new Array();
    var list = false;
    var results = searcher.record_sets[0].records;
    var total_record_count = searcher.record_sets[0].totalRecordCount; 
    var start_index = ( search.start_index ) ? search.start_index : 1;
      
    for( var i = 0; i < results.length; i++ ) {
        if ( results[i].point.lat &&  results[i].point.lon ) {
            // Create marker 
            var marker = createSearchResultMarker ( results[i], start_index - 1 + i );
            markers.push( marker );
            
            // Create list DOM elements
            if (results_list_el)  {
                if (!list) {
                    var list = document.createElement( 'ol' );
                    list.start = start_index;
                    results_list_el.appendChild(list); 
                } 
                var li = createSearchResultListItem ( results[i], start_index -1 + i, marker );
                list.appendChild( li );
           } 
        }
    } 

    // Autoscale the map to fit the points found
    if( markers.length > 0 ) {
        var location = mapviewer.getAutoScaleLocation( markers );
        mapviewer.goToPosition( location );
    }

    // Pagination
    if ( results.length < total_record_count ) {
        var p = document.createElement( 'p' );
        p.className = 'pagination';
        
        if ( start_index > 1 ) {
            var a = document.createElement( 'a' );
            a.href = '#';
            a.className = 'prev';
            a.onclick = function () {
                search.start_index = start_index - search.count;
                searcher.search ( search);
                return false;
            };
            var a_text = '< prev ';
            a.appendChild( document.createTextNode( a_text ) );
            p.appendChild( a );
        }
        if ( ( start_index + results.length ) < total_record_count ) {
            var a = document.createElement( 'a' );
            a.href = '#';
            a.className = 'next';
            a.onclick = function () {
                search.start_index = start_index + search.count;
                searcher.search ( search);
                return false;
            };
            var a_text = ' next >';
            a.appendChild( document.createTextNode( a_text ) );
            p.appendChild( a );
        }
        
        var numresults = document.createTextNode( 'Results found: '  + total_record_count );
        
        if(move_pagination){
        	results_list_el.insertBefore( p,results_list_el.firstChild);
        	if(show_total_results_found){
        		results_list_el.insertBefore(numresults,p);
        	}
      	} else {	
        	results_list_el.appendChild( p); 
        	if(show_total_results_found){
        		results_list_el.insertBefore(numresults,p);
        	}
        }
    }
     

    displayCheckedPois();

}

    
// ==========================
function createSearchResultMarker ( record, num ) {
    // Create info box html
    var html =''; 
    var caption = record [ results_list_text_field ];    
    if ( caption != '') {html += '<h1>' + caption + '</h1>';}
    var addr = '';
    if (record.street && record.street != '') {addr += record.street + '<br/>'; }
    if (record.town && record.town != '') {addr += record.town + '<br/>'; }
    if (record.pc && record.pc != '') {addr += record.pc; }
    if (addr != '') {html += '<p class="address" >'+addr+'</p>'; }

    if ( record.url ) {
        if ( record.url.substring( 0, 7 ) != 'http://' ) {
            record.url = 'http://'+record.url;
        }
        html += '<p><a href="'+record.url+'" target="_blank">Visit Website</a></p>';
    }
    
    if ( search_result_zoom_in.info_box_text != '' ) {
        html += '<p><a href="#" onclick="mapviewer.goToPosition( new MMLatLon( ' + record.point.lat + ',' + record.point.lon + '), ' + search_result_zoom_in.zoom_factor + ' ); return false;">' + search_result_zoom_in.info_box_text + '</a></p>';
    }

    // Declutter search results markers 
    if ( search_result_icon.groupName != '' ) mapviewer.declutterGroup( search_result_icon.groupName, {}, MM_DECLUTTER_AGGREGATE );

    // Create marker
    var marker = mapviewer.createMarker( new MMLatLon( record.point.lat, record.point.lon) , { 'label': caption, icon: search_result_icon, text : num + 1 } );
    marker.setInfoBoxContent (html);
    marker.setAttribute('lon', record.point.lon);
    marker.setAttribute('lat', record.point.lat);
    return marker; 
}

// ==========================
function createSearchResultListItem ( record, num, marker ) {
    var li = document.createElement( 'li' );
    var a = document.createElement( 'a' );
    a.href = '#';
    a.onclick = onClickResult ( marker );
    var a_text = record[ results_list_text_field ];
    if (search_params.distance_units == 'miles') {
        var a_text2 = ' Distance from location  ' + record['distance']['miles']  + ' miles';
    } else {
        var a_text2 = ' Distance from location  ' + record['distance']['km']  + ' km';
    }
    a.appendChild( document.createTextNode( a_text ) );
    a.appendChild( document.createElement( 'br' ) );
    a.appendChild( document.createTextNode( a_text2 ) );
    li.appendChild( a );
    return li;
}
// ====================================================
// ====================================================
function initRouting() {
    if ( show_route_steps && document.getElementById( route_id ) )  route_el = document.getElementById( route_id ); 
    route_finder = new MMRouteRequester( processRoutingResults );
}
function doRouting ( locations ) {
    loadingStatus( search_el, true );
    
    route = new MMRoute( locations );
    route_finder = new MMRouteRequester( processRoutingResults );
    
    for( var key in route_params ) {
        route[ key ] = route_params [key]; 
    }
    for( var i = 0, l = route_overlays.length; i < l; ++i ) {
      mapviewer.removeOverlay( route_overlays[i] );
    }
    route_finder.request(route);
}
// ==========================
function processRoutingResults () {
    if (route.error_code) {
        var msg = err_routing_failed;
        if ( show_error_code ) {
            msg += '<p><em>' + ( (route.error_explanation) ? route.error_explanation : '') + ' (' + route.error_code + ') <' + '/em><' + '/p>';
        }
        displayError(true, msg);
        loadingStatus( search_el, false );
        return false;
    } 
    route_overlays = [];  
    displayError (false);
    mapviewer.goToPosition( mapviewer.getAutoScaleLocation( route.bounds ) );
    if ( route_el ) {
        while (route_el.firstChild) {
            route_el.removeChild(route_el.firstChild);
        }   
        displayStages (route, route_el);
    }  
    for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
      route_overlays.push ( route.polyLine[i] );   
      mapviewer.addOverlay( route.polyLine[i] );
    }
    loadingStatus( search_el, false );
}
var max_zindex = 1000;
// ==========================
function displayStages(route, container) {
    var curr_step = 1;
    var stages = route.stages; 

    var h2 = document.createElement('h2');
    h2.appendChild(document.createTextNode('Travel directions'));
    container.appendChild(h2);
   
    //var summary = '';
    //summary += 'Start: ' + stages[0].start_address;
    //summary += '<br />End: ' + stages[stages.length - 1].end_address;
    //summary += '<br />Total Distance: ' + route.distance.miles + ' mile(s)';
    //summary += '<br />Estimated Total Time: ';
    //if (route.duration.days > 0) { summary += route.duration.days + ' day(s) '; }
    //if (route.duration.hours > 0) { summary += route.duration.hours + ' hour(s) '; }
    //if (route.duration.minutes > 0) { summary += route.duration.minutes + ' minute(s) '; }
    //var p = document.createElement('p');
    //p.innerHTML = summary;
    //container.appendChild(p);
    
    for (var count=0; count < stages.length; count++) {
    
        if (count == 0 ) createOverviewMarker(stages[count].start_point, '<a href="#" onclick="playRoute();return false;">Animate route...</a>');
         
        if (stages.length > 1) {
            var p = document.createElement('p');
            p.appendChild(document.createTextNode('Stage ' + (count + 1)));
            container.appendChild(p);
        }
        
        var ol = document.createElement('ol');
        ol.id = 'stage_' + count;
        ol.start = curr_step;

        var steps = stages[count].steps;

        for (var step_count=0; step_count < steps.length; step_count++) {
            var li = createRouteStepListItem ( steps[step_count], count, step_count, curr_step )
            ol.appendChild(li);
            ++curr_step;
        }
        container.appendChild(ol);
    }            
    
    container.style.display = 'block'; 
}
// ==========================
function createRouteStepListItem ( record, stage, step, global_step_num ) {
    var instruction = record.instruction;
    var roadname = record.road_name;
    var roadnumber = record.road_number; 
    var turndirection = record.turn_direction;

    if (roadname && roadnumber) {
        instruction += ' ' + roadname + ' (' + roadnumber + ') ';
    } else if (roadname) {
        instruction += ' ' + roadname + ' ';
    } else if (roadnumber) {
        instruction += ' ' + roadnumber + ' ';
    }
    var turnicon = ''; 
    turnicon += '<img src="/demos/turn_';
    turnicon += turndirection;
    turnicon += '.png" />';

    var distance = '';            
    if (record.distance.miles > 0 && route_params.distance_units == 'miles' ) { distance += record.distance.miles + ' mile(s) '; }
    if (record.distance.km > 0 && route_params.distance_units == 'km' ) { distance += record.distance.km + ' km '; }
    if (distance != '') { distance = ' | ' + distance };
    
    var li = document.createElement('li');
    var a = document.createElement( 'a' );
    a.href = '#';
    a.mmStage = stage;
    a.mmStep = step;
    a.mmInstruction = instruction;
    a.mmStepNum = global_step_num;
    a.onclick = function () { moveToStep (this.mmStage, this.mmStep, this.mmInstruction, this.mmStepNum); return false; };

    a.innerHTML = instruction + distance + turnicon;
    li.appendChild( a );
    return li; 
}

var animationCurrentStage = 0;
var animationCurrentStep = 0;   
var animationStageTotal = 0;
var animationCurrentStepTotal = 0;    
var overviewMarkers = new Array();
var stepMarkers = new Array();
         
// ==========================
function moveToNextStep () {
    var stepsList = document.getElementById('stage_' + animationCurrentStage);
    if (animationCurrentStep != 0) {
        var prevStepNode = stepsList.childNodes[animationCurrentStep-1].firstChild;
        prevStepNode.style.background = 'white';
    }
    var stepNode = stepsList.childNodes[animationCurrentStep].firstChild;
    stepNode.style.background = 'yellow';
    
    moveToStep (stepNode.mmStage, stepNode.mmStep, stepNode.mmInstruction, stepNode.mmStepNum );

    animationCurrentStep++;
    
    if (animationCurrentStep == animationCurrentStepTotal) {
       stepNode.style.background = 'white';
       clearInterval(animationInterval);
    }
                
}
// ==========================
function moveToStep (stage, step, instruction, num) {
     for (var markerCount=0; markerCount < stepMarkers.length; markerCount++) {
        mapviewer.removeOverlay(stepMarkers[markerCount]);
     }
     
     var step_start = route.stages[stage].steps[step].start_point;
     var step_end = route.stages[stage].steps[step].end_point;

     createStepMarker ( step_start, instruction, num );
     
     mapviewer.panToPosition(mapviewer.getAutoScaleLocation([step_start, step_end]));
 }
// ==========================
function createStepMarker(location, instruction, num ) {
   var marker = mapviewer.createMarker(location, { text: num } );
   marker.setInfoBoxContent ('<p>' + instruction + '<' + '/p>');
   stepMarkers.push ( marker );
   marker.openInfoBox ();
}
// ==========================
function createOverviewMarker(location, display_name) {
   var marker = mapviewer.createMarker( location, {text : 'x' } );
   marker.setInfoBoxContent ('<p>' + display_name + '</p>');
   overviewMarkers.push(marker);
}
// ==========================
function playRoute () {
    animationCurrentStage = 0;
    animationCurrentStep = 0;
    animationStageTotal = route.stages.length;
    animationCurrentStepTotal = document.getElementById('stage_0').childNodes.length;
    moveToNextStep();
    animationInterval = setInterval(moveToNextStep,2000);    
}

// ====================================================
// ====================================================
function loadingStatus( container, bool ) {
    // If we're loading values we want to disable the form elements
    // and change presentation to show activity
    var form_elements = container.getElementsByTagName('input');
    for (i = 0; i < form_elements.length; i++) {
        form_elements[i].disabled = bool; 
    } 
    var form_elements = container.getElementsByTagName('select');
       for (i = 0; i < form_elements.length; i++) {
        form_elements[i].disabled = bool; 
    } 
    var form_elements = container.getElementsByTagName('textarea');     
    for (i = 0; i < form_elements.length; i++) {
        form_elements[i].disabled = bool; 
    } 
    class_name = container.className;
    class_name = class_name.replace( /loading/, '' ); 
    if (bool) class_name += 'loading'; 
    container.className = class_name;
}
// ==========================
function cleanUp() {
    // Remove any existing markers from the map
    mapviewer.removeAllOverlays();
    // Clean up prev results
    if ( search_new ) {
        while ( ambiguous_el && ambiguous_el.firstChild) {
            ambiguous_el.removeChild(ambiguous_el.firstChild);
        } 
        ambiguous_el.style.display = 'none';
    }   
    while (results_list_el && results_list_el.firstChild) {
        results_list_el.removeChild(results_list_el.firstChild);
    }   
    while (route_el && route_el.firstChild) {
        route_el.removeChild(route_el.firstChild);
    }   
    displayError (false);
}

// ==========================
function displayError ( show, msg ) {
    if (!errors_el) {
        if (show && msg) alert(msg);
    } else {
        if (show && msg) {
            errors_el.innerHTML = msg;
            errors_el.style.display = 'block';
        } else {
            errors_el.innerHTML = ''; 
            errors_el.style.display = 'none';
        }
    }
}
// ==========================
function onClickResult ( marker ) {
    return function() { 
        marker.openInfoBox();
        mapviewer.goToPosition( marker.getPosition() );
        return false;
    };
}
// ====================================================
// ====================================================
MMAttachEvent( window, 'load', function () {
        if (initMapviewer()) {
            initPOIs ();
            initSearch ();
            initGeocoder ();
            initRouting ();
        }
        var urlparams = getUrlParams();
        if ( urlparams['location'] ) {
            // set the value of your input field = urlparams[‘location’];
            addressBox = document.getElementById ('qs');
            addressBox.value = urlparams['location'];
            doSearch();
        }
    } );

function getUrlParams( sDelim ) {
    var oParams, aParam, oUrlParams = {}, sDelim = sDelim || '&';
        try {
            oParams = window.location.search.split( '?' )[1].split( sDelim );
            for ( var i = 0; i < oParams.length; i++ ) {
                aParams = oParams[i].split( '=' );
                oUrlParams[aParams[0]] = aParams[1];
            }
        } catch( e ) {};
            this.getUrlParams = function( sDelim ) {
            return oUrlParams;
        }
    return this.getUrlParams();
}










