var cor = ["#99CC33","#99CCCC","#CC6600","#FFCC99","#DF0101",'#6E6E6E','#6F4612','#3D59D3','#ED7878','#0B3B0B','#FF8000'];
var coresPorId = new Array();
var actual = 0;
var selectControl, selectedFeature;


OpenLayersRoteiroFacade = function(map) {

	this.init(map);
}


jQuery.extend(OpenLayersRoteiroFacade.prototype, {
	
	map: null,
		
	layers: [],
		
	layerTrazos: null,
		
	numLayers: 0,

	init: function(map){
	
		this.map = map;
		this.map.events.register('click', this, this.onPoligonoClick);
	},
		
	obterEstilo: function(){
			
		//Definimos un estilo para debuxar as 'features' sobre o mapa.
			
		var style = new OpenLayers.Style({},{
				
		    context: {
				
	        image: function(feature) {
	    			
				if(feature.attributes.count > 1){
						
					return "";
				}
				else{
	
					return "./icons/"+feature.cluster[0].attributes.tipoelemento+".png";	
				}
	    	},
	    		
	    	numeroElementos: function(feature) {
	    			
	    		if(feature.attributes.count>1){
	    				
	    			return "+";
	    		}
	    		else{
	    				
	    			return "";
	    		}
	    	},
	    		
	    	opacidad: function(feature) {
	    			
	    		if(feature.attributes.count>1){
	    				
	    			return "1";
	    		}
	    		else{
	    				
	    			return "0";
	    		}
	    			
	    	},
	    		
	    	asignarCorRoteiro: function(feature) {

					return obterC(feature.cluster[0].attributes.idroteiro);
	    	},
	    		
	    	asignarCorLina: function(feature) {
	    			
	    		if(feature.attributes.count > 1){
						
					return "black";
				}
				else{
	
					return obterC(feature.cluster[0].attributes.idroteiro);
				}
	    	},
	    		
	    	perimetroCadro: function(feature) {
	    			
	    		if(feature.attributes.count > 1){
	    				
	    			return 6;
	    		}
	    		else{
	    				
	    			return 3;
	    		}
	    	},
	    		
	    	anchoLina: function(feature) {
	    			
	    		if(feature.attributes.count > 1){
	    				
	    			return 1;
	    		}
	    		else{
	    				
	    			return 2;
	    		}
	    	},
	    		
	    	title: function(feature){
	    			
	    		if(feature.attributes.count > 1){
	    				
	    			return "Prema para despregar "+feature.attributes.count+" puntos";
	    		}
	    		else{
	    				
	    			return feature.cluster[0].attributes.nome;
	    		}
	    	}
	    }});
		
		

		var regraLonxe = new OpenLayers.Rule({

				  symbolizer: {
				
						pointRadius: "6",
				        fillColor: "${asignarCorRoteiro}",
				        fillOpacity: "${opacidad}",
				        graphicName: "square",
				        backgroundGraphic: "${image}",
				        strokeColor: "${asignarCorLina}",
				        strokeWidth: "${anchoLina}",
				        strokeOpacity: "1",
				        cursor: "pointer",
				        graphicOpacity: "1",
				        label: "${numeroElementos}",
				        fontSize: "9px",
				        fontWeight: "bold",
				        fontColor: "white",
				        explain: "${title}"
				  }
		});

		
		style.addRules([regraLonxe]);
			
		return style;
	},
		
	obterEstiloEspacio: function(){
			
			//Definimos un estilo para debuxar as 'features' sobre o mapa. 
			
			var style = new OpenLayers.Style({}, {
				
		        context: {
				
		            fondo: function(feature) {
		    			
						if(feature.attributes.tipoelemento == 'rio'){
							
							return "#4080FF";
						}
						else{
		
							return "#BADD8D";	
						}
		    		},
		    		
		    		linea: function(feature) {
		    			
						if(feature.attributes.tipoelemento == 'rio'){
							
							return "#4180FC";
						}
						else{
		
							return "#68AE0F";	
						}
		    		}
				}
			});

			var regraLonxe = new OpenLayers.Rule({

				  symbolizer: {
				
				        fillColor: "${fondo}",
				        fillOpacity: 0.3,
				        strokeColor: "${linea}",
				        strokeWidth: 1,
				        strokeOpacity: 1,
				        cursor: "pointer"
				  }
			});

			style.addRules([regraLonxe]);
			
			return style;
	},
		
	obterEstiloRio: function(){
			
			//Definimos un estilo para debuxar as 'features' sobre o mapa. 
			
			var style = new OpenLayers.Style();

			var regraLonxe = new OpenLayers.Rule({

				  symbolizer: {
				
				        fillColor: "#4080FF",
				        fillOpacity: 0.2,
				        strokeColor: "#4080FF",
				        strokeWidth: 1,
				        strokeOpacity: 1,
				        cursor: "pointer"
				  }
			});

			style.addRules([regraLonxe]);
			
			return style;
	},
		
	engadirTodos: function(){
			
			//Creamos a url para realizar a peticion WFS ao servidor de mapas.
				
			requestUrl = '/geoserver/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=getfeature&typename=topp:vista_puntos_interes';
					
			request = OpenLayers.Request.GET({
				url: requestUrl,
				async: false
			});

			//Realizamos a peticion WFS e parseamos o GML resultante obtendo así as 'features'
			
			var feat = new OpenLayers.Format.GML().read(request.responseText);
			var roteiros = new Array();
			
			for(var f in feat){
				
				feat[f].geometry.transform(new OpenLayers.Projection("EPSG:23029"),new OpenLayers.Projection("EPSG:900913"));
				
				if(roteiros[feat[f].attributes.idroteiro] == null){
					
					roteiros[feat[f].attributes.idroteiro] = new Array();
				}
				
				roteiros[feat[f].attributes.idroteiro][roteiros[feat[f].attributes.idroteiro].length] = feat[f];
			}
			
			for(var r in roteiros){
				
				var layer = new OpenLayers.Layer.Vector("Roteiro"+r, {
					strategies: [
			                     new OpenLayers.Strategy.Cluster({distance:13})
			        ],
					displayInLayerSwitcher: false,
					styleMap: new OpenLayers.StyleMap({
			            "default": this.obterEstilo()
			        }),
					projection: new OpenLayers.Projection("EPSG:900913") 
			    });
				
				this.engadirRiosEspazos(r);
				this.map.addLayers([layer]);
				layer.addFeatures(roteiros[r]);
				this.actualizarControl();
			}

	},
		
	engadirRoteiro: function(id,recentrar,trameado,cor){
		
			this.engadirRiosEspazos(id);
		
			if(this.map.getLayersByName("Roteiro"+id).length == 0){
					
					//Creamos a url para realizar a peticion WFS ao servidor de mapas.
				
					requestUrl = '/geoserver/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=getfeature&typename=topp:vista_puntos_interes';
					requestUrl = requestUrl+'&Filter=<Filter><PropertyIsEqualTo><PropertyName>idroteiro</PropertyName><Literal>'+id+'</Literal></PropertyIsEqualTo></Filter>';
			
					request = OpenLayers.Request.GET({
						url: requestUrl,
						async: false
			});

			//Creamos unha capa que contera todos os puntos do roteiro 'id' asignandolle o estilo que vimos de crear.
			
			var layer = new OpenLayers.Layer.Vector("Roteiro"+id, {
				strategies: [
		                     new OpenLayers.Strategy.Cluster({distance:13})
		        ],
				displayInLayerSwitcher: false,
				styleMap: new OpenLayers.StyleMap({
		            "default": this.obterEstilo()
		        }),
				projection: new OpenLayers.Projection("EPSG:900913")     
		    });
			
			this.map.addLayers([layer]);
			
			//Realizamos a peticion WFS e parseamos o GML resultante obtendo así as 'features'
			
			var feat = new OpenLayers.Format.GML().read(request.responseText);
		
			for(var f in feat){
				
				feat[f].geometry.transform(new OpenLayers.Projection("EPSG:23029"),new OpenLayers.Projection("EPSG:900913"));
			}
			
			layer.addFeatures(feat);
		
			//Coas novas capas engadidas actualizamos o control de seleccionar as features.
			
			this.actualizarControl();
			
			if(recentrar == true){
				
				this.map.zoomToExtent(layer.getDataExtent());
				this.map.zoomToExtent(layer.getDataExtent());
				
				if(this.map.getZoom()>8){
					
					this.map.zoomTo(8);
				}
			}
			
			}
			
			else{
				
				this.map.getLayersByName("Roteiro"+id)[0].display(true);
			}
		},

		borrarRoteiro: function(id){

			//Borrar un roteiro consiste en eliminar a capa dos poligonos, eliminar a capa do roteiro, e a capa das liñas 'id'
			//e despois actualizar o control de seleccionar as features.

			this.map.getLayersByName("Roteiro"+id)[0].destroy();
			this.map.getLayersByName("Poligonos"+id)[0].destroy();
			this.map.getLayersByName("Lineas"+id)[0].destroy();
			this.actualizarControl();
		},
		
		centrarRoteiro: function(id){
			
			centerLayer = this.map.getLayersByName("Roteiro"+id)[0];
			this.map.zoomToExtent(centerLayer.getDataExtent());
			this.map.zoomToExtent(centerLayer.getDataExtent());
			this.map.setBaseLayer(this.map.getLayersByClass("OpenLayers.Layer.Google")[0]);
		},
		
		onPopupClose: function(evt) {
			
		    selectControl.unselect(selectedFeature);
		},

		actualizarControl: function(){
			
			//Actualiza o control 'SelectFeature' cada vez que se engade ou elimina unha capa. Permite seleccionar unha feature de
			//calquera das capas que se amosan no mapa e non so de unha.
			
			this.map.removeControl(selectControl);
			
			//Capas visibles no mapa
			
			this.layers = [];
			
			for(l in this.map.layers){
				
				if(this.map.layers[l].CLASS_NAME == 'OpenLayers.Layer.Vector'){
					this.layers[this.layers.length] = this.map.layers[l];
				}
			}
			
			this.numLayers = this.layers.length;
			
			selectControl = new OpenLayers.Control.SelectFeature(this.layers,
					{scope:{"map":this.map,"onPopupClose": this.onPopupClose} ,onSelect: this.onFeatureSelect, onUnselect: this.onFeatureUnselect});
			
			this.map.addControl(selectControl);
			selectControl.activate();
		},
		
		onFeatureSelect: function(feature) {

			//Evento que se lanza cada vez que se preme sobre unha feature.
			
			selectedFeature = feature;

			//Se prememos sobre un grupo onde existen mais de un elemento, amosarase unha lista cos elementos nese punto.
			
			if(selectedFeature.cluster){
			
				if(selectedFeature.attributes.count > 1){
				
					var idElemento;
				    html = "<div class='titleBar'>Puntos de interese</div><div class='contentBar'>";
				    
				    for(f in feature.cluster){
				    	
				    	currentFeature = feature.cluster[f];
				    	var name = currentFeature.attributes.nome;
				    	
				    	if(currentFeature.attributes.ecasa == 'true'){
				    		
				    		idElemento = currentFeature.attributes.idcasa;
				    	}
				    	else{
				    		
				    		idElemento = currentFeature.attributes.idelementoxeografico;
				    	}
			
				    	html = html+"<div class='linea'><div class='izq'><b><a class='thickbox' href='javascript:verElemento(\""+currentFeature.attributes.tipoelemento+"\","+idElemento+");'>" + name +"</a></b><br /><i>" + currentFeature.attributes.tipoelemento+"</i></div>"+
				        "<div class='der'><img src='./icons/"+currentFeature.attributes.tipoelemento+".png'/></div><div class='clear'></div></div>";
				    }
		
				    html = html+"</div>";
				    
				    
				    if(this.map.size.w <= 300){
				    	
				    	ll = this.map.getLonLatFromPixel(new OpenLayers.Pixel(10,45));
				    }
				    else{
				    	
				    	ll = feature.geometry.getBounds().getCenterLonLat();
				    };
		
				    popup = new OpenLayers.Popup.Anchored("info", 
				                             ll,
				                             null, html,
				                             null, true, this.onPopupClose);
		
				    feature.popup = popup;
				    this.map.addPopup(popup);
				    
				}
				else{
					
					//Se prememos sobre un so elemento abrirase unha ventana modal coa informacion do elemento empregando o
					//metodo 'verElemento' que se atopa en '/scripts/xeografiafacade/HTMLXeografiaFacade.js'
					
					if(selectedFeature.cluster[0].attributes.ecasa == 'true'){
			    		
			    		idElemento = selectedFeature.cluster[0].attributes.idcasa;
			    	}
			    	else{
			    		
			    		idElemento = selectedFeature.cluster[0].attributes.idelementoxeografico;
			    	}
					
					verElemento(selectedFeature.cluster[0].attributes.tipoelemento,idElemento);
				}
			}
			
			else{
				
				verElemento(selectedFeature.attributes.tipoelemento,selectedFeature.attributes.idelementoxeografico);
			}
		},

		onFeatureUnselect: function(feature) {
			
			if(feature.popup != null){
				this.map.removePopup(feature.popup);
			}
		},
		
		desmarcarFeature: function() {
			
			if(selectControl && selectedFeature)
				selectControl.unselect(selectedFeature);
		},
		
		engadirRiosEspazos: function(idRoteiro) {
			
			//Creamos outra capa que contera aos espazos do roteiro 'id' que se obteñen dunha peticion WMS.
			

			poligonoUrl = '/geoserver/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=getfeature&typename=topp:vista_poligonos_interes';
			poligonoUrl = poligonoUrl+'&Filter=<Filter><PropertyIsEqualTo><PropertyName>idroteiro</PropertyName><Literal>'+idRoteiro+'</Literal></PropertyIsEqualTo></Filter>';
			
			var poligonos = new OpenLayers.Layer.Vector("Poligonos"+idRoteiro, {
				
                strategies: [
                    new OpenLayers.Strategy.Fixed()
                ],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: poligonoUrl,
                    format: new OpenLayers.Format.GML({geometryName: "poly_geom"})
                }),
                styleMap: new OpenLayers.StyleMap({
		            "default": this.obterEstiloEspacio()
		        }),
		        displayInLayerSwitcher: false
			});
			
			//Creamos outra capa que contera aos rios do roteiro 'id' que se obteñen dunha peticion WMS.
			
			lineaUrl = '/geoserver/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=getfeature&typename=topp:vista_lineas_interes';
			lineaUrl = lineaUrl+'&Filter=<Filter><PropertyIsEqualTo><PropertyName>idroteiro</PropertyName><Literal>'+idRoteiro+'</Literal></PropertyIsEqualTo></Filter>';
			
			var lineas = new OpenLayers.Layer.Vector("Lineas"+idRoteiro, {
				
                strategies: [
                    new OpenLayers.Strategy.Fixed()
                ],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: lineaUrl,
                    format: new OpenLayers.Format.GML({geometryName: "line_geom"})
                }),
                styleMap: new OpenLayers.StyleMap({
		            "default": this.obterEstiloRio()
		        }),
		        displayInLayerSwitcher: false
			});

			this.map.addLayers([lineas,poligonos]);
			this.actualizarControl();
		}
//		,
//		onPoligonoClick: function(evt) {
//		
//			//Cando prememos nun poligono realizamos unha petición ao servidor de mapas e amosamos unha
//			//ventana modal coa informacion recibida.
//			
//			var url =  this.map.getLayersByName("Concellos")[0].getFullRequestString(
//	                {
//	                    REQUEST: "GetFeatureInfo",
//	                    EXCEPTIONS: "application/vnd.ogc.se_xml",
//	                    BBOX: this.map.getExtent().toBBOX(),
//	                    X: evt.xy.x,
//	                    Y: evt.xy.y,
//	                    INFO_FORMAT: 'application/vnd.ogc.gml',
//	                    QUERY_LAYERS: 'topp:vista_poligonos_interes,topp:vista_lineas_interes',
//	                    WIDTH: this.map.size.w,
//	                    HEIGHT: this.map.size.h,
//	                    FEATURE_COUNT: 50
//	                    
//	                },
//	                "/geoserver/wfs"
//	        );
//			
//			request = OpenLayers.Request.GET({
//				   url: url,
//				   async: false
//			});
//
//			
//			var features = new OpenLayers.Format.GML().read(request.responseText);
//			
//			if(features.length>0){
//				verElemento(features[0].attributes.tipoelemento,features[0].attributes.idelementoxeografico);
//			}
//			
//		}
});

function obterC(id){

	if(coresPorId[id]){
		
		return coresPorId[id];
	}
	else{
		coresPorId[id] = cor[actual];
		actual = (actual+1) % cor.length;
		return coresPorId[id];
	}
}
