$(function() {
    var map = L.map('map', {
        center: [30, 0],
        zoom: 2,
        maxBounds: [[-90,-180],[90,180]]
    });
    window.lmap = map;
    L.tileLayer(
        "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        {
            attribution: gettext("Map data © OpenStreetMap contributors")
        }
    ).addTo(map);
    
    var coordCache = [],
        coordIdCache = [],
        defaultIcon = new L.Icon.Default(),
        orangeIcon = new L.Icon.Default({iconUrl: urls.static_url + "jocondelab/lib/images/marker-orange.png"});
    
    function getData() {
        var bounds = map.getBounds();
        $.getJSON(
            urls.ajax_geo_coords,
            {
                min_lat: bounds.getSouth(),
                max_lat: bounds.getNorth(),
                min_lng: bounds.getWest(),
                max_lng: bounds.getEast()
            },
            function(data) {
                _(data).each(function(coord) {
                    if (coordIdCache.indexOf(coord.dbpedia_uri) === -1) {
                        coordIdCache.push(coord.dbpedia_uri);
                        coordCache.push(coord);
                    }
                });
                coordCache = _(coordCache).sortBy(function(coord) {
                    return -coord.sum_notices;
                });
                showData();
            }
        );
        showData();
    }
    
    var itemCount = 12;
    
    function selectCoord(coord) {
        _(coordCache).each(function(coord) {
            coord.isCurrent = false;
            if (coord.marker) {
                coord.marker.setIcon(defaultIcon);
            }
        });
        coord.isCurrent = true;
        showCoord(coord);
        coord.marker.setIcon(orangeIcon);
        map.setView([coord.latitude, coord.longitude], Math.max(Math.min(12,map.getZoom() + 1),6));
        
        $(".results").empty().load(
            urls.ajax_contents + "?random=1&dbpedia_uri=" + encodeURIComponent(coord.dbpedia_uri)
        );
    }
    
    function showCoord(coord) {
        if (!coord.marker) {
            coord.marker = L.marker([coord.latitude, coord.longitude]).addTo(map);
            bindDbpediaBox(coord.marker._icon,coord.dbpedia_uri);
            coord.marker.on("click", function() { selectCoord(coord); });
        }
    }
    
    function showData() {
        var n = 0,
            bounds = map.getBounds(),
            nsew = {
                w: bounds.getWest(),
                e: bounds.getEast(),
                n: bounds.getNorth(),
                s: bounds.getSouth()
            };
        _(coordCache).each(function(coord) {
            if (coord.isCurrent || (n < itemCount && coord.latitude > nsew.s && coord.latitude < nsew.n && coord.longitude > nsew.w && coord.longitude < nsew.e) ) {
                n++;
                showCoord(coord);
            } else {
                if (coord.marker) {
                    map.removeLayer(coord.marker);
                    coord.marker = null;
                }
            }
        });
    }
    
    var debouncedGetData = _.debounce(getData,500);
    
    debouncedGetData();
    
    map.on("moveend", debouncedGetData);
    
    $(".map-search-input").autocomplete({
        source: urls.ajax_geo_search,
        select: function(event, ui) {
            var coord = ui.item;
            if (coordIdCache.indexOf(coord.dbpedia_uri) === -1) {
                coordIdCache.push(coord.dbpedia_uri);
                coordCache.push(coord);
                coordCache = _(coordCache).sortBy(function(coord) {
                    return -coord.sum_notices;
                });
            }
            selectCoord(coord);
        }
    })
});
