var map = (function() {
    var _data = null;
    var _markerManager;
    var _zoomBound;
    var _geocoder;
    var _apiKey;
    var _sqid;

    return {
        detailUrl: null,

        init: function(options, apiKey, data) {
            _apiKey = apiKey;

            if (GBrowserIsCompatible()) {
                _map = new GMap2(document.getElementById("map_canvas"));
                _map.addControl(new GLargeMapControl());
                _map.setCenter(new GLatLng(options.latitude, options.longitude), options.zoom);
                _map.enableDoubleClickZoom();

                _data = data;
                this._addMarkers();
            }
        },

        display: function() {
            _markerManager.refresh();
            if (_data.length > 0 && _data.length < 80) {
                _map.setCenter(_zoomBound.getCenter());
                _map.setZoom(_map.getBoundsZoomLevel(_zoomBound));
            }
        },

        setDsqid: function(id) {
            _sqid = id;
        },

        getPostcode: function(city, callback) {
            var vars = {
                q: city,
                gl: 'NL',
                output: 'json',
                oe: 'utf8',
                sensor: 'false',
                key: _apiKey
            };

            $.getJSON('http://maps.google.com/maps/geo?callback=?', vars, function(data) {
                if (data.Placemark.length > 0) {
                    var coords = data.Placemark[0].Point.coordinates;

                    vars.q = coords[1] +','+ coords[0];
                    $.getJSON('http://maps.google.com/maps/geo?callback=?', vars, function(data) {
                        if (data.Placemark.length > 0) {
                            var postcode = null;
                            try
                            {
                                postcode = data.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.DependentLocality.PostalCode.PostalCodeNumber;
                            }
                            catch(e)
                            {
                                postcode = null;
                            }
                            callback(postcode);
                        }
                    });
                }

            });
        },

        _addMarkers: function() {
            _markerManager = new MarkerManager(_map);
            _markerManager.addMarkers(this._getMarkers(200), 6);
        },

        _getMarkers: function (n) {
            var batch = [];

            var self = this;
            _zoomBound = new GLatLngBounds;
            $.each(_data, function(item, dealer) {
                var point = new GLatLng(dealer.latitude, dealer.longitude);
                var marker = new GMarker(point, { icon: self._getIcon() });
                marker.dealer = dealer;

                GEvent.addListener(marker, "click", function() {
                    self._displayPanel(marker, point)});

                _zoomBound.extend(point);
                batch.push(marker);
            });

            return batch;
        },

        _displayPanel: function(marker, point) {
            var dealer = marker.dealer;
            var sqidPart = "";

            var myHtml = "<span class='dealer-name'>" + dealer.name +"</span><br>" +
            "<div class='dealer-address'>" +
            dealer.street + " " + dealer.number + "<br>" +
            dealer.postcode + " " + dealer.city + "<br><br>" +
            dealer.telephone + "<br>";

            if (dealer.email.search(/@/) > 0) {
                myHtml += "<a href='mailto:"+ dealer.email +"'>" + dealer.email + "</a><br>";
            }
            myHtml += "</div>";

            _map.openInfoWindowHtml(point, myHtml, {maxWidth: 120});
        },

        _getIcon: function () {
            // Create our "tiny" marker icon
            var blueIcon = new GIcon(G_DEFAULT_ICON);
            blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png";
            return blueIcon;
        }
    }
}());
