// Nivells d'usuari
var LEVEL_CONVIDAT=0;
var LEVEL_USUARI=1;  
var LEVEL_PUBLICADOR=2;
var LEVEL_ADMINISTRADOR=3;


/**
*	Inicialització del mapa a partir de la configuració del legend.xml
*/
function loadMap() {
	try{
		initProj4js();

		var hasWfs=false;
		
		OpenLayers.ImgPath="img/";

		// aquí es pot definir una acció quan hi ha un error carregant una imatge/tile
		OpenLayers.Util.onImageLoadError = function() {
			//alert("Error carregant imatge...");
			this.src = "img/blanc.gif";
			this.style.display = "";
		};

		if (typeof(proxyUrl)!="undefined") OpenLayers.ProxyHost=proxyUrl;//utilitzat en peticions wfs. Definit al config.js

		// definim mapa i apliquen configuracions del legend
		var mapConfig ={
						controls:[]
						,units: "m" // valors per defecte. Despres sobrecarreguem amb config del legend.
						,projection: new OpenLayers.Projection( treeContent.map_projection)
						,theme:null // per despres poder carregar estils propis CSS
						//,displayProjection: new OpenLayers.Projection("EPSG:4326")

						/*,maxExtent: new OpenLayers.Bounds(257000, 4485000, 532000, 4750000)
						,resolutions: new Array(529.167725002117,264.583862501058,132.291931250529,66.1459656252646)
						,tileSize : new OpenLayers.Size(256,256)*/

						}

		map = new OpenLayers.Map( 'map' , mapConfig);

		OpenLayers.DOTS_PER_INCH = 96; // important: ajustar-ho al mateix valor que el servidor per tenir les escales correctes

		setMapConfig(treeContent,map);
		setMapLayers(treeContent,map);
		setMapIdentify(treeContent,map);
		setMapControls(treeContent,map);
		setMeasureControl(map);

		initMap();
	}
	catch (e){
		alert("Error a loadMap()\n"+e.message);
	}
}

/**
* inicialitza el mapa: extensió inicial, bubble, ...
*/
function initMap() {
	try{
		// agafem els valors de la url
		var p= new UrlParser(window.location.href);
		var names=p.getNameArray();
		var values=p.getValueArray();

		var urlExtent=null;
		var urlCenter=null;
		var urlScale=null;
		var urlText=null;
		var urlRC=null;
		var urlDataset=null; var urlFilter=null;
		var urlLon=null; var urlLat=null; var urlZoom=null;
		
		// tractem els paràmetres de la url
		for (var i=0; i<p.getMaxVars(); i++) {
			if (names[i].toLowerCase()=="extent") {
				urlExtent=OpenLayers.Bounds.fromString(values[i]);
			}else if (names[i].toLowerCase()=="scale") {
				try{
					urlScale=parseFloat(values[i]);
				} catch (e){
					urlScale=null;
				}
			}else if (names[i].toLowerCase()=="center") {
				try{
					var aux=values[i].split(",");
					var x=parseFloat(aux[0]);
					var y=parseFloat(aux[1]);
					urlCenter=new OpenLayers.LonLat(x,y);
				} catch (e){
					urlCenter=null;
				}
			}else if (names[i].toLowerCase()=="rc") {
				urlRC=values[i];
			}else if (names[i].toLowerCase()=="text") {
				urlText=values[i];
			}else if (names[i].toLowerCase()=="dataset") {
				urlDataset=values[i];
			}else if (names[i].toLowerCase()=="filter") {
				urlFilter=values[i];
			}else if (names[i].toLowerCase()=="lon") {
				urlLon=values[i];
			}else if (names[i].toLowerCase()=="lat") {
				urlLat=values[i];
			}else if (names[i].toLowerCase()=="zoom") {
				urlZoom=values[i];
			}
		}

		// decidim on centrem.
		if (urlExtent!==null){
			map.zoomToExtent(urlExtent,true);
		} else if (urlCenter!==null){
			// podem tenir centre i escala o només centre
			if (urlScale!==null) map.setCenter(urlCenter,map.getZoomForResolution(OpenLayers.Util.getResolutionFromScale(urlScale,'m'),true));
			else map.setCenter(urlCenter);

		} else if (urlRC!==null){// referencia cadastral
			var q=new OpenLayers.NGCatastroWS({'map':map});
			q.queryRC(urlRC);

		} else if (urlDataset!==null && urlFilter!==null){// filtrar directament sobre dataset
			//alert("urlDataset: "+urlDataset+" urlFilter: "+urlFilter);
			map.zoomToMaxExtent();
			zoomToFilterCQL(urlSearchWfs,"topp:"+urlDataset.toUpperCase(),urlDataset.toUpperCase(),unescape(urlFilter));

		} else if (urlLon!==null && urlLat!==null && urlZoom!==null){// quan venim d'un permalink no hem de fer res, l'OL ja centrarà.
		
		} else if (treeContent.conf_xmin!=null && treeContent.conf_ymin!=null && treeContent.conf_xmax!=null && treeContent.conf_ymax!=null && // si han definit l'extensio al legend tag <persona> l'utilitzem per centrar.
				treeContent.conf_xmin!="" && treeContent.conf_ymin!="" && treeContent.conf_xmax!="" && treeContent.conf_ymax!="") {
			var bounds=new OpenLayers.Bounds(treeContent.conf_xmin,treeContent.conf_ymin,treeContent.conf_xmax,treeContent.conf_ymax);
			map.zoomToExtent(bounds,false); // param2: Find the zoom level that most closely fits the specified bounds.  Note that this may result in a zoom that does not exactly contain the entire extent		

		} else {
			map.zoomToMaxExtent();

		}

		// mostrem popup/bubble
		if (urlText!==null){
			var pp=new OpenLayers.NGPopups({'map':map});
			pp.addPopup(map.getCenter(),urlText);
		}

		
	}
	catch (e){
		alert("Error a initMap()"+e.message);
		map.zoomToMaxExtent();
	}
}



/**
* Configuració de projeccions, extensions, escales, resolucions
*/
function setMapConfig(treeContent,map) {
	if (treeContent.map_projection!=null && treeContent.map_projection.length>0){
		map.projection=treeContent.map_projection;
	}
	if (treeContent.map_projection_units!=null && treeContent.map_projection_units.length>0){
		map.units=treeContent.map_projection_units;
	}
	if (treeContent.map_tilesize_x!=null && treeContent.map_tilesize_y!=null){
		map.tileSize=new OpenLayers.Size(treeContent.map_tilesize_x,treeContent.map_tilesize_y);
	}
	if (treeContent.map_maxExtent_xmin!=null && treeContent.map_maxExtent_ymin!=null && treeContent.map_maxExtent_xmax!=null && treeContent.map_maxExtent_ymax!=null){
		var b=new OpenLayers.Bounds(treeContent.map_maxExtent_xmin,treeContent.map_maxExtent_ymin,treeContent.map_maxExtent_xmax,treeContent.map_maxExtent_ymax);
		map.maxExtent=b;
	}
	if (treeContent.map_restrictedExtent_xmin!=null && treeContent.map_restrictedExtent_ymin!=null && treeContent.map_restrictedExtent_xmax!=null && treeContent.map_restrictedExtent_ymax!=null){
		var b=new OpenLayers.Bounds(treeContent.map_restrictedExtent_xmin,treeContent.map_restrictedExtent_ymin,treeContent.map_restrictedExtent_xmax,treeContent.map_restrictedExtent_ymax);
		map.restrictedExtent=b;
	}
	if (treeContent.map_scalesArray!=null && treeContent.map_scalesArray.length>0){
		var resArray=new Array(treeContent.map_scalesArray.length);
		for(var nesc=0;nesc<resArray.length;nesc++){
			resArray[nesc]=OpenLayers.Util.getResolutionFromScale(treeContent.map_scalesArray[nesc],map.units);
		}
		map.resolutions=resArray;
	} else if (treeContent.map_maxScale!=null && treeContent.map_minScale!=null){
		map.maxResolution=OpenLayers.Util.getResolutionFromScale(treeContent.map_maxScale,map.units);
		map.minResolution=OpenLayers.Util.getResolutionFromScale(treeContent.map_minScale,map.units);
	}
}

/**
* configuració dels layers de l'OL
*/
function setMapLayers(treeContent,map) {
	// recorrem services del legend per anar definint layers de l'OL.
	var numberOfLayers=treeContent.getServiceCount();

	// posem sempre un layer buit.
	var base = new OpenLayers.Layer("dummy",{isBaseLayer: true});
	map.addLayer(base);

	for (var i=0; i<numberOfLayers; i++) {
		var service=treeContent.services[i];

		if (service.type=="wms") {
			var wmsLayers=treeContent.getVisibleLayersNames(service.id);
			var wmsparams={
					service: "WMS",
					layers: wmsLayers, 
					version: "1.1.1",
					request: "GetMap", 
					styles: "",
					exceptions: null,
					format: treeContent.getBestFormat(service.id),
					transparent: (service.url_transparent!=null && service.url_transparent.toLowerCase()==="true") // ull: quan transparent =true pot canviar el format per passar de jpeg a gif o png.
					//,userid: unescape(userId)
			};
			if (typeof(userId)!="undefined") wmsparams.userid=unescape(userId);
			if (service.url_bgcolor!=null) wmsparams.bgcolor=service.url_bgcolor;
			var layer = new OpenLayers.Layer.WMS(
					service.id,
					service.urlArray,
					wmsparams,{
						isBaseLayer: treeContent.map_baseServices.contains(service.id),
						buffer:0,
						gutter:0,
						visibility: wmsLayers.length>0,
						singleTile: !service.tiled,
						ratio:1 // si ratio = 1.2 catastro a escala 1000000 no es correspon amb versió impresa.
					}
			);
			
			if (
				 treeContent.map_baseServices.length===0// si no tenim cap servei definit com a base, els posem tots amb l'efecte de resize pq no ens desapareixi al fen un pan
				 || treeContent.map_baseServices.contains(service.id)// transició resize només els baselayers
				) layer.transitionEffect="resize";
			else layer.transitionEffect="";

			if (service.transparency) layer.setOpacity(parseFloat(100-service.transparency)/100);
			//layer.visibility=service.type!="info";
			map.addLayer(layer);
		
		} else if (service.type=="ags92") {

			var imageExtension=treeContent.getLayerValueByAttributeValue(service.id,"format" ,"#","visible","1");
			if (imageExtension.indexOf("#")>-1) {
				alert("Error a la llegenda: El service amb id='"+service.id+"' te definits layers amb diferents formats d'imatge. S'utilitzarà el primer trobat.");
				imageExtension=imageExtension.substr(0,imageExtension.indexOf("#"));
			}

			var params={
				isBaseLayer: treeContent.map_baseServices.contains(service.id),
				layername: '_alllayers', //TODO: posar el nom del layer?
				type: imageExtension,
				tileOrigin: new OpenLayers.LonLat(treeContent.map_tileOrigin_x,treeContent.map_tileOrigin_y),
				projection: new OpenLayers.Projection(treeContent.map_projection),
				tsize: treeContent.map_tilesize_y,
				ymin: map.maxExtent.bottom
				,maxExtent: map.maxExtent.clone()
			};
			var layer = new OpenLayers.Layer.AGS( 
					service.id, 
					service.urlArray, 
					params
			);
			map.addLayer(layer);

		} else if (service.type=="wfs") {
			var wfsArray = treeContent.getWFSConfigArray(service.id);

			// Capes WFS
			for (var j=0; j<wfsArray.length; j++){
				var wfsLayerID = wfsArray[j].pop();
				var wfsLayerImageWidth = wfsArray[j].pop();
				var wfsLayerImageHeight = wfsArray[j].pop();
				var wfsLayerImagePath = wfsArray[j].pop();

				// Definim l'estil
				var layerStyle = OpenLayers.Util.applyDefaults({
					externalGraphic: wfsLayerImagePath,
					graphicWidth: wfsLayerImageWidth,
					graphicHeight: wfsLayerImageHeight,
					graphicYOffset: 0,
					graphicOpacity: 1
				}, OpenLayers.Feature.Vector.style['default']);

				var layer = new OpenLayers.Layer.WFS( 
						wfsLayerID,
		                service.url,
		                {typename: wfsLayerID,maxfeatures: 200},{style: layerStyle }
					); 
				map.addLayer(layer);

				// Si la capa no està activa no la mostrem 
				if (!treeContent.isLayerVisible(treeContent.getVisibleLayersNames(service.id), wfsLayerID)){
					layer.setVisibility(false);
				}
			}
		}	
	}// for
}

/**
* Configuració de l'identify.
*/
function setMapIdentify(treeContent,map) {
	if (treeContent.map_controls_identifyButtonsArray.length >1) alert("LLegenda: Només està suportat un sol boto d'identify.\nRevisa el node <identifyButtons>");

	for (var i=0;i<treeContent.map_controls_identifyButtonsArray.length ;i++ ){		
		var button=treeContent.map_controls_identifyButtonsArray[i];

		var identifyConfig= {
			usercontrol:	button.usercontrol,
			target:			button.target,
			targetdivid:	button.targetdivid,
			service:		button.service,
			treeContent:	treeContent,
			infoFormat:		"gml",
			exceptions:		"application/vnd.ogc.se_xml"
			//,radius: 7
			,featureCount: 99
		};
		
		map.identifyConfig=identifyConfig;

	}//for
	

	/**
	*	Crea la configuració per fer una petició de identify.
	*/
	/*map.getIdentifyObject = function () {
	
		var identifyParams=new Object();
		// camps per la petició wms
		identifyParams.infoFormat="text/plain";
		//identifyParams.infoFormat="gml";
		identifyParams.exceptions="application/vnd.ogc.se_xml";
		identifyParams.queryLayers=null;

		identifyParams.targetAction="window";

		// capa de l'OL sobre la que fem info. Necessari per muntar url de petició.
		identifyParams.layerObj=null;

		// camps de configuració del popup.
		identifyParams.popupBgcolor="#ffffff";
		identifyParams.popupOpacity=0.8;
		identifyParams.popupBorder="2px solid black";

		// definim l'acció a realitzar al rebre la resposta d'info.
//		identifyParams.targetFunction=null; // mostrarà la info a un popup.
		identifyParams.targetFunction=processIdentifyTOCResponse; // cridarà la funció
		
		if (typeof(treeContent.serviceInfo)=="undefined") {
			// exemple on fem info al service d'esplugues pois amb els elements triats.
			identifyParams.queryLayers=treeContent.getVisibleLayersNames("ESPLUGUES_POIS");
			identifyParams.layerObj=this.getLayersByName("ESPLUGUES_POIS")[0];
		} else {
			
			// CAS DE SALUT		
			identifyParams.targetAction="popup";
			identifyParams.infoFormat="gml";
			identifyParams.popupSize=new OpenLayers.Size(300,250);
			identifyParams.layerObj=this.getLayersByName(treeContent.serviceInfo.id)[0];
			identifyParams.queryLayers=treeContent.getVisibleLayersNames(null,","); // TODO: falta muntar el dd amb els layers queryables a escollir per fer info.
		}
		
		return identifyParams;
		
	}*/
}

/**
* configuració dels controls del mapa: barra canvi d'escala, mostrar coordenades del punt, escalimetre, mapa overview, botons canvi cartografia tipus google,...
*/
function setMapControls(treeContent,map) {

	// definim els elements de la nostra barra d'eines.
	var pan = new OpenLayers.Control.DragPan({title: getLangDescription("pan"), 
															id: "drag",
															displayClass: "olControlPan"});

	var mouseDefaults=new OpenLayers.Control.MouseDefaults(
															{title:'per utilitzar els controls per defecte. scroller, .. Als css ocultem aquest boto'});

	var zoomIn = new OpenLayers.Control.ZoomBox(
															{title:"Apropar",displayClass: "olControlZoomBoxIn"});
	
	var zoomOut = new OpenLayers.Control.ZoomBox(
															{out:true,title:"Allunyar-se",displayClass: "olControlZoomBoxOut"});

	var ngInfo = new OpenLayers.Control.NGIdentify({title: getLangDescription("info"), 
															windowWidth:500,
															windowHeight:500,
														    displayClass: "olControlIdentify"});

	var ngMeasure = new OpenLayers.Control.Button({			displayClass: "olControlMeasure",
															type: OpenLayers.Control.TYPE_TOOL,
															title: "Mesurar distància"
															});
	ngMeasure.events.register("activate",ngMeasure, function() {
															if (this.map) map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure")[0].activate();
	});
	ngMeasure.events.register("deactivate",ngMeasure, function() {
															if (this.map) {
																if (map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure").length>0) {
																	map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure")[0].deactivate();
																	var control=map.getControlsBy("CLASS_NAME","OpenLayers.Control.NGMeasureInfo")[0];
																	control.hide();
																	if (map.getControlsBy("CLASS_NAME","OpenLayers.Control.Navigation")>0)
																		map.getControlsBy("CLASS_NAME","OpenLayers.Control.Navigation")[0].activate();// BUG? PQ TORNI A FUNCIONAR SCROLLER
																}
															}
	});
	var ngMeasureArea = new OpenLayers.Control.Button({		displayClass: "olControlMeasureArea",
															type: OpenLayers.Control.TYPE_TOOL,
															title: "Mesurar àrea"
															});
	ngMeasureArea.events.register("activate",ngMeasureArea, function() {
															if (this.map) map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure")[1].activate();
	});
	ngMeasureArea.events.register("deactivate",ngMeasureArea, function() {
															if (this.map) {
																if (map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure").length>0) 
																	map.getControlsBy("CLASS_NAME","OpenLayers.Control.Measure")[1].deactivate();
																var control=map.getControlsBy("CLASS_NAME","OpenLayers.Control.NGMeasureInfo")[0];
																control.hide();
																if (map.getControlsBy("CLASS_NAME","OpenLayers.Control.Navigation")>0)
																	map.getControlsBy("CLASS_NAME","OpenLayers.Control.Navigation")[0].activate();// BUG? PQ TORNI A FUNCIONAR SCROLLER
															} 
	});
	var ngEsborrar = new OpenLayers.Control.Button({		displayClass: "olControlEsborrar",
															title: "Ocultar popups",
															trigger: function() {
																if (this.map) {
																	layers=map.getLayersByName("Markers");
																	if (layers.length>0)
																	layers[0].destroy();
																	while (this.map.popups.length>0){
																		this.map.popups[0].destroy();
																	}
																}
															}
													});

	var ngMaximize = new OpenLayers.Control.Button({		displayClass: "olControlMaximize",
															title: "Maximitzar mapa",
															trigger: function() {
																	if (this.map) {
																		maximizeMap();
																	}
																}
															});

	var ngKmlButton = new OpenLayers.Control.Button({	displayClass: "olControlKML",
														title: "Descarregar KML",
														trigger: function() {
															if (this.map) {
																googleEarthClick();
															}
														}
													});

	var ngHelpButton = new OpenLayers.Control.Button({	displayClass: "olControlHelp",
														title: "Mostrar ajuda",
														trigger: function() {
															if (this.map) {
																viewHelp();
															}
														}
													});
	var ngLegendButton = new OpenLayers.Control.Button({	displayClass: "olControlLegend",
															title: "Mostrar llegenda",
															trigger: function() {
																if (this.map) {
																	openLegend();
																}
															}
														});

	var ngSendMailButton = new OpenLayers.Control.Button({	displayClass: "olControlSendMail",
														title: "Enviar per email",
														trigger: function() {
															if (this.map) {
																sendMail();
															}
														}
													});

	var panel = new OpenLayers.Control.Panel({defaultControl: pan,'div':OpenLayers.Util.getElement('toolbarDivOL')});
		panel.addControls([
				mouseDefaults, 
				zoomIn,
				zoomOut,
				pan,
				new OpenLayers.Control.ZoomToMaxExtent({title:"Extensió màxima",displayClass: "olControlMaxExtent"}),
				ngMeasure,
				ngInfo,
			//	ngEsborrar,
				ngSendMailButton,
				ngKmlButton,
				ngMaximize,
				ngLegendButton,
				ngHelpButton
		]);
	map.addControl(panel);

	// el control on mostrem la informació.
	map.addControl(new OpenLayers.Control.NGEmptyControl());
	
	// barra de canvi d'escala
	map.addControl(new OpenLayers.Control.PanZoomBar({"slideFactor":Math.round(map.getSize().h*0.8)}));

//	map.addControl(new OpenLayers.Control.LayerSwitcher());//visualització de les capes actives

//	map.addControl(new OpenLayers.Control.Permalink("permalinkOL"));

	var controlScale=new OpenLayers.Control.Scale();
	controlScale.updateScale= function() {
        var scale = this.map.getScale();
        if (!scale) {
            return;
        }
		/*
        if (scale >= 9500 && scale <= 950000) {
            scale = Math.round(scale / 1000) + "K";
        } else if (scale >= 950000) {
			var s=(Math.round(scale) / 1000000);
			if (s % 1 == 0){
				scale = Math.round(scale / 1000000) + "M";
			} else {
				scale = (scale / 1000000).toFixed(1) + "M";
			}
        } else {
            scale = Math.round(scale);
        }    */
		scale=Math.round(scale);

        this.element.innerHTML = "<font class='textBoldGray'>Escala:&nbsp;<input readonly value='"+scale+"' class='inputTextSmall' size='12'> </input></font>";
    }

	map.addControl(controlScale);

	// mostra les coordenades del punt
	if (treeContent.map_controls_coordinates_active) {
		var options={granurality:5};
		if (treeContent.map_controls_coordinates_epsg!=null) options.displayProjection= new OpenLayers.Projection("EPSG:"+treeContent.map_controls_coordinates_epsg);
		if (treeContent.map_controls_coordinates_prefix!=null) options.prefix= treeContent.map_controls_coordinates_prefix;
		if (treeContent.map_controls_coordinates_separator!=null) options.separator=treeContent.map_controls_coordinates_separator;
		if (treeContent.map_controls_coordinates_suffix!=null) options.suffix=treeContent.map_controls_coordinates_suffix;
		if (treeContent.map_controls_coordinates_numDigits!=null) options.numDigits=treeContent.map_controls_coordinates_numDigits;
		if (treeContent.map_controls_coordinates_tooltip!=null) options.title=treeContent.map_controls_coordinates_tooltip;

		mp=new OpenLayers.Control.MousePosition(options);

		// si hem de mostrar el decimal degrees, canviem funció per formatejar graus mins, segons.
		if (treeContent.map_controls_coordinates_epsg!=null) {
			if (treeContent.map_controls_coordinates_epsg=="4326") {
				mp.formatCoords= function (base) {
					var t, t2;
					var degrees = Math.floor(base);
					var minutes = Math.floor(t = ( base - degrees ) * 60);
					var seconds = Math.floor(t2 = ( t - minutes ) * 3600);
					seconds = seconds / 100.00;
					return "" + degrees + "\u00B0 " + minutes + "\u0027 " + seconds + "\u0022";
				};
				mp.formatOutput= function(lonLat) {
					newHtml =  this.prefix + 
					this.formatCoords(lonLat.lon)  +
					this.separator +
					this.formatCoords(lonLat.lat) +
					this.suffix;
					return newHtml;
				};
			} else {
				mp.formatOutput= function(lonLat) {
					//return "<font class='textBoldGray'>ETRS89 FUS 31N&nbsp;X:&nbsp;<input type='text' value='"+lonLat.lon.toFixed(0)+"' readonly class='inputTextSmall' name='impcoordX' size='10'/>m&nbsp;&nbsp;Y:&nbsp;<input class='inputTextSmall' readonly  value='"+lonLat.lat.toFixed(0)+"' type='text' name='impcoordY' size='10'/>m</font></div>";
					newHtml = "<font class='textBoldGray'>" +
					this.prefix + 
					"<input type='text' value='" +
						lonLat.lon.toFixed(0) +
						"' readonly class='inputTextSmall' name='impcoordX' size='10'/>" +
					this.separator +
					"<input type='text' value='" +
						lonLat.lat.toFixed(0) +
						"' readonly class='inputTextSmall' name='impcoordY' size='10'/>" +
					this.suffix +
					"</font>";
					return newHtml;
				};
			}
		}

		map.addControl(mp);
	}
	
	// escalimetre
	if (treeContent.map_controls_scalebar_active) map.addControl(new OpenLayers.Control.ScaleLine());

	// mapa de situacio/overview
	if (treeContent.map_controls_overview_active) {

		
		var mapOverviewOptions={
						minResolution: OpenLayers.Util.getResolutionFromScale(50000,map.units),// escala mínima que volen al mapa de situació
						maxResolution: OpenLayers.Util.getResolutionFromScale(8000000,map.units),
						maxExtent: map.maxExtent.clone(), 
						outsideViewport: true, 
						units: map.units, 
						projection: map.projection

			};
		// Create the overview map
		var overview = new OpenLayers.Control.OverviewMap({
			mapOptions: mapOverviewOptions,
			size: new OpenLayers.Size(150,110), 
			minRatio:16,
			maxRatio:64
		});

		
		// el layer wms
		if (typeof(treeContent.map_controls_overview_service)!="undefined" && treeContent.map_controls_overview_service!=null){
			var overviewLayer = new OpenLayers.Layer.WMS(
					"overviewLayer",
					treeContent.getServiceById(treeContent.map_controls_overview_service).url,
					{
						service: "WMS",
						layers: treeContent.map_controls_overview_layers, 
						version: "1.1.1",
						request: "GetMap", 
						styles: "",
						exceptions: null,
						format: treeContent.map_controls_overview_format,
						transparent: false
					},{
						singleTile: true
					}
			);
			overview.layers=[overviewLayer];
		} else if (typeof(treeContent.map_controls_overview_imageSource)!="undefined" && treeContent.map_controls_overview_imageSource!=null){
			// mapa estàtic
			var graphic = new OpenLayers.Layer.Image(
									'overview static image',
									treeContent.map_controls_overview_imageSource,
									new OpenLayers.Bounds(treeContent.map_controls_overview_xmin,treeContent.map_controls_overview_ymin,treeContent.map_controls_overview_xmax,treeContent.map_controls_overview_ymax),
									new OpenLayers.Size(126, 126),
									{numZoomLevels: 1}
			);
			overview.layers=[graphic];
		}
		
		// Adds the overview map to the map
		map.addControl(overview);
		if (treeContent.map_controls_overview_open) overview.maximizeControl(); 

		// Recenter on move end
		map.events.register("moveend",overview,overview.updateOverview);
	}

	// definim el botons tipus google
	if (treeContent.map_controls_baseButtonsArray.length>0) {
		var buttonsArray=new Array(treeContent.map_controls_baseButtonsArray.length);

		for (var i=0;i<treeContent.map_controls_baseButtonsArray.length;i++ ){
			var b=treeContent.map_controls_baseButtonsArray[i];
			var button= {
				text: b.title,
				title: b.desc,
				layers: map.getLayersByName(b.service)
			};
			buttonsArray[i]=button;

		}
		
		bSwitcher = new OpenLayers.Control.NGButtonSwitcher({
			buttons: buttonsArray,
			allowUnseleted: true,
			dummyLayer: map.getLayersByName("dummy")[0]
		});
		map.addControl(bSwitcher);
	}
	
}

/**
*	petició per demanar els configurl dels serveis i redefinir el mapa.
*/
function reloadServicesConfigUrl() {
	try{
		DebugOut("reloadServicesConfigUrl()",DEBUG);
		// guardem extensió actual. modifiquem els valors de l'arbre i ja hi centrarà
		var ext=map.getExtent();
		treeContent.conf_xmin=ext.left;
		treeContent.conf_ymin=ext.bottom;
		treeContent.conf_xmax=ext.right;
		treeContent.conf_ymax=ext.top;

		map.destroy();

		treeContent.queryConfigUrls();
	}
	catch (e){
		alert("Error a reloadServicesConfigUrl()\n"+e.message);
	}
}

/**
*	Configura els sistemes de referencia que utilitzarem
*/
function initProj4js() {
	// mercator
	Proj4js.defs["EPSG:54004"] = "+title=world mercator EPSG:54004 +proj=merc +lat_ts=0 +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs";

	// ed50 / UTM
	Proj4js.defs["EPSG:23029"] = "+title=ED50 / UTM zone 29N  +proj=utm +zone=29 +ellps=intl +units=m +no_defs";
	Proj4js.defs["EPSG:23030"] = "+title=ED50 / UTM zone 30N  +proj=utm +zone=30 +ellps=intl +units=m +no_defs";
	Proj4js.defs["EPSG:23031"] = "+title=ED50 / UTM zone 31N  +proj=utm +zone=31 +ellps=intl +units=m +no_defs";
	Proj4js.defs["EPSG:23032"] = "+title=ED50 / UTM zone 32N  +proj=utm +zone=32 +ellps=intl +units=m +no_defs";
	
	// ETRS89 / UTM
	Proj4js.defs["EPSG:25829"] = "+proj=utm +zone=29 +ellps=GRS80 +units=m +no_defs";
	Proj4js.defs["EPSG:25830"] = "+proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs";
	Proj4js.defs["EPSG:25831"] = "+proj=utm +zone=31 +ellps=GRS80 +units=m +no_defs";
	Proj4js.defs["EPSG:25832"] = "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs";

	// WGS84 / UTM
	Proj4js.defs["EPSG:32629"] = "+proj=utm +zone=29 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
	Proj4js.defs["EPSG:32630"] = "+proj=utm +zone=30 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
	Proj4js.defs["EPSG:32631"] = "+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
	Proj4js.defs["EPSG:32632"] = "+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";

	// geografiques
	Proj4js.defs["EPSG:4326"] = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ";// wgs84
	Proj4js.defs["EPSG:4230"] = "+proj=longlat +ellps=intl +no_defs";// ed50
	Proj4js.defs["EPSG:4258"] = "+proj=longlat +ellps=GRS80 +no_defs";// etrs89
}

// Precarga de les imatges del document
var imgarray = new Array; 
var iptr = 0;

function PreLoadImg(isrc){
	imgarray[iptr] = new Image;
	imgarray[iptr].src = isrc;
	tr = iptr;
	iptr++;
	return tr;
}

// Precarrega les imatges. S'ha d'executar al body.OnLoad
function PreloadImages(){
	// eines
	var aux;
	aux = PreLoadImg("img/fletxa.gif");
	aux = PreLoadImg("img/bg_title.gif");
	aux = PreLoadImg("img/bg_title_o.gif");
	aux = PreLoadImg("img/treeview/checked_disabled.gif");
	aux = PreLoadImg("img/treeview/checked_mid.gif");
	aux = PreLoadImg("img/treeview/checked_off.gif");
	aux = PreLoadImg("img/treeview/checked_off_filtered.gif");
	aux = PreLoadImg("img/treeview/checked_off_filtrable.gif");
	aux = PreLoadImg("img/treeview/checked_on.gif");
	aux = PreLoadImg("img/treeview/checked_on_filtered.gif");
	aux = PreLoadImg("img/treeview/checked_on_filtrable.gif");
	aux = PreLoadImg("img/treeview/collapsed.gif");
	aux = PreLoadImg("img/treeview/edit_delete.gif");
	aux = PreLoadImg("img/treeview/edit_geometry.gif");
	aux = PreLoadImg("img/treeview/edit_values.gif");
	aux = PreLoadImg("img/treeview/edit_zoom.gif");
	aux = PreLoadImg("img/treeview/empty.gif");
	aux = PreLoadImg("img/treeview/expanded.gif");
	aux = PreLoadImg("img/treeview/folder.gif");
	aux = PreLoadImg("img/treeview/identify_empty.gif");
	aux = PreLoadImg("img/treeview/identify_off.gif");
	aux = PreLoadImg("img/treeview/identify_on.gif");
	aux = PreLoadImg("img/treeview/layer.gif");
	aux = PreLoadImg("img/treeview/layer_theme.gif");
	aux = PreLoadImg("img/treeview/line.gif");
	aux = PreLoadImg("img/treeview/menu_add.gif");
	aux = PreLoadImg("img/treeview/menu_config.gif");
	aux = PreLoadImg("img/treeview/menu_delete.gif");
	aux = PreLoadImg("img/treeview/menu_delete_.gif");
	aux = PreLoadImg("img/treeview/menu_down.gif");
	aux = PreLoadImg("img/treeview/menu_filter.gif");
	aux = PreLoadImg("img/treeview/menu_in.gif");
	aux = PreLoadImg("img/treeview/menu_out.gif");
	aux = PreLoadImg("img/treeview/menu_up.gif");
	aux = PreLoadImg("img/treeview/menu_zoom.gif");
	aux = PreLoadImg("img/treeview/point.gif");
	aux = PreLoadImg("img/treeview/polygon.gif");
	aux = PreLoadImg("img/treeview/range.gif");
	aux = PreLoadImg("img/select_box.png");
	aux = PreLoadImg("img/select_box_on.png");
	aux = PreLoadImg("img/select_clear.png");
	aux = PreLoadImg("img/select_clear_on.png");
	aux = PreLoadImg("img/select_geom.png");
	aux = PreLoadImg("img/select_geom_on.png");
	aux = PreLoadImg("img/select_point.png");
	aux = PreLoadImg("img/select_point_on.png");
	aux = PreLoadImg("img/separador.gif");

}
// Preload image buttons
PreloadImages();
/*
// Changes selected tool in map object
function changeTool(mapObj, tool) {
	map.clearPrintBboxExtent();
	DebugOut("changeTool: " + tool , DEBUG);
	if (tool=='zoomin') mapObj.setCurrentTool("ZOOMIN");
	else if (tool=='zoomout') mapObj.setCurrentTool("ZOOMOUT");
	else if (tool=='pan') mapObj.setCurrentTool("PAN");
	else if (tool=='identify') mapObj.setCurrentTool("IDENTIFY");
	changeImage(tool);
	try {
		document.getElementById("printPreviewCheckbox").checked=false;
	}
	catch (e) {}
}
*/
function mouseOver(imgId,imgName) {
	if (document.getElementById(imgId).src.indexOf("_p.gif")>0) return;
	document.getElementById(imgId).src="img/"+imgName+"_o.gif";
}

function mouseOut(imgId,imgName) {
	if (document.getElementById(imgId).src.indexOf("_p.gif")>0) return;
	document.getElementById(imgId).src="img/"+imgName+".gif";
}

// Copies current map image to clipboard
function copyToClipboard(map){
	DebugOut("copyToClipboard",DEBUG);

	var ddDiv = document.createElement("div");
	ddDiv.setAttribute("id", "copy2clipboardDiv");
	ddDiv.style.zIndex="9999";
	ddDiv.style.position="absolute";
	ddDiv.style.top="0px";
	ddDiv.style.left="0px";
	ddDiv.style.width="200px";
	ddDiv.style.height="200px";
	ddDiv.style.visibility="hidden";
	
	var url=map.getCurrentMapImageUrl();
	DebugOut("copyToClipboard URL: "+url,DEBUG);
	var str='<img id="copy2clipboardImg" src="'+url+'" onLoad="javascript:copyImageToClipBoard(this.id);" />';
	ddDiv.innerHTML =str;
	var bodyN=document.getElementsByTagName("body")[0];
	bodyN.appendChild(ddDiv);

}

// Copies this img id to clipboard: only IE
function copyImageToClipBoard(imgObjId){
	var oRng=document.body.createControlRange();
	oRng.addElement(document.getElementById(imgObjId));
	oRng.execCommand("Copy");

	alert(langArr.IMAGEN_COPIADA_CLIPBOARD);

	var bodyN=document.getElementsByTagName("body")[0];
	var nestedN=document.getElementById("copy2clipboardDiv");
	var throwaway_node = bodyN.removeChild(nestedN);
}


// Refreshes current map
function refresh(map) {
	DebugOut("mainFunctions :: refresh()",DEBUG);
	//setTimeout("map.centerAndZoom(map.getCenter(),map.getScale())",150);// workaround for IE. otherwise hangs.why?
	setTimeout("map.centerToExtent(map.getExtent())",150);// workaround for IE. otherwise hangs.why?
}

// Centers to the coords specified at the select control.
function centerToCoord(map,sel) {
	DebugOut("mainFunctions :: centerToCoord()",DEBUG);
	var coords =sel.options[sel.selectedIndex].value.split(",");
	map.centerAndZoom(new NPoint(coords[0],coords[1]),150000);
}

// Centers to the coords specified at hidden inputs. From WS searches
function zoomToSearch(){
	var x1=document.getElementById("zoomSearchX1").value;
	var y1=document.getElementById("zoomSearchY1").value;
	var x2=document.getElementById("zoomSearchX2").value;
	var y2=document.getElementById("zoomSearchY2").value;
	var searchText=document.getElementById("wsTextInput").value;

	if (x1=="" && y1=="") return;

	if (x2!="" && y2!="") {
		// zoom to box
		var x1v=parseFloat(x1);
		var y1v=parseFloat(y1);
		var x2v=parseFloat(x2);
		var y2v=parseFloat(y2);
		/*var difX=Math.abs(x2v-x1v)*0.02;
		var difY=Math.abs(y2v-y1v)*0.02;
		if (difX<difY) var dif=difX;
		else var dif=difY;*/

		var ext=new NExtent(new NPoint(x1v,y1v),new NPoint(x2v,y2v));
		map.pois.clear();
		var poi=new NPoi(ext.getCenter(),"img/poi.gif",20,20,"identifier",searchText,searchText);
		map.pois.add(poi);

		//DebugOut("zoomToSearch() 2: [" + (x1v) + "," + (y2v)+"] ["+ (x2v) + "," + (y2v) + "]",DEBUG);
		map.centerToExtent(ext);

	} else {
		// creem un poi
		map.pois.clear();
		var poi=new NPoi(new NPoint(x1,y1),"img/poi.gif",20,20,"identifier",searchText,searchText);
		map.pois.add(poi);

		// zoom to coords+scale
		map.centerAndZoom(new NPoint(x1,y1),25000);
	}
}

/**
*
*/
function soapServerChanged() {
	var obj=document.getElementById("wsTextInput");
	obj.value="";
}

/**
*
*/
function zoomToExtent(x0,y0,x1,y1) {
	var catExtent=new NExtent( new NPoint(parseFloat(x0),parseFloat(y0)) , new NPoint(parseFloat(x1),parseFloat(y1)) );
	map.centerToExtent(catExtent);
}

/**
*	to activate debug type "javascript: debugon();" at explorers url
*/
function debugon() {
	debugLevel=DEBUG;
	if (document.getElementById("debugoutput").style.display=="block") var d="none";
	else  var d="block";
	document.getElementById("debugoutput").style.display=d;
	document.getElementById("debugbutton").style.display=d;
	
}

/**
*	show tree with main page variables
*/
function debugtree() {
//	javascript:s=document.body.appendChild(document.createElement('script'));s.id='sst';s.language='javascript';void(s.src='library/js_tree/js_tree.js');
}

function addItems2Array(sourceList, targetArray) {
	var array1=sourceList.split("$");
	var targetArrayCount=targetArray.length;
	if (targetArrayCount>0)targetArrayCount++;

	for (var i=0;i<array1.length-1 ;i++ ){
		var array2=array1[i].split("#"); //name#title#desc
		var obj= {};
		obj["name"]=array2[0];
		obj["title"]=array2[1];
		obj["desc"]=array2[2];
		targetArray[targetArrayCount+i]=obj;
		//DebugOut(" >> " + targetArray[targetArrayCount+i]["name"] + "   " + targetArray[targetArrayCount+i]["title"] + "   " + targetArray[targetArrayCount+i]["desc"] , DEBUG);
	}
}

/**
*	Opens the dropdown to select the queryable layers
*/
/*function identifyDropdownShow(target) {

	var queryListVisible=treeContent.getQueryableLayersNames(true,1);
	var queryListNoVisible=treeContent.getQueryableLayersNames(true,2);
	
	var arrayVisible= new Array();
	var arrayNoVisible= new Array();

	addItems2Array(queryListVisible,arrayVisible);
	addItems2Array(queryListNoVisible,arrayNoVisible);

	function mysortfn(a,b) {
		try {
			var txt1=a["title"].replaceKnownCharacters().toUpperCase();
			var txt2=b["title"].replaceKnownCharacters().toUpperCase();
			if (txt1<txt2) return -1;
			if (txt1>txt2) return 1;
			return 0;
		}
		catch (e) {
			alert("Error a mysortfn()\n"+e.message);
		}
	}
	arrayVisible.sort(mysortfn);
	arrayNoVisible.sort(mysortfn);

	var ddContent=new CDropdownContent();

	for (var i=0;i<arrayVisible.length ;i++ ){
		ddContent.addItem(arrayVisible[i]["name"],arrayVisible[i]["title"],arrayVisible[i]["desc"]);
	}
	
	ddContent.addSeparator();

	for (var i=0;i<arrayNoVisible.length ;i++ ){
		ddContent.addItem(arrayNoVisible[i]["name"],arrayNoVisible[i]["title"],arrayNoVisible[i]["desc"]);
	}

	var dd = new CDropdown(target,ddContent,260);
	dd.processFunction= function(code,text,title) {
		try {
			var textObj=document.getElementById("identifyLayersText"); // la 1a petició en IE dona error, fet un catch + repetir ja funciona. raro raro raro...
			identifyClick();// activem eina identify
			configurarIdentify(code);
			textObj.firstChild.nodeValue=text;
		}
		catch (e) {
			//alert("al catch");
			var textObj=document.getElementById("identifyLayersText");
			identifyClick();// activem eina identify
			configurarIdentify(code);
			textObj.firstChild.nodeValue=text;
		}
	};
	dd.show(false);
}*/
//
///**
// *	configura el layer i el servidor al que fer l'identify a partir del name del layer.
// */
//function configurarIdentify(layerName) {
//	var serviceId=treeContent.getContentNodeByName(layerName).getLayerService();
//	var serviceObj=treeContent.getServiceById(serviceId);
//	map.setIdentifyLayers(layerName);
//	map.setMapServerIdentifyUrl(serviceObj.url);// TODO. posar el servei del layer, no el de l'info.
//}
//
///**
//*	Called when identify button is clicked
//*/
//function identifyClick() {
//
//	changeTool(map,'identify');
//
//	if (map.getIdentifyLayers()!= "") {
//		// already selected a layer
//		var queryList=treeContent.getQueryableLayersNames(true,0);//name1#title1#desc1$name2#title2#desc2$...
//		var array1=queryList.split("$");
//		var i=0;
//		var trobat=false;
//		while (i<array1.length-1 && !trobat) {
//			var array2=array1[i].split("#"); //name#title#desc
//			if (array2[0]==map.getIdentifyLayers()) {
//				layerNames=array2[1];
//				trobat=true;
//			}
//			i++;
//		}
//	} else {
//		// none layer has been selected
//		var queryList=treeContent.getQueryableLayersNames(true,0);
//		var array1=queryList.split("$");
//		var array2=array1[0].split("#");// name#title#desc
//		map.setIdentifyLayers(array2[0]);
//		var layerNames=map.getIdentifyLayers();
//		var openDropDown=true;
//	}
//	
//	if (openDropDown==true && map.getIdentifyLayers()=="") openIdentifyDropDown();
//}
//
//// opens the dropdown list
//function openIdentifyDropDown() {
//	var obj=document.getElementById("identifyDropDownDiv");
//	identifyDropdownShow(obj);
//
//}
//
//
//function scaleDropdownShow(target) {
//
//	var ddContent=new CDropdownContent();
//	var trobat=false;
//	for (var i=0; i<scales.item.length ;i++ ){
//		/*if (!trobat && parseFloat(map.getScale()) < parseFloat(scales.item[i].name)) {
//			ddContent.addItem(map.getScale(),FormatNumber(map.getScale(),false,false,false,true) + " (ACTUAL)","");
//			trobat=true;
//		}*/
//		ddContent.addItem(scales.item[i].name,scales.item[i].title,scales.item[i].desc);
//	}
//
//	var dd = new CDropdown(target,ddContent,160);
//	dd.processFunction= function(code,text,title) {
//		map.centerAndZoom(map.getCenter(),code);
//		//updateScaleValue(code);
//	};
//	dd.show(false);
//}


// Obtener el valor de un parámetro de la url
function GetURLParam(param,url) {						
	if (typeof(url)=="undefined")
		var url = document.location.href + "&";

	var sep = "&";
	var i = url.indexOf(sep+param+"=");
	if (i < 0 ) {
		sep = "?";
		i = url.indexOf(sep+param+"=");
		if (i < 0) {
			return "";
		}
	}

	url = url.substr(i+param.length+2);

	i = url.indexOf("&");
	if (i < 0 ) {
		return "";
	}

	url = url.substring(0, i);

	return unescape(url);
}

/**
*	click a carregar representacio personal/comuna. 
*/
function clickLegendPersonalRepresentation() {
	if (typeof(skipReload)=="undefined") skipReload=false;

	var imgObj=document.getElementById("imgLegendRepresentation");
	if (imgObj.src.indexOf("_disabled.gif")>0) {
		alert(langArr.SIN_REPRESENTACIONES_PERSONALES_DISPONIBLES);
		return;
	} else if (imgObj.src.indexOf("_off.gif")>0) {
		legend_loadComu=false;
		setTemaPersHabilitada(true);
	} else if (imgObj.src.indexOf("_mid.gif")>0) {
		legend_loadComu=false;
		setTemaPersHabilitada(true);
	} else if (imgObj.src.indexOf("_on.gif")>0) {
		legend_loadComu=true;
		setTemaPersHabilitada(false);
	}
}

/**
*	Modifica la imatge de representació. Casos que ens poden passar:
*
*	CAS			>	ICONA			TOOLTIP				
*	-----------------------------------
*	disabled:		gris			disabled
*	off:			gris			habilita pers.
*	mid:			gris/verd		habilita pers.
*	on:				verd			deshabilita pers.
*/
function setPersonalRepresentationImage(cas) {
	try {
		if (cas=="disabled") {
			var src="img/legend_representation_disabled.gif";
			var tit=langArr.SIN_REPRESENTACION_PERSONAL;

		} else if (cas=="off") {
			var src="img/legend_representation_off.gif";
			var tit=langArr.CARGAR_REPRESENTACION_PERSONAL;
			//legend_loadComu=true;

		} else if (cas=="mid"){
			var src="img/legend_representation_mid.gif";
			var tit=langArr.COMPLETAR_REPRESENTACION_PERSONAL;
			//legend_loadComu=true;

		} else if (cas=="on") {
			var src="img/legend_representation_on.gif";
			var tit=langArr.DESHABILITAR_REPRESENTACION_PERSONAL;
			//legend_loadComu=false;

		} else alert("setPersonalRepresentationImage(). Cas no reconegut: "+cas);

		var imgObj=document.getElementById("imgLegendRepresentation");
		imgObj.src=src;
		imgObj.title=tit;
	}
	catch (e) {}// no generem cap error! quan l'usuari no tingui permisos no hi haurà la imatge.
}

/**
*	Envia una petició al servidor per canviar l'estat de tema_pers.habilitada.
*/
function setTemaPersHabilitada(habilitada) {
	try {
		var pers=new NPersonalitzacio();
		pers.persona_id=desencriptar(userId);
		pers.processSendPersonalitzacioOK=function() {
			//alert ('>> :pers ok. recarreguem content');
			forceContentReload(); // ja podem recarregar 
		}
		pers.saveTemaPersHabilitat(habilitada,userId);
	}
	catch (e) {
		alert("Error a setTemaPersHabilitada()\n"+e.message);
	}
}

/**
*	Click al boto de ordenació comuna. Segons l'estat actual demana la ordenació comuna o la personal.
*/
function legendHiddenContent() {
	var imgObj=document.getElementById("imgHiddenContent");

	if (imgObj.src.indexOf("_p.gif")>0) {
		if (confirm(langArr.DESHABILITAR_CONTENIDOS_OCULTOS)==false) return;
		imgObj.src="img/legend_hidden.gif";
		imgObj.title=langArr.HABILITA_CONTENIDOS_OCULTOS;
		legend_loadOcults=false;
	}
	else {
		if (confirm(langArr.HABILITAR_CONTENIDOS_OCULTOS)==false) return;
		imgObj.src="img/legend_hidden_p.gif";
		imgObj.title=langArr.DESHABILITA_CONTENIDOS_OCULTOS;
		legend_loadOcults=true;
	}
	forceContentReload();
}


/**
*	Rep un error capturat amb un try/catch
*/
function errorHandler(e) {
	var str="";
	for(var i in obj){
		var tmp = '(error)';
		if(i.match(/^(expose|header|footer|ivn|dygolk|ad_)/))
		  tmp = '(excluding as a known custom method or property)';
		else{
		  try{ tmp = obj[i]; } catch(e){}
		}
		str += i+':'+tmp;

	}
	alert("errorHandler:"+str);
}

/**
*	Click a obrir dataloader
*/
function openDataLoader() {
	try {	
		window.open(urlOpenDataLoader+"userid="+userId,'',"width=750,height=500,toolbar=0,url=0,resizable=1;");
	} catch (e) {alert ('openDataLoader() :' + e.message);}
}

/**
*	Click a obrir manteniment de datasets
*/
function openMantDataset() {
	try {	
		window.open(urlOpenDataset+"name=&owner=&userid="+userId,'',"width=725,height=400,toolbar=0,url=0,resizable=1;");
	} catch (e) {alert ('openMantDataset() :' + e.message);}
}

/**
*	
*/
function openMantBloc() {
	try {	
		window.open(urlOpenBloc+"id="+"&userid="+userId,'',"width=725,height=400,toolbar=0,url=0,resizable=1;");
	} catch (e) {alert ('openMantDataset() :' + e.message);}
}

/**
*	
*/
function openMantTema(userId,id,persona_id) {
	var wh = (debugLevel == OFF ? "width=680,height=420" : "width=800,height=500");

	try {	
		window.open(urlOpenTema+"userid="+userId+"&id="+id+"&persona_id="+escape(persona_id),'',wh+",toolbar=0,url=0;");
	} catch (e) {alert ('openMantTema() :' + e.message);}
}

/**
//*
//*/
//function openPrint() {
//
//	openDojoPane(null,"Impressió","modalPrint2.html?cache="+new Date(),130,130,330,300);
//	return false;
//}

/**
*
*/
function returnFunction() {
		//	alert("returnFunction");
		}

///**
//*
//*/
//function closePoi(e) {
//
//	if (!e) var e = window.event;
//	e.cancelBubble = true;
//	if (e.stopPropagation) e.stopPropagation();
//
//		map.pois.clear();
//		return true;
//		
//}

/**
*
*/
//function openDojoPane(dojoWidget,title,url,left,top,width,height) {
//	if (typeof(title)=="undefined") title="";
//	if (typeof(left)=="undefined") left=50;
//	if (typeof(top)=="undefined") top=50;
//	if (typeof(width)=="undefined") width=500;
//	if (typeof(height)=="undefined") height=400;
//
//	if (typeof(dojoWidget)!="undefined" && typeof(identifyDojoPaneDestroyed)!="undefined" && !identifyDojoPaneDestroyed) {
//		//dojo.widget.byId("testing").setUrl("http://www.elpais.com");
//
//		dojoWidget.setUrl(url);
//		return dojoWidget;
//	}
//	
//	// Set DOJO Debug
//	var djConfig = {isDebug: true};
//	djConfig.debugAtAllCosts = true;
//
//	// Import DOJO Modules
//	//dojo.require("dojo.widget.Toolbar");
//	dojo.require("dojo.widget.FloatingPane");	
//	dojo.require("dojo.widget.ContentPane"); 
//	
//	// Open DOJO FloatingPane
//	dojo.debug("Testing DOJO FloatingPane");
//	var properties = {
//		hasShadow: false,
//		displayMinimizeAction: false,
//		displayMaximizeAction: false,
//		displayCloseAction: true,
//		href: url,
//		executeScripts: true,
//		style: "",
//		title: title,
//		titleHeight: "20",
//		id: "testing"
//	};
//
//	properties.id = "testing";
//	node = document.createElement(properties.id);
//	node.style.position = "absolute";
//	node.style.width = ""+width+"px";
//	node.style.height = ""+height+"px";
//	node.style.left = ""+left+"px";
//	node.style.top = ""+top+"px";
//	document.body.appendChild(node);
//
//	var fig = dojo.widget.createWidget("FloatingPane",properties,node);
//
//	identifyDojoPaneDestroyed=false;
//	fig.destroy = function () {
//		identifyDojoPaneDestroyed=true;
//	};
//	return fig;
//}

//---------------------

resizeCount=0;
resizeDate=new Date();

function windowResize() {
	try {
		if ((new Date()-resizeDate)<1000) {
			return;
		}
		resizeDate=new Date();
		resizeCount++;
		mapMaximized=!mapMaximized;
		resizeid=setTimeout("maximizeMap()",500);
		
	}
	catch (e) {
		alert("Error a windowResize()\n"+e.message);
	}
}

function ubicar_buscar() {
	alert("crida a ubicar_buscar");
}

/**
*
*/
function print_escalaChange(obj) {
	try {
		
		var printScale=obj.value;
		if (printScale=="actual") printScale=map.getScale();

		var printPixWidth=600;
		var printPixHeight=400;
		
		var pixWidth=printPixWidth;
		var pixHeight=printPixHeight;
		var centerPoint=map.getCenter();
		var scaleDen=printScale;
		var coord1=map.pixelsToCoordsWithParams (0,0,pixWidth,pixHeight,centerPoint,scaleDen);
		var coord2=map.pixelsToCoordsWithParams (printPixWidth,printPixHeight,pixWidth,pixHeight,centerPoint,scaleDen);

		map.setDrawBboxExtent(new NExtent(coord1,coord2));


	
	}
	catch (e) {
		alert("Error a ubicar_buscar()\n"+e.message);
	}
}
/**
*	Click a radio de de escala o mida
*/
function previewPrintRadioChange(radioId) {
	try {
		var obj=document.getElementById(radioId);
		if (obj.checked) previewPrintChange(obj);
	}
	catch (e) {
		alert("Error a previewPrintRadioChange()\n"+e.message);
	}
}

/**
*	Click a checkbox de previsualitzar caixa de impressió. També cridat en canviar les opcions d'impressió.
*/
function previewPrintChange(obj) {
	//try {

		if (obj.checked) {
			showPrintPreview();
		} else {
			hidePrintPreview();
		}
	/*}
	catch (e) {
		alert("Error a previewPrintChange()\n"+e.message);
	}*/
}

/**
*	Mostra un preview de l'area d'impressió sobre el mapa.
*/
function showPrintPreview(skipRegisterEvent) {
	if (typeof(skipRegisterEvent)=="undefined") skipRegisterEvent=false;
	//setPrintParameters(true);
	if (typeof(printObj)=="undefined"){
		printObj=new printBase({
			map: map,
			config: {},
			afterLayerCreated: function() {
				//alert("ole ole... afterLayerCreated");
			},
			setCurRotation: function(rotation) {//no es crida en final, es crida continuament
				//alert("rotation changed");
				document.getElementById("printAngle").value=-rotation;
			},
			setCurCenter: function(center) {//no es crida en final, es crida continuament
				//alert("center changed: "+center);
				map.panTo(center);
			}
		});
	}

	printObj.onHideEvent();
	printObj.onShowEvent();

	var center=map.getCenter();

	var printConfig=getPrintConfig(72);
	var scale=printConfig.scale;
	var layout={
		map: {
			width:printConfig.width,
			height:printConfig.height
		}
	};
	var rotation=-printConfig.rotation;
	var feature=printObj.createRectangle(center, scale, layout, rotation);
	printObj.createRotateHandle(feature);
	
//	map.layers[0].events.register("loadstart", map.layers[0], printLoadStart);
	globalVarPrintScale=scale;
	map.events.unregister("moveend", map, printLoadEnd);
	if (!skipRegisterEvent) map.events.register("moveend", map, printLoadEnd);
		
}

function printLoadEnd() {
	if (Math.abs(this.getScale()-globalVarPrintScale)>10){
		// canvi d'escala
		showPrintPreview(true);
	}
}

/**
*
*/
function hidePrintPreview() {

	map.events.unregister("moveend", map, printLoadEnd);
	printObj.onHideEvent();
}

/*
*	retorna un objecte amb la configuració d'impressió del a interficie.
*/
function getPrintConfig(dpi) {
	// angle 
	var angle=document.getElementsByName("angle")[0];
	var angleValue=0;
	if (typeof(angle)!="undefined") angleValue=parseFloat(angle.value);

	// escala 
	var escales=document.getElementsByName("escala");
	var printScale=0;
	for (var i=0;i<escales.length ;i++ ) {
		if (escales[i].checked) printScale=escales[i].value;
	}
	if (printScale=="actual") printScale=map.getScale();

	// paper
	var mides=document.getElementsByName("mida");
	var pixWidth=0;
	var pixHeight=0;
	for (var i=0;i<mides.length ;i++ ) {
		if (mides[i].checked) {
			var cmWidth=parseFloat(mides[i].attributes.mapWidth.nodeValue);
			var cmHeight=parseFloat(mides[i].attributes.mapHeight.nodeValue);
			var pixWidth=Math.round(cmWidth*0.3937008*dpi);
			var pixHeight=Math.round(cmHeight*0.3937008*dpi);
		}
	}

	return {
		rotation:angleValue,
		scale:printScale,
		width:pixWidth,
		height:pixHeight
	};
}

/**
*	Mostra un preview de l'area d'impressió sobre el mapa.
*/
function setPrintParameters(printer,showPreview) {
	try {
		var printConfig=getPrintConfig(96);
		var angleValue=printConfig.rotation;
		var printScale=printConfig.scale;
		var pixWidth=printConfig.width;
		var pixHeight=printConfig.height;

		if (typeof(printObj)=="undefined"){
			var centerPoint=map.getCenter();
			var scaleDen=parseFloat(printScale);
		} else {
			var centerPoint=printObj.rectangleFeature.geometry.getBounds().getCenterLonLat();
			var scaleDen=printObj.curScale;
		}

		var coordArray = new NPois();
		//coordArray.add(new NPoi(map.getCenter(),"http://ms.nexusgeografics.com/scugat2/images/ban_bulleti.gif",0,0));
		
		var pixelArray=new NPois();
		pixelArray.add(new NPoi(new NPoint(pixWidth/2,pixHeight-20), urlImatges+"marcaAigua.gif",0,0));
		printer.printerServlet=urlOpenImprimir;// TODO
		printer.setPrintConfig(pixWidth,pixHeight,scaleDen,centerPoint,angleValue,showPreview,null,null,null,coordArray,pixelArray);
		//Exemple de petició definint el servidor:		map.setPrintConfig(pixWidth,pixHeight,scaleDen,centerPoint,angleValue*180/Math.PI,showPreview,"http://shagrat.icc.es/lizardtech/iserv/ows?","mtc50m,","image/png",coordArray,pixelArray);
		
	} catch (e) {
		alert("error a previewPrint()\n"+e.message);
	}
}

/**
*
*/
function imprimir() {

	try {
		var printer=new OpenLayers.NGPrint(map,treeContent);
		setPrintParameters(printer,false);

		//printer.createRectangle(map.getCenter(), map.getScale(), null, null);

		var now=new Date();
		var date=now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear();
		var size="A4";
		var orientation="H";
		var pages="1";
		var scale=parseInt(map.getScale());

		var mides=document.getElementsByName("mida");
		for (var i=0;i<mides.length ;i++ ) {
			if (mides[i].checked)size=mides[i].value;
		}

		var escales=document.getElementsByName("escala");
		for (var i=0;i<escales.length ;i++ ) {
			if (escales[i].checked)scale=escales[i].value;
		}
		if(scale=="actual")scale=map.getScale();

		scale=Math.round(scale);
		scale=format(scale);

		printer.createPDF("legendUrl",treeContent.servletUrl,
			"formatsize",size,
			"formatorientation",orientation,
			"formatpages",pages,
			"title",printTitle,
			"comment",printComment,
			"scale",scale,
			"date",date);
		return;
		
	}
	catch (e) {
		alert("error a imprimir()\n"+e.message);
	}
}


	function format(nStr){
		nStr += '';
		x = nStr.split('.');
		x1 = x[0];
		x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + '.' + '$2');
		}
		return( x1 + x2);
	}

/**
*	Click al boto de maximitzar o tornar a mida normal.
*/
function maximizeMap() {
	try {
		var maximizeDiv=document.getElementById("maximizeDiv");
		var toolbarDivOL=document.getElementById("toolbarDivOL");
		var mapDiv=document.getElementById("map");
		var treeviewDiv=document.getElementById("treeviewDiv");
		var fonts=document.getElementById("fonts");
		var editToolbar=map.getControlsByClass("OpenLayers.Control.NGEditingToolbar")[0];
//		var iniciarSessioLink=document.getElementById("iniciarSessioLink");

		if (!mapMaximized) {// maximitzar
			var windowclientWidth=getAvailableWidth();
			var windowclientHeight=getAvailableHeight();

			maximizeDiv.style.position="absolute";// si fem resize dels altres però no del maximizeDiv, l'IE fa desapareixer mapa al fer pans.
			maximizeDiv.style.margin="0px";
			maximizeDiv.style.top="0px";
			maximizeDiv.style.left="0px";
			maximizeDiv.style.width=windowclientWidth-3+"px";

			fonts.style.bottom="30px";
			fonts.style.left="10px";

			toolbarDivOL.style.position="absolute";
			toolbarDivOL.style.float="left";
			toolbarDivOL.style.top="10px";
			toolbarDivOL.style.left="50px";
			toolbarDivOL.style.zIndex=999999;

			if (typeof(editToolbar)!=="undefined"){
				editToolbar.div.style.top="8px";
				editToolbar.div.style.left="390px";
			}
			
			mapDiv.style.width=windowclientWidth-3+"px";
			mapDiv.style.height=windowclientHeight-10+"px"

			// per l'ie6 hem d'ocultar el toc: els elements select, combos, ... queden visibles sobre el mapa
			treeviewDiv.style.display="none";

			mapMaximized=!mapMaximized;

		} else {// minimitzar
			maximizeDiv.style.position="relative";// si fem resize dels altres però no del maximizeDiv, l'IE fa desapareixer mapa al fer pans.
			maximizeDiv.style.margin="0px";
			maximizeDiv.style.top="";
			maximizeDiv.style.left="";
			maximizeDiv.style.width="100%";
			maximizeDiv.style.height="";

			fonts.style.bottom="68px"; 
			fonts.style.left="250px";

			toolbarDivOL.style.position="relative";
			toolbarDivOL.style.top="";
			toolbarDivOL.style.left="";
			toolbarDivOL.style.zIndex=999999;
			toolbarDivOL.style.width="";

			if (typeof(editToolbar)!=="undefined"){
				editToolbar.div.style.top="10px";
				editToolbar.div.style.left="80px";
			}

			mapDiv.style.width="55px";
			mapDiv.style.height="55px";

			// per l'ie6 hem d'ocultar el toc: els elements select, combos, ... queden visibles sobre el mapa
			treeviewDiv.style.display="block";
			
			mapMaximized=!mapMaximized;
			placeMapDiv();
		}
		if (typeof(map)!="undefined") map.updateSize();// evitar error en ie6 carrega inicial
	}
	catch (e) {
		alert("Error a maximizeMap()\n"+e.message);
	}
}

/**
*	Retorna cert si el mapa esta maximitzat.
*	@return {boolean}
*/
function mapIsMaximized() {
	var obj=document.getElementById("maximizeDiv");
	return obj.style.position=="absolute";
}


/**
*	activa eina de mesurar distàncies.
*/
function mesurarDistancia() {
	try {
		changeImage("mesurar");
		map.resetToolMeasure();
		map.setCurrentTool("MEASURE");
	}
	catch (e) {
		alert("error a mesurarDistancia()\n"+e.message);
	}
}

/**
*	Genera una url amb la configuració actual de continguts i reemplaça la url del navegador.
*/
function permalink() {
	try {
		var url=getPermalink();

		//window.location.replace(url.join(""));
		window.location.href=url;
	}
	catch (e) {
		alert("error a permalink()\n"+e.message);
	}
}

/**
*	Genera una url amb la configuració actual de continguts i reemplaça la url del navegador.
*/
function getPermalink() {
	var separador="~";
	try {
		// config capes i capes visibles
		var services="";
		var layers="";
		var target=document.getElementById("configDiv_sel");
		for (var i=0; i<target.options.length; i++ ) {
			var id=target.options[i].value;
			var transpValue=treeContent.getServiceById(id).transparency;

			if (services!="") services+=separador;
			services+=id+":"+transpValue;

			if (layers!="") layers+=separador;
			layers+=treeContent.getVisibleLayersNames(id,separador);
		}

		var url=new Array();
		url.push(hostname+"/"+context+"/index.html");


		var mapExtent = map.getExtent();
		var maxExtent = map.maxExtent;
		url.push("?extent="+Math.max(mapExtent.left, maxExtent.left)+","+Math.max(mapExtent.bottom, maxExtent.bottom)+","+Math.min(mapExtent.right, maxExtent.right)+","+Math.min(mapExtent.top, maxExtent.top));
		url.push("&layers="+layers);
		url.push("&services="+services);

		return url.join("");
	}
	catch (e) {
		alert("error a getPermalink()\n"+e.message);
	}
}

/**
*	Obre la finestra de enviar per correu electrònic.
*/
function sendMail() {
	try {
		var lang="ca";
		var url="";
		// hem de passar un parametre link amb la url: centre+escala+categories+
		url=getPermalink()+"&lang="+lang;
		//window.open(urlOpenCorreu+"?link="+escape(url)+"&lang="+lang,"",urlOpenCorreuConf);
		showPopWin(urlOpenCorreu+"?link="+escape(url)+"&lang="+lang, 345,260, null);
	}
	catch (e) {
		alert("error a sendMail()\n"+e.message);
	}
}


/**
*	downloads config of the current file
*/
function downloadCurrentMapConfig() {
	map.downloadConfig(map.getCenter(),map.getScale());
}


var casosEspecials=new Array(new Array("*","F3aD34gI9C") );
var keyArray=new Array(-8,5,12,-11,5,-4,7,6);

/**
*	Realitza la desencriptació.
*	
*	@param text El text a desencriptar
*	@return {String}
*/
function desencriptar(text)
{
	text=unescape(text);
	try 
	{
	  var ret="";
	  
	  ret =getCasEspecial(text,false);
	  if (ret!="") return ret;
	  
	  for (var i=0; i < text.length; ++i ) {
		//var c = text[i];
		var j = text.charCodeAt(i);
		
		//ret+=new Character((char)decode(j,i)).toString();
		ret+=String.fromCharCode(decode(j,i));

	   }
	  
	  return ret;  
	  
	} catch (ex) { 
	  handleError("Error al desencriptar",ex);
	} 
}

/**
*	Comprova si el text és un dels casos especials pels que tenim una taula d'equivalencies.
*	
*	@param text  El text a comprovar
*	@param esEncoding  Boolea per mirar a la taula el valor encriptat/desencriptat
*	@returns un string amb el corresponent encriptat/desencriptat o un string buit si no es un cas especial.
*	
*/
function getCasEspecial(text,esEncoding) 
{
	var indexI=0;
	var indexO=1;
	if (!esEncoding) {
	  indexI=1;
	  indexO=0;
	}

	for (var i=0 ;i<casosEspecials.length ;i++ ) 
	{
	  if (casosEspecials[i][indexI]==text) {
		return casosEspecials[i][indexO];
	  }
	}

	return "";
}

/**
*
*/
function decode(ascii,pos) 
{
	var arrayPos=pos % keyArray.length;
	return ascii-keyArray[arrayPos];
}


function handleMeasurements(event) {
	var geometry = event.geometry;
	var units = event.units;
	var order = event.order;
	var measure = event.measure;
	var control=map.getControlsBy("CLASS_NAME","OpenLayers.Control.NGMeasureInfo")[0];
	control.show();
	var element = control.element;
	var out = "";
	if(order == 1) {
		out += "distància: " + measure.toFixed(2) + " " + units;
		if (map.getProjection() == "EPSG:4326") {
			out += "<br /> Great Circle Distance: " + 
				calcVincenty(geometry).toFixed(3) + " km *"; 
		}        
	} else {
		out += "àrea: " + measure.toFixed(2) + " " + units + "<sup>2</" + "sup>";
	}
	element.innerHTML = out;
}

function setMeasureControl(map) {
	
	// el control on mostrem la informació.
	map.addControl(new OpenLayers.Control.NGMeasureInfo({divId:"NGMeasureInfoDivId"}));
	
	var measureControls;
	// style the sketch fancy
	var sketchSymbolizers = {
		"Point": {
			pointRadius: 4,
			graphicName: "square",
			fillColor: "white",
			fillOpacity: 1,
			strokeWidth: 1,
			strokeOpacity: 1,
			strokeColor: "#333333"
		},
		"Line": {
			strokeWidth: 3,
			strokeOpacity: 1,
			strokeColor: "#666666",
			strokeDashstyle: "dash"
		},
		"Polygon": {
			strokeWidth: 2,
			strokeOpacity: 1,
			strokeColor: "#666666",
			fillColor: "white",
			fillOpacity: 0.3
		}
	};
	var style = new OpenLayers.Style();
	style.addRules([
		new OpenLayers.Rule({symbolizer: sketchSymbolizers})
	]);
	var styleMap = new OpenLayers.StyleMap({"default": style});
	
	var options = {
		handlerOptions: {
			style: "default", // this forces default render intent
			layerOptions: {styleMap: styleMap},
			persist: true
		}
	};
	measureControls = {
		line: new OpenLayers.Control.Measure(
		  OpenLayers.Handler.Path, options
		),
		polygon: new OpenLayers.Control.Measure(
			OpenLayers.Handler.Polygon, options
		)
	};
	
	var control;
	for(var key in measureControls) {
		control = measureControls[key];
		control.events.on({
			"measure": handleMeasurements,
			"measurepartial": handleMeasurements
		});
		map.addControl(control);
	}
}


/**
*	Carrega el layer de tipus vector. 
*	@param {Object} configObj configuració del layer WFS.
*	@param {String} filterStr el filtre ogc per carregar l'element WFS. Cal utilitzar el filtre 'filterStr' o el 'filterCQLStr'
*	@param {String} filterCQLStr filtre CQL per carregar l'element WFS. Cal utilitzar el filtre 'filterStr' o el 'filterCQLStr'
*	@param {boolean} loadEditToolbar si cal carregar la barra d'eines d'edició.
*	@param {String} geomType tipus de geometria a editar. 'point'|'path'|'polygon'|...
*	@param {boolean} hasGeom indica si ja te geometria.
*	@param {String} fid l'identificador del feature. Quan no te geometria i s'ha de crear, hem d'actualitzar-la a aquest feature.
*/
function initVectorLayerEdition(configObj, filterStr, filterCQLStr, loadEditToolbar, geomType, hasGeom, fid) {

	if (filterStr==='') filterStr=null;
	if (loadEditToolbar==='') loadEditToolbar=false;

	edit_unloadEditingToolbar();

	// si hi la el layer de visualitzar sel·lecció, el borrem.
	if (map.getLayersByName("selectionVector").length>0) {
		var vlayer=map.getLayersByName("selectionVector")[0];
		map.removeLayer(vlayer);
	}

	if (typeof(configObj.associatedLayerName)!="undefined") var wmsLayer=map.getLayersByName(configObj.associatedLayerName)[0];

	// definim el layer
	var vectorLayer = new OpenLayers.Layer.Vector("vectorLayer", {
		strategies: [
			new OpenLayers.Strategy.Fixed()
		],
		protocol: new OpenLayers.Protocol.HTTP({
			url: configObj.wfsUrl,
			//headers: {'Content-Type': 'application/xml'},
			params: {
				format: "WFS",
				version: '1.0.0',
				typename: configObj.typeName,
				//featureNS: configObj.featureNS,
				service: "WFS",
				request: "GetFeature",
				srs: treeContent.map_projection,
				cache: new Date(),
				filter : filterStr,
				cql_filter: filterCQLStr
			},
			//data: wfsQuery,
			format: new OpenLayers.Format.GML()
		})
		,layerName:configObj.layerName
		//,featureNS:configObj.featureNS
		,geometry_column:configObj.geometryColumn
		,typename: configObj.typeName
		,url: configObj.wfsUrl
	});
	vectorLayer.onLoadZoomToFeatures=true;
	// afegim event perque quan s'hagi afegit un feature hi centri.
	vectorLayer.events.register("featuresadded", vectorLayer, function() {
		if (this.featuresadded_executed) return; //volem que s'executi 1 vegada i prou, sinò al afegir una geometria també s'executa.
		this.featuresadded_executed=true;
		//alert("featuresadded");
		try{
			if (map.getCenter()===null && this.features.length===0) map.zoomToMaxExtent();// centrar via url i sense features a la resposta.

			var extent=null;
			try{
				extent=this.getDataExtent();
			}
			catch (e){
				extent=null;
				for (var i=0;i<this.features.length ; i++){
					if (this.features[i].geometry!==null) {
						if (extent===null) extent=this.features[i].geometry.getBounds();
						else extent.extend(this.features[i].geometry.getBounds());
					}
				}
			}
			
			if (this.onLoadZoomToFeatures && extent.getWidth()>0) {
				this.map.zoomToExtent(extent ,true);
			} else {
				if (map.getCenter()===null)map.zoomToMaxExtent();// cas de centrar quan encara no hi ha extensió
				this.map.panTo(extent.getCenterLonLat());
			}
		}
		catch (e){
		}
	});

	map.addLayers([vectorLayer]);
	
	if (geomType==="null"){// quan xsl no sap quina geometria és: agafem la de defecte del dataset.
		geomType=configObj.geometryType;
	}

	// configuració del toolbar d'edició. Depen de la geometria a visualitzar o de si cal afegir-ne, del tipus de geometria per defecte.
	var options={
		drawPointOn: !hasGeom && geomType==="point",
		dragFeatureOn: hasGeom,
		deleteFeatureOn: false,//hasGeom,
		drawPathOn: !hasGeom && geomType==="line",
		drawPolygonOn: !hasGeom && geomType==="polygon",
		drawRegularPolygonOn: false,
		modifyFeatureOn: geomType==="polygon",
		featureFid: fid, // identificador del feature
		defaultTool: (hasGeom)? OpenLayers.Control.NGEditingToolbar.TOOL_DRAG_FEATURE : OpenLayers.Control.NGEditingToolbar.TOOL_DRAW_POINT,
		associatedLayer: wmsLayer,
		addEditLog: configObj.addEditLog,
		saveFeatureCallback: function (success, response,features) {
			var bounds=null;
			for (var i=0;i<features.length ;i++ ){
				if (bounds!=null) bounds.add(features[i].geometry.bounds);
				else if (features[i].geometry!=null) //quan afegim geom a un element que no en te, te la geom a null.
					bounds=features[i].geometry.bounds.clone();
			}
			// centrem al nou centre
			var lonlat=bounds.getCenterLonLat();
			map.panTo(lonlat);
			// substituim el nou centre a l'element de la llista.
			var fid=features[0].fid;
			var obj=document.getElementById("edit_"+fid);
			if (obj==null) return;
			//obj.setAttribute("center",lonlat.toShortString());
		}
	};
	options.editUserColumn=(typeof(configObj.editUserColumn)!="undefined")? configObj.editUserColumn: null;
	options.editOriginColumn=(typeof(configObj.editOriginColumn)!="undefined")? configObj.editOriginColumn: null;
	options.editDateColumn=(typeof(configObj.editDateColumn)!="undefined")? configObj.editDateColumn: null;

	if (loadEditToolbar) map.addControl(new OpenLayers.Control.NGEditingToolbar(vectorLayer,options));

}



/*
function vectorLayerCommit() {
	var vectorLayer=map.getLayersByName("vectorLayer")[0];
	vectorLayer.commit();
}
*/

/**
* Fa una petició WFS per carregar els elements que cumpleixen el filtre passat.
*/
function edit_loadListElements(filterStr) {
	try {
		if (filterStr==='') filterStr=null;

		if (typeof(edit_listMaxFeatures)!="undefined") var maxfeatures=edit_listMaxFeatures;
		else var maxfeatures=null;
		
		// configuració del servidor wfs
		var configObj=edit_getCurrentLayerConfig();
		if (configObj===null) return;//no han escollit

		var obj=document.getElementById("edit_listDiv");
		obj.innerHTML="carregant...";

		function handler(request) {
			// do something with the response
//			alert(request.responseXML);
			var obj=document.getElementById("edit_listDiv");
			obj.innerHTML=request.responseText;
		}

		var request = OpenLayers.Request.GET({
			url: configObj.wfsUrl,
			params: {
				format: "WFS",
				version: '1.0.0',
				typename: configObj.typeName,
				featureNS: configObj.featureNS,
				service: "WFS",
				request: "GetFeature",
				srs: treeContent.map_projection,
				cache: new Date(),
				xsl: "featureedit.xsl",
				filter : filterStr,
				maxfeatures : maxfeatures
			},
			callback: handler
		});

	}
	catch (e) {
		alert("Error a edit_loadListElements()\n"+e.message);
	}
}

/**
* carrega els elements a editar a la llista que tenen el camp geometria a null.
*/
function edit_loadListElementsWithoutGeometry() {
	try {
		var configObj=edit_getCurrentLayerConfig();
		if (configObj===null) return;//no han escollit
		geomField=configObj.geometryColumn;
		if (geomField==null)geomField="GEOM";

		var f='<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:PropertyIsNull><ogc:PropertyName>'+geomField+'</ogc:PropertyName></ogc:PropertyIsNull> </ogc:Filter>';
		edit_loadListElements(f);
	} catch (e) {
		alert("Error a edit_loadListElementsWithoutGeom()\n"+e.message);
	}
}

/**
* carrega els elements a editar a la llista que estan dins l'estensió de la geometria passada.
*/
function edit_loadListElementsFromFeatureGeometry(geometry,geomField) {
	try {
		var bounds=geometry.bounds;
		if (bounds.getWidth()==0){
			var marginPixels=6;
			var marginCoords=map.getLonLatFromPixel(new OpenLayers.Pixel(marginPixels,0)).lon-map.getLonLatFromPixel(new OpenLayers.Pixel(0,0)).lon;
			var x0=geometry.bounds.left-marginCoords/2;
			var y0=geometry.bounds.bottom-marginCoords/2;
			var x1=geometry.bounds.right+marginCoords/2;
			var y1=geometry.bounds.top+marginCoords/2;
			bounds=new OpenLayers.Bounds(x0,y0,x1,y1);
		}
		if (geomField==null) {
			var configObj=edit_getCurrentLayerConfig();
			if (configObj===null) return;//no han escollit
			geomField=configObj.geometryColumn;
		};
		var f='<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">'
				+'<ogc:BBOX>'
				+	'<ogc:PropertyName>'+geomField+'</ogc:PropertyName>'
				+	'<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="http://www.opengis.net/gml/srs/epsg.xml#23031">'
				+		'<gml:coordinates>'+bounds.left+','+bounds.bottom+' '+bounds.right+','+bounds.top+'</gml:coordinates>'
				+	'</gml:Box>'
				+'</ogc:BBOX>'
				+'</ogc:Filter>';
		edit_loadListElements(f);
	} catch (e) {
		alert("Error a edit_loadListElementsFromFeatureGeometry()\n"+e.message);
	}
}

function edit_clearList() {
	document.getElementById("edit_listDiv").innerHTML="";
}

/**
* Si hi ha un feature modificat pregunta si vols cancel·lar l'edició.Retorna true si han escollit cancel·lar.
*/
function edit_askCancelEdit() {
	var editToolbar=map.getControlsByClass("OpenLayers.Control.NGEditingToolbar")[0];
	if (editToolbar && editToolbar.featureModified && !confirm("Cancel·lar edició en curs ?")) {
		return true;
	}
}

/**
* Cancel·la l'edició i treu el layer de vectors utilitzat en l'edició i el toolbar amb els botons.
*/
function edit_unloadEditingToolbar() {
	// si hi ha el control d'edició el destruim.
	var editToolbar=map.getControlsByClass("OpenLayers.Control.NGEditingToolbar")[0];
	if (editToolbar) map.removeControl(editToolbar);

	// si el layer per l'edició ja està carregat el destruim
	var vectorLayer=map.getLayersByName("vectorLayer")[0];
	if (vectorLayer) map.removeLayer(vectorLayer);
}

/**
* zoom amb el filtre CQL que es demanarà al servidor WFS.
*/
function zoomToFilterCQL(wfsUrl,typeName,layerName,filterCQL) {
	
	var loadEditToolbar=false;
	// configuració del servidor wfs
	var configObj=new Object();
	configObj.wfsUrl=urlSearchWfs;
	configObj.typeName=typeName;
	configObj.layerName=layerName;
	initVectorLayerEdition(configObj, null, filterCQL, loadEditToolbar);
}

/**
*	Centrar el mapa al punt donat.
*	@param {String} fid identificador únic de la geometria WFS
*	@param {String} point centre de la geometria.
*/
function edit_zoomTo(fid,point) {
	// mirem si hi ha una edició en curs.
	if (edit_askCancelEdit())return;

	var obj=document.getElementById("edit_"+fid);
	if (obj==null) return;
	/*var point=obj.getAttribute("center");

	var p=point.split(",");
	var x=parseFloat(p[0]);
	var y=parseFloat(p[1]);
	//map.panTo(new OpenLayers.LonLat(x,y));*/

	//--------------
	// definim el filtre pel WFS
/*	var filter=
		new OpenLayers.Filter.Comparison({
			type: OpenLayers.Filter.Comparison.EQUAL_TO,
			property: "FID",
			value: fid
		})
	;
	
	// serialitzem el filtre a string
	var xml = new OpenLayers.Format.XML();
	var filter_1_0 = new OpenLayers.Format.Filter({version: "1.0.0"});
	var filterStr=""+xml.write(filter_1_0.write(filter));
	//--------------
*/
	fid=fid.replace(/&/g,"&amp;");// codifiquem ampersand
	fid=fid.replace(/%27/g,"%27%27");// doblem cometa
	filterStr='<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="'+fid+'"/></ogc:Filter>';
	
	var loadEditToolbar=false;var configObj=edit_getCurrentLayerConfig();
	if (configObj===null) return;//no han escollit
	initVectorLayerEdition(configObj, filterStr, null, loadEditToolbar);
}

/**
*	Editar geometria.
*	@param {String} fid identificador únic de la geometria WFS
*	@param {String} geomType tipus de geometria a editar. 'point'|'path'|'polygon'|...
*	@param {boolean} hasGeom indica si ja te geometria.
*	@param {String} point centre de la geometria.
*/
function edit_editGeometry(fid,geomType,hasGeom,point) {
	// mirem si hi ha una edició en curs.
	if (edit_askCancelEdit()) return;

	/*if (hasGeom) {
		var p=point.split(",");
		var x=parseFloat(p[0]);
		var y=parseFloat(p[1]);
		//map.panTo(new OpenLayers.LonLat(x,y));
	}*/
	fid=fid.replace(/&/g,"&amp;");
	fid=fid.replace(/%27/g,"%27%27");
	var filterStr='<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="'+fid+'"/></ogc:Filter>';

	var loadEditToolbar=true;
	var configObj=edit_getCurrentLayerConfig();
	if (configObj===null) return;//no han escollit
	initVectorLayerEdition(configObj, filterStr, null, loadEditToolbar, geomType, hasGeom,fid);
}

/**
* 
*/
/*function loadSelectionToolbar() {
	
	if (map.getLayersByName("selectionVector").length>0) var vlayer=map.getLayersByName("selectionVector")[0];
	else {
		var vlayer = new OpenLayers.Layer.Vector( "selectionVector");
		map.addLayer(vlayer);
	}
	
	panel = new OpenLayers.Control.SelectionToolbar(vlayer,{'div':document.getElementById('selectionToolbarDiv')});

	map.addControl(panel);
	panel.controls[1].activate();
}*/

/**
* Crea o retorna el layer de tipus vector per mostrar la sel·lecció d'elements a editar.
*/
function edit_getSelectionVectorLayer() {
	if (map.getLayersByName("selectionVector").length>0) {
		var vlayer=map.getLayersByName("selectionVector")[0];
		return vlayer;
	}
	
	var styleMap=edit_getSelectionStyleMap();

	var vlayer = new OpenLayers.Layer.Vector( "selectionVector" , {'styleMap': styleMap });
	map.addLayer(vlayer);
	return vlayer;
}

/**
* crea i retorna l'estil per mostrar a la sel·lecció de features a editar.
*/
function edit_getSelectionStyleMap() {
	var sketchSymbolizers = {
		"Point": {
			pointRadius: 6,
			graphicName: "circle",
			fillColor: "white",
			fillOpacity: 0.3,
			strokeWidth: 2,
			strokeOpacity: 1,
			strokeColor: "#333333"
		},
		"Line": {
			strokeWidth: 3,
			strokeOpacity: 1,
			strokeColor: "#666666",
			strokeDashstyle: "dash"
		},
		"Polygon": {
			strokeWidth: 2,
			strokeOpacity: 1,
			strokeColor: "#666666",
			fillColor: "white",
			fillOpacity: 0.3
		}
	};
	var style = new OpenLayers.Style();
	style.addRules([
		new OpenLayers.Rule({symbolizer: sketchSymbolizers})
	]);
	var styleMap = new OpenLayers.StyleMap({"default": style});
	return styleMap;
}

/**
*	eina de sel·lecció de features en un punt.
*/
function edit_selectWithPoint(obj) {
	if (edit_askCancelEdit())return;
	edit_unloadEditingToolbar();

	var currentSrc="img/select_point.png";
	obj.src="img/select_point_on.png";
	
	var vlayer=edit_getSelectionVectorLayer();
	var theStyle=edit_getSelectionStyleMap();
	// canviar estils mentre s'està editant:http://n2.nabble.com/Modifying-a-vector-object%27s-styling-td1831334.html#a1831334
	box = new OpenLayers.Control.DrawFeature(vlayer,
								OpenLayers.Handler.Point,
				{title:'Draw selection box', 'displayClass': 'olControlBox', handlerOptions: {'style': 'default'/*, layerOptions:{'styleMap': theStyle}*/, persist: true}});
		box.events.register("activate",null, function() { if(this.layer.features.length) this.layer.destroyFeatures(); });
		box.featureAdded = function(feature) { 
				this.deactivate();
				feature.state = OpenLayers.State.INSERT; 
				try{
					this.sourceButton.src=this.sourceButtonSrc;
				} catch (e){}
				edit_loadListElementsFromFeatureGeometry(feature.geometry);
		};
	box.sourceButton=obj; 
	box.sourceButtonSrc=currentSrc;
	map.addControl(box);
	box.activate();

}

/**
*	eina de sel·lecció de features de dins d'un bbox.
*/
function edit_selectWithBox(obj) {
	if (edit_askCancelEdit())return;
	edit_unloadEditingToolbar();
	
	var currentSrc="img/select_box.png";
	obj.src="img/select_box_on.png";

	var vlayer=edit_getSelectionVectorLayer();
	var theStyle=edit_getSelectionStyleMap();
		
	box = new OpenLayers.Control.DrawFeature(vlayer,
								OpenLayers.Handler.RegularPolygon,
				{title:'Draw selection box', 'displayClass': 'olControlBox', handlerOptions: {sides: 4,irregular:true, 'style': 'default'/*, layerOptions:{'styleMap': theStyle}*/, persist: true}});
		box.events.register("activate",null, function() { if(this.layer.features.length) this.layer.destroyFeatures(); });
		box.featureAdded = function(feature) { 
				this.deactivate();
				feature.state = OpenLayers.State.INSERT; 
				try{
					this.sourceButton.src=this.sourceButtonSrc;
				} catch (e){}
				edit_loadListElementsFromFeatureGeometry(feature.geometry);
				
		};
	box.sourceButton=obj; 
	box.sourceButtonSrc=currentSrc;
	map.addControl(box);
	box.activate();

}

/**
* petició a eliminar l'element
*/
function edit_deleteFeature(fid,point) {
	if (edit_askCancelEdit())return;
	edit_unloadEditingToolbar();

	if (!confirm("Eliminar?")) return;

	var configObj=edit_getCurrentLayerConfig();
	if (configObj===null) return;//no han escollit

	var data='<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" version="1.0.0" service="WFS"><wfs:Delete typeName="'+configObj.layerName+'"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="'+fid+'"/></ogc:Filter></wfs:Delete></wfs:Transaction>';

	// guardem variable global amb fid
	edit_deleteFeature_fid=fid;

	var request = OpenLayers.Request.POST({
		url: configObj.wfsUrl,
		data: data,
		headers: {
		"Content-Type": "application/xml"
		},

	   callback: edit_deleteFeatureCallback
	});
}

/**
* callback de la petició d'eliminar.
*/
function edit_deleteFeatureCallback(response) {
	if (response.status===200){
		// eliminat correctament. Posem a invisible l'element de la llista.
		document.getElementById("edit_"+edit_deleteFeature_fid).style.display="none";

		// TODO: refresquem el layer wms associat.
	} else {
		alert("Error eliminant:\n"+response.responseText);
	}
}

/**
* editar els atributs d'un feature.
*/
function edit_editAttributes(fid,point) {
	var configObj=edit_getCurrentLayerConfig();
	if (configObj===null) return;//no han escollit

	var id=fid.split(".")[1];

	var url=configObj.modifyUrl.replace("#id#",id);
	window.open(url);

}


// index del layer sel·leccionat
var editableLayersConfig_selectedIndex=null;
var editableLayersConfig;/* = [
	{
		"id":"1",
		"title":"Inversió primària",
		"serverUrl":"http://cervia:8080/geoserver/wfs",
		"typeName":"INVERSIO_LPRIMARIA",
		"layerName":"topp:INVERSIO_LPRIMARIA",
		"featureNS":"http://www.openplans.org/topp",
		"geometryColumn":"GEOM",
		"geometryType":"point",
		"associatedLayerName":"CERVIA"
	},
	{
		"id":"2",
		"title":"equipaments",
		"serverUrl":"http://cervia:8080/geoserver/wfs",
		"typeName":"equipaments",
		"layerName":"topp:equipaments",
		"featureNS":"http://www.openplans.org/topp",
		"geometryColumn":"the_geom",
		"geometryType":"polygon",
		"associatedLayerName":"CERVIA"
	},
	{
		"id":"3",
		"title":"INVERSIO_LSALUTMENTAL",
		"serverUrl":"http://cervia:8080/geoserver/wfs",
		"typeName":"INVERSIO_LSALUTMENTAL",
		"layerName":"topp:INVERSIO_LSALUTMENTAL",
		"featureNS":"http://www.openplans.org/topp",
		"geometryColumn":"GEOM",
		"geometryType":"point",
		"associatedLayerName":"CERVIA"
	},
	{
		"id":"4",
		"title":"INVERSIO_LHOSPITALS",
		"serverUrl":"http://cervia:8080/geoserver/wfs",
		"typeName":"INVERSIO_LHOSPITALS",
		"layerName":"topp:INVERSIO_LHOSPITALS",
		"featureNS":"http://www.openplans.org/topp",
		"geometryColumn":"GEOM",
		"geometryType":"point",
		"associatedLayerName":"CERVIA"
	}
];*/

/**
*
*/
function edit_getCurrentLayerConfig() {
	if (editableLayersConfig_selectedIndex===0) return null;
	return editableLayersConfig[editableLayersConfig_selectedIndex-1];
}


/**
* carrega la configuració dels layers editables al select.
*/
function edit_layerSelectorLoad() {
	var obj=document.getElementById("edit_layerSelect");
	if (obj==null) {
		// la petició es fa quan encara no s'ha carregat el toc_edicio.jsp. Esperem un segon.
		setTimeout("edit_layerSelectorLoad();",1000);
		return;
	}

	var o=new Option();
	o.value=-1;
	o.text="(cap dataset)";//TODO
	obj.options[0]=o;

	for (var i=0;i<editableLayersConfig.length ;i++ ){
		var layer=editableLayersConfig[i];
		var o=new Option();
		o.value=i;
		o.text=layer.title;
		obj.options[i+1]=o;
	}
	editableLayersConfig_selectedIndex=0;
}

/**
* layer editable canviat. Cal carregar el layer wms per visualitzar-lo.
*/
function edit_layerSelectChange(obj) {
	// si estem en mode edició i no volen cancel·lar, deixem l'anterior.
	if (edit_askCancelEdit()){
		obj.selectedIndex=editableLayersConfig_selectedIndex;
		return;
	}
	editableLayersConfig_selectedIndex=obj.selectedIndex;
	edit_unloadEditingToolbar();
	edit_clearList();

	// configuració del servidor wfs
	var configObj=edit_getCurrentLayerConfig();
	if (configObj===null) {//han escollit (cap dataset): desactivem edició.
		var layer=map.getLayersByName("wfs_edition_preview")[0];
		if (layer){
			layer.setVisibility(false);
		}
		return;
	}

	if (map.getLayersByName("wfs_edition_preview").length>0){
		var layer=map.getLayersByName("wfs_edition_preview")[0];
		layer.params.LAYERS=configObj.layerName;
		layer.setUrl(configObj.wmsUrl);
		layer.setVisibility(true);// el setvisibility ja fa redibuixar el layer quan passa d'inactiu a actiu
		layer.redraw();
	} else {
		var wmsparams={
				service: "WMS",
				layers: configObj.layerName, 
				version: "1.1.1",
				request: "GetMap", 
				styles: "",
				exceptions: null,
				format: "image/gif",
				transparent: true
				,userid: unescape(userId)
		};
		
		var layer = new OpenLayers.Layer.WMS(
				"wfs_edition_preview",
				configObj.wmsUrl,
				wmsparams,{
					isBaseLayer: false,
					buffer:0,
					gutter:0,
					visibility: true,
					singleTile: true,
					ratio:1 // si ratio = 1.2 catastro a escala 1000000 no es correspon amb versió impresa.
				}
		);
		map.addLayer(layer);
	}

	
}

function openLegend(){
	window.open(urlLlegenda);
}

function googleEarthClick(){

	try {

		var printer=new OpenLayers.NGPrint(map,treeContent);
		setPrintParameters(printer,false);

		printer.printerServlet=urlKml;

		var now=new Date();
		var date=now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear();
		var size="A4";
		var orientation="H";
		var pages="1";

		printer.createPDF("legendUrl",treeContent.servletUrl,
			"formatsize",size,
			"formatorientation",orientation,
			"formatpages",pages,
			"title",printTitle,
			"comment",printComment,
			"scale",parseInt(map.getScale()),
			"date",date);

		return;
		
	}
	catch (e) {
		alert("error a googleEarth()\n"+e.message);
	}
}
function esborrarPopup(){
	if (this.map) {
		layers=map.getLayersByName("Markers");
		if (layers.length>0)
		layers[0].destroy();
		while (this.map.popups.length>0){
			this.map.popups[0].destroy();
		}
	}
}

function viewHelp() {
	try {
		var lang="ca";
		var url="";
		showPopWin(urlHelp+"?link="+escape(url)+"&lang="+lang, 345,200, null, "popupTitleBar2");
	}
	catch (e) {
		alert("error a viewHelp()\n"+e.message);
	}
}
