/**
 * This is the basic class needed to instanciate a mapping environment suitable
 * for BDN
 */

Carto = OpenLayers
		.Class( {
			base_url : null,
			wms_url : null,
			wfs_url : null,
			wfs_layer : null,
			legend_url : null,
			printUrl : null,
			map : null,
			toolbar : null,
			layertree : null,
			popup_timer : null,
			map_div : null,
			searcher: null,
			bb : null, // bounding box to zoom to on startup (if any)

			initialize : function(options) {
			
				OpenLayers.Util.extend(this, options);
				
				//
				// Définition de la map
				//

				var map_div_el = document.getElementById(this.map_div);
				if (!map_div_el) {
					map_div_el = document.createElement("div");
					var new_map_class = document.createAttribute("id");
					new_map_class.nodeValue = this.map_div;
					map_div_el.setAttributeNode(new_map_class);
					document.body.appendChild(map_div_el);
				}
				var map = new OpenLayers.Map(map_div_el, {
					units :'m',
					projection :proj,
					maxExtent :bounds,
					controls : [],
					resolutions :resolutions,
					tileSize :new OpenLayers.Size(500, 500),
					theme :null
				});

				// loading indicator ...
				map.addControl(new OpenLayers.Control.LoadingPanel(null, {
					map :map
				}));

				
				// Layer de base (fond blanc)
				var baseLayer = new OpenLayers.Layer("No baselayer",{isBaseLayer:true}); 
				map.addLayer(baseLayer);
				
				// Ajout des controls
				map.addControl(new OpenLayers.Control.PanZoomBar( {
					title :'PanZoomBar'
				}));

				// Affichage de la position du curseur
				map.addControl(new OpenLayers.Control.MousePosition( {
					prefix :'X: ',
					separator :' - Y: ',
					suffix :' m (L2e)',
					numDigits :0,
					title :'MousePosition'
				}));

				// Echelle
				map.addControl(new OpenLayers.Control.Scale(null, {
					title :'Scale'
				}));

				// Barre d'échelle
				map.addControl(new OpenLayers.Control.ScaleLine( {
					title :'ScaleLine'
				}));

				this.map = map;

				//
				// Légende
				//
				// Le modèle pour la légende est généré dynamiquement

				this.layertree = new Ifn.IfnLayerTree(
						{
							id :'layertree',
							title :'Couches',
							border :false,
							map :this.map,
							model :model,
							listeners : {
								'checkchange' : function(node, check) {
                                        if (check) {
                                            if (node.attributes.layerNames != undefined) {
                                                // On récupère le nom du layer 
                                                var layername = node.attributes.layerNames;
                                                layername = layername.toString().split(':')[0];
                                                
                                                // On récupère l'objet correspondant
                                                var layer = eval(layername);
                                                
                                                // On l'ajoute à la carte
                                                this.map.addLayer(layer);
                                                
                                                // Et on ajoute la légende si besoin
                                                if (layer.hasLegend) {
                                                    document.getElementById(node.attributes.layerNames).style.display = 'block';
                                                }
                                            }
                                        }
                                        else {
                                        
                                            if (node.attributes.layerNames != undefined) {
                                                // On récupère le nom du layer 
                                                var layername = node.attributes.layerNames;
                                                layername = layername.toString().split(':')[0];
                                                
                                                // On récupère l'objet correspondant
                                                var layer = eval(layername);
                                                
                                                // On le retire de la carte
                                                this.map.removeLayer(layer);
                                                
                                                // Et on masque la légende
                                                if (layer.hasLegend) {
                                                	document.getElementById(node.attributes.layerNames).style.display = 'none';
                                                }
                                            }
                                        }
                                        
                                    for(var nchild =0;nchild< node.childNodes.length; nchild++){
                                        this.layertree.fireEvent('checkchange',node.childNodes[nchild],check);
                                    }
                                    
								},
                                'remove':function(tree, parent, node){
                                    tree.fireEvent('checkchange',node,false);
                                },
								'append' : function(tree, parent, node, index ){
                                    tree.fireEvent('checkchange',node,node.isSelected());
								},
								scope :this
							}
						});

				// Déclenche la mise à jour du layertree lors d'un changement de zoom
				this.map.events
						.register(
								'zoomend',
								this.layertree,
								function() {
									var mapScale = Math.round(this.map
											.getScale());
									this
											.getRootNode()
											.cascade(
													function(node) {
														if ((node.attributes.minscale && mapScale < node.attributes.minscale)
																|| (node.attributes.maxscale && mapScale > node.attributes.maxscale)) {
															node.disable();
														} else {
															node.enable();
														}
													}, this);
								});


				this.toolbar = new mapfish.widgets.toolbar.Toolbar( {
					map :this.map,
					configurable :false
				});

				// this is to fix a pb in mapfish.widgets.toolbar.Toolbar
				// initComponent : autoheight = true, which should'nt be there.
				this.toolbar.autoHeight = false;
				this.toolbar.height = 25;

               // ajoute les légendes
                 var createLegend = function(node){
                         if (node.attributes.layerNames !== undefined) {//leaf
                            var longueur = node.attributes.layerNames;
                            var textediv = node.text;
                            var tabsplit = longueur.toString().split(':');
                            var layerName = tabsplit[0];              
                            
                            layerName = layerName.toString().split(',')[0];
                            
                            var mapservLayerName = tabsplit[1].toString().split(',')[0];
                            
                            var layer = eval(layerName);
                            
                            if (layer.hasLegend) {                            
	                            var div = OpenLayers.Util.createDiv(    longueur,
	                                                                    null, 
	                                                                    null, 
	                                                                    null, 
	                                                                    null, 
	                                                                    null
	                                                                );
	                            var imgdiv = OpenLayers.Util.createImage(   longueur, 
	                                                                        null, 
	                                                                        null, 
	                                                                        mapfish.Util
	                                                                        .getIconUrl(this.legend_url, {
	                                                                            layer :mapservLayerName,
	                                                                            format :'image/png'
	                                                                        }), 
	                                                                        null, 
	                                                                        null, 
	                                                                        null, 
	                                                                        null
	                                                                    );
	                            
	                            div.style.position = 'static';
	                            div.innerHTML = '<span class="legendText">'+textediv + '</span><br/>';                   
	                            div.appendChild(imgdiv);
	                            
	                            if(node.attributes && node.attributes.checked && layer.hasLegend) {
	                                div.style.display = 'block';
	                            } else {
	                                div.style.display = 'none';
	                            }
	                            
	                            document.getElementById('tabLegend').appendChild(div);
                            }
                            
                         } 
                    };
                    
                //lance pour chaque noeud la func (parcours tout l'arbre à partir de la racine)
                this.layertree.root.cascade(createLegend,this);
                
                // Chargement des layers
                Ext.each(this.layertree.getChecked(),
                    function(node){
                        node.getOwnerTree().fireEvent('checkchange', node, true);
                    },
                    this.layertree
                );
				
                
                //
                // Interrogation attributaire 
                //
				var protocol = mapfish.Protocol.decorateProtocol({
		            protocol: new OpenLayers.Protocol.WFS({
		                url: this.wfs_url,
		                typename: this.wfs_layer
		            }),
		            TriggerEventDecorator: null
		        });

		        this.searcher = new mapfish.Searcher.Map({
		            mode: mapfish.Searcher.Map.BOX,
		            protocol: protocol ,
		            displayDefaultPopup: true,
		            displayPopup: this.displayPopup,
		            searchTolerance:1
		        });

		        map.addControl(this.searcher);
                
		        //
                // add the LayerSwitcher
		        //
                layerSwitcher = new OpenLayers.Control.IfnLayerSwitcher();
                layerSwitcher.ascending = false;
                map.addControl(layerSwitcher);


			},
			
			
			// Fonction d'affichage des infos attributaires
			displayPopup: function (response) {
				
				var html = response.features;
				
				if (html!="") {			
				 	var popup = new OpenLayers.Popup.FramedCloud(
			                "mapfish_popup",    // popup id
			                this.popupLonLat,   // OpenLayers.LonLat object
			                null,               // popup is autosized
			                html,           // html string
			                null,               // no anchor
			                true                // close button
			            );
			            this.map.addPopup(popup, true);
				}
		    },


			
			// Initialisation de la toolbar
			initToolbarContent : function() {
				this.toolbar.addControl(new OpenLayers.Control.ZoomToMaxExtent(
						{
							map :this.map,
							title :'Etendue maximale de la carte'
						}), {
					iconCls :'zoomfull'
				});

				this.toolbar.addMySeparator();

				this.toolbar.addControl(new OpenLayers.Control.ZoomBox( {
					title :'Zoom en avant par clic simple ou par boîte'
				}), {
					iconCls :'zoomin'
				});

				this.toolbar.addControl(new OpenLayers.Control.ZoomBox( {
					out :true,
					title :'Zoom en arrière par clic simple ou par boîte'
				}), {
					iconCls :'zoomout'
				});

				this.toolbar.addControl(new OpenLayers.Control.Navigation( {
					isDefault :true,
					title :'Déplacement intuitif de la carte avec la souris'
				}), {
					iconCls :'pan'
				});

				this.toolbar.addMySeparator();

				// Navigation history : back and next.
				var nav = new OpenLayers.Control.NavigationHistory( {});
				this.map.addControl(nav);
				nav.activate();

				var buttonPrevious = new Ext.Toolbar.Button( {
					iconCls :'back',
					tooltip :'Vue précédente',
					disabled :true,
					handler :nav.previous.trigger
				});

				var buttonNext = new Ext.Toolbar.Button( {
					iconCls :'next',
					tooltip :'Vue suivante',
					disabled :true,
					handler :nav.next.trigger
				});

				this.toolbar.add(buttonPrevious);
				this.toolbar.add(buttonNext);

				nav.previous.events.register("activate", buttonPrevious,
						function() {
							this.setDisabled(false);
						});

				nav.previous.events.register("deactivate", buttonPrevious,
						function() {
							this.setDisabled(true);
						});

				nav.next.events.register("activate", buttonNext, function() {
					this.setDisabled(false);
				});

				nav.next.events.register("deactivate", buttonNext, function() {
					this.setDisabled(true);
				});

				this.toolbar.addMySeparator();

				this.toolbar
						.add( {
							iconCls :'layerinfobutton',
							tooltip :'Description générale des données cartographiques',
							handler : function() {
								w = 600;
								h = 800;
								pop = window
										.open(
												description_URL,
												'pop',
												'dependent=yes, height='
														+ h
														+ ',width='
														+ w
														+ ',status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=yes');
								pop.focus();
							}
						});
				
				if (site != 'france') {
					this.toolbar
					.add( {
						iconCls :'layerinfobuttondep',
						tooltip :'Fiche d\'information départementale',
						handler : function() {
							w = 600;
							h = 800;
							pop = window
									.open(
											description_dep_URL,
											'pop',
											'dependent=yes, height='
													+ h
													+ ',width='
													+ w
													+ ',status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=yes');
							pop.focus();
						}
					});
				}

				this.toolbar.addMySeparator();

				if (site == 'france') {
					// Combobox de sélection des départements
					// asynchrone !!!!
					function departementComboSelect(record) {
						var cmb = Ext.getCmp('depcombo');
						cmb.collapse();
						cmb.setValue(record.data.nom);
						this.map.zoomToBB(record.data.extent);
					}

					var comboArea = new Ext.form.ComboBox( {
						id :'depcombo',
						store :departementsStore,
						displayField :'libelle',
						typeAhead :true,
						mode :'local',
						triggerAction :'all',
						emptyText :'Sélectionner un département',
						selectOnFocus :true,
						width :170,
						onSelect :departementComboSelect.createDelegate(this)
					});

					this.toolbar.addField(comboArea);

					this.toolbar.addMySeparator();

				} else {

					// Combobox de sélection des communes

					function communeComboSelect(record) {
						var cmb = Ext.getCmp('communescombo');
						cmb.collapse();
						cmb.setValue(record.data.nom);
						this.map.zoomToBB(record.data.extent);
					}

					var comboArea = new Ext.form.ComboBox( {
						id :'communescombo',
						store :communesStore,
						displayField :'libelle',
						typeAhead :true,
						mode :'local',
						triggerAction :'all',
						emptyText :'Sélectionner une commune',
						selectOnFocus :true,
						width :170,
						onSelect :communeComboSelect.createDelegate(this)
					});

					this.toolbar.addField(comboArea);

					this.toolbar.addMySeparator();

				}

				var measureOptions = {
					handlerOptions : {
						style :"default",
						persist :true
					}
				}
				var lineMeasure = new OpenLayers.Control.Measure(
						OpenLayers.Handler.Path, measureOptions);
				var polygonMeasure = new OpenLayers.Control.Measure(
						OpenLayers.Handler.Polygon, measureOptions);

				lineMeasure.events.on( {
					"measure" :handleDistanceMeasurements,
					"measurepartial" :handleDistanceMeasurements
				});
				polygonMeasure.events.on( {
					"measure" :handleAreaMeasurements,
					"measurepartial" :handleAreaMeasurements
				});

				function handleAreaMeasurements(event) {
					var units = event.units;
					var measure = event.measure;
					var element = document.getElementById('measureOutput');
					var out = "";
					out += "Surface: " + measure.toFixed(3) + " " + units
							+ "<sup>2</sup>";
					element.innerHTML = out;
				}
				function handleDistanceMeasurements(event) {
					var units = event.units;
					var measure = event.measure;
					var element = document.getElementById('measureOutput');
					var out = "";
					out += "Distance: " + measure.toFixed(3) + " " + units;
					element.innerHTML = out;
				}

				this.toolbar.addControl(lineMeasure, {
					iconCls :'measuredistance',
					tooltip :'Mesure de distances'
				});
				this.toolbar.addControl(polygonMeasure, {
					iconCls :'measurearea',
					tooltip :'Mesure de surfaces'
				});
				
				// L'interrogation attributaire
				if (site != 'france') {
					this.toolbar.addControl(this.searcher, {
			            iconCls: 'searcher',
			            tooltip: 'Interrogation attributaire des types forestiers départementaux'
			        });
				}
				
				// Ajout d'un filler
				this.toolbar.add({xtype: 'tbfill'});
				
				// Ajout du lien mailto
				this.toolbar.add({xtype: 'tbtext', text: '<a href="'+this.base_url+'pdf/manuel.pdf" target="aide">Aide</a>'});
				

				this.toolbar.activate();

				// initial map positioning must come here :
				// (map now has its definite size)
				this.map.zoomToMaxExtent();				
				this.map.moveTo(new OpenLayers.LonLat(this.x_center,this.y_center),this.zoom_level, null);
				

			},

			setMapTitle : function(string) {
				// FIXME: other panel or map status bar ...
				// Ext.getCmp('center-panel').setTitle(string);
			}
		});