// global vars
var map = null;

// variables pour page 1
var rep_marker = null; // marker pour le reportage, un seul visible en tout temps
var geocoder = null;
var page = null;
var mode = 'point';
var polyline = null; // polyline du trajet

// variables pour page 2
var id_to_trajet = {}; // map: id -> array des points/info d'un trajet
var displayed_trajet = null; // polyline, un a la fois
var trajet_info_overlay = [];
var all_markers = [];


var info_icon = new GIcon(G_DEFAULT_ICON);
info_icon.image = "/img/gmaps/info.png"; 
info_icon.shadow = "/img/gmaps/info.shadow.png"; 
info_icon.iconSize = new GSize(32, 32);
info_icon.shadowSize = new GSize(59, 32);

var arrow_active_image = "/img/gmaps/item.normal.png"; 
var arrow_passive_image = "/img/gmaps/item.passive.png"; 
var arrow_selected_image = "/img/gmaps/item.selected.png"; 

var arrow_icon = new GIcon(G_DEFAULT_ICON); // default color
arrow_icon.image = arrow_active_image;
//arrow_icon.shadow = "/img/gmaps/arrow.shadow.png"; 
arrow_icon.iconSize = new GSize(20, 40);
//arrow_icon.shadowSize = new GSize(59, 32);

var start_icon = new GIcon(G_DEFAULT_ICON); 
start_icon.image = "/img/gmaps/dd-start.png"; 
start_icon.shadow = "/img/gmaps/msmarker.shadow.png"; 
start_icon.iconSize = new GSize(20, 34);
start_icon.shadowSize = new GSize(59, 32);

var end_icon = new GIcon(G_DEFAULT_ICON); 
end_icon.image = "/img/gmaps/dd-end.png"; 
end_icon.shadow = "/img/gmaps/msmarker.shadow.png"; 
end_icon.iconSize = new GSize(20, 34);
end_icon.shadowSize = new GSize(59, 32);

function init() {

    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
        map.setMapType(G_PHYSICAL_MAP);
        if (page == 1)
            map.addControl(new GLargeMapControl());
        else
            map.addControl(new GSmallZoomControl());
        //map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(45.5, -73.6), 12); // ~Montreal

        geocoder = new GClientGeocoder();

        $('#point_rb').attr('checked', true);
        return true;

    } else {
        alert('Votre navigateur web n\'est pas compatible avec le module de localisation géographique.');
        return false;
    }
}

function initPolylineListeners()
{
	// EVENT: clicking on a trajet vertex
	GEvent.addListener(polyline, 'click', function(point, vertex_index) {
//	alert('click!');
		if (typeof vertex_index != 'undefined' && !polyline.info_points[vertex_index]) { // must be on a vertex +
			var info_marker = new GMarker(point, {                                        // must not already exist
				icon: info_icon
			});
//		alert('click2!');

			map.addOverlay(info_marker);
			polyline.info_points[vertex_index] = { 
				marker: info_marker
			};
			GEvent.addListener(info_marker, 'click', function() {
				
				var info_div = document.createElement('div');
				info_div.innerHTML = '<textarea id="info_ta' + vertex_index + '" name="info" rows="6" cols="25">' + polyline.info_points[vertex_index].text + '</textarea><br>';
				var destroy_btn = document.createElement('button');
				destroy_btn.appendChild(document.createTextNode('Détruire'));
				destroy_btn.onclick = function() {
					map.removeOverlay(polyline.info_points[vertex_index].marker);
					polyline.info_points[vertex_index] = null;
					GEvent.clearListeners(info_marker, 'infowindowbeforeclose');
					info_marker.closeInfoWindow();
				};
				info_div.appendChild(destroy_btn);
				info_marker.openInfoWindow(info_div);
				GEvent.addListener(info_marker, 'infowindowbeforeclose', function() {
					// Etant donne que le node ne reste pas de le DOM quand la fenetre est fermee,
					// il faut sauvegarder le texte juste avant de detruire la fenetre
					polyline.info_points[vertex_index].text = $('#info_ta' + vertex_index).val();
				});
			});
		}
	});
	GEvent.addListener(polyline, 'lineupdated', function(point, vertex_index) {
		$.each(polyline.info_points, function(i, val) {
			if (val) {
				val.marker.setLatLng(polyline.getVertex(i));
			}
		});
	});
}

function addEditablePolylinePoint(point)
{
	if (polyline) {
		polyline.disableEditing();
		polyline.enableEditing({maxVertices: polyline.getVertexCount() + 1});
		polyline.insertVertex(polyline.getVertexCount(), point);
		polyline.info_points.push(null);
	} else {
		polyline = new GPolyline(point);
		polyline.insertVertex(polyline.getVertexCount(), point);
		polyline.info_points = [null];
		map.addOverlay(polyline);
		polyline.enableEditing({maxVertices: 2});
		initPolylineListeners();
		
	}

}

function setEditableMarker(point)
{
	if (rep_marker) map.removeOverlay(rep_marker);
	rep_marker = new GMarker(point, { 
		draggable: true,
		icon: arrow_icon
	});
	map.addOverlay(rep_marker);
	$('#save_btn').attr('disabled', false);
}

function init_page1(id_to_load) {
    page = 1;
    if (!init()) 
      return;
	if( id_to_load)
	{
		$.ajax({
        	url: $('#fcon').val()+'/geolocalizer/axLoad',
        	dataType: 'json',
        	type: 'POST',
        	async: false,
        	cache: false, // pour IE je crois que c'est necessaire..
        	data: {
        	    id: id_to_load,
        		all_status: 1
        	}, 
        	success: function(resp) {
        	    createReloadedEditable(resp);
        	},
        	error: function(resp) {
        	    alert('geolocalizer: erreur dans le reload du point existant');
        	}
    	});
	}
      
    GEvent.addListener(map, "click", function(overlay, point) {
        if (point) {

            if (mode == 'point') {
				setEditableMarker(point);

            } else {

				addEditablePolylinePoint(point);

            }
        }
    });
}

function init_page2() {
    page = 2;
    id_to_trajet = {};
    if (!init()) return;
}

function loadAll()
{
    $.ajax({
      	url: $('#fcon').val()+'/geolocalizer/axLoad',
        dataType: 'json',
       	type: 'POST',
       	async: false,
        cache: false, // pour IE je crois que c'est necessaire..
        data: {
        //	all_status: 1
        }, 
        success: function(resp) {
            displayEntities(resp);
            //displayFilters(resp);
        },
       	error: function(resp) {
	   	    alert('geolocalizer: erreur dans le reload de tous les points');
       	}

    });

}
function loadWeek(week_id)
{
    $.ajax({
      	url: $('#fcon').val()+'/geolocalizer/axLoad',
        dataType: 'json',
       	type: 'POST',
       	async: false,
        cache: false, // pour IE je crois que c'est necessaire..
        data: {
        //	all_status: 1,
        	week_id: week_id
        }, 
        success: function(resp) {
            displayEntities(resp);
            //displayFilters(resp);
        },
       	error: function(resp) {
	   	    alert('geolocalizer: erreur dans le reload de tous les points');
       	}

    });
}
function loadParticipant(user_id)
{
    $.ajax({
      	url: $('#fcon').val()+'/geolocalizer/axLoad',
        dataType: 'json',
       	type: 'POST',
       	async: false,
        cache: false, // pour IE je crois que c'est necessaire..
        data: {
        //	all_status: 1,
        	user_id: user_id
        }, 
        success: function(resp) {
            displayEntities(resp);
            //displayFilters(resp);
        },
       	error: function(resp) {
	   	    alert('geolocalizer: erreur dans le reload de tous les points');
       	}

    });
}

function zoomToId(id)
{}

function createMarker(coord, story) {
    var marker = new GMarker(coord, {
        icon: arrow_icon
    });
        
    id = story['id'];
    GEvent.addListener(marker, 'click', function() {
        if (displayed_trajet) {
            map.removeOverlay(displayed_trajet);
            displayed_trajet = null;
            $.each(trajet_info_overlay, function(i, val) {
                map.removeOverlay(val);
            });
            trajet_info_overlay = [];
        }

        // set all markers green, and selected one yellow
        $.each(all_markers, function(i, val) {
            val.setImage(arrow_active_image);
        });
        marker.setImage(arrow_selected_image);
        marker.openInfoWindow('<strong>'+story['author']+'</strong>'+ "<br/>"+story['week_text'] + "<br/>"+story['title']);
        if (id_to_trajet[id].length > 0) {
            var bounds = new GLatLngBounds();           
            displayed_trajet = new GPolyline(new GLatLng(id_to_trajet[id][0][0], id_to_trajet[id][0][1]));
            $.each(id_to_trajet[id], function(i, val) {
                var p = new GLatLng(val[0], val[1]);
                displayed_trajet.insertVertex(displayed_trajet.getVertexCount(), p);
                bounds.extend(p);

                // special markers..

                if (i == 0) { // on ajoute fleche-depart
                    var start_marker = new GMarker(p, { icon: start_icon });                 
                    map.addOverlay(start_marker);
                    trajet_info_overlay.push(start_marker);
                } else if (i == id_to_trajet[id].length - 1) {
                    var end_marker = new GMarker(p, { icon: end_icon });
                    map.addOverlay(end_marker);
                    trajet_info_overlay.push(end_marker);
                }

                if (val[2]) {
                    var info_marker = new GMarker(p, { 
                        icon: info_icon
                    });
                    map.addOverlay(info_marker);
                    trajet_info_overlay.push(info_marker);
                    info_marker.bindInfoWindowHtml(val[2]);
                }

            });
            map.addOverlay(displayed_trajet);
            var center = bounds.getCenter();
            var bzl = map.getBoundsZoomLevel(bounds);
            if (bzl > 18) bzl = 18; // eviter que le zoom soit trop precis
            map.setCenter(center, bzl);
            //map.panTo(center);
            //map.setZoom(bzl);
        }
    });
//    GEvent.addListener(marker, 'mouseout', function() {
//        marker.closeInfoWindow();
//    });        
    return marker;
}


function print_r( array, return_val ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Michael White (http://crestidg.com)
    // +   improved by: Ben Bryan
    // *     example 1: print_r(1, true);
    // *     returns 1: 1
    
    var output = "", pad_char = " ", pad_val = 4;
 
    var formatArray = function (obj, cur_depth, pad_val, pad_char) {
        if (cur_depth > 0) {
            cur_depth++;
        }
 
        var base_pad = repeat_char(pad_val*cur_depth, pad_char);
        var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
        var str = "";
 
        if (obj instanceof Array || obj instanceof Object) {
            str += "Array\n" + base_pad + "(\n";
            for (var key in obj) {
                if (obj[key] instanceof Array) {
                    str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char);
                } else {
                    str += thick_pad + "["+key+"] => " + obj[key] + "\n";
                }
            }
            str += base_pad + ")\n";
        } else if(obj == null || obj == undefined) {
            str = '';
        } else {
            str = obj.toString();
        }
 
        return str;
    };
 
    var repeat_char = function (len, pad_char) {
        var str = "";
        for(var i=0; i < len; i++) { 
            str += pad_char; 
        };
        return str;
    };
    output = formatArray(array, 0, pad_val, pad_char);
 
    if (return_val !== true) {
        document.write("<pre>" + output + "</pre>");
        return true;
    } else {
        return output;
    }
}

function createReloadedEditable(resp) {
   
    if (resp['msg'] <= 0)
    	return;
    //alert(print_r(resp['msg'][0],true));
    
    map.clearOverlays();
    var bounds = new GLatLngBounds();
    val = resp['msg'][0];
    var ll = new GLatLng(val['latitude'], val['longitude']);
    bounds.extend(ll);
    setEditableMarker(ll);
    if (val['GeoPathPoints']) {
    	var ar = Array();
    	var info_points=[null];
    	$.each(val['GeoPathPoints'], function(i, val2) {
	        var p = new GLatLng(val2['latitude'], val2['longitude']);
    	    ar[i]=p;
    		info_points.push(null);
    	    bounds.extend(p);
        });
        polyline = new GPolyline(ar);
        polyline.info_points = info_points;
        map.addOverlay(polyline);
		polyline.setStrokeStyle({color: '#559'})
        initPolylineListeners();
        //polyline.hide();
        //polyline.show();
		    
    }
    var center = bounds.getCenter();
    var bzl = map.getBoundsZoomLevel(bounds);
    if (bzl > 18) bzl = 18; // eviter que le zoom soit trop precis
    map.setCenter(center, bzl);
    //console.log(id_to_trajet);
}

function displayEntities(resp) {
    map.clearOverlays();
    all_markers = [];
    var bounds = new GLatLngBounds();
    $.each(resp['msg'], function(i, val) {
        var ll = new GLatLng(val['latitude'], val['longitude']);
        bounds.extend(ll);
        //alert(val['title']);
        var m = createMarker(ll, val);
        map.addOverlay(m);
        all_markers.push(m);
        id_to_trajet[val['id']] = val['GeoPathPoints'];
        if (id_to_trajet[val['id']].length > 0) { // mettre le trajet dans bounds pour s'assurer qu'il sera visible au niveau de zoom final
            $.each(id_to_trajet[val['id']], function(j, val) {
                bounds.extend(new GLatLng(val['longitude'], val['latitude']));
            });
        }        
    });
    var center = bounds.getCenter();
    var bzl = map.getBoundsZoomLevel(bounds);
    if (bzl > 18) bzl = 18; // eviter que le zoom soit trop precis
    map.setCenter(center, bzl);
    //console.log(id_to_trajet);
}

function displayFilters(resp) {
    $.each(resp.tags, function(i, val) {
        var a = $("<a href='#' id=" + val + ">" + val + "</a>");
        $('#filters').append(a);
        $('#filters').append('<br>');
        $('#' + val).bind('click', function(e) {
            var tag = e.target.id;
            $.ajax({
                url: 'php/entity.php',
                dataType: 'json',
                cache: false, // pour IE je crois que c'est necessaire..
                data: {
                    action: 'filter',
                    tag: tag
                }, 
                success: displayEntities
            });            
        });
    });
    var a = $("<a href='#' id='all'>Tous les tags</a>");
    $('#filters').append(a);
    $('#filters').append('<br>');
    $('#all').bind('click', function(e) {
        var tag = e.target.id;
        $.ajax({
            url: 'php/entity.php',
            dataType: 'json',
            cache: false, // pour IE je crois que c'est necessaire..
            data: {
                action: 'load_all'
            }, 
            success: displayEntities
        });            
    });
}

function getLatLonArr(pt_as_str) { 
    var m = pt_as_str.match(/\((.*), *(.*)\)/);
    if (m) {
        return [m[1], m[2]];
    } else {
        alert('error');        
        return;
    }   
}

function pointToAddress() {
    var addr = $('#addr_tf').val();
    geocoder.getLatLng(
        addr,
        function(point) {
            if (!point) {
                alert("L'adresse n'a pas été trouvée..");
            } else {
                map.setCenter(point, 14);
                if (rep_marker) map.removeOverlay(rep_marker);
                rep_marker = new GMarker(point, { 
                    draggable: true,
                    icon: arrow_icon
                });
                
                map.addOverlay(rep_marker);
                $('#save_btn').attr('disabled', false);
           }
        }
    );
}

function toggleMode(m) {
    mode = m;
    $('#point_mode_div').css('display', mode=='point'?'block':'none');
    $('#trajet_mode_div').css('display', mode=='trajet'?'block':'none');
    if (mode == 'trajet') {
        if (rep_marker) { 
            rep_marker.disableDragging();
            rep_marker.setImage(arrow_passive_image);
        }
        if (polyline) {
            polyline.setStrokeStyle({color: '#00f'});
            polyline.enableEditing({maxVertices: polyline.getVertexCount()});
            $.each(polyline.info_points, function(i, val) {
                if (val) val.marker.show();
            });
        }
    } else {
        if (rep_marker) { 
            rep_marker.enableDragging();
            rep_marker.setImage(arrow_active_image);
        }
        if (polyline) {
            polyline.setStrokeStyle({color: '#559'})
            polyline.disableEditing();
            $.each(polyline.info_points, function(i, val) {
                if (val) val.marker.hide();
            });
        }
    }
}

function removeTrajet() {
    if (polyline) {
        polyline.disableEditing();
        map.removeOverlay(polyline);
        polyline = null;
    }
}

function removeSegment() {
    if (polyline) {
        if (polyline.getVertexCount() == 2) { 
            removeTrajet();
            return;
        }
        if (polyline.info_points[polyline.getVertexCount() - 1]) { // on enleve le marker info
            map.removeOverlay(polyline.info_points[polyline.getVertexCount() - 1].marker);
        }
        polyline.disableEditing();
        polyline.info_points.pop();
        polyline.deleteVertex(polyline.getVertexCount() - 1);
        polyline.enableEditing({maxVertices: polyline.getVertexCount()});
    }
}

function geo_validate_submit()
{
    if (!rep_marker) {
        alert('SVP spécifiez un point principal sur l\'outil de géolocalisation');
        return false;
    }
}

function geo_save() {

    if (!$('#story_id').val()) {
        alert('Geolocalization: no story_id specified.');
        return;
    }
    if (!rep_marker) {
        if(polyline && polyline.getVertexCount())
        	alert("Pour sauvegarder le trajet de la geolocalisation, vous devez aussi placer un point principal. Pour l'instant, aucune information sur la géolocalisation ne sera sauvegardée.");
        return;
    }
    var pt_arr = new Array();
    if (polyline) {
        for (var i = 0; i < polyline.getVertexCount(); i++) {
            ll_arr = getLatLonArr(polyline.getVertex(i).toString());
            var info = '';
            if (polyline.info_points[i]) {
                info = polyline.info_points[i].text;
            }
            pt_arr.push(ll_arr[0] + ':' + ll_arr[1] + ':' + info);
        }
    }
    
    // lat/lon du point de reportage
    
    ll_arr = getLatLonArr(rep_marker.getPoint().toString());
    $.ajax({
        url: $('#fcon').val()+'/geolocalizer/axSave',
        dataType: 'json',
        type: 'POST',
        success: function (data, textStatus) 
                {
  					if(data.status=='ERROR')
  						alert("Geolocalizer: ajax-save error: "+data.msg);
					else if(data.status=='SUCCESS')
  						{}// do nothing ... 
  						//alert("Geolocalizer: ajax-save success:"+data.msg);
					else alert("Geolocalizer: unknown ajax return code: "+data.status);
				
				},
        error: function (XMLHttpRequest, textStatus, errorThrown)
                {
  					alert("Geolocalizer: Error during call to ajax-save data. Textstatus:"+textStatus+" | Error: "+errorThrown);
				},

        async: false,
        cache: false, // pour IE je crois que c'est necessaire..
        data: {
            id: $('#story_id').val(),
            trajet_str: pt_arr.join('|'),
            lat: ll_arr[0],
            lon: ll_arr[1]
        }
    });
}