﻿(function ($) {

    $.saturneoDialogGoogleMaps = function (options) {
        var MAPFILES_URL = "http://maps.gstatic.com/intl/en_us/mapfiles/";

        var map = null;
        var geocoder = null;
        var shadow = null;
        var clickIcon = null;
        var clickMarker = null;
        var markers = null;
        var selected = null;
        var infowindow = null;
        var boundsOverlay = null;
        var viewportOverlay = null;
        var initialized = false;

        var GeocoderStatusDescription = {
            "OK": "Localisation effectuée",
            "UNKNOWN_ERROR": "La demande de localisation a rencontré une erreur inconnue",
            "OVER_QUERY_LIMIT": "Le nombre maximal de requêtes a été dépassé",
            "REQUEST_DENIED": "La page n'est pas autorisée à effectuer la localisation",
            "INVALID_REQUEST": "La demande de localisation n'est pas valide",
            "ZERO_RESULTS": "La localisation n'a donné aucun résultat",
            "ERROR": "Les serveurs Google n'ont pas pu être contactés"
        };

        var GeocoderLocationTypeDescription = {
            "ROOFTOP": "The returned result reflects a precise geocode.",
            "RANGE_INTERPOLATED": "The returned result reflects an approximation (usually on a road) interpolated between two precise points (such as intersections). Interpolated results are generally returned when rooftop geocodes are unavilable for a street address.",
            "GEOMETRIC_CENTER": "The returned result is the geometric center of a result such a line (e.g. street) or polygon (region).",
            "APPROXIMATE": "The returned result is approximate."
        }

        var defaults = {
            dialogId: 'dialogGMaps',
            mapcanvasId: 'map_canvas',
            latitude: 48.8566667,
            longitude: 2.3509871,
            zoom: 5
        };

        // ... validate data
        var validatorOptions = {
            rules: {
                Address: {
                    required: true
                }
            },
            errorPlacement: function (error, element) {
                FormValidation.PlaceErrors({
                    error: error,
                    element: function () { return element; }
                });
            },
            errorClass: "errorBubble",
            messages: {
                Address: "Veuillez préciser l'adresse à localiser."
            }
        }; // validatorOptions END

        // Merges received parameters and default values.
        options = $.extend(defaults, options);

        if ($('#' + options.dialogId).length != 0) {
            $('#' + options.dialogId).dialog('destroy');
            $('#' + options.dialogId).empty();
            $('#' + options.dialogId).remove();
        }

        if ($('#' + options.dialogId).length == 0) {
            var $elt = $('<div id="' + options.dialogId + '"/>').appendTo('body');

            $elt.load(
                $.url('Search/GetGoogleMapsLocator'),
                null,
                function () {
                    var $dialog = $elt.dialog({
                        resizable: false,
                        draggable: false,
                        width: 700,
                        height: 590,
                        position: "top",
                        autoOpen: false,
                        modal: true,
                        title: "Indiquez le lieu de votre recherche",
                        open: function () {
                            //_map_initialize();
                        },
                        close: function () {
                        }
                    }); // dialog

                    var $form = $('#' + options.dialogId).find('form:first');
                    _ensureFormInitialization($form);
                    $dialog.dialog('open');
                    _init();

                } // function
            ); // load
            return;
        } // if

        // Ensures that the form is initialized.
        // Caution : initialization must occur only once
        function _ensureFormInitialization($form) {
            $('#btnSubmitQuery').click(function () {
                submitQuery();
            });
            $('#query').keyup(function (e) {
                if (e.keyCode != 13) return;
                $('#query').blur();
                submitQuery();
            });
        } // _ensureFormInitialization - END


        function _init() {
            var params = {};
            _clearOptions();
            _setOptions(params);

            var mapOptions = {
                'zoom': (params.zoom ? params.zoom : options.zoom),
                'center': (params.center ? params.center : new google.maps.LatLng(options.latitude, options.longitude)),
                'mapTypeId': google.maps.MapTypeId.ROADMAP,
                'scaleControl': true
            }
            map = new google.maps.Map(document.getElementById("map"), mapOptions);

            geocoder = new google.maps.Geocoder();

            infowindow = new google.maps.InfoWindow({
                'size': new google.maps.Size(292, 120)
            });

            shadow = new google.maps.MarkerImage(
                MAPFILES_URL + "shadow50.png",
                new google.maps.Size(37, 34),
                new google.maps.Point(0, 0),
                new google.maps.Point(10, 34)
              );

            clickIcon = new google.maps.MarkerImage(
                MAPFILES_URL + 'dd-start.png',
                new google.maps.Size(20, 34),
                new google.maps.Point(0, 0),
                new google.maps.Point(10, 34)
              );

            google.maps.event.addListener(map, 'rightclick', function (event) {
                document.getElementById("query").value = event.latLng.toUrlValue(6);
                _geocode({ 'latLng': event.latLng });
            });

            // Bounds changes are asynchronous in v3, so we have to wait for the idle
            // event to ensure that viewport biasing picks up the correct viewport
            google.maps.event.addListener(map, 'idle', function () {
                if (document.getElementById("query").value && !initialized) {
                    submitQuery();
                }
                initialized = true;
            });
        }


        function _clearOptions() {
            document.getElementById("query").value = '';
        }

        function _setOptions(params) {
            if (params.query) {
                document.getElementById("query").value = params.query;
            }
        }

        function submitQuery() {
            var query = $("#query").val();
            if (/\s*^\-?\d+(\.\d+)?\s*\,\s*\-?\d+(\.\d+)?\s*$/.test(query)) {
                var latlng = _parseLatLng(query);
                if (latlng == null) {
                    document.getElementById("query").value = "";
                } else {
                    _geocode({ 'latLng': latlng });
                }
            } else {
                _geocode({ 'address': query.replace(/\'/g, ' ') });
            }
        }

        function _geocode(request) {
            _resetMap();

            if (request.latLng) {
                clickMarker = new google.maps.Marker({
                    'position': request.latLng,
                    'map': map,
                    'title': request.latLng.toString(),
                    'clickable': false,
                    'icon': clickIcon,
                    'shadow': shadow
                });
            }

            geocoder.geocode(request, _showResults);
        }

        function _parseLatLng(value) {
            value.replace('/\s//g');
            var coords = value.split(',');
            var lat = parseFloat(coords[0]);
            var lng = parseFloat(coords[1]);
            if (isNaN(lat) || isNaN(lng)) {
                return null;
            } else {
                return new google.maps.LatLng(lat, lng);
            }
        }

        function _resetMap() {
            infowindow.close();

            if (clickMarker != null) {
                clickMarker.setMap(null);
                clickMarker = null;
            }

            for (var i in markers) {
                markers[i].setMap(null);
            }

            markers = [];
            selected = null;
            _clearBoundsOverlays();

            document.getElementById("responseCount").style.display = "none";
            document.getElementById("matches").style.display = "none";
        }

        function _showResults(results, status) {
            var reverse = (clickMarker != null);

            if (!results) {
                alert("La localisation a échoué.");
            } else {
                document.getElementById("statusDescription").innerHTML = GeocoderStatusDescription[status];

                document.getElementById("responseInfo").style.display = "";

                if (status == google.maps.GeocoderStatus.OK) {
                    if (results.length > 1) {
                        document.getElementById("responseStatus").style.display = "block";
                    }
                    document.getElementById("matchCount").innerHTML = results.length;
                    document.getElementById("responseCount").style.display = "inline-block";
                    _plotMatchesOnMap(results, reverse);
                } else {
                    document.getElementById("responseStatus").style.display = "block";
                    if (!reverse) {
                        map.setCenter(new google.maps.LatLng(0.0, 0.0));
                        map.setZoom(1);
                    }
                }
            }
        }

        function _plotMatchesOnMap(results, reverse) {

            markers = new Array(results.length);

            var openInfoWindow = function (resultNum, result, marker) {
                return function () {
                    if (selected != null) {
                        infowindow.close();
                        document.getElementById('p' + selected).style.backgroundColor = "white";
                        _clearBoundsOverlays();
                    }

                    map.fitBounds(result.geometry.viewport);
                    var onclick = "SelectSearchLocation("
                                + result.geometry.location.lat() + ","
                                + result.geometry.location.lng() + ","
                                + "'"+ result.formatted_address.replace(/\'/g, '\\\'')+ "'," 
                                + "'" + options.dialogId + "')";
                    var html = '<div class="infoWindowContent" style="z-index:1000;">'
                             + '<div>' + result.formatted_address + '</div>'
                             + '<div><a id="selectAddress" href="#" onclick="' + onclick + '"><b><center>Cliquez ici pour enregistrer votre position</center></b></a></div>'
                             + '</div>';
                    infowindow.setContent(html);
                    infowindow.open(map, marker);

                    if (result.geometry.bounds) {
                        boundsOverlay = new google.maps.Rectangle({
                            'bounds': result.geometry.bounds,
                            'strokeColor': '#ff0000',
                            'strokeOpacity': 1.0,
                            'strokeWeight': 2.0,
                            'fillOpacity': 0.0
                        });
                        boundsOverlay.setMap(map);
                        document.getElementById('boundsLegend').style.display = 'block';
                    } else {
                        boundsOverlay = null;
                    }

                    viewportOverlay = new google.maps.Rectangle({
                        'bounds': result.geometry.viewport,
                        'strokeColor': '#0000ff',
                        'strokeOpacity': 1.0,
                        'strokeWeight': 2.0,
                        'fillOpacity': 0.0
                    });
                    viewportOverlay.setMap(map);
                    document.getElementById('viewportLegend').style.display = 'block';

                    document.getElementById('p' + resultNum).style.backgroundColor = "#eeeeff";
                    document.getElementById('matches').scrollTop =
                            document.getElementById('p' + resultNum).offsetTop -
                            document.getElementById('matches').offsetTop;
                    selected = resultNum;
                }
            }

            $('#matches').empty();
            var html = '';
            html += '<div class="info">';
            html += '<table><tr valign="top">';
            html += '<td style="padding: 2px;font-weight:bold;text-align:center;font-size:14px;" colspan="2">Cliquez sur un lieu pour le centrer sur la carte</td>';
            html += '</tr></table>';
            html += '</div>';
            $('#matches').append(html);

            for (var i = 0; i < results.length; i++) {
                var icon = new google.maps.MarkerImage(
                      _getMarkerImageUrl(i),
                      new google.maps.Size(20, 34),
                      new google.maps.Point(0, 0),
                      new google.maps.Point(10, 34)
                    );

                markers[i] = new google.maps.Marker({
                    'position': results[i].geometry.location,
                    'map': map,
                    'icon': icon,
                    'shadow': shadow
                });

                google.maps.event.addListener(markers[i], 'click', openInfoWindow(i, results[i], markers[i]));

                var html = '<a onclick="//_selectMarker(' + i + ')">';
                html += '<div class="info" id="p' + i + '">';
                html += '<table><tr valign="top">';
                html += '<td style="padding: 2px"><img src="' + _getMarkerImageUrl(i) + '"/></td>';
                html += '<td style="padding: 2px">' + _getResultDescription(results[i]) + '</td>';
                html += '</tr></table>';
                html += '</div></a>';

                $('#matches').append(html);
                $('#p' + i).bind('click',
                                { result: results[i], resultIndex: i },
                                function (event) {
                                    // map.setCenter(new google.maps.LatLng(event.data.result.geometry.location.lat(), event.data.result.geometry.location.lng()));
                                    _selectMarker(event.data.resultIndex);
                                });
            }

            document.getElementById("p0").style.border = "none";
            document.getElementById("matches").style.display = "block";

            if (!reverse) {
                _zoomToViewports(results);
            }
            _selectMarker(0);
        }

        function _selectMarker(n) {
            google.maps.event.trigger(markers[n], 'click');
        }

        function _zoomToViewports(results) {
            var bounds = new google.maps.LatLngBounds();

            for (var i in results) {
                bounds.union(results[i].geometry.viewport);
            }

            map.fitBounds(bounds);
        }

        function _getMarkerImageUrl(resultNum) {
            return MAPFILES_URL + "marker" + String.fromCharCode(65 + resultNum) + ".png";
        }

        function _getResultDescription(result) {
            var bounds = result.geometry.bounds;
            var html = '<table class="tabContent">';
            html += tr('', result.formatted_address);
            html += '</table>';
            return html;
        }

        function tr(key, value) {
            return '<tr>' +
           '<td class="key">' + key + (key ? ':' : '') + '</td>' +
           '<td class="value">' + value + '</td>' +
         '</tr>';
        }

        function br() {
            return '<tr><td colspan="2"><div style="width: 100%; border-bottom: 1px solid grey; margin: 2px;"</td></tr>';
        }

        function _clearBoundsOverlays() {
            if (boundsOverlay != null) {
                boundsOverlay.setMap(null);
                document.getElementById('boundsLegend').style.display = 'none';
            }
            if (viewportOverlay != null) {
                viewportOverlay.setMap(null);
                document.getElementById('viewportLegend').style.display = 'none';
            }
        }



    }; // saturneoDialogGoogleMaps - END

})(jQuery);

function SelectSearchLocation(latitude, longitude, address, dialogId) {
    var expires = 1000 * 60 * 60 * 24 * 120; // 120 days
    var path;
    var domain;
    var secure;

    // set time, it's in milliseconds
    var today = new Date();
    today.setTime(today.getTime());
    var expires_date = new Date(today.getTime() + (expires));

    var cookie_value = '' + latitude + '|' + longitude + '|' + address;

    document.cookie = "QJRSEARCHLOCATION=" + escape(cookie_value) +
                ((expires) ? ";expires=" + expires_date.toGMTString() : "") +
                ((path) ? ";path=" + path : "") +
                ((domain) ? ";domain=" + domain : "") +
                ((secure) ? ";secure" : "");


    $('#latitude').val(latitude);
    $('#longitude').val(longitude);
    $('#currentAddress').html(address);
    $('#' + dialogId).dialog('close');
}

