﻿/*
*
* Custom Triodus Maps 
*
* */

// Load and callback function createMaps
$.getScript('http://maps.google.com/maps/api/js?v=3.1&async=2&hl=nl&sensor=false&region=nl&callback=createMaps&language=NL')

// Globals
var infoWindow;
var mapClicked;
var maps = new Array();
var maps_zoom = new Array();
var maps_bounds = new Array();
var markers = new Array();
var cult = $("meta[http-equiv='Content-language']").attr("content");
var geocoder = null;
var g_maxzoom = 15; // max. zoom level when auto-zooming after geocoding
var g_bounds = null;
var g_address = "Den Haag";


function createMaps() {
    // bind to keyup of search block
    $('#locationSearch').keyup(function () {
        locationSearch($(this));
    });
    
    // Loop all div's that have .googlemap class and loadMap()
    $('.googleMap').each(function () {
        if ($(this).css("height") == undefined) {
            $(this).css({
                height: $('#container').height()
            });
        }

        var elm = $(this)[0];
        var location = $(this).find('.map_cords').val();
        var scale = ($(this).find('.map_scale').val());
        //var noMapTypeControl = $(this).find('.map_type').val();

        var noMapTypeControl = false;
        if ($(this).hasClass('map_noMapTypeControl')) {
            noMapTypeControl = true;
        }

        var disableUI = false;
        if ($(this).hasClass('map_disableUI')) {
            disableUI = true;
        }

        var disableScroll = false;
        if ($(this).hasClass('map_disableScroll')) {
            disableScroll = true;
        }

        if (location.indexOf('address:') == 0 || g_address == "") {
            var address = g_address || location.substr(8);
            if (geocoder == null) {
                geocoder = new google.maps.Geocoder();
            }
            geocoder.geocode({ 'address': address, 'region': 'nl' }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    $('.googleMap').removeClass('hidden');
                    latlng = results[0].geometry.location;
                    loadMap(elm, latlng, scale, noMapTypeControl, disableUI, disableScroll);
                }
                else {
                    $('.googleMap').addClass('hidden');
                }
            });
        }
        else {
            var lat = location.split(',')[0];
            var lng = location.split(',')[1];
            var latlng = new google.maps.LatLng(lat, lng);
            loadMap(elm, latlng, scale, noMapTypeControl, disableUI, disableScroll);
        }
    });
}


// Create google map control
function loadMap(elm, latlng, scale, noMapTypeControl, disableUI, disableScroll) {
    var parent = $(elm).parent();
    var link = parent.attr('href');
    var hasLink = (link != null && link != '');

    var options = $.extend({
        zoom: parseInt(scale),
        center: latlng,
        scrollwheel: !disableScroll,
        navigationControl: !disableUI,
        mapTypeControl: !noMapTypeControl,
        panControl: !disableUI,
        panControlOptions: {
            position: google.maps.ControlPosition.LEFT_TOP
        },
        zoomControl: !disableUI,
        zoomControlOptions: {
            style: google.maps.ZoomControlStyle.LARGE,
            position: google.maps.ControlPosition.LEFT_TOP
        },
        scaleControl: false,
        streetViewControl: false,
        draggable: true,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }, options);

    var map = new google.maps.Map(elm, options);
    createMarkers(map);

    // Add custom control to 'push' google maps controls down on the page
    if (disableUI == false) {
        var controlDiv = document.createElement('DIV');
        controlDiv.style.height = '200px';
        controlDiv.style.width = '10px';
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(controlDiv);
    }

    // Add settings to global array's for reset functions
    maps[maps.length] = map;
    maps_zoom[maps_zoom.length] = map.getZoom();
    google.maps.event.addListenerOnce(map, 'bounds_changed', function(){
        maps_bounds[maps_bounds.length] = this.getBounds();
    });
}

function checkZoom(map) {
    if (map.getZoom() > g_maxzoom) {
        map.setZoom(g_maxzoom);
    }
    zoomToFirstMarker(map);
}

function resetMap(index) {
    maps[index].fitBounds(maps_bounds[index]);
    maps[index].setZoom(maps_zoom[index]);
}

function zoomToFirstMarker(map) {
    var zoom = map.getZoom();
    for (var z = zoom; z > 0; z--) {
        var bounds = map.getBounds();
        for (var i = 0; i < markers.length; i++) {
            // obtain the attribues of each marker
            var latlng = markers[i].position;
            if (bounds.contains(latlng) == true) {
                // a marker was found, fit and exit
                map.fitBounds(bounds);
                map.setCenter(latlng);
                return;
            }
        }
        map.setZoom(z);
    }
}

/* Markers */
var types = new Array();
var handlerUrl = '/HTTPHandlers/Locations.ashx';
var typeHandlerUrl = '/HTTPHandlers/LocationTypes.ashx';
function createMarkers(map) {
    if (types.length < 1) { 
        $.getJSON(typeHandlerUrl, function (data) { saveTypes(data, map); });
    }
    else {
        setMarkers(map);
    }
}

function setMarkers(map)
{
    //console.log('setMarkers');
    $.getJSON(handlerUrl, function (data) {
        renderMarkers(data, map);
    });
}

function renderMarkers(data, map) {
    //console.log('renderMarkers');
    $.each(data.Locations, function (i, item) {
        setMarker(i, item, map);
    });
}

function saveTypes(data, map) {
    types = new Array();
    $.each(data.LocationType, function (i, item) {
        types[types.length] = item;
    });
    setMarkers(map);
}

function getType(key) {
    for (i = 0 ; i <= types.length - 1; i++) {
        if (types[i].Key == key) {
            return types[i];
        }
    }
    return null;
}

function setMarker(i, item, map) {
    //console.log('setMarker: '+item.Name);
    var image = 'http://www.google.com/intl/en_us/mapfiles/ms/micons/red-dot.png';
    var ltype = getType(item.Type1);
    if (ltype != null) {
        image = ltype.Image;
    }

    var mapInfo = item.Coordinates.split('|');
    var lat = mapInfo[0].split(',')[0];
    var lng = mapInfo[0].split(',')[1];
    var latlng = new google.maps.LatLng(lat, lng);
    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: image,
        title: item.Name
    });
    google.maps.event.addListener(marker, 'click', function () {
        createInfoWindow(latlng, item.Id);
    });

    // add to global markers array
    markers[markers.length] = marker;
}

var infoHandlerUrl = '/HTTPHandlers/Location.ashx';
function createInfoWindow(latlng, itemId) {
    if (infoWindow != null) { infoWindow.close(); }
    infoWindow = new google.maps.InfoWindow({
        disableAutoPan: false,
        position: latlng
    });
    $.getJSON(infoHandlerUrl, { NodeID: itemId }, function (data) {
        renderInfoWindow(data.Location); 
    });
}

function renderInfoWindow(item) {
    infoWindow.setContent('<div class="infobox"><a href="' + item.Uri + '">' + item.Name + '</a></div>');
    infoWindow.open(maps[0]);
} 

function hideInfoWindow() {
    infoWindow.close();
}


/* Geocode for search */
function loadGeocodeMap() {
    geocode();
    return false;
}

var geoCodeIndex = 0;
function geocode(index) {
    var address = $(".mapsaddress").val();
    doGeoCode(index, address);
  }

  function doGeoCode(index, address) {
    if (geocoder == null) {
        geocoder =  new google.maps.Geocoder();
    }
    if (index > 0 && index != undefined) {
        geoCodeIndex = index;
    }
    geocoder.geocode({
      'address': address,
      'region': 'nl',
      'partialmatch': true}, geocodeResult);
  }

  function geocodeResult(results, status) {
    if (status == 'OK' && results.length > 0) {
        maps[geoCodeIndex].fitBounds(results[0].geometry.viewport);
        checkZoom(maps[geoCodeIndex]);
    } else {
        if (status == 'ZERO_RESULTS') {
            resetMap(geoCodeIndex);
        }
        else {
            console.warn("Geocode was not successful for the following reason: " + status);
        }
        //$(".search .row").addClass(".error");
        //$(".search .row .inputs").append('<p class="errorMessage">Locatie is ongeldig. Vul een <em>geldige</em> locatie in</p>');
    }
  }

  

/* Geocode handler for search-autocomplete */
function geocodeAutocomplete(request, response) {
    if (geocoder == null) {
        geocoder = new google.maps.Geocoder();
    }

    geocoder.geocode({ 'address': request.term, 'region': 'nl' }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var searchLoc = results[0].geometry.location;
            var lat = results[0].geometry.location.lat();
            var lng = results[0].geometry.location.lng();
            var latlng = new google.maps.LatLng(lat, lng);
            var bounds = results[0].geometry.bounds;

            geocoder.geocode({ 'latLng': latlng }, function (results1, status1) {
                if (status1 == google.maps.GeocoderStatus.OK) {
                    if (results1[1]) {
                        // limit number of results
                        var max = 2;
                        if (results1.length < 2) {
                            max = results1.length;
                        }
                        // return suggestions
                        response($.map(results1, function (loc, index) {
                            if (index <= max) {
                                return {
                                    label: loc.formatted_address,
                                    value: loc.formatted_address,
                                    bounds: loc.geometry.bounds
                                }
                            }
                        }));
                    }
                }
            });
        }
    });
}

/* Geocode handler for search-autocomplete */
function geocodeSelect(event, ui) {
    var pos = ui.item.position;
    var lct = ui.item.locType;
    var bounds = ui.item.bounds;

    if (bounds) {
        maps[0].fitBounds(bounds);
        checkZoom(maps[0]);
        $("#location_search").val(ui.item.label);
    }
}

/* Find Locations: Location search block using JSon */
function locationSearch(input) {
    // get UL
    var locations = $('#location_results');
    locations.empty(); //clear

    var rgx = new RegExp('^[0-9]{4}\\s{0,1}[a-zA-Z]{2}$', 'i'); // dutch zipcode regex
    if (input.val().match(rgx)) {
        //search  function
        var geocoder = new google.maps.Geocoder();
        var result = "";
        geocoder.geocode({ 'address': input.val(), 'region': 'nl' }, function (results, status) {
            // geoCode
            if (status == google.maps.GeocoderStatus.OK) {
                result = results[0].geometry.location;
                var lat = result.lat();
                var long = result.lng();
                //console.log('lat: '+lat+' lag:'+long);
                if (lat != '' && long != '') {
                    $.getJSON('/HTTPHandlers/LocationNearest.ashx', { latitude: lat, longitude: long }, function (data) {
                        $.each(data.Locations, function (i, item) {
                            var units = item.Units == 'Kilometers' ? 'km' : 'mi';
                            locations.prepend('<li><a href="' + item.Uri + '">' +
                                '<span class="name">' + item.Name + '</span>' +
                                '<span>' + item.Distance.toFixed(2) + units + '</span>' +
                                '</a></li>');
                        });
                        // set results
                        $('#searchBtnLocation').removeAttr('disabled');
                        $('#locationResults').slideDown(500);
                    });
                }
            } else {
                // no results
                result = "Unable to find address: " + status;
                $('#searchBtnLocation').attr('disabled', 'disabled');
                locations.prepend('<li><a href="#">' +
                    '<span class="name">Geen locatie gevonden</span>' +
                    '<span>...</span>' +
                    '</a></li>');
                $('#locationResults').slideDown(500);
            }
        });
        // --- end search function
    } else {
        $('#searchBtnLocation').attr('disabled', 'disabled');
        $('#locationResults').slideUp(500);
    }
}


// filter markers and location list
function filterLocations(index) {
    var categories = new Array();
    var map = maps[index];

    if (map) {
        if ($('.location_radio_group input:checked').length < 1) {
            // all inputs are not:checked, show all items
            createMarkers(map);
        }
        else {
            // some inputs are checked, show items filtered
            $('.location_radio_group input:checked').each(function (i, item) {
                // create list of allowed categories
                var cat = $(item).attr('id');
                var end = cat.lastIndexOf('_');
                categories[categories.length] = cat.substring(end + 1);
                // filter the stuff
                clearMarkers();
                refreshMarkers(map, categories);
            });
        }
        // filter list of locations
        refreshQuickList(categories);
    }
}

function refreshMarkers(map, categories)
{
    $.getJSON(handlerUrl, function (data) {
        refreshMarkerData(data, map, categories); 
    });
}

// render markers filterd
function refreshMarkerData(data, map, categories) {
    $.each(data.Locations, function (i, item) {
        if ($.inArray(item.Type1, categories) > -1 ||
            $.inArray(item.Type2, categories) > -1 ||
            $.inArray(item.Type3, categories) > -1) {
            //console.log('refreshMarkerData, setMarker: '+item.Name);
            setMarker(i, item, map);
        }
    });
}

// clear all markers from map
function clearMarkers() {
    //console.log('clearMarkers');
    for (var i = 0; i < this.markers.length; i++) {
        this.markers[i].setMap(null);
    }
    this.markers = new Array();
}

// filter items in list of locations
function refreshQuickList(categories) {
    if (categories.length > 0) {
        categories = $(categories);
        // show filterd
        $('#locationGroups a').each(function (i, item) {
            var link = $(item)
            link.css('display', 'none');
            categories.each(function (i, cat) {
                if (link.hasClass('.'+cat)) {
                    link.css('display', '');
                }
            });
        });
    }
    else {
        // show all
        $('#locationGroups a').each(function (i, item) {
            $(item).css('display', '');
        });
    }
}

