/*
 * Ext JS Library 2.2
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.com/license
 */

/**
 * @author Shea Frederick
 */

Ext.namespace('Ext.ux');
 
/**
 *
 * @class GMapPanel
 * @extends Ext.Panel
 */
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
    initComponent : function(){
		
        var defConfig = {
            plain: true,
            zoomLevel: 3,
            yaw: 180,
            pitch: 0,
            zoom: 0,
            gmapType: 'map',
            border: false
        };
        
        Ext.applyIf(this,defConfig);
        
        Ext.ux.GMapPanel.superclass.initComponent.call(this);        

    },
    afterRender : function(){
		
        var wh = this.ownerCt.getSize();
        Ext.applyIf(this, wh);
        
        Ext.ux.GMapPanel.superclass.afterRender.call(this);    
        
        if (this.gmapType === 'map'){
            this.gmap = new GMap2(this.body.dom);
        }
        
        if (this.gmapType === 'panorama'){
            this.gmap = new GStreetviewPanorama(this.body.dom);
        }
        
        if (typeof this.addControl == 'object' && this.gmapType === 'map') {
            this.gmap.addControl(this.addControl);
        }
        
        if (typeof this.setCenter === 'object') {
            if (typeof this.setCenter.geoCodeAddr === 'string'){
                this.geoCodeLookup(this.setCenter.geoCodeAddr);
            }else{
                if (this.gmapType === 'map'){
                    var point = new GLatLng(this.setCenter.lat,this.setCenter.lng);
                    this.gmap.setCenter(point, this.zoomLevel);    
                }
                if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
                    this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear);
                }
            }
            if (this.gmapType === 'panorama'){
                this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
            }
        }
		
		if (navigator.appName == 'Microsoft Internet Explorer') {
			var point = new GLatLng(44,0.7827523076124293);
			this.gmap.setCenter(point, this.zoomLevel);
		}

		// ajout GéoPyrénées
		var map1 = this.getMap();
		var locations;
		var z;
		var extendPercent = 50 / 100;
		
		this.addMapControls();
		this.addOptions();
		
		map1.addMapType(G_PHYSICAL_MAP);
		map1.removeMapType(G_HYBRID_MAP);
		map1.setMapType(G_PHYSICAL_MAP);
		//map1.addControl(new ExtLargeMapControl());
		
		G_NORMAL_MAP.getMinimumResolution = function(){return 8};
		G_PHYSICAL_MAP.getMinimumResolution = function(){return 8};
		G_SATELLITE_MAP.getMinimumResolution = function(){return 8};
		
		GEvent.addListener(map1, 'zoomend', function() {
			var centerLat = map1.getCenter().lat();
			var centerLng = map1.getCenter().lng();
			var north = map1.getBounds().getNorthEast().lat();
			var south = map1.getBounds().getSouthWest().lat();
			var west = map1.getBounds().getNorthEast().lng();
			var east = map1.getBounds().getSouthWest().lng();

			Ext.getCmp('carto').addLayer();
		});
		
		var centerLat = map1.getCenter().lat();
		var centerLng = map1.getCenter().lng();
		
		var north = map1.getBounds().getNorthEast().lat();
		var south = map1.getBounds().getSouthWest().lat();
		var west = map1.getBounds().getNorthEast().lng();
		var east = map1.getBounds().getSouthWest().lng();
		
		GEvent.addListener(map1, 'moveend', function() {
			//var centerLat = map1.getCenter().lat();
			//var centerLng = map1.getCenter().lng();
			var north = map1.getBounds().getNorthEast().lat();
			var south = map1.getBounds().getSouthWest().lat();
			var west = map1.getBounds().getNorthEast().lng();
			var east = map1.getBounds().getSouthWest().lng();
			
			var centerMoveLat = map1.getCenter().lat();
			var centerMoveLng = map1.getCenter().lng();
			
			var extendY = Math.abs(north - south)*extendPercent;
			var extendX = Math.abs(west - east)*extendPercent;
			
			if ((centerMoveLng > (centerLng + extendX)) || (centerMoveLng < (centerLng - extendX))){
				centerLat = map1.getCenter().lat();
				centerLng = map1.getCenter().lng();
				north = map1.getBounds().getNorthEast().lat();
				south = map1.getBounds().getSouthWest().lat();
				west = map1.getBounds().getNorthEast().lng();
				east = map1.getBounds().getSouthWest().lng();
				Ext.getCmp('carto').addLayer();
			}
			if ((centerMoveLat > (centerLat + extendY)) || (centerMoveLat < (centerLat - extendY))){
				centerLat = map1.getCenter().lat();
				centerLng = map1.getCenter().lng();
				north = map1.getBounds().getNorthEast().lat();
				south = map1.getBounds().getSouthWest().lat();
				west = map1.getBounds().getNorthEast().lng();
				east = map1.getBounds().getSouthWest().lng();
				Ext.getCmp('carto').addLayer();
			}
			
		});
		
		// barre de progression
		function waiting(){};
		waiting.prototype = new GControl();
		waiting.prototype.initialize = function(map1) {
			var waiting_div = document.createElement("div");
			//waiting_div.id = "id_waiting_div";
			var progress_div = document.createElement("div");
			progress_div.id = "id_progress_div";
			progress_div.innerHTML = "";

			map1.getContainer(map1).appendChild(waiting_div);
			waiting_div.appendChild(progress_div);
   
			map1.getContainer().appendChild(waiting_div);
			return waiting_div;
		}
		
		var centre = new GSize((map1.getSize().width / 2) - 100, (map1.getSize().height / 2) - 35);
		waiting.prototype.getDefaultPosition = function() {
			return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, centre);
		}
		var waitingControl = new waiting();
		this.getMap().addControl(waitingControl);
		//document.getElementById("id_waiting_div").style.visibility="hidden";
		document.getElementById("id_progress_div").style.visibility="hidden";
		// fin ajout GéoPyrénées
		

        GEvent.bind(this.gmap, 'load', this, function(){
            this.onMapReady();
        });

    },
	
	// ajout GéoPyrénées
	addLayer : function(){
		
		// on efface tous les marqueurs
		this.getMap().clearOverlays();
		
		// on ajoute les marqueurs
		var listType = new Array();
		for(i=0;i<Ext.getCmp('tree-panel').getChecked().length;i++){
			var database = Ext.getCmp('tree-panel').getChecked()[i].id;
			listType.push(database);
		}
		
		var maxY = this.getMap().getBounds().getNorthEast().lat();
		var minY = this.getMap().getBounds().getSouthWest().lat();
		var minX = this.getMap().getBounds().getSouthWest().lng();
		var maxX = this.getMap().getBounds().getNorthEast().lng();
		var zoomLevel = this.getMap().getZoom();
		z = 0;
		
		var urlstr = "./php_geopyrenees/getObj.php?maxY="+maxY+"&minY="+minY+"&minX="+minX+"&maxX="+maxX+"&zoomLevel="+zoomLevel+"&listType="+listType;
		GDownloadUrl(urlstr, function(data) {
			var xmlDoc = GXml.parse(data);
			var root = xmlDoc.documentElement;
			locations = root.getElementsByTagName("marker");			
			//document.getElementById("id_waiting_div").style.visibility="visible";
			document.getElementById("id_progress_div").style.visibility="visible";
			document.getElementById("id_progress_div").innerHTML = "Chargement ...";
			Ext.getCmp('carto').loadMarqueurs();
		});

	},
	loadMarqueurs : function(){
		
		if (z < locations.length){
			var lat_marker = parseFloat(locations[z].getAttribute("lat_objet"));
			var lng_marker = parseFloat(locations[z].getAttribute("lng_objet"));
			
			var point = new GLatLng(lat_marker,lng_marker);
			
			if (locations[z].getAttribute("cluster")==1){
				var baseIcon = new GIcon();
				//baseIcon.shadow = "./icon/marker/markerGroupShadow.png";
				//baseIcon.iconSize = new GSize(52, 58);
				//baseIcon.shadowSize = new GSize(68, 59);
				//baseIcon.iconAnchor = new GPoint(9, 34);
				//baseIcon.infoWindowAnchor = new GPoint(9, 2);
				//baseIcon.infoShadowAnchor = new GPoint(18, 25);
				//baseIcon.shadow = "./icon/marker/shadow.png";
				baseIcon.iconSize = new GSize(24.0, 38.0);
				baseIcon.shadowSize = new GSize(44.0, 38.0);
				baseIcon.iconAnchor = new GPoint(12.0, 38);
				baseIcon.infoWindowAnchor = new GPoint(12.0, 19.0);
				
				baseIcon.image = "./icon/marker/markerGroup_orange.png";
				
				var infobulle_html = locations[z].getAttribute("nb_marker")+' objets';
				var alt_title = locations[z].getAttribute("nb_marker")+' objets - Zoomez pour voir les objets';
				Ext.getCmp('carto').addMarqueurCluster(point,{icon: baseIcon, title: alt_title },infobulle_html,this.getMap());
			}
			else{
				var icon = new GIcon();
				if (locations[z].getAttribute("affichage_objet") == "t"){
					icon.image = "./icon/marker/c"+locations[z].getAttribute("id_type")+".png";
				}
				else{
					icon.image = "./icon/marker/c"+locations[z].getAttribute("id_type")+"_nb.png";
				}
				icon.shadow = "./icon/marker/shadow.png";
				icon.iconSize = new GSize(24.0, 38.0);
				icon.shadowSize = new GSize(44.0, 38.0);
				icon.iconAnchor = new GPoint(12.0, 38);
				icon.infoWindowAnchor = new GPoint(12.0, 19.0);
				
				var lib_objet = locations[z].getAttribute("lib_objet");
				if (locations[z].getAttribute("affichage_objet") == "t"){
					var infobulle_html = '<img src="./icon/marker/c'+locations[z].getAttribute("id_type")+'.png" align="middle"/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2f4493;font-size: 14px;font-weight: bold;">'+lib_objet+'</span>';
				}
				else{
						var infobulle_html = '<img src="./icon/marker/c'+locations[z].getAttribute("id_type")+'_nb.png" align="middle"/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2f4493;font-size: 14px;font-weight: bold;">'+lib_objet+'</span>';
				}
				infobulle_html += '<br><br>';
				infobulle_html += 'longitude : '+lng_marker;
				infobulle_html += '<br>';
				infobulle_html += 'latitude : '+lat_marker;
				if (locations[z].getAttribute("alt_objet") != ""){
					infobulle_html += '<br>';
					infobulle_html += 'altitude : '+locations[z].getAttribute("alt_objet")+' m.';
				}
				
				if (locations[z].getAttribute("url_wikipedia_objet") != ""){
					infobulle_html += '<br><br>';
					infobulle_html += 'page Wikipédia : <a href="'+locations[z].getAttribute("url_wikipedia_objet")+'" target="_blank">cliquez ici</a>';
				}
				
				if (locations[z].getAttribute("refuge_id_url") != ""){
					infobulle_html += '<br><br>';
					infobulle_html += 'Lien vers la fiche du refuge : <a href="http://www.pyrenees-refuges.com/fr/affiche.php?numenr='+locations[z].getAttribute("refuge_id_url")+'" target="_blank">cliquez ici</a>';
				}
				// enlever cette condition dès que lacs des pyrénées sera un partenaire
				if (locations[z].getAttribute("id_type") != 31){
					if (locations[z].getAttribute("url_bis_objet") != ""){
						infobulle_html += '<br><br>';
						infobulle_html += 'autre lien : <a href="'+locations[z].getAttribute("url_bis_objet")+'" target="_blank">cliquez ici</a>';
					}
				}
				
				if (locations[z].getAttribute("affichage_objet") == "f"){
					infobulle_html += '<br><br>';
					infobulle_html += '<b>En cours de validation.</b>';
				}
				Ext.getCmp('carto').addMarqueur(point,{icon: icon,title: lib_objet},infobulle_html);
			}
			z++;
			if (parseInt(z*100/locations.length) < 30){
				setTimeout("Ext.getCmp('carto').loadMarqueurs()",10);
			}
			else{
				document.getElementById("id_progress_div").style.width = parseInt(z/locations.length*210)+"px";
				document.getElementById("id_progress_div").innerHTML = parseInt(z*100/locations.length)+"%";
				setTimeout("Ext.getCmp('carto').loadMarqueurs()",1);
			}
		}
		else{
			document.getElementById("id_progress_div").innerHTML = "Carte complète ...";
			setTimeout('document.getElementById("id_progress_div").style.visibility="hidden";',300);
			k = 0;
		}
		
	},
	addMarqueur : function(point, marker, infobulle){
        var mark = new GMarker(point,marker);
		GEvent.addListener(mark, 'click', function() {
			mark.openInfoWindowHtml(infobulle);
		});
        this.getMap().addOverlay(mark);
    },
	
	addMarqueurCluster : function(point, marker, infobulle,map){
        var mark = new GMarker(point,marker);
		GEvent.addListener(mark, 'click', function() {
			map.setCenter(mark.getLatLng(),map.getZoom()+1);
		});
        this.getMap().addOverlay(mark);
    },
	// fin d'ajout GéoPyrénées
	
    onMapReady : function(){
        this.addMarkers(this.markers);
        this.addMapControls();
        this.addOptions();  
    },
    onResize : function(w, h){

        if (typeof this.getMap() == 'object') {
            this.gmap.checkResize();
        }
        
        Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);

    },
    setSize : function(width, height, animate){
        
        if (typeof this.getMap() == 'object') {
            this.gmap.checkResize();
        }
        
        Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);
        
    },
    getMap : function(){
        
        return this.gmap;
        
    },
    getCenter : function(){
        
        return this.getMap().getCenter();
        
    },
    getCenterLatLng : function(){
        
        var ll = this.getCenter();
        return {lat: ll.lat(), lng: ll.lng()};
        
    },
    addMarkers : function(markers) {
        
        if (Ext.isArray(markers)){
            for (var i = 0; i < markers.length; i++) {
                var mkr_point = new GLatLng(markers[i].lat,markers[i].lng);
                this.addMarker(mkr_point,markers[i].marker,false,markers[i].setCenter, markers[i].listeners);
            }
        }
        
    },
    addMarker : function(point, marker, clear, center, listeners){
        
        Ext.applyIf(marker,G_DEFAULT_ICON);

        if (clear === true){
            this.getMap().clearOverlays();
        }
        if (center === true) {
            this.getMap().setCenter(point, this.zoomLevel);
        }

        var mark = new GMarker(point,marker);
        if (typeof listeners === 'object'){
            for (evt in listeners) {
                GEvent.bind(mark, evt, this, listeners[evt]);
            }
        }
        this.getMap().addOverlay(mark);

    },
    addMapControls : function(){
        
        if (this.gmapType === 'map') {
            if (Ext.isArray(this.mapControls)) {
                for(i=0;i<this.mapControls.length;i++){
                    this.addMapControl(this.mapControls[i]);
                }
            }else if(typeof this.mapControls === 'string'){
                this.addMapControl(this.mapControls);
            }else if(typeof this.mapControls === 'object'){
                this.getMap().addControl(this.mapControls);
            }
        }
        
    },
    addMapControl : function(mc){
        
        var mcf = window[mc];
        if (typeof mcf === 'function') {
            this.getMap().addControl(new mcf());
        }    
        
    },
    addOptions : function(){
        
        if (Ext.isArray(this.mapConfOpts)) {
            var mc;
            for(i=0;i<this.mapConfOpts.length;i++){
                this.addOption(this.mapConfOpts[i]);
            }
        }else if(typeof this.mapConfOpts === 'string'){
            this.addOption(this.mapConfOpts);
        }        
        
    },
    addOption : function(mc){
        
        var mcf = this.getMap()[mc];
        if (typeof mcf === 'function') {
            this.getMap()[mc]();
        }    
        
    },
    geoCodeLookup : function(addr) {
        
        this.geocoder = new GClientGeocoder();
        this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));
        
    },
    addAddressToMap : function(response) {
        
        if (!response || response.Status.code != 200) {
            Ext.MessageBox.alert('Error', 'Code '+response.Status.code+' Error Returned');
        }else{
            place = response.Placemark[0];
            addressinfo = place.AddressDetails;
            accuracy = addressinfo.Accuracy;
            if (accuracy === 0) {
                Ext.MessageBox.alert('Unable to Locate Address', 'Unable to Locate the Address you provided');
            }else{
                if (accuracy < 7) {
                    Ext.MessageBox.alert('Address Accuracy', 'The address provided has a low accuracy.<br><br>Level '+accuracy+' Accuracy (8 = Exact Match, 1 = Vague Match)');
                }else{
                    point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                    if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
                        this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true, this.setCenter.listeners);
                    }
                }
            }
        }
        
    }
 
});

Ext.reg('gmappanel',Ext.ux.GMapPanel); 