//Définition des variables globales 
var map;
var bulle;
var markersArray = []; //Stocker les markers pour pouvoir les effacer à l'affichage d'un nouveau parcours
var titrePointInfo = []; 
var sTitrePointInfo = [];


window.onload = function(){
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(success);
    } else {
      error('Geo Location is not supported');
    }

    function success(position){
        var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        
        var options = {
            center: coords,
            zoom: 15,
            mapTypeId: google.maps.MapTypeId.HYBRID,
            styles:[{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"labels.text.stroke","stylers":[{"visibility":"off"}]}]
        };

        // Instanciation de la carte google
        map = new google.maps.Map(document.getElementById("mapSection"), options); 
        // Options d'affichage de la carte
        var GeoMarker = new GeolocationMarker(map);
        GeoMarker.setCircleOptions({fillColor: '#808080'});
        google.maps.event.addListenerOnce(GeoMarker, 'position_changed', function() {
            map.setCenter(this.getPosition());
            map.fitBounds(this.getBounds());
        });
        google.maps.event.addListener(GeoMarker, 'geolocation_error', function(e) {
            alert('There was an error obtaining your position. Message: ' + e.message);
        });

        //Definition de la variable google ici pour eviter l'affichage de plusieurs parcours en meme temps
        directionsDisplay =  new google.maps.DirectionsRenderer({suppressMarkers: true});
        infowindow = new google.maps.InfoWindow({size: new google.maps.Size(150,50)});

    }//sucess
}//window.onload

//Recuperer les informations sur le parcours à afficher
function recupInfo(str){

    lines = str.split('<br/>'); //On split le resultat de AJAX avec les balises <br/>
    var latPoint = []; var lonPoint = []; var nbPoints = 0;
    effacerInfos();

    for (var i = 0; i < lines.length; i++){
        if(lines[i][0] == "<" && lines[i][1] == "p"){
            infos = lines[i].split("||");  
            if(parseFloat(infos[1]) && parseFloat(infos[2])){
                latPoint.push(infos[1]); lonPoint.push(infos[2]);//Recuperer la latitude et la longitude
                nbPoints += 1; //Un point en plus !
            }
            else{
                titrePointInfo.push(infos[1]); sTitrePointInfo.push(infos[2]);//Recuperer le titre du point et son sous-titre
            }
        }
    }

    //Fonction JQuery pour afficher le parcours sur la map
    jQuery(function() {
        //Construire la liste des points du parcours
        var waypoints = [];

        //Prendre la latitude et la longitude des points du parcours
        for(var i = 0; i < nbPoints; i++){
            waypoints.push({"Geometry":{"Latitude":parseFloat(latPoint[i]),"Longitude":parseFloat(lonPoint[i])}})
        }

        //Initialisation des variables de google; Un google.maps.DirectionsRenderer par parcours
        directionsService = new google.maps.DirectionsService();

        //Lancer la fonction de nettoyage
        effacerMarker();

        //Lancement des fonctions d'affichage
        loadMap(map, directionsDisplay);
        fitBounds(map, waypoints);

        //Lancer le calcul + affichage du parcours
        if (waypoints.length > 1){
            calcRoute(directionsService, directionsDisplay, waypoints);
        }

    });//jQuery(function()
}//recupInfo

function effacerInfos(){
    titrePointInfo.length = 0;
    sTitrePointInfo.length = 0;
}

//Effacer les markers de la map
function effacerMarker(){
    //On supprime les markers présents sur la map un à un
    for(var i = 0; i < markersArray.length; i++){
        markersArray[i].setMap(null);
    }
    markersArray.length = 0;
}

//instancier la map
function loadMap(map, directionsDisplay){
    //Instanciation des options
    var myOptions = {
        zoom: 13,
        mapTypeId: window.google.maps.MapTypeId.HYBRID,
        //styles : retirer les labels de Google
        styles:[{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"labels.text.stroke","stylers":[{"visibility":"off"}]}]
    };
    map.setOptions(myOptions);
    directionsDisplay.setMap(map);
}//loadMap

//Creer le tableau de waypoints
function fitBounds(map, stops) {
    var bounds = new window.google.maps.LatLngBounds();
    //Pour tout les waypoints, on crée la variable google de Lat et Lon
    jQuery.each(stops, function (key, val) {
        var myLatlng = new google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
        bounds.extend(myLatlng);
    });
    map.fitBounds(bounds);
}//fitBounds


//Afficher la route sur la map
function calcRoute(directionsService, directionsDisplay, stops) {
    //Declaration des variables
    var batches = [];
    var itemsPerBatch = 10; //Limite imposée par Google
    var itemsCounter = 0;
    var wayptsExist = stops.length > 0;

    //Tant qu'il y a encore des waypoints dans le tableau
    while (wayptsExist) {
        var subBatch = [];
        var subitemsCounter = 0;

        for (var j = itemsCounter; j < stops.length; j++){
            subitemsCounter++;
            subBatch.push({
                location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
                stopover: true
            });
            if (subitemsCounter == itemsPerBatch){ 
                //Si on atteint la limite, on arrête et on fait un nouveau tableau (on continue la boucle)
                break;
            }
        }
        itemsCounter += subitemsCounter;
        batches.push(subBatch);
        wayptsExist = itemsCounter < stops.length;
        itemsCounter--;
    }//while

    var combinedResults;
    var unsortedResults = [{}];
    var directionsResultsReturned = 0;

    for (var k = 0; k < batches.length; k++) {
        //Le point de départ, d'arrivé et les waypoints
        var lastIndex = batches[k].length - 1;
        var start = batches[k][0].location;
        var end = batches[k][lastIndex].location;
                
        var waypts = [];
        waypts = batches[k];
        waypts.splice(0, 1);
        waypts.splice(waypts.length - 1, 1);

        var request = {
            origin: start,
            destination: end,
            waypoints: waypts,
            travelMode: window.google.maps.TravelMode.WALKING
        };

        (function (kk) {
            //On lance le calcul de la route
            directionsService.route(request, function (result, status) {
                if (status == window.google.maps.DirectionsStatus.OK) {
                    var unsortedResult = { order: kk, result: result };
                    unsortedResults.push(unsortedResult);

                    directionsResultsReturned++;

                    if (directionsResultsReturned == batches.length){
                        //Remettre en ordre les points
                        unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
                        var count = 0;
                        for (var key in unsortedResults){
                            if (unsortedResults[key].result != null){
                                if (unsortedResults.hasOwnProperty(key)){
                                    if (count == 0)
                                        combinedResults = unsortedResults[key].result;
                                    else {
                                        combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
                                        combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);

                                        combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
                                        combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
                                    }
                                    count++;
                                }
                            }
                        }
                            directionsDisplay.setDirections(combinedResults);
                            //Creer les markers et rajouter les informations dans les infobulles
                            var legs = combinedResults.routes[0].legs;
                            for (var i=0; i < legs.length;i++){
                                /////L'implementation des points visibles/invisibles est très simple, il suffit de faire des tests
                              //Si c'est un point visible : on fait ca
                              var markerletter = "A".charCodeAt(0);
                              markerletter += i;
                              markerletter = String.fromCharCode(markerletter);
                              createMarker(directionsDisplay.getMap(),legs[i].start_location,titrePointInfo[i],sTitrePointInfo[i],markerletter);
                              //Sinon on passe
                            }
                            //On teste a nouveau si c'est un point visible
                            var i=legs.length;
                            var markerletter = "A".charCodeAt(0);
                            markerletter += i;
                            markerletter = String.fromCharCode(markerletter);
                            createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,titrePointInfo[i],sTitrePointInfo[i],markerletter);
                    }
                }
                    });
        })(k);//function(kk)
    }//for de calcRoute
}//calcRoute


var icons = new Array();
//icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
      // This marker is 20 pixels wide by 34 pixels tall.
//      new google.maps.Size(20, 34),
      // The origin for this image is 0,0.
//      new google.maps.Point(0,0),
      // The anchor for this image is at 9,34.
//      new google.maps.Point(9, 34));

function getMarkerImage(iconStr) {
   if ((typeof(iconStr)=="undefined") || (iconStr==null)) { 
      iconStr = "red"; 
   }

   if (!icons[iconStr]) {
      icons[iconStr] = new google.maps.MarkerImage("http://www.google.com/mapfiles/marker"+ iconStr +".png",
      // This marker is 20 pixels wide by 34 pixels tall.
      new google.maps.Size(20, 34),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0),
      // The anchor for this image is at 9,34.
      new google.maps.Point(9, 34));
   } 

   return icons[iconStr];
}//getMarkerImage


function createMarker(map, latlng, label, html, color) {
    //console.log("createMarker("+latlng+","+label+","+html+","+color+")");

    var contentString = '<b>'+label+'</b><br>'+html;

    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: getMarkerImage(color),
        title: label,
        zIndex: Math.round(latlng.lat()*-100000)<<5
    });

    marker.myname = label;

    markersArray.push(marker);

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
    });

    return marker;
}//createMarker