﻿//** Name:          ScholenOverzicht
//** Author:        Kees Jan Verkerk
//** Organisation:  vo-raad
//** Version:       1.0
//** Date:          02-02-2011

// This script displays secondary schools (voortgezet onderwijs) in the Netherlands on a map
// It uses Google maps for displaying the schools. To do so, the functions interact
// with the Google maps API, version 2. The data is retrieved from the GetScholen Webservice method.
// this method works in conjunction with MarkerClusterer to cluster schools into a single display on low zoom levels.
// Clustering markers yields an enormous gain in performance when visualizing the map.oo

// Load the google maps API, version 2
try {
    google.load("maps", "2", { other_params: "sensor=false" });
    google.setOnLoadCallback(initMap);
}
catch (e) {
    alert('Kan geen verbinding maken met Google maps, de scholenkaart kan niet worden weergegeven. Onze excuses voor het ongemak.');
};


///*** Declaration of global variables ***///
var googleMap;
var streetView;
var panoClient;
var geocoder;



var dvGoogleMap;
var dvStreetViewMap;
var dvClose;
var dvMapContainer;


var markerClusterer = new Array;
var schoolMarkerLayout = new Array;
var schoolIconGroup01 = new Array;
var schoolIcon01 = new Array;
var nrOfSchoolsLabelColour = new Array;

// Define a reference to the 'venster' of a speficied school, used for referal when clicking the marker
// or the anchor that is defined in the InfoWindow.
// The refSchoolToken is merely a placeholder for the actual schoolcode that is substituted at runtime.
var refSchoolToken = 'BRINVEST';
var refSchoolShowToken = 'BRINSHOW';

var constIndicatorMarktAandeel = 'indicator16';
var constIndicatorAlgemeen = 'indicator00';

var countryCode = 'NL'; //The country to use to scope for searching withing the map

var refSchoolsiteBasic;
var refSchoolsiteNotPublished;

if (document.URL.indexOf('test.schoolvo.nl', 0) >= 0) {
    refSchoolsiteBasic = 'http://www.test.schoolvo.nl';
    refSchoolsiteNotPublished = 'https://mijn.test.schoolvo.nl';
}
else {
    refSchoolsiteBasic = 'http://www.schoolvo.nl';
    refSchoolsiteNotPublished = 'https://mijn.schoolvo.nl';
}

var refSchoolsiteClean = refSchoolsiteBasic + '/?p_schoolcode=' + refSchoolToken;

//There is a difference reference for published schools and for not published schools.
var refSchoolsite = [];

//The reference for published schools
refSchoolsite[40] = '<a href= \"' + refSchoolsiteClean + '\" target="_blank\">' + refSchoolShowToken + '</a>';

//The reference for not publised schools until release 3.3, 14-01-2011, as of this date, no difference exists between published (complete) and incomplete schools 
//refSchoolsite[0] = '<a href= \"' + refSchoolsiteNotPublished + '/website/Pages/RenderStatus.aspx?Code=' + refSchoolToken + '&Type=Preview\" target="_blank\">' + refSchoolShowToken + '</a>';
//refSchoolsite[10] = refSchoolsite[0];
//refSchoolsite[20] = refSchoolsite[0];
//refSchoolsite[30] = refSchoolsite[0];

refSchoolsite[0] = refSchoolsite[40];
refSchoolsite[10] = refSchoolsite[40];
refSchoolsite[20] = refSchoolsite[40];
refSchoolsite[30] = refSchoolsite[40];


var schoolImageNoPhoto = './ScholenOverzicht/images/noSchoolPhoto_map.png';

var gridSizeCluster = 32; // the number of pixels that is the reach of a cluster (smaller value is less performance)
var maxClusterZoom;       // The maximum zoom level at which schools may be grouped to clusters

var mapDisplayContextPublic = 'public';     // Constant representing public context (default)
var mapDisplayContext = mapDisplayContextPublic; // the context in which the map is displayed. If the map is opened from the management context, then also non-public schoolvensters can be viewed

// set the default center of the map on the Vo-raad office in Utrecht.
//var defaultLat = 52.0962692;
//var defaultLong = 5.1135193;

// Set the default center of the map to approx. the center of the Netherlands.
var defaultLat = 52.227589;
var defaultLong = 5.484238;

var maxNameDisplayLength = 50; //defines the max length of a name displayed in an info window. Longer names are truncated and displayed with trailing ...

var defaultZoom = 7; // The initial zoom level
var searchZoom = 13;  // The search zoom level
var zoomInZoomLevel = 17;
var zoomOutZoomLevel = 8;
var schoolContextZoom = 13; // The zoom level when navigating from a specific school from the beheervenster (CMS)
var schoolAreaContextZoom = 11;  // the zoom level when showing postal codes and student distribution

var showAll = true; // currently deprecated, used to discriminate the view of all schools (when logged in) from only published schools (public)

var iconGroup = '11'; //variable to choose from a specified group of icons (initialy used to choose the appropriate color palette)
///*** END of Declaration of global variables ***///


/// Global variable that determines the code of the school to set initial focus on. The value is read from the querystring
var schoolWithFocus = '';

// Global variable that indicates a specific view on the map, specific to the indicator.
var indicator = '';

/// Global variable that determines the name of the city to set initial focus on. The value is read from the querystring
var plaatsWithFocus = '';

/// Initialize the map and its default contents
function initMap() {

    //Initialize context settings from the querystring
    initQueryStringParams();


    // default zoom level and maxCluster zoom level are dependent on whether public or logged in view is displayed.
    if (showAll) {

        //When fully published schools are to be shown solely,
        //clustering will be performed only at low zoom levels
        //In case all is to be shown, schools are clustered until zoom level 12.
        maxClusterZoom = 21;
    }
    else {
        maxClusterZoom = 7;
    }


    schoolIconGroup01[0] = './ScholenOverzicht/images/schoolStateNotParticipatingGroup' + iconGroup + '.png';
    schoolIconGroup01[10] = './ScholenOverzicht/images/schoolStateNotParticipatingGroup' + iconGroup + '.png';
    schoolIconGroup01[20] = './ScholenOverzicht/images/schoolStateNotPublishedGroup' + iconGroup + '.png';
    schoolIconGroup01[30] = './ScholenOverzicht/images/schoolStatePartialPublishedGroup' + iconGroup + '.png';
    schoolIconGroup01[40] = './ScholenOverzicht/images/schoolStatePublishedGroup' + iconGroup + '.png';
    schoolIconGroup01[99] = './ScholenOverzicht/images/schoolStatePublishedGroup' + iconGroup + '.png';

    schoolIcon01[0] = './ScholenOverzicht/images/schoolStateNotParticipating' + iconGroup + '.png';
    schoolIcon01[10] = './ScholenOverzicht/images/schoolStateNotParticipating' + iconGroup + '.png';
    schoolIcon01[20] = './ScholenOverzicht/images/schoolStateNotPublished' + iconGroup + '.png';
    schoolIcon01[30] = './ScholenOverzicht/images/schoolStatePartialPublished' + iconGroup + '.png';
    schoolIcon01[40] = './ScholenOverzicht/images/schoolStatePublished' + iconGroup + '.png';

    nrOfSchoolsLabelColour[0] = 'black';
    nrOfSchoolsLabelColour[10] = 'black';
    nrOfSchoolsLabelColour[20] = 'black';
    nrOfSchoolsLabelColour[30] = 'black';
    nrOfSchoolsLabelColour[40] = 'black';

    // Define the map and its position
    dvGoogleMap = document.getElementById('map');
    dvMapContainer = document.getElementById('rightpane');

    googleMap = new google.maps.Map(dvGoogleMap);
    geocoder = new GClientGeocoder();
    var latlng = new google.maps.LatLng(defaultLat, defaultLong);
    // Set the center of the map and the initial zoom level.
    googleMap.setCenter(latlng, defaultZoom);
    // Define the controls on the map and its appearance
    googleMap.setMapType(G_NORMAL_MAP);
    googleMap.setUIToDefault();
    googleMap.enableRotation();
    panoClient = new GStreetviewClient();


    if (showAll && indicator != constIndicatorMarktAandeel) {


        //Load all schools of any state (99 = all states)
        loadSchools(99);
    }

    if (indicator == constIndicatorAlgemeen && schoolWithFocus.length > 0) {
        loadSchoolForIndicator00(schoolWithFocus);
    }
    else if (schoolWithFocus.length > 0) {
        //do special initialisation for a school that has focus

        // load a school that is is in focus at present
        loadSchoolFromCMS(schoolWithFocus);

        if (indicator == constIndicatorMarktAandeel) {
            //Get the postal codes and plot on the map as polygons
            Vensters.Gis.WebServices.VvvWebServicePublic.GetAantalLeerlingen(schoolWithFocus, showAantalLeerlingen);
        }        
    }
    else if (plaatsWithFocus.length > 0) {
        showAddress(plaatsWithFocus, searchZoom, null);
    }
    

};

// Clear the template text
var initialValue = true;
function searchTextClicked() {
    if (initialValue == true) {
        var searchAddress = document.getElementById('searchAddress');
        searchAddress.value = '';
        searchAddress.className = 'searchAddressFilled';
        initialValue = false;
    }
};

// read parameters from the querystring
function initQueryStringParams() {
    var qs = new Querystring();
    var temp = qs.get('mapcontext');
    if (temp != null && temp != '')
        mapDisplayContext = temp;

    temp = qs.get('icongroup');
    if (temp != null && temp != '')
        iconGroup = temp;

    temp = qs.get('school_code');
    if (temp != null && temp != '')
        schoolWithFocus = temp;

    temp = qs.get('indicator');
    if (temp != null && temp != '')
        indicator = temp;

    temp = qs.get('plaatsOpKaart');
    if (temp != null && temp != '')
        plaatsWithFocus = temp;

};

///
// Function to find an adres of postal code, within Netherlands
// based on the Google geocoding services
function showAddress(address, zoomLevel, callback) {
    if (geocoder) {
        geocoder.setBaseCountryCode(countryCode); //Use the address found in the Netherlands in case of ambigious results.

        if (zoomLevel == null)
            zoomLevel = searchZoom;

        var addressFoundInNL = false;
        geocoder.getLocations(address,
            function (response) {
                if (response.Status.code == 200) {
                    // Retrieve the object 
                    var i;
                    for (i = 0; i < response.Placemark.length; i++) {
                        place = response.Placemark[i];
                        if (place.AddressDetails.Country != null &&
                            place.AddressDetails.Country.CountryNameCode == countryCode) {
                            // Retrieve the latitude and longitude 
                            point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                            googleMap.setCenter(point, zoomLevel);
                            if (callback != null) {
                                callback(point);
                            }
                                
                            addressFoundInNL = true;
                            break;
                        }
                    }
                }
                if (!addressFoundInNL)
                    alert(address + " is niet gevonden op deze kaart.");
                else {
                    // Save the search context in the session state for later retrieval
                    Vensters.Gis.WebServices.VvvWebServicePrivate.SetSearchContext(address);
                }
            }
        );
    }

};


// load a set of schools using the GetScholen Web Method 
// and show their contents on a map
function loadSchools(schoolStatus) {
    var wRequest = new Sys.Net.WebRequest();
    wRequest.get_headers()["Content-Type"] = "application/json; charset=utf-8";
    wRequest.set_httpVerb("GET");
    var path = "/ScholenOverzicht/data2.json";
    wRequest.add_completed(initSchoolsClustered);
    wRequest.set_url(path);
    wRequest.invoke();
};


//function loadSchools(schoolStatus) {
//    Vensters.Gis.WebServices.VvvWebServicePrivate.GetSchools(schoolStatus, initSchoolsClustered);
//};

// load all schools that have published all their indicators
function loadSchoolsPublished() {
    Vensters.Gis.WebServices.VvvWebServicePublic.GetPublishedSchools(initSchoolsClustered);
};

// load a single school 
function loadSchoolFromCMS(schoolCode) {
    if (schoolCode.length > 0) {
        try {
            Vensters.Gis.WebServices.VvvWebServicePublic.GetSchool(schoolCode, initSchoolFromCMS);
        }
        catch (err) {//swallow, zoom to school is not a crusial function
        }
    }
};

// load a single school 
function loadSchoolForIndicator00(schoolCode) {
    if (schoolCode.length > 0) {
        try {
            Vensters.Gis.WebServices.VvvWebServicePublic.GetSchool(schoolCode, initDraggableMarker);
        }
        catch (err) {//swallow, zoom to school is not a crusial function
        }
    }
};


// Zoom in to a school that was loaded from CMS and directly display its info window
function initSchoolFromCMS(school) {
    if (school != null && school.latitude > 0 && school.longitude > 0) {
        googleMap.addOverlay(createSchoolMarker(school));

        var schoolLocation = new GLatLng(school.latitude, school.longitude);

        if (indicator == constIndicatorMarktAandeel) {
            zoomGLatLong(schoolLocation, schoolAreaContextZoom);
        }
        else {
            //show the info window of the school
            initInfowindow(school, null, schoolLocation, true);
            //zoom in on the school location
            zoomGLatLong(schoolLocation, schoolContextZoom);
        }
    }
};

//Create and return a school Icon that represents the school on the map.
function createSchoolIcon(schoolstatus) {

    //Define the lay-out of a single school representation on the map
    var singleSchoolIcon = new GIcon(G_DEFAULT_ICON);
    singleSchoolIcon.iconSize = new GSize(35, 35);
    singleSchoolIcon.iconAnchor = new GPoint(34, 0);
    singleSchoolIcon.infoWindowAnchor = new GPoint(34, 0);
    singleSchoolIcon.image = schoolIcon01[schoolstatus];

    return singleSchoolIcon;

};

//Create and return a marker based on a given school,
//Also creates the corresponding Icon
function createSchoolMarker(school) {
    var singleSchoolIcon = createSchoolIcon(school.venster_status_id);

    return createSchoolMarkerFromGivenIcon(school, singleSchoolIcon);
};

//Create and return a marker based on a given school and given Icon,
//Uses the Icon passed in to represent the marker
function createSchoolMarkerFromGivenIcon(school, schoolIcon) {
    var markerOptions = { icon: schoolIcon, title: createSchoolTitle(school) };
    var schoolLocation = new GLatLng(school.latitude, school.longitude);

    return new GMarker(schoolLocation, markerOptions);
};

//Create the markers on the map using the Cluster Manager
function initSchoolsClustered(executor, eventArgs) {
    if (executor.get_responseAvailable()) {
        var schoolResult = executor.get_object().d;

        //Define the lay-out of a single school representation on the map
        var singleSchoolIcon = [];
        singleSchoolIcon[10] = createSchoolIcon(10);
        singleSchoolIcon[20] = createSchoolIcon(20);
        singleSchoolIcon[30] = createSchoolIcon(30);
        singleSchoolIcon[40] = createSchoolIcon(40);

        var showSchoolDirect = false;

        //create the markers that will represent schools and add them to the Marker Clusterer
        var markers = [];
        for (var i = 0; i < schoolResult.SchoolSet.length; i++) {
            if (schoolResult.SchoolSet[i].latitude != null && schoolResult.SchoolSet[i].longitude != null) {
                var schoolLocation = new GLatLng(schoolResult.SchoolSet[i].latitude, schoolResult.SchoolSet[i].longitude);
                var schoolMarker = createSchoolMarkerFromGivenIcon(schoolResult.SchoolSet[i], singleSchoolIcon[schoolResult.SchoolSet[i].venster_status_id]);

                //install an event listener for the mouse over event: show the corresponding info window.
                initInfowindow(schoolResult.SchoolSet[i], schoolMarker, schoolLocation, false);
                markers.push(schoolMarker);
            }
        }
        var mcStyles = [];
        //opt_anchor defines the location of the group amount label: the number of pixels from top and to the right of the upper left corner
        //mcStyles.push({ url: schoolIconGroup01[schoolResult.RequestedStatus], width: 40, height: 40, opt_textColor: nrOfSchoolsLabelColour[schoolResult.RequestedStatus], opt_anchor: [6, 20] });
        mcStyles.push({ url: schoolIconGroup01[99], width: 34, height: 34, opt_textColor: nrOfSchoolsLabelColour[99] });
        // mcStyles.push({ url: schoolIcon01[schoolResult.RequestedStatus], width: 30, height: 30, opt_textColor: nrOfSchoolsLabelColour[schoolResult.RequestedStatus], opt_anchor: [15, 15] });
        // mcStyles.push({ url: schoolIcon01[schoolResult.RequestedStatus], width: 40, height: 40, opt_textColor: nrOfSchoolsLabelColour[schoolResult.RequestedStatus], opt_anchor: [20, 20] });

        var mcOptions = { gridSize: gridSizeCluster, maxZoom: maxClusterZoom, styles: mcStyles };

        //Fill the marker clusterer with the created markers. This will also trigger the display on the map
        markerClusterer[schoolResult.RequestedStatus] = new MarkerClusterer(googleMap, markers, mcOptions);
    }
    else if (!schoolResult.Success) {
        alert('Er is een fout opgetreden bij het ophalen van schooldata. De scholen kunnen niet op de kaart worden getoond. Onze excuses voor het ongemak. Details:\n' + schoolResult.CallDetails);
    }
};

// Create a title for the marker. The title is shown when the user hovers over the marker.
function createSchoolTitle(school) {
    var seperator = ", ";
    var title = truncateString(filterNull(school.naam), maxNameDisplayLength) + seperator + filterNull(school.adres) + seperator + filterNull(school.woonplaats);
    return title;
};


// Create an infowindow specific to the school provided and install an eventhandler
// NOTE: if showDirect == true, the event handler is not installed, but instead
// the infowindow is displayed instantly. 
function initInfowindow(school, icoon, location, showDirect) {

    if (!showDirect) {
        //add listener for the mouse click event: open the infowindow
        GEvent.addListener(icoon, 'click', mouseClickEventHandler);
    }
    // show the info window directly
    else
        mouseClickEventHandler();

    // Marker mouseover eventhandler: display an infowindow
    function mouseClickEventHandler() {

        //store the place of the school that is shown here as context for list view
        Vensters.Gis.WebServices.VvvWebServicePrivate.SetSearchContext(school.woonplaats);

        panoClient.getNearestPanorama(location, createInfoWindowVariableStreetview);

        //Create an infowindow that has will only display the StreetView link button if
        //Street view is available for that location.
        function createInfoWindowVariableStreetview(panoData) {
            var streetViewAvailable = true;
            if (panoData.code == null || panoData.code != 200) {
                streetViewAvailable = false;
            }

            // Google Maps info window requires the outer DIV to define the width. Otherwise text will be rendered outside of the info window.
            // The Width of the Info window is determined based on the existence of an image of the school.

            //Defines three divs inside one container. Specify no other style properties than width and heigth for the container in order to keep 
            //the lay-out presented correctly in the InfoWindow of google maps.
            // The three divs are: a div for the image, top left
            // a div for the adress and other info, top right
            // a div for the actions at the bottom (presented as a bar)
            var infoHtml = '<div style=\"width: 290px; height: 135px">';
            infoHtml += '<div id=\"schoolImage\"; style=\"width: 140px; z-index: 0; position: absolute; left: 5px; top: 15px; height: 95px; overflow:hidden\" >';


            var schoolPhotoUrl; //represents a reference to a school photo.

            if (!school.pad_gebouw)
                schoolPhotoUrl = schoolImageNoPhoto;
            else
                schoolPhotoUrl = refSchoolsiteBasic + school.pad_gebouw;

            infoHtml += '<IMG src = \"' + schoolPhotoUrl + '" width=140px alt=\"foto schoolgebouw\">';
            infoHtml += '</div>'; //End div of SchoolImage
            infoHtml += '<div id=\"schoolInfo\"; style=\"width: 140px; z-index: 0; position: absolute; left: 150px; top: 15px; height: 95px; font-size:small \">';

            // Show the School name name in a <a> tag, Referencing the schoolvenster of this school
            infoHtml += refSchoolsite[school.venster_status_id].replace(refSchoolToken, school.school_code).replace(refSchoolShowToken, truncateString(filterNull(school.naam), maxNameDisplayLength)) + '<br/>';

            infoHtml += filterNull(school.adres) + '<br/>';
            infoHtml += filterNull(school.postcode) + ' <a href=\"' + refSchoolsiteBasic + '?plaats=' + filterNull(school.woonplaats) + '\"> ' + filterNull(school.woonplaats) + '<\a><br/>';
            infoHtml += '</div>'; // End div of schoolInfo
            infoHtml += '<div id=\"acties\" style=\"position: absolute; background-color:Silver; top: 120px; left: 5px; height: 15px; width: 285px; font-size:xx-small; vertical-align:bottom; text-align:justify\">';

            //Link to open Venster, published Vensters can always be opened, not-published (incomplete) ones will also be visible to the public, as of release 3.3, 14-01-2011
            infoHtml += refSchoolsite[school.venster_status_id].replace(refSchoolToken, school.school_code).replace(refSchoolShowToken, 'Open venster');

            if (school.homepage != null && school.homepage.length > 0)
                infoHtml += ' | <a href=\"' + school.homepage + '\" target="_blank\">Website school<\a>';
            infoHtml += ' | <a href=\"#" onclick=\"zoom(' + location.toUrlValue() + ', ' + zoomInZoomLevel.toString() + ');return false;\">Zoom in<\a>';
            infoHtml += ' | <a href=\"#" onclick=\"zoom(' + location.toUrlValue() + ', ' + zoomOutZoomLevel.toString() + ');return false;\">Zoom uit<\a>';
            if (streetViewAvailable == true) {
                infoHtml += ' | <a href=\"#" onclick=\"showStreetView(' + location.toUrlValue() + ');return false;\">Streetview<\a>';
            }
            infoHtml += '</div>';
            infoHtml += '</div>';
            googleMap.openInfoWindowHtml(location, infoHtml);
        }
    }
};


//Zoom in or out to the given point, and present a view at given zoom level
function zoom(latitude, longitude, zoomLevel) {
    zoomGLatLong(new GLatLng(latitude, longitude), zoomLevel);
};

//Zoom in or out to the given point, and present a view at given zoom level
//Does not use Google Maps' panning or zoomto functions because these are too slow.
function zoomGLatLong(latlong, zoomLevel) {
    googleMap.setCenter(latlong, zoomLevel);
};

//Show a streetview image
function showStreetView(latitude, longitude) {
    var schoolLocation = new GLatLng(latitude, longitude);
    createOverLayStreetDiv();
    panoramaOptions = { latlng: schoolLocation, enableFullScreen: true };
    streetView = new GStreetviewPanorama(dvStreetViewMap, panoramaOptions);
    GEvent.addListener(streetView, "error", handleStreetViewError);
};


//Eventhandler to alert errors in viewing the Street View modus.
function handleStreetViewError(errorCode) {
    closeStreetView();

    if (errorCode == 603) {
        alert("Street View is niet beschikbaar. Uw browser ondersteunt geen Flash of de versie van Flash is niet geschikt voor Google Street View.");
        return;
    }
    else if (errorCode == 600) {
        alert("Street View kan geen foto's tonen. Er zijn geen foto's beschikbaar voor deze locatie.");
        return;
    }
    else {
        alert("Er is een fout opgetreden bij het tonen van Street View");
        return;
    }
};

// filter null values. Return value or '' if the variable is null
function filterNull(variable) {
    if (!variable) {
        return ' ';
    }
    else {
        return variable;
    }
};

// Truncate a string if it is longer than len characters
// In that case trailing dots (...) are added
function truncateString(stringVar, len) {
    if (stringVar.length > len) {
        return stringVar.substring(0, len - 4) + '...';
    }
    else {
        return stringVar;
    }
};

// function to be executed on unload of the form (body)
function onUnload() {
    GUnload(); // free memory (solve potential circular references and avoid memory leaks).
};

//Create a seperate Streetview overlay.
function createOverLayStreetDiv() {
    //overlay

    var dv = document.createElement('div');
    var l = 0, t = 0, w = 0, h = 0;

    l = dvGoogleMap.offsetLeft;
    t = dvGoogleMap.offsetTop;
    w = dvGoogleMap.clientWidth;
    h = dvGoogleMap.clientHeight;

    // let the streetview div overlap the google map div
    with (dv) {

        style.position = 'absolute';
        style.left = l + 'px';
        style.top = t + 'px';
        style.width = w + 'px';
        style.height = h + 'px';
        style.zIndex = 2000;
        style.backgroundColor = '#FFFFFF';
        style.display = '';
    }
    dvMapContainer.appendChild(dv);

    //Create the Close Streetview button
    var closeDiv = document.createElement('div');
    closeDiv.className = 'close';
    closeDiv.style.position = 'absolute';


    // In Internet Explorer version 7, the street view close button is not visible if it is
    // above the streetview div, which is on top of the linkpane div, dispite the z-index.
    // In Google chrome, the street view close button is not visible if it on top of the 
    // street view div. Therefore a distinction is created below.
    //
    var navigatorName = navigator.appName;
    if (navigatorName == null || navigatorName == 'Microsoft Internet Explorer') {
        closeDiv.style.left = (l + w - 38) + 'px';
        closeDiv.style.top = (t + 9) + 'px';
    }
    else {
        closeDiv.style.left = (l + w - 14) + 'px';
        closeDiv.style.top = (t - 16) + 'px';
    }
    closeDiv.style.zIndex = 2100;

    closeDiv.onclick = closeStreetView;

    closeDiv.onmouseout = function () {
        this.className = 'close';
    };
    dvMapContainer.appendChild(closeDiv);

    dvStreetViewMap = dv;
    dvClose = closeDiv;
};

//Close the Streetview div and all of its contents and objects
function closeStreetView() {
    try {
        streetView.remove();
    }
    catch (err) {
        // swallow, streetView variable may not be initialized in the first place.
    }
    dvStreetViewMap.style.display = 'none';
    dvMapContainer.removeChild(dvStreetViewMap);
    dvClose.style.display = 'none';
    dvMapContainer.removeChild(dvClose);
};

//**************************** Indicator00 Functions (Draggable marker to change schoollocation)

var markerSchoolLocation;

function initDraggableMarker(school) {

    var qs = new Querystring();

    var latMarker = indicatorQueryStringParam(qs, 'latBIS').replace(',','.');
    var lngMarker = indicatorQueryStringParam(qs, 'lngBIS').replace(',', '.');

    var schoolcode = indicatorQueryStringParam(qs, 'school_code');


    if (latMarker != '' && lngMarker != '') {
        //default situation, lat and lng already have the correct values
    }
    else if (school.latitude > 0.0 && school.longitude > 0.0) {
        latMarker = school.latitude;
        lngMarker = school.longitude;
    }
    else {
        latMarker = defaultLat;
        lngMarker = defaultLong;
    }

    var latlng = new google.maps.LatLng(latMarker, lngMarker);
    markerSchoolLocation = new GMarker(latlng, { draggable: true });

    GEvent.addListener(markerSchoolLocation, "dragstart", function () { 
        googleMap.closeInfoWindow(); });

    GEvent.addListener(markerSchoolLocation, "dragend", updateLocation);
    googleMap.addOverlay(markerSchoolLocation);
    updateLocation();
    zoomGLatLong(latlng, zoomInZoomLevel);


    //Write the schoolcode, lattite and longitude to the textbox for user to copy (and paste in "ServiceVenster")
    function updateLocation() {
        writeLatLongCodeString(schoolcode,markerSchoolLocation);
    };
};

function writeLatLongCodeString(schoolcode, marker) {
    var position = marker.getLatLng();

    // Global replace (posstring.replace(/./g,","); ) doesn't seem to work:
    //    var x = 'jantje.pietje.klaasje';
    //    x = x.replace(/./g, ",");
    // results in ',,,,,,,,,,,,,,,';
    // Therefore the code beneath is a bit ugly workaround.

    var posString1 = schoolcode + '|' + position.lat(); 
    var posString2 = '|' + position.lng();

    posString1 = posString1.replace('.', ',');
    posString2 = posString2.replace('.', ',');
    $('#TBCopyPosition').val(posString1+posString2);
}

function indicatorQueryStringParam(queryString, paramName) {   

    var temp = queryString.get(paramName);
    if (temp != null && temp != '') {
        return temp;
    }
    else {
        return '';
    }
};

function markerToAddress() {    
    var qs = new Querystring();
    var adress = indicatorQueryStringParam(qs, 'adres');
    var zipCode = indicatorQueryStringParam(qs, 'postcode');
    var city = indicatorQueryStringParam(qs, 'woonplaats');

    showAddress(adress + ' , ' + zipCode + ' , ' + city, zoomInZoomLevel, markerToAdressPos);
}

function markerToAdressPos(point) {
    var queryStr = new Querystring();
    var schoolcode = indicatorQueryStringParam(queryStr, 'school_code');
    markerSchoolLocation.setLatLng(point);
    writeLatLongCodeString(schoolcode, markerSchoolLocation)
}

//**************************** Indicator16 Functions (Drawing of Postal code areas on to the map)


//Convert a dimension in format 123px to its number (123)
function divDimensionAsNumber(dimension) {
    dimension = dimension.replace('px', '');
    return dimension.valueOf();
};


function initLegenda() {
    //Plaats op de goede plek en maak visible
    var oLegenda = window.$get('legenda');

    oLegenda.style.top = divDimensionAsNumber(dvGoogleMap.style.height) - 40 - divDimensionAsNumber(oLegenda.style.height) + 'px';
    oLegenda.style.left = 10 + 'px';
    oLegenda.innerHTML = '<img src="/ScholenOverzicht/Images/legenda_aantal_ll.png" height="34" width="110" alt="legenda" />';
    oLegenda.style.visibility = 'visible';
};


// teken de postcodes op de kaart
function showAantalLeerlingen(lijst) {
    //Error handling
    if (lijst == null) return;

    initLegenda();

    // We krijgen de coordinaten als subset van de postcodes mee terug. We hebben dus een loop binnen een loop nodig om alles te tonen.
    Array.forEach(lijst, function (pp) {
        var aLatLong = new Array;

        //Het lijkt niet mogelijk om een nested foreach te gebruiken, dus gebruiken we nu een for loop.
        for (i = 0; i < pp.postcode_coordinatens.length; i++) {
            aLatLong.push(new GLatLng(pp.postcode_coordinatens[i].latitude, pp.postcode_coordinatens[i].longitude));
        }

        var shapeBackground = new 
        GPolygon(aLatLong, // the vertices
                "#f5e7a0", // the color of the edges of the polygon
                0,         // the width of the edges
                0,         // the opacity of the edges
                "#f5e7a0", // the fill color of the region
                0.3);      // the fill opacity of the region

        //We creeeren de shape en tekenen hem op de kaart 
        var shape = new 
        GPolygon(aLatLong, // the vertices
                "#000000", // the color of the edges of the polygon
                1,         // the width of the edges
                1,         // the opacity of the edges
                "#b40000", // the fill color of the region
                GetOpacity(pp.waarde)); // the fill opacity of the region


        GEvent.addListener(shape, 'mouseover', mouseOverEventHandler);
        GEvent.addListener(shape, 'click', mouseOverEventHandler);
        GEvent.addListener(shape, 'mouseout', mouseOutEventHandler);

        // Marker mouseover eventhandler: display an infowindow
        function mouseOverEventHandler(latlong) {
            shape.setStrokeStyle({ weight: 2 });
            window.$get('legenda').innerHTML = 'Postcode: ' + pp.postcode + '<br/>' + 'Aantal leerlingen:' + GetStudentCount(pp.waarde);
        }

        // Marker mouse out eventhandler: display an infowindow
        function mouseOutEventHandler(latlong) {
            shape.setStrokeStyle({ weight: 1 });
            window.$get('legenda').innerHTML = '<img src="./ScholenOverzicht/images/legenda_aantal_ll.png" height="34" width="110" alt="legenda" />';
        }

        googleMap.addOverlay(shapeBackground);
        googleMap.addOverlay(shape);
    });
};

function GetOpacity(iAantal) {
    if (iAantal <= 10) { return 0.30; }
    if (iAantal <= 25) { return 0.45; }
    if (iAantal <= 50) { return 0.63; }

    return 0.86;
};

function GetStudentCount(count) {
    if (count < 5) {
        return '<5';
    }
    else {
        return count;
    }
};

