var map;
var geocoder;
var DIRECTIONS_RENDERER;
var LAT;
var LNG;
var homePoint;
var SEARCH_ADDRESS      = '';
var DIRECTIONS_ORIGIN   = '';
var destinationLatLong  = '';    // Added by Paul 3/9/2008 as the destination when showing directions
var destinationStoreId  = '0';   // Added by Paul 5/9/2008 as the destination store ID number when showing directions

if (SAVED_LOCATION == undefined) {
    SAVED_LOCATION;
}

var DEFAULT_LAT             = 51.7;
var DEFAULT_LNG             = -2;
var DEFAULT_CENTER          = new google.maps.LatLng(DEFAULT_LAT, DEFAULT_LNG);
var DEFAULT_ZOOM            = 7;
var DEFAULT_MAX_ZOOM        = 17;
var DEFAULT_MIN_ZOOM        = 7;
var DEFAULT_MARKER_MIN_ZOOM = 9;
var DEFAULT_SIDEBAR_LIMIT   = 5;

var INFOWINDOW;
var SELECTED_BRANCH;
var VIEW = {};

var SIDEBAR_NUMBER = 1;

var latTo               = ''
var firstSearch         = true;
var lngTo               = ''
var directionsChecked   = false;



function asciivals(s)
{
    var r = '';

    for (var i = 0; i < s.length; i++) {
        r += "&#" + s.charCodeAt(i) + ";";
    }

    return r;
}



function checkGoogle(searchQuery)
{
    geocoder.geocode({
        address: searchQuery + ' UK', // KLUDGE: the region parameter is not strong enough to bias results on its own
        region: 'uk'
        },

        function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                LAT = 0;
                LNG = 0;

                $('searchHeader').style.display = 'block';
                searchLocationsNear(results[0].geometry.location);
            } else {
                $('searchHeader').style.display = 'none';
                hideLoading();
                showSideBar();
                handleGeocoderStatus(status, searchQuery);
            }
        }
    );

    $('searchQuery').innerHTML = searchQuery;

    if (searchQuery == SAVED_LOCATION) {
        $('remember').checked = true;
    } else {
        $('remember').checked = false;
    }
}



function checkLocally(searchQuery)
{
    new Ajax.Request('/postcode_search/', {
        method:     'post',
        parameters: {
            q: searchQuery
        },

        onSuccess: function (transport) {
            var response = transport.responseText;

            if (response != '') {
                var location    = transport.responseJSON;
                var point       = new google.maps.LatLng(location.lat, location.lng);

                $('searchHeader').style.display = 'block';
                searchLocationsNear(point);
            } else {
                checkGoogle(searchQuery);
            }
        },
        
        onFailure: function () {
            checkGoogle(searchQuery);
        }
    });
}



function closeSideBarEntries()
{
    var previous_branches = $('store_list_ul').select('.selected-branch');
    
    previous_branches.each(function (branch) {
        branch.className = 'normal-branch';
        branch.select('.branch-more-link')[0].style.display = 'block';
        branch.select('.more-branch-details')[0].blindUp({duration: 0.4});
    });  
}



function clearDirections()
{
    DIRECTIONS_RENDERER.setMap();   // clears directions on map
    DIRECTIONS_RENDERER.setPanel(); // clears contents of directions panel
}



// This is called each time a marker should be displayed on the map. 
function createMarker(branch, hasSideBarEntry)
{
    if (Number(branch.spraystore) == 1) {
        var marker_img = '/images/spraystoreflag.png';
    } else {
        var marker_img = '/images/Storeflag.png';
    }

    var icon = new google.maps.MarkerImage(marker_img,
        new google.maps.Size(100, 64),
        new google.maps.Point(0, 0),
        new google.maps.Point(0, 64)
    );

    var shadow = new google.maps.MarkerImage('/images/store_finder/Storeflagshadow.png',
        new google.maps.Size(100, 64),
        new google.maps.Point(0, 0),
        new google.maps.Point(0, 64)
    );

    var position = new google.maps.LatLng(branch.lat, branch.lng);

    var marker = new google.maps.Marker({
        position: position,
        icon: icon,
        shadow: shadow
    });

    // create side bar entry if needed
    if (hasSideBarEntry) {
        var side_bar_entry = createSideBarEntry(marker, branch);
        $('store_list_ul').appendChild(side_bar_entry);
    }
    
    // build the branch address html
    var branch_address = '';

    if (branch.address1)    { branch_address += branch.address1 + '<br />'; }
    if (branch.address2)    { branch_address += branch.address2 + '<br />'; }
    if (branch.city)        { branch_address += branch.city + '<br />'; }
    if (branch.county)      { branch_address += branch.county + '<br />'; }
    if (branch.postcode)    { branch_address += branch.postcode; }

    var html = '';
    html += '<div class="address">';
    html += '<h4 style="font-size: 1.2em; font-weight: bold;">' + branch.name + ' ' + branch.city + '</h4>';
    html += '<div id="more_' + branch.id + '" style="padding-top: 3px; margin-top: 3px; border-top: 1px solid #CCC;"></div>';
    html += '<p style="font-size: 1em;">' + branch_address + '</p>';

    if (Number(branch.parking) == 1) {
        html += '<img class="parking" src="images/icons/parking.png" alt="Parking available" />';
    }

    if (Number(branch.spraystore) > 0) {
        html += '<img class="icon_spraystore" src="images/icons/icon_spraystore.png" alt="Spraystore" />';
    }

    // add get directions form
    var branchlatlng = branch.lat + ',' + branch.lng;

    html += '<div id="get-directions">';
    html += '   <form method="get" action="#" onsubmit="getDirectionsBetween(\'' + branchlatlng + '\', this.pc.value, \'' + branch.id + '\'); return false;">';
    html += '       <p><label for="directions_origin_input">Get directions to this branch from:</label></p>';
    html += '       <p><input name="pc" type="text" size="25" onfocus="this.value = \'\';" class="text_input" id="directions_origin_input" value="{DIRECTIONS_ORIGIN}" /> <input type="submit" value="Go" /></p>';
    html += '   </form>';
    html += '</div>';

    html += '</div>';

    marker.html         = html;
    marker.branch_id    = branch.id;

    google.maps.event.addListener(marker, 'click', function() {
        if (SELECTED_BRANCH == undefined || marker.branch_id != SELECTED_BRANCH.branch_id) {
            SELECTED_BRANCH = marker;

            // if map is zoomed out beyond the point where markers display
            if (map.getZoom() < DEFAULT_MARKER_MIN_ZOOM) {
                map.setZoom(DEFAULT_MARKER_MIN_ZOOM);
            }

            // if INFOWINDOW has opened update the sidebar - set this up before opening the info window
            google.maps.event.addListenerOnce(INFOWINDOW, 'zindex_changed', function () {
                closeSideBarEntries();

                if (hasSideBarEntry) {
                    updateSideBarSelected(side_bar_entry);
                }
            });

            // open the INFOWINDOW
            var bounds = map.getBounds();

            if (bounds.contains(marker.getPosition())) {
                openInfoWindow(marker);
            } else {
                google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
                    openInfoWindow(marker);
                });

                map.setCenter(marker.getPosition());
                google.maps.event.trigger(map, 'dragend'); // KLUDGE: force the dragend event to update MarkerManager
            }
        }
    });

    return marker;
}



// Last argument added by Paul 5/9/2008 to say whether it should be open by default
function createSideBarEntry(marker, branch)
{
    var li          = document.createElement('li');
    var distance    = '';

    // build the branch address html
    var branch_address = '';

    if (branch.address1)    { branch_address += branch.address1 + '<br />'; }
    if (branch.address2)    { branch_address += branch.address2 + '<br />'; }
    if (branch.city)        { branch_address += branch.city + '<br />'; }
    if (branch.county)      { branch_address += branch.county + '<br />'; }
    if (branch.postcode)    { branch_address += branch.postcode; }


    if (branch.distance) {
        distance = '(' + Number(branch.distance).toFixed(1) + ' miles)';
    } else {
        distance = '';
    }

    var html =  '';
    html += '<div class="address">';
    html += '<h4 class="title"><span class="small">' + SIDEBAR_NUMBER + '.</span> ';
    html += '<a href="javascript:;"><b>' + branch.city + '</b></a> <span class="small" style="font-size: 11px;">' + distance + '</span></h4>';
    html += '<h4 style="font-size: 1.2em;"><strong>Tel:</strong> ' + branch.phone + '</h4>';

    if (branch.fax) {
        html += '<h4 style="font-size: 1.2em;"><strong>Fax:</strong> ' + branch.fax + '</h4>';
    }

    html += '<p class="branch-more-link"><a href="javascript:;">more&hellip;</a></p>';
    
    html += '<div class="more-branch-details" style="display: none">';

    if (branch.code == 'PNY') { // MS: temporary fix for Putney opening times
        html += '<div class="hr"></div><p><b>Open</b><br /><small>Mon - Thu ' + branch.hoursweek;
        html += '<br />Fri 7.30am &mdash; 4.00pm';
    } else {
        html += '<div class="hr"></div><p><b>Open</b><br /><small>Mon - Fri ' + branch.hoursweek;
    }

    if (branch.hourssaturday.substr(0, 1) != '.') {
        html += '<br/>Saturday ' + branch.hourssaturday;
    }

    if (branch.hourssunday.substr(0, 1) != '.') {
        html += '<br/>Sunday ' + branch.hourssunday;
    }

    html += '</small>';
    html += '</p>';

    if (branch.messages) {
        html += '<div id="branch_messages">' + branch.messages + '</div>';
    }

    if (branch.branch_img_src) {
        html += '<img class="branch-img" src="' + branch.branch_img_src + '" alt="' + branch.branch_img_alt + '" />';
    } else {
        html += '<div class="hr"></div>';
    }

    html += '<p>' + branch_address + '</p>';

    if (Number(branch.parking) == 1) {
        html += '<img class="parking" src="images/icons/parking.png" alt="Parking available" />';
    }

    if (Number(branch.spraystore) > 0) {
        html += '<img class="icon_spraystore" src="images/icons/icon_spraystore.png" alt="Spraystore" />';
    }

    html += '<div class="hr"></div>';

    if (branch.managervisible && (branch.manager_img_src || branch.contact)) {
        html += '<div class="branch-manager-details">';

        if (branch.manager_img_src) {
            html += '<img class="branch-manager-img" src="' + branch.manager_img_src + '" alt="' + branch.manager_img_alt + '" />';
        }

        if (branch.contact) {
            html += '<p><small>Branch Manager: </small><b>' + branch.contact + '</b></p>';
        }

        html += '</div>';
        html += '<div class="hr"></div>';
    }

    if (branch.retail_cat != '') {
        html += '<p>' + branch.retail_cat + '</p>';
    }

    // email addresses for Brewers intranet users only
    if (bi) { // if we've come via Brewers intranet

        // check if any emails exist
        var email_exists    = false;
        var rep_count       = 0;

        if (branch.branch_email != undefined) {
            email_exists        = true;
            var branch_email    = branch.branch_email;
        }

        if (branch.admin_email != undefined) {
            email_exists    = true;
            var admin_email = branch.admin_email;
        }

        if (branch.m2_email != undefined) {
            email_exists    = true;
            var m2_email    = branch.m2_email;
        }

        if (branch.rep1_email != undefined) {
            email_exists    = true;
            var rep1_email  = branch.rep1_email;
            rep_count++;
        }

        if (branch.rep2_email != undefined) {
            email_exists    = true;
            var rep2_email  = branch.rep2_email;
            rep_count++;
        }

        if (branch.rep3_email != undefined) {
            email_exists    = true;
            var rep3_email  = branch.rep3_email;
            rep_count++;
        }

        if (branch.rep4_email != undefined) {
            email_exists    = true;
            var rep4_email  = branch.rep4_email;
            rep_count++;
        }

        if (email_exists) { // if at least one email exists

            if (branch_email != undefined) { // if the branch email exists
                html += '<p><small>Branch:<br />';
                html += '<a href="' + asciivals('mailto:' + branch_email) + '"><strong>' + asciivals(branch_email) + '</strong></a></small></p>';
            }

            if (admin_email != undefined) { // if the admin email exists
                html += '<p><small>' + branch.city + ' admin:<br />';
                html += '<a href="' + asciivals('mailto:' + admin_email) + '"><strong>' + asciivals(admin_email) + '</strong></a></small></p>';
            }

            if (m2_email != undefined) { // if the M2 branch manager email exists
                html += '<p><small>M2 Branch Manager:<br />';
                html += '<a href="' + asciivals('mailto:' + m2_email) + '">';
                html += (branch.m2_name != undefined) ? '<strong>' + branch.m2_name + '</strong>' : asciivals(m2_email);
                html += '</a></small></p>';
            }

            if (rep_count) { // if one of the rep emails exists
                html += '<p><small>Rep' + ((rep_count > 1) ? 's' : '') + ':</small>';

                if (rep1_email != undefined) { // if the rep1 email exists
                    html += '<br /><small>';
                    html += '<a href="' + asciivals('mailto:' + rep1_email) + '">';
                    html += (branch.rep1_email != undefined) ? '<strong>' + branch.rep1_name + '</strong>' : asciivals(rep1_email);
                    html += '</a></small>';
                }

                if (rep2_email != undefined) { // if the rep2 email exists
                    html += '<br /><small>';
                    html += '<a href="' + asciivals('mailto:' + rep2_email) + '">';
                    html += (branch.rep2_email != undefined) ? '<strong>' + branch.rep2_name + '</strong>' : asciivals(rep2_email);
                    html += '</a></small>';
                }

                if (rep3_email != undefined) { // if the rep3 email exists
                    html += '<br /><small>';
                    html += '<a href="' + asciivals('mailto:' + rep3_email) + '">';
                    html += (branch.rep3_email != undefined) ? '<strong>' + branch.rep3_name + '</strong>' : asciivals(rep3_email);
                    html += '</a></small>';
                }

                if (rep4_email != undefined) { // if the rep4 email exists
                    html += '<br /><small>';
                    html += '<a href="' + asciivals('mailto:' + rep4_email) + '">';
                    html += (branch.rep4_email != undefined) ? '<strong>' + branch.rep4_name + '</strong>' : asciivals(rep4_email);
                    html += '</a></small>';
                }
            }

            html += '</p><div class="hr"></div>'; // close the email section
        }
    }

    // Added by Paul 8/10/2008 to show the print details link
    html += '<p><small><a href="" onclick="printDetails(' + branch.id + '); return false;">Print details of this branch</a></small></p></div>';

    li.innerHTML            = html;
    li.style.cursor         = 'pointer';
    li.style.marginBottom   = '5px';
    li.className            = 'normal-branch';

    google.maps.event.addDomListener(li, 'click', function () {
        if (map.streetView.getVisible()) {
            map.streetView.setVisible(false);
        }

        if (li.className != 'selected-branch') {
            google.maps.event.trigger(marker, 'click');
        }
    });

    google.maps.event.addDomListener(li, 'mouseover', function() {
        if (li.className != 'selected-branch') {
            li.className = 'highlight-branch';
        }
    });

    google.maps.event.addDomListener(li, 'mouseout', function() {
        if (li.className != 'selected-branch') {
            li.className = 'normal-branch';
        }
    });

    SIDEBAR_NUMBER++;

    return li;
}



function createStartMarker(position, name)
{
    //alert("createStartMarker");

    var marker = new google.maps.Marker({
        position: position
    });

    /* MS: Don't think this is really needed but it was in the v2 map
    var html = '<strong>' + name + '</strong>';
    
    var infowindow = new google.maps.InfoWindow({
        content: html,
        position: position
    });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map, marker);
    });
    */

    return marker;
}



function getDirections(destination, storeid)
{
    // if the directions panel is not already open, save the current view
    if ($('directions_panel').style.display == 'none') {
        saveView();
    }

    destinationLatLong  = destination;  // this is the destination for the directions, used to show the "Print Directions" link, added by Paul 3/9/2008
    destinationStoreId  = storeid;      // this is the destination store ID number, used to show the "Print Directions" link, added by Paul 3/9/2008
    //MS: 'destination' is a string

    var directionsService = new google.maps.DirectionsService();
    
    var request = {
        origin:         homePoint.lat() + ',' + homePoint.lng(),
        destination:    destination,
        travelMode:     google.maps.TravelMode.DRIVING,
        unitSystem:     google.maps.UnitSystem.IMPERIAL,
        region:         'uk',
        provideRouteAlternatives: false
    };

    setDirectionsRenderer(); // set a new directions renderer

    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            DIRECTIONS_RENDERER.setDirections(result);
            onDirectionsLoad();
        }
    });
}



// This function was added by Paul 3/9/2008 to get directions from a place rather than lat/lng.
// First it runs the local version and then the Google code. It is a copy and paste of the checkLocally and checkGoogle functions above.
// It could have been done better, but I wanted to get it working quickly.
function getDirectionsBetween(branch, postcode, storeid)
{
    clearDirections();

    DIRECTIONS_ORIGIN = postcode;

    new Ajax.Request('/postcode_search/', {
        method:     'post',
        parameters: {
            q: postcode
        },

        onSuccess: function (transport) {

            var response = transport.responseText;

            if (response != '') {
                var location    = transport.responseJSON;
                homePoint       = new google.maps.LatLng(location.lat, location.lng);
                getDirections(branch, storeid);
            } else {
                geocoder.geocode({
                    address: postcode + ' UK', // KLUDGE: the region parameter is not strong enough to bias results on its own
                    region: 'uk'
                },

                function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        homePoint = results[0].geometry.location;
                        getDirections(branch, storeid);
                    } else {
                        handleGeocoderStatus(status, postcode);
                    }
                });
            }
        }
    });
}



function handleGeocoderStatus(status, searchQuery)
{
    if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
        alert("'" + searchQuery + "' could not be found, please try a different location");
        return;
    } else if (status == google.maps.GeocoderStatus.ERROR || status == google.maps.GeocoderStatus.UNKNOWN_ERROR) {
        alert("There was a problem with the location service, please try your search again");
        return;
    } else if (status == google.maps.GeocoderStatus.INVALID_REQUEST) {
        alert("There was a problem with your search, please check your location entry and try again");
        return;
    } else {
        // status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT || google.maps.GeocoderStatus.REQUEST_DENIED
        alert("We're sorry but this service is not currently available, please try again later");
        return;
    }
}



function hideDirections()
{
    $('directions_panel').fade({duration: 0, queue: {position: 'end', scope: 'controls'}});
    $('directions_title').fade({duration: 0, queue: {position: 'end', scope: 'controls'}});
    $('store_list').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});

    clearDirections();
    restoreView();
}



function hideLoading()
{
    firstSearch = false;
    $('smallLoadingSymbol').fade({duration: 0, queue: {position: 'end', scope: 'controls'}});
    $('searchBoxGoogle').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});

    if (latTo != '' && directionsChecked == false) { // MS: Not sure when this happens
        getDirections(latTo + ',' + lngTo);
        directionsChecked = true;
    }
}



function hideSideBar()
{
    $('store_list_ul').fade({duration: 0.4, queue: {position: 'end', scope: 'controls'}});
}



function load()
{
    // intitialise map
    var mapOptions = {
        zoom:       DEFAULT_ZOOM,
        center:     DEFAULT_CENTER,
        mapTypeId:  google.maps.MapTypeId.ROADMAP,
        maxZoom:    DEFAULT_MAX_ZOOM,
        minZoom:    DEFAULT_MIN_ZOOM
    };

    map = new google.maps.Map($('google_map'), mapOptions);

    // intitialise manager for markers
    mgr = new MarkerManager(map);

    // intitialise InfoWindow
    INFOWINDOW = new google.maps.InfoWindow({
        content: ''
    });

    // intitialise geocoder
    geocoder = new google.maps.Geocoder();

    // intitialise directions renderer
    setDirectionsRenderer();

    // add StreetView listener: if the map changes to/from StreetView hide/show the markers
    google.maps.event.addListener(map.streetView, 'visible_changed', function () {
        if (map.streetView.getVisible()) {
            mgr.hide();
        } else {
            mgr.show();
        }
    });
}



function onDirectionsLoad()
{
    $('store_list').fade({duration: 0, queue: {position: 'end', scope: 'controls'}});
    $('directions_title').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});
    $('directions_panel').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});
    
    openInfoWindow(SELECTED_BRANCH); // KLUDGE: refreshes the get directions input contents with the latest origin
}



function openInfoWindow(marker) {
    var html = marker.html.replace('id="directions_origin_input" value="{DIRECTIONS_ORIGIN}"', 'id="directions_origin_input" value="' + DIRECTIONS_ORIGIN + '"');
    INFOWINDOW.setContent(html);
    INFOWINDOW.open(map, marker);
    google.maps.event.trigger(INFOWINDOW, 'zindex_changed'); // force the zindex_changed event to fire to open up sidebar entries
}



// Added by Paul 8/10/2008 to print details of this branch
function printDetails(storeid)
{
    if (storeid > 0) {
        window.open('/branch-locator/print-details/?store=' + storeid);
    }
}



function printDirections(destination, storeid)
{
    if (!destination) {
        destination = destinationLatLong; // if it has not been set (when the click the link on the left), then retrieve from the variable set above, added by Paul 3/9/2008
    }

    if (!storeid) {
        storeid = destinationStoreId; // if it has not been set (when the click the link on the left), then retrieve from the variable set above, added by Paul 5/9/2008
    }

    window.open('/branch-locator/print-directions/?origin=' + homePoint.lat() + ',' + homePoint.lng() + '&destination=' + destination + '&store=' + (storeid ? storeid : 0));
}



function restoreView()
{
    var bounds = map.getBounds();

    if (bounds.contains(VIEW.center)) {
        map.panTo(VIEW.center);
    } else {
        map.setCenter(VIEW.center);
    }

    map.setZoom(VIEW.zoom);
}



function saveView()
{
    VIEW.center = map.getCenter();
    VIEW.zoom   = map.getZoom();
}



// There are a few ways of calling this function:
// 1) by clicking on a branch in the Flash map
// 2) from the Head Office link in the contact us section (similar to Flash map link)
// 3) by filling in the search form in the top right, or on top of the map (ends up calling checkLocally below)
function searchLocations(searchQuery)
{
    if ($('directions_panel').style.display != 'none') {
        hideDirections();
    }

    showLoading();
    hideSideBar();

    SEARCH_ADDRESS              = searchQuery;
    show_head_office            = false;        // MS: 2008.10.03: Added to help filter Head Office
    showspraystoreonly          = false;        // MS: 2008.10.14: Added to help filter Spraystore only branches
    $('searchQuery').innerHTML  = searchQuery;
    var start_zoom              = DEFAULT_ZOOM; // MS: Added to provide a non Flash search case

    var loc     = document.location.toString();
    var hash    = loc.indexOf('#');

    if (hash > 0 && firstSearch) {
        var hashdirections = loc.indexOf('#lat');

        if (hashdirections > 0) {
            latTo           = (loc.substr(loc.indexOf('#lat=') + 5, (loc.length-loc.indexOf('lng')) - 6));
            lngTo           = (loc.substr(loc.indexOf('lng') + 4));
            SEARCH_ADDRESS  = '';
            checkLocally(searchQuery);

        } else { // This is run when it comes from Flash, passing in startlat
            SEARCH_ADDRESS  = '';
            querystring     = (loc.substr(loc.indexOf('#startlat=') + 10));
            startLat        = querystring.substr(0, querystring.indexOf('&startlng='));
            querystring     = (querystring.substr(querystring.indexOf('&startlng=') + 10));
            startLng        = querystring.substr(0, querystring.indexOf('&start'));

            if ((querystring.indexOf('&ho') == -1) && ((querystring.indexOf('&ss') == -1))) { // MS: 2008.10.03: Added to filter out Head Office & Spraystore only
                start_zoom = Number(querystring.substr(querystring.indexOf('&startzoom=') + 11)); // MS: original start_zoom code for non HO & Spraystore links
            } else {
                if (querystring.indexOf('&ho') != -1) {
                    // MS: Adapted code to allow for extra HO link string
                    querystring         = (querystring.substr(querystring.indexOf('&startzoom=') + 11));
                    start_zoom          = Number(querystring.substr(0,querystring.indexOf('&ho')));
                    show_head_office    = true;
                }

                if (querystring.indexOf('&ss') != -1) {
                    // MS: Adapted code to allow for extra Spraystore only link string
                    querystring         = (querystring.substr(querystring.indexOf('&startzoom=') + 11));
                    start_zoom          = Number(querystring.substr(0, querystring.indexOf('&ss')));
                    showspraystoreonly  = true;
                }
            }			

            google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
                searchLocationsNear(map.getCenter(), true); // Pass in true so that it knows that it has come from Flash, Paul 5/9/2008
            });

            map.setCenter(new google.maps.LatLng(startLat, startLng));
            map.setZoom(start_zoom);
        }

    } else {
        checkLocally(searchQuery);
    }
}



// fromflash argument added by Paul 5/9/2008 so it knows it has come from Flash
function searchLocationsNear(center, fromflash)
{
    if (fromflash == undefined) {
        fromflash = false;
    }

    DIRECTIONS_ORIGIN   = SEARCH_ADDRESS;
    SIDEBAR_NUMBER      = 1;
    LAT                 = center.lat();
    LNG                 = center.lng();
    homePoint           = center;
    var nearest_branch;

    new Ajax.Request('/get_stores/', {
        method:     'post',
        parameters: {
            homeLat:    LAT,
            homeLng:    LNG,
            show_hof:   (show_head_office ? 1 : 0)
        },

        onSuccess: function (transport) {
            var response = transport.responseJSON;

            // clean up previous search
            mgr.clearMarkers();
            $('store_list_ul').innerHTML = '';

            // set up local variables
            var sidebarLimit    = DEFAULT_SIDEBAR_LIMIT;
            var branch_count    = 0;
            var nearest_branch;

            var bounds = new google.maps.LatLngBounds();
            bounds.extend(center);

            // use Prototype each() function to cycle through response object
            $H(response).each(function (branches) {
                var branch = branches.value;

                branch_count++;

                if (branch.spraystore == '1' && !showspraystoreonly) { // Skip Spraystore only branches unless clicked directly from the Flash map
                    sidebarLimit++; // Adjusts sidebarLimit if any Spraystore only branches occur in the results
                    return; // knocks each() onto next interation
                }

                var marker = createMarker(branch, branch_count <= sidebarLimit);

                mgr.addMarker(marker, DEFAULT_MARKER_MIN_ZOOM, DEFAULT_MAX_ZOOM);

                // the first/nearest branch
                if (branch_count == 1) {
                    nearest_branch = marker;
                    bounds.extend(nearest_branch.getPosition());
                }
            });

            hideLoading();

            // if no branches are found - don't execute rest of function
            if (!branch_count) {
                map.setCenter(DEFAULT_CENTER);
                map.setZoom(DEFAULT_ZOOM);
                alert("No branches were found, please try a different search.");
                return;
            }

            showSideBar();

            // set up listener before setting the map
            google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
                google.maps.event.trigger(nearest_branch, 'click');
            });

            if (fromflash) {
                google.maps.event.trigger(map, 'dragend'); // force the dragend event to update MarkerManager

                // KLUDGE: setTimeout used to allow MarkerManager time to render the markers - TODO: ideally this would be an event listener set once on mgr
                setTimeout("google.maps.event.trigger(map, 'tilesloaded')", 500); // force the tilesloaded event to fire (center and zoom have already been set in searchLocationsNear())
            } else {
                // add a home location marker if not coming from the Flash map
                var homeMarker = createStartMarker(center, SEARCH_ADDRESS);
                mgr.addMarker(homeMarker, DEFAULT_MIN_ZOOM + 2, DEFAULT_MAX_ZOOM);
                map.fitBounds(bounds); // fires the tilesloaded listener set above
            }

            setLocation(SEARCH_ADDRESS);
        },

        onFailure: function () {
            map.setCenter(DEFAULT_CENTER);
            map.setZoom(DEFAULT_ZOOM);
            alert("There was a problem with your search, please try again");
            return;
        }
    });
}



function setDirectionsRenderer()
{
    // set up directions renderer
    DIRECTIONS_RENDERER = new google.maps.DirectionsRenderer({
        map:    map,
        panel:  $('directions_panel')
    });
}



function setLocation(newLocation)
{
    new Ajax.Request('/set_location/', {
        method:     'post',
        parameters: {
            newLocation:    newLocation,
            locationLat:    LAT,
            locationLng:    LNG
        }
    });

    SAVED_LOCATION = newLocation;
}



function showLoading()
{
    $('searchBoxGoogle').fade({duration: 0, queue: {position: 'end', scope: 'controls'}});
    $('smallLoadingSymbol').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});
}



function showSideBar()
{
    $('store_list_ul').appear({duration: 0.4, queue: {position: 'end', scope: 'controls'}});
}



function updateSideBarSelected(selected)
{
    selected.className = 'selected-branch';
    $('store_list_ul').select('.selected-branch .branch-more-link')[0].style.display = 'none';
    $('store_list_ul').select('.selected-branch .more-branch-details')[0].blindDown({duration: 0.4}); // KLUDGE: used select via store_list_ul rather than selected.select to fix IE7 bug
}
