// VEE AJAX functionality for searching
// (c) 2008 Loco (Loohuis Consulting), http://www.loohuis-consulting.nl/
// This work is licensed under a 
// Creative Commons Attribution-Share Alike 3.0 Netherlands License
// see http://www.loohuis-consulting.nl/development/cc-by-sa.php

// script url
var url = window.location.protocol + '//' + window.location.host + window.location.pathname;
// search application interface
var searchAppURL = 'http://www.vaneigenerf.nl/search/app.php';

// google map
var map;
// global marker storage
var points;
var markers = new Array();
// lookup table, use indexOf to find marker
var markerLookup = new Array();
var mgr;
// info window index, tracks marker bindings
var infoWindowIndex = new Array();
// zoom level at which markers appear
var markerThreshold = 4;
// active location
var active = 0;
// visible info window
var info = 0;
// default layout of map
var defaultCenter = new GLatLng(52.2, 5.2);
var defaultZoom = 6;
var locateZoom = 11;
// suggestions
// minimum length to show suggestions for
var minSuggestLength = 3;
// timeout before fetching suggestions in milliseconds
var suggestTimeout = 700;
var suggestTimer;

// display Google map
function loadMap() {
    map = new GMap2($("minimap"));
    map.addControl(new GSmallMapControl());
    map.addControl(new GHierarchicalMapTypeControl()); // GMapTypeControl
    map.removeMapType(G_HYBRID_MAP);
    map.removeMapType(G_SATELLITE_MAP);
    map.addMapType(G_PHYSICAL_MAP);
//    map.addControl(new GScaleControl());
    map.setCenter(defaultCenter, defaultZoom);
    map.enableScrollWheelZoom();
    map.setMapType(G_PHYSICAL_MAP);
    mgr = new MarkerManager(map);
//    GEvent.addListener(map, 'moveend', refreshSearch);

    // create the icons
    veeIcon = new GIcon();
    veeIcon.image = "/skin/vee-point.png";
    veeIcon.iconSize = new GSize(22, 22);
    veeIcon.iconAnchor = new GPoint(1, 21);
    veeIcon.infoWindowAnchor = new GPoint(1, 21);
    noveeIcon = new GIcon();
    noveeIcon.image = "/skin/no_vee-point.png";
    noveeIcon.iconSize = new GSize(22, 22);
    noveeIcon.iconAnchor = new GPoint(1, 21);
    noveeIcon.infoWindowAnchor = new GPoint(1, 21);
    afhaalIcon = new GIcon();
    afhaalIcon.image = "/skin/afhaal-point.png";
    afhaalIcon.iconSize = new GSize(22, 22);
    afhaalIcon.iconAnchor = new GPoint(1, 21);
    afhaalIcon.infoWindowAnchor = new GPoint(1, 21);
    // get point data
    var json = eval($('locationdata').points.value);
    points = $A(json.points);
    points.each(function(p)
    {
        if (p && p.lat > 0 && p.lon > 0) {
            if (p.veelid > 0)
                var m = new GMarker(new GLatLng(p.lat, p.lon), veeIcon);
            else if (p.afhaalpunt > 0)
                var m = new GMarker(new GLatLng(p.lat, p.lon), afhaalIcon);
            else
                var m = new GMarker(new GLatLng(p.lat, p.lon), noveeIcon);
            GEvent.addListener(m, 'click', function() {showMeta(p.lid)});
            markers.push(m);
        }
    });
    // use marker manager
    mgr.addMarkers(markers, markerThreshold);
    mgr.refresh();
}

// show meta-info in separate area
function showMeta(lid)
{
    $$('#miniresults div').each(function(d) {d.hide();});
    $('info_' + lid).show();
}

// refresh search results on map events dragend, moveend, and zoomend
// note: drag and zoom events also trigger move event
function refreshSearch()
{
//    $('throbber').show();
    var zoom = map.getZoom();
    var center = map.getCenter();
    var bounds = map.getBounds();
    // only search when markers are visible
    if (zoom >= markerThreshold) {
        new Ajax.Updater('searchresults', searchAppURL, {
            parameters: { 
                'search': '1',
                'searchtype': $F('searchtype'),
                'zoom': zoom,
                'lon': center.lng(),
                'lat': center.lat(),
                'north': bounds.getNorthEast().lat(),
                'east': bounds.getNorthEast().lng(),
                'south': bounds.getSouthWest().lat(),
                'west': bounds.getSouthWest().lng()
            },
            onComplete: function() {
                // add triggers
                var links = $$('.blowup');
                links.each(function(l)
                {
                    // add map blowup to marker
                    Event.observe(l, 'click', showOnMap);
                    // add info window binding to marker
                    var lid = l.getAttribute('name');
                    // only bind info window if not yet the case
                    if (!infoWindowIndex[lid]) {
//                        markers[markerLookup.indexOf(lid)].bindInfoWindow('<h1>lid: ' + lid + '</h1>');
                        var info = $('info_' + lid).innerHTML;
                        markers[markerLookup.indexOf(lid)].bindInfoWindow(info);
                        infoWindowIndex[lid] = true;
                    }
                });
//                $('throbber').hide();
                repaint();
            }
        });
    }
    else {
        $('searchresults').update();
//        $('throbber').hide();
    }
}

// show map blowup
function showOnMap(e)
{
    var elm = Event.element(e);
    info = elm.getAttribute('name');
    var infoContent = $('info_' + info).innerHTML;
    markers[markerLookup.indexOf(info)].openInfoWindow(infoContent);
//    markers[markerLookup.indexOf(active)].showMapBlowup();
//    repaint();
}

// repaint active result highlight in case search is refreshed by map event
function repaint()
{
    // clear search results
    var links = $$('.blowup');
    links.each(function(l) { l.up('li').removeClassName('active')});
    if ($('lid_' + active)) {
        $('lid_' + active).addClassName('active');
//        $('lid_' + active).scrollTo();
    }
    if (info) {
        $('lid_' + info).addClassName('active');
//        $('lid_' + info).scrollTo();
    }
    active = 0;
//    info = 0;
}

// adjust map location based on search
function setLocation(e)
{
    clearTimeout(suggestTimer);
    $('suggestions').hide();
    $('location').blur();
    elm = Event.element(e);
    debug = new Ajax.Request(searchAppURL, {
        parameters: { 
            'location': $F('location')
        },
        onSuccess: function(r) {
            if (r.responseJSON.adjust.lat > 0 && r.responseJSON.adjust.lon > 0) {
                map.setCenter(new GLatLng(r.responseJSON.adjust.lat, r.responseJSON.adjust.lon), locateZoom);
                refreshSearch();
            }
            // else error message?
        }
    });
    Event.stop(e);
}

// center map after marker is clicked
function centerOnMarker(lat, lon)
{
    if (lat > 0 && lon > 0) {
        map.panTo(new GLatLng(lat, lon));
        refreshSearch();
//        repaint();
    }
}

// get suggestions for location
function getSuggestions(e)
{
    clearTimeout(suggestTimer);
    $('suggestions').hide();
    var suggestBase = $F('location');
    // only retrieve suggestions if minimum length
    // and doesn't start with digit (exclude pcodes)
    if ((suggestBase.length >= minSuggestLength) && (!suggestBase.match(/^\s*\d/))) {
        suggestTimer = setTimeout("getDelayedSuggestions('" + escape(suggestBase) + "')", suggestTimeout);
    }
}

// set a city as the location and refresh the search
function setCity(e)
{
    elm = Event.element(e);
    $('location').value = elm.name;
    $('suggestions').hide();
    setLocation(e);
}

// overall application setup
function init()
{
    // always load map, adjust after loading search results
    if ($('minimap')) {
        Event.observe(window, 'unload', GUnload, false);
        loadMap();
    }
}

Event.observe(window, 'load', init, false);
