﻿
/*
    This function initializes the Google Map on the Store Locator control, and sets the default map view
    and zoom level to display the entire United States.
*/
function initialize() {
    map = new google.maps.Map2(document.getElementById('googleMapCanvas'));
    map.addControl(new google.maps.SmallMapControl());
    map.addControl(new google.maps.MapTypeControl());
    var point = new google.maps.LatLng(39.22587, -94.515381);

    map.setCenter(point, 3);
}

/*
    This function verifies that the information provided by the user is sufficient and valid, 
    hides the search panel if it is visible, and then searches for nearby stores.
*/
function Find(city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, searchPanelId, togglePanel, toggleLabel, databaseConnection) {
    // Determine the proper category
    var brandToLocate = document.getElementById('txtBrandToLocate').value;

    if ((category == 'All' || category == 'all') && brandToLocate != 'all') {
        category = brandToLocate;
    }

    // Validate the form before generating the results
    if ((zip == '' || zip == null) && (state == 'State' || city == 'City')) {
        // Invalid - display error
        document.getElementById('locatorErrorBox').style.display = 'block';
        document.getElementById('locatorErrorBox').style.marginBottom = '5px';
        document.getElementById('locatorError').innerHTML = '<strong>Required Field:</strong> Please indicate a Zip Code or a City and State.';
        document.getElementById('locatorCityStateZipErrorSpan').style.display = 'inline';
        document.getElementById('locatorZipErrorSpan').style.display = 'inline';
    }
    else if (zip != '' && zip != null && (!zip.match(/^\d{5}$/) || zip == '00000')) {
        // Invalid zip code - display error
        document.getElementById('locatorErrorBox').style.display = 'block';
        document.getElementById('locatorErrorBox').style.marginBottom = '5px';
        document.getElementById('locatorError').innerHTML = '<strong>Invalid Field:</strong> Zip Code must be 5 digits.';
        document.getElementById('locatorZipErrorSpan').style.display = 'inline';
    }
    else {
        // Form is valid, get the search results
        document.getElementById('locatorErrorBox').style.display = 'none';
        document.getElementById('locatorErrorBox').style.marginBottom = '0px';
        document.getElementById('locatorCityStateZipErrorSpan').style.display = 'none';
        document.getElementById('locatorZipErrorSpan').style.display = 'none';
        document.getElementById('txtCurrentPage').value = 0;

        document.getElementById('lblNumResults').innerHTML = '';
        document.getElementById('lblRangeStart').innerHTML = '0';
        document.getElementById('lblRangeEnd').innerHTML = '0';
        document.getElementById('lblRangeTotal').innerHTML = '0';

        // If the search panel is visible, call ToggleElementVisibility to hide it. Otherwise, call SearchLocations to 
        // begin searching for nearby stores. SearchLocations is only called in the "else" portion, because this function
        // is called again by ToggleElementVisibility. This is necessary because of a bug in IE6. In IE6, if the search panel
        // is collapsed by a user (thus calling ToggleElementVisibility), and the map is visible, the map container will slide 
        // up the page, but the Google Map will not. It must be reinitialized and repopulated with stores.    
        if (document.getElementById(searchPanelId).style.display != 'none' && togglePanel) {
            ToggleElementVisibility(searchPanelId, city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, false, toggleLabel, databaseConnection)
        }
        else {
            document.getElementById('locatorMapContainer').style.display = 'block';
            initialize();

            var sidebar = document.getElementById('googleMapSidebar');
            sidebar.innerHTML = '';
            sidebar.innerHTML = '<strong>Retrieving search results...</strong>';

            SearchLocations(city, state, zip, resultsPerPage, radius, dataPageUrl, 'next', category, brand, product, databaseConnection);
        }
    }
        pageTracker._trackEvent('StoreLocator', 'Click', 'Find');
}

/*
    This function determines the latitude and longitude of the user's location, determines which page of data needs
    to be retrieved, and calls SearchStoresNear to populate the map. 
*/
function SearchLocations(city, state, zip, resultsPerPage, radius, dataPageUrl, pageChange, category, brand, product, databaseConnection) {
    // Determine the proper category
    var brandToLocate = document.getElementById('txtBrandToLocate').value;

    if ((category == 'All' || category == 'all') && brandToLocate != 'all') {
        category = brandToLocate;
    }

    // Determine the address
    var address;

    if (zip != null && zip != "") {
        address = zip;
    }
    else if (city != null && state != null && city != '0' && state != 'State') {
        address = city + ", " + state;
    }

    var page = parseInt(document.getElementById('txtCurrentPage').value);
    var total = parseInt(document.getElementById('lblRangeTotal').innerHTML);
    var curRangeEnd = parseInt(document.getElementById('lblRangeEnd').innerHTML);

    // Only advance the page if there are more results than are visible in the current range
    // or if the map is being generated for the first time.
    if (pageChange == 'next' && (curRangeEnd < total || page == 0)) {
        page++;
    }
    // Only decrement the page if not on page 1.
    else if (pageChange == 'previous' && page > 1) {
        page--;
    }
    else {
        return;
    }

    var geocoder = new google.maps.ClientGeocoder();
    geocoder.getLatLng(address,
                       function(latLng) {
                           if (!latLng) {
                               alert(address + ' not found.');
                           }
                           else {
                               SearchStoresNear(latLng, resultsPerPage, radius, page, dataPageUrl, category, brand, product, databaseConnection, zip);
                           }
                       });
}

/*
    This function determines which stores in the database are within the specified radius from the search location,
    retrieves the proper stores from the database based on the current page, and populates the store information in
    the sidebar and on the map itself.
*/
function SearchStoresNear(latLng, resultsPerPage, radius, page, dataPageUrl, category, brand, product, databaseConnection, userZip) {
    var searchUrl = dataPageUrl + '?lat=' + latLng.lat() + '&lng=' + latLng.lng() + '&rad=' + radius + '&rpp=' + resultsPerPage +
                    '&page=' + page + '&category=' + encodeURIComponent(category) + '&brand=' + encodeURIComponent(brand) +
                    '&product=' + product + '&conn=' + databaseConnection;

    google.maps.DownloadUrl(searchUrl, function(data) {
        var xml = google.maps.Xml.parse(data);
        var totalNode = xml.documentElement.getElementsByTagName('total');
        var markers = xml.documentElement.getElementsByTagName('marker');
        map.clearOverlays();

        // Determine map paging labels...
        //var totalLabel = document.getElementById('lblNumResults');
        var totalVal = totalNode[0].getAttribute('totalStores');
        document.getElementById('lblNumResults').innerHTML = 'There are ' + totalVal + ' stores in your area';
        document.getElementById('lblRangeTotal').innerHTML = totalVal;

        document.getElementById('txtCurrentPage').value = page;
        document.getElementById('lblRangeStart').innerHTML = ((page - 1) * resultsPerPage) + 1;
        document.getElementById('lblRangeEnd').innerHTML = (page * resultsPerPage);

        if (parseInt(document.getElementById('lblRangeEnd').innerHTML) > totalVal) {
            document.getElementById('lblRangeEnd').innerHTML = totalVal;
        }

        if (parseInt(document.getElementById('lblRangeStart').innerHTML) > totalVal) {
            document.getElementById('lblRangeStart').innerHTML = totalVal;
        }

        // Build the map sidebar...
        var sidebar = document.getElementById('googleMapSidebar');
        sidebar.innerHTML = '';

        if (markers.length == 0) {
            sidebar.innerHTML = 'No results found.';
            map.setCenter(new google.maps.LatLng(40, -100), 4);

            // Display the map results
            document.getElementById('locatorMapContainer').style.display = 'block';
            return;
        }

        var bounds = new google.maps.LatLngBounds();
        for (var i = 0; i < markers.length; i++) {
            var name = markers[i].getAttribute('name');
            var address = markers[i].getAttribute('address');
            var city = markers[i].getAttribute('city');
            var state = markers[i].getAttribute('state');
            var zip = markers[i].getAttribute('zip');
            var distance = parseFloat(markers[i].getAttribute('distance'));
            var phone = markers[i].getAttribute('phone');
            var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute('latitude')),
                                                                      parseFloat(markers[i].getAttribute('longitude')));

            var marker = CreateMarker(point, name, address, city, state, zip, distance, phone, userZip);
            map.addOverlay(marker);
            var sidebarEntry = CreateSidebarEntry(marker, name, address, city, state, zip, distance, phone);
            sidebar.appendChild(sidebarEntry);
            bounds.extend(point);
        }

        map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

        // Display the map results
        document.getElementById('locatorMapContainer').style.display = 'block';
    });
}

/*
    This method accepts the information about a particular store, and creates a sidebar entry
    on the control's sidebar.
*/
function CreateSidebarEntry(marker, name, address, city, state, zip, distance, phone) {
    var div = document.createElement('div');
    var html = '<p><strong>' + name + '</strong><br />' + address + '<br />' + city + ', ' + state + ' ' + zip +
                '<br />Phone: ' + phone + '<br />' + distance + ' Miles</p>';
    div.innerHTML = html;
    div.style.cursor = 'pointer';
    //div.style.marginBottom = '5px';
    google.maps.Event.addDomListener(div, 'click', function() {
        google.maps.Event.trigger(marker, 'click');
    });

    google.maps.Event.addDomListener(div, 'mouseover', function() {
        div.style.backgroundColor = '#E1EAFE';
    });

    google.maps.Event.addDomListener(div, 'mouseout', function() {
        div.style.backgroundColor = '#fff';
    });

    return div;
}

/*
    This function accepts the information about a particular store, and creates a new marker
    on the Google Map.
*/
function CreateMarker(point, name, address, city, state, zip, distance, phone, userZip) {
    var marker = new google.maps.Marker(point);
    var html = '<strong>' + name + '</strong><br />' + address + '<br />' + city + ', ' + state + ' ' + zip +
                '<br />Phone: ' + phone + '<br />' + distance + ' Miles <br /><br />' +
                '<a href=\"http://maps.google.com/maps?f=d&hl=en&saddr=' + userZip + '&daddr=' +
                address + ' ' + city + ' ' + state + ' ' + zip + ' (' + name + ')' +
                '\" target=\"_blank\">Get driving directions</a>';

    google.maps.Event.addListener(marker, 'click', function() {
        marker.openInfoWindowHtml(html);
    });

    return marker;
}

/*
    This function toggles the visibility of the search panel, and calls the Find function if the map is already visible or
    if the toggle command came from another javascript function. This is necessary due to a bug in IE6. In IE6, if the search panel
    is collapsed by a user (thus calling ToggleElementVisibility), and the map is visible, the map container will slide 
    up the page, but the Google Map will not. It must be reinitialized and repopulated with stores.
*/
function ToggleElementVisibility(elementName, city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, isUserToggle, toggleLabel, databaseConnection) {
    if (document.getElementById(elementName).style.display == 'none') {
        document.getElementById(elementName).style.display = 'block';
        document.getElementById(toggleLabel).innerHTML = 'Search&nbsp;&nbsp;&nbsp;(hide)';
        document.getElementById(toggleLabel).style.fontSize = '1.0em';
    }
    else {
        document.getElementById(elementName).style.display = 'none';
        document.getElementById(toggleLabel).innerHTML = 'Need to Search Again? Click Here';
        document.getElementById(toggleLabel).style.fontSize = '1.3em';

        //hide errors
        document.getElementById('locatorErrorBox').style.display = 'none';
        document.getElementById('locatorErrorBox').style.marginBottom = '0px';
        document.getElementById('locatorCityStateZipErrorSpan').style.display = 'none';
        document.getElementById('locatorZipErrorSpan').style.display = 'none';
    }

    if (document.getElementById('locatorMapContainer').style.display == 'block') {
        initialize();
        Find(city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, elementName, false, toggleLabel, databaseConnection);
    }
    else if (!isUserToggle) {
        Find(city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, elementName, false, toggleLabel, databaseConnection);
    }
}

/*

*/
function DisplayErrorMessage(message) {
    document.getElementById('locatorErrorBox').style.display = 'block';
    document.getElementById('locatorErrorBox').style.marginBottom = '5px';
    document.getElementById('locatorError').innerHTML = message;
}

function CheckKeyCode(city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, searchPanelId, togglePanel, toggleLabel, databaseConnection, e) {
    var keyCode;

    // IE
    if (window.event) {
        keyCode = window.event.keyCode;
    }
    else {
        keyCode = e.keyCode;
    }

    if (keyCode == 13) {
        Find(city, state, zip, resultsPerPage, radius, dataPageUrl, category, brand, product, searchPanelId, togglePanel, toggleLabel, databaseConnection);
        return false;
    }
}
