/* OpenLayers */
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 2;
OpenLayers.Layer.Grid.buffer = 0;
OpenLayers.Layer.Grid.prototype.buffer = 0;

/* VISORUMAT */
VisorUMAT = function() {
	var _this = this;

    this.map;
    this.overview;
	this.layerSwitcher;
	this.panel;
	this.featureInfo;
	this.queryEventHandler;
	this.full_screen;

	this.initial_zoom_completed = false;
	this.initial_zoombox = 0;

	// Canviar la mida dels divs per ajustar-nos a la pantalla
    this.resizeTimer = null;

    $(window).bind('resize', function() {
        if (_this.resizeTimer) clearTimeout(_this.resizeTimer);
		_this.resizeTimer = setTimeout(_this.window_resized, 250);
    });

	this.window_resized = function() {
		var borders_vertical = jQuery.browser.msie ? 0 : 0;
		var win = $(window);
		var height = win.height();
		var width = win.width();
		var capsalera = $('#capsalera');
		var contingut = $('#mapDiv');
		var div_contingut = $('#div_contingut');
		var eines_mapa = $('#div_eines_mapa');
		var peupagina = $('#peupagina');
		var content_left = $('#content_left');

		capsalera_height = $('#capsalera').is(':visible')? capsalera.height() : 0;
		peupagina_height = $('#peupagina').is(':visible')? peupagina.height() : 0;
//		contentleft_height = $('#contentleft_width').is(':visible')? content_left.width() : 0;
//		contentleft_width = $('#contentleft_width').is(':visible')? content_left.width() : 0;
		
		var new_height;
		if ((content_left.height() + capsalera_height) < win.height()) {
			if ((content_left.height() + capsalera_height + eines_mapa.height() + borders_vertical) < win.height()) {
				new_height = win.height() - capsalera_height - peupagina_height - eines_mapa.height() - borders_vertical;
			} else {
				new_height = content_left.height() - eines_mapa.height() - borders_vertical;
			}
		} else {
			new_height = win.height() - capsalera_height - eines_mapa.height() - borders_vertical;
		}

		contingut.height(new_height);
		// sense animació perquè l'IE ho fa a sotregades
		// contingut.animate({height: new_height}, "fast")

		if (_this.map) {
			var controls = _this.map.getControlsByClass('OpenLayers.Control.OptionsButton');
			for (i in controls) {
				if (controls[i].active) {
					controls[i]._options_position();
				}
			}
		}
	}

    this.init = function(conf) {
		/*
		layer2 = new OpenLayers.Layer.WMS("Noms barris",
				"http://arcgis:8399/arcgis/services/aparcaments_bici/MapServer/WMSServer", {layers: ['4'], format: "image/png", transparent: "true"}
				, {isBaseLayer: false, transparent: true}
				 );
		map.addLayer(layer2);
		*/
	}
    
    this.ajax_error = function(XMLHttpRequest, textStatus, errorThrown) {
		alert("No s'ha pogut recuperar les dades: " + textStatus);
		popup.setContentHTML('Error');
    }

    this.layer_toggle_visible = function(nom) {
    	var layer = _this.map.getLayersBy('code', nom)[0];
    	
    	if (layer.isBaseLayer) {
        	if (_this.map.baseLayer.name != nom) {
        		var previousBase = _this.map.baseLayer; 
        		layer.setVisibility(true);
        		_this.map.setBaseLayer(layer);
        		previousBase.setVisibility(false);
        	} else {
        		if (_this.baseDefault != undefined) {
            		var previousBase = _this.map.baseLayer; 
            		_this.baseDefault.setVisibility(true);
            		_this.map.setBaseLayer(_this.baseDefault);
            		previousBase.setVisibility(false);
        		}
        	}
    	} else {
    		layer.setVisibility( ! layer.getVisibility());
    	}
    }

    this.check_identify_visibility = function() {
    	var sel = $("#layerActiu").val();
    	var layers = _this.map.getLayersBy('identify', sel);
    	for (i in layers) {
    		layer = layers[i];
    		if (! layer.getVisibility()) {
    			layer.setVisibility(true);
    		}
    	}
    }

    this.visibility_changed = function(event) {
    	var layer = event.object
    	if (layer.getVisibility()) {
        	if (layer.grupVisibilitat) {
        		var gv = _this['gv_' + layer.grupVisibilitat];
        		for (var i in gv) {
        			if (gv[i] == layer.code) continue;
        			_this.map.getLayersBy('code', gv[i])[0].setVisibility(false);
        		}
        	}
        	
        	$('#layer_' + layer.code).addClass('icon_visible');
    	} else {
        	$('#layer_' + layer.code).removeClass('icon_visible');
    	}

    	layers = _this.map.getLayersBy('sourceLayer', layer.code);
    	for (i in layers) {
    		linked = layers[i];
    		linked.setVisibility(layer.getVisibility());
    	}

    	for (i in _this.map.popups) {
    		popup = _this.map.popups[i];
    		if (popup.sourceLayer == layer.code) {
	    		if (layer.getVisibility()) {
	    			popup.show();
	    		} else {
	    			popup.hide();
	    		}
	    	}
    	}

    	// Identify
    	if (layer.getVisibility() && layer.identify) {
    		$("#layerActiu").val(layer.identify);
    	}
    	
    }

    this.zoom_changed = function(event) {
    	var map = event.object;
    	for (var i in map.layers) {
    		var layer = map.layers[i];
    		if (layer.calculateInRange()) {
    			$('#layer_' + layer.code).removeClass('disabled');
    		} else {
    			$('#layer_' + layer.code).addClass('disabled');
    		}
    	}

    	for (var j in _this) {
    		if (j.substring(3,0) == "ls_") {
    			var layer = map.getLayersByName(j.substring(3))[0];
    			if (layer.calculateInRange()) {
    				for (var k in _this[j]) {
    					$('#layer_' + _this[j][k].name).removeClass('disabled');
    				}
        		} else {
    				for (var k in _this[j]) {
    					$('#layer_' + _this[j][k].name).addClass('disabled');
        			}
        		}
    		}
    	}

    }
    
    this.identify = function(event, popup) {
        pos = _this.map.getLonLatFromPixel(event.xy);

    	var params = {};
//    	params['x'] = event.xy.x;
//    	params['y'] = event.xy.y;
//    	params['x'] = pos.lon;
//    	params['y'] = pos.lat;
    	params['id'] = $('#layerActiu').val();
    	params['BBOX'] = _this.map.getExtent().toBBOX();
    	params['X'] = event.xy.x;
    	params['Y'] = event.xy.y;
    	params['WIDTH'] = _this.map.size.w;
    	params['HEIGHT'] = _this.map.size.h;
//        QUERY_LAYERS: wms.params.LAYERS,

    	$.ajax({
    		url: "visor/identify",
    		cache: false,
    		data: params,
    		dataType: "json",
    		error: _this.ajax_error,
    	success:
    		function(data, textStatus){
    		if (data['error'] != undefined) {
    			alert("No s'ha pogut recuperar les dades: " + data['error']);
				popup.setContentHTML('Error');
    			return;
    		}

           	popup.setContentHTML(data['html']);
           	popup.sourceLayer = data['source_layer'];
    	}
    	});
    }

    this.seleccio = function(selector, valor, zoombox) {
    	var params = {};
    	params['sel'] = selector;
    	params['valor'] = valor;

    	if (zoombox != undefined) {
        	params['zoombox'] = zoombox;
    	}
    	
    	$.ajax({
    		url: "visor/seleccio",
    		cache: false,
    		data: params,
    		dataType: "json",
    		error: _this.ajax_error,
    	success:
    		function(data, textStatus){
    		if (data['error'] != undefined) {
    			alert("No s'ha pogut recuperar les dades: " + data['error']);
    			if (!_this.initial_zoom_completed) {
    				//FIXME: vista inicial en comptes de full extent
    				_this.map.zoomToMaxExtent();
    				_this.initial_zoom_completed = true;
    			}
    			return;
    		}

//    		alert('success: ' + data['layerName'] + ' ' + data['fieldName'] + ' - source: ' + data['sourceLayer']);

    		var bounds = new OpenLayers.Bounds(data['box']['minx'], data['box']['miny'], data['box']['maxx'], data['box']['maxy']);
/*
			if (!_this.initial_zoom_completed && _this.initial_zoombox) {
				bounds.left -= _this.initial_zoombox;
				bounds.bottom -= _this.initial_zoombox;
				bounds.right += _this.initial_zoombox;
				bounds.top += _this.initial_zoombox;
			}
*/
    		_this.map.zoomToExtent(bounds);

    		_this.initial_zoom_completed = true;

    		var layername = "highlight_" + data['layerName'];
//    		for (i in data) {
//    			alert(i + ": " + data[i]);
//    		}
    		
    		var layer = _this.map.getLayersByName(layername)[0];
    		if (layer) {
    			_this.map.removeLayer(layer);
    		}

//    		var filter = data['layerName'] + ':' + data['fieldName'] + " = '" + data['fieldValue'] + "'";
    		var filter = data['tipus'] + ':' + data['fieldName'] + " = '" + data['fieldValue'] + "'";
    		
    		layer = new OpenLayers.Layer.WMS(layername,
                "visor/seleccio_wms?LAYERDEFS=" + filter, 
				{layers: data['layerName'], format: "image/png", transparent: "TRUE"},
				{isBaseLayer: false, visibility: false, buffer: 0});
            _this.map.addLayer(layer);

    		//layer.filter = data['fieldName'] + " LIKE '%" + data['fieldValue'] + "%'";
    		layer.filter = data['fieldName'] + " = '" + data['fieldValue'] + "'";
    		//layer.setLayerFilter(data['layerName'], layer.filter);
    		
    		if (data['sourceLayer']) {
    			layer.sourceLayer = data['sourceLayer'];
    			try {
    				var layer2 = _this.map.getLayersByName(data['sourceLayer'])[0];
    				layer2.setVisibility(true);
    			} catch (e) {}
    		}
    		layer.redraw();
    		layer.setVisibility(true);
    	}
    	});
    }
    
	this.select_eina_pan = function() {
		panel.getControlsByClass("OpenLayers.Control.Navigation")[0].activate();
	}

    this.layerswitcher_toggle_visible = function(nom, layername) {
    	var layer = _this.map.getLayersBy('code', nom)[0];
		var ls = _this['ls_' + nom];
    	var new_layers = [];

		for (var i = ls.length - 1; i >= 0; i -= 1) {
    		if (ls[i].name == layername) {
    			ls[i].visibility = ! ls[i].visibility;
    			if (ls[i].visibility) {
    				$('#layer_' + layername).addClass('icon_visible');
        		} else {
        			$('#layer_' + layername).removeClass('icon_visible');
        		}
    		}

    		if (ls[i].visibility) {
    			for (j in ls[i].layers) {
        			new_layers.push(ls[i].layers[j]);
    			}
    		}
    	}

    	if (new_layers.length > 0) {
    		layer.params['LAYERS'] = new_layers;
    		layer.setVisibility(true);
    		layer.redraw();
    	} else {
    		layer.setVisibility(false);
    		layer.params['LAYERS'] = new_layers;
    	}
    }
};


	var previousPopup;

	function doOnHover(feature) {
		if (previousPopup != undefined) {
			map.removePopup(previousPopup);
		}

		html = feature.attributes.name + "<br/>" + (feature.attributes.total ? feature.attributes.total : "");
		var popup = new OpenLayers.Popup.FramedCloud(
                        "chicken", 
						feature.geometry.bounds.getCenterLonLat(),
                        null,
                        html,
                        null,
                        true);
		map.addPopup(popup);
		previousPopup = popup;
	}

	
		function init2() {
//            map.setCenter(new OpenLayers.LonLat(2.46, 41.57), 1);
//            map.setCenter(new OpenLayers.UTM(482000, 4645000), 14);
            
        }


OpenLayers.Control.OptionsButton = OpenLayers.Class(OpenLayers.Control, {
	initialize: function(options) {
		OpenLayers.Control.prototype.initialize.apply(this, arguments);
	},

    setMap: function() {
		this.events.register("activate", this, function() { this._on_activate(); });              
		this.events.register("deactivate", this, function() { this._on_deactivate(); });
    },     

    on_activate: function() {},
    _on_activate: function() {
    	$('#' + this.optionsdivid + 'OptionsDiv').show();

//    	this._options_position();
    	this.on_activate();
    },
    
    on_deactivate: function() {},
    _on_deactivate: function() {
    	$('#' + this.optionsdivid + 'OptionsDiv').hide();
    	this.on_deactivate();
    },

    _options_position: function() {
    	var x_max = $('#div_contingut').width() - $('#' + this.optionsdivid + 'OptionsDiv').width();
       	
    	var pos = $("." + this.displayClass + "ItemInactive").position() || $("." + this.displayClass + "ItemActive").position();
    	var parent = $("." + this.displayClass + "ItemInactive").parent().position() || $("." + this.displayClass + "ItemActive").parent().position();
    	var x_eina = pos.left - parent.left;

    	var x_posicio = x_eina - ($('#' + this.optionsdivid + 'OptionsDiv').width() / 2)
    	x_posicio = Math.max(0, x_posicio);

//    	$('#' + this.optionsdivid + 'OptionsDiv').css('margin-left', Math.min(x_posicio, x_max));
    },

    CLASS_NAME: "OpenLayers.Control.OptionsButton"
});

OpenLayers.Control.OptionsPanel = OpenLayers.Class(OpenLayers.Control, {

	initialize: function(options) {
		OpenLayers.Control.prototype.initialize.apply(
				this, arguments
		);
	},

	draw: function() {
//        OpenLayers.Control.prototype.draw.apply(this, arguments);
        
        var eventsToStop = ['click', 'dblclick', 'mousedown'];
        var eventsToStop = [];
        
        for (var i=0, len=eventsToStop.length; i<len; i++) {
            OpenLayers.Event.observe(this.div,
                                     eventsToStop[i], 
                                     OpenLayers.Event.stop);
        }

        return this.div;
    }
});

OpenLayers.Control.PanZoomBarUMAT = OpenLayers.Class(OpenLayers.Control.PanZoomBar, {
	
	img_base: "http://terra2.girona.cat/static/VisorUMAT-3.0/theme/default/img/",

    initialize: function() {
        OpenLayers.Control.PanZoomBar.prototype.initialize.apply(this, arguments);
    },

    destroy: function() {
        OpenLayers.Control.PanZoomBar.prototype.destroy.apply(this, arguments);
    },

    draw: function(px) {
	    // initialize our internal div
        OpenLayers.Control.prototype.draw.apply(this, arguments);
	    px = this.position.clone();
	
	    // place the controls
	    this.buttons = [];
	
	    var sz = new OpenLayers.Size(18,18);
        var centered = new OpenLayers.Pixel(px.x+sz.w, px.y);
	    var wposition = sz.w;

	    var imgLocation = this.img_base + "panzoombar_background.png";
	    var btn = OpenLayers.Util.createAlphaImageDiv(
	            this.id + "_" + "background", 
	            px,
	            new OpenLayers.Size(54,55),
	            imgLocation,
	            "absolute");

	    //we want to add the outer div
	    this.div.appendChild(btn);
		this.buttons.push(btn);

	    this._addButton("panup", "panzoombar_north2.png", centered, sz);
	    px.y = centered.y+sz.h;
	    this._addButton("panleft", "panzoombar_west2.png", px, sz);
	    this._addButton("zoomstart", "zoom-world-mini.png", px.add(sz.w, 0), sz);
	    wposition *= 2;
	    this._addButton("panright", "east-mini.png", px.add(wposition, 0), sz);
	    this._addButton("pandown", "south-mini.png", centered.add(0, sz.h*2), sz);
	    this._addButton("zoomin", "zoom-plus-mini.png", centered.add(-1, sz.h*3+5), sz);
        centered = this._addZoomBar(centered.add(-1, sz.h*4 + 5));
	    this._addButton("zoomout", "zoom-minus-mini.png", centered.add(0, 0), sz);
	    return this.div;
	},

    _addButton:function(id, img, xy, sz) {
        var imgLocation = this.img_base + img;
//        var btn = OpenLayers.Util.createAlphaImageDiv(
//                                    this.id + "_" + id, 
//                                    xy, sz, imgLocation, "absolute");

		var btn = OpenLayers.Util.createDiv(this.id + "_" + id);

        //we want to add the outer div
        this.div.appendChild(btn);

        OpenLayers.Event.observe(btn, "mousedown", 
            OpenLayers.Function.bindAsEventListener(this.buttonDown, btn));
        OpenLayers.Event.observe(btn, "dblclick", 
            OpenLayers.Function.bindAsEventListener(this.doubleClick, btn));
        OpenLayers.Event.observe(btn, "click", 
            OpenLayers.Function.bindAsEventListener(this.doubleClick, btn));
        btn.action = id;
        btn.className = 'panZoomBar_' + id;
        btn.map = this.map;
//        btn.position = xy.clone();
        btn.style.left = xy.x + "px";
        btn.style.top = xy.y + "px";
    
        if(!this.slideRatio){
            var slideFactorPixels = this.slideFactor;
            var getSlideFactor = function() {
                return slideFactorPixels;
            };
        } else {
            var slideRatio = this.slideRatio;
            var getSlideFactor = function(dim) {
                return this.map.getSize()[dim] * slideRatio;
            };
        }

        btn.getSlideFactor = getSlideFactor;

        //we want to remember/reference the outer div
        this.buttons.push(btn);
        return btn;
    },

    _addZoomBar:function(centered) {
//        var imgLocation = OpenLayers.Util.getImagesLocation();
        var imgLocation = this.img_base;

        var id = this.id + "_" + this.map.id;
        var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();
/*
*/
        var slider = OpenLayers.Util.createAlphaImageDiv(id,
                       centered.add(0, zoomsToEnd * this.zoomStopHeight), 
                       new OpenLayers.Size(21,11), 
                       imgLocation + "panzoombar_slider.png",
                       "absolute");
        this.slider = slider;

/*
        centered.add(-1, zoomsToEnd * this.zoomStopHeight)

		var slider = OpenLayers.Util.createDiv(this.id + "_" + 'slider');
        slider.className = 'panZoomBar_' + 'slider';
        slider.style.position = "absolute";
        slider.style.left = centered.x + "px";
        slider.style.top = centered.y + "px";
        this.slider = slider;
*/        

        this.sliderEvents = new OpenLayers.Events(this, slider, null, true,
                                            {includeXY: true});
        this.sliderEvents.on({
            "mousedown": this.zoomBarDown,
            "mousemove": this.zoomBarDrag,
            "mouseup": this.zoomBarUp,
            "dblclick": this.doubleClick,
            "click": this.doubleClick
        });
        
        var sz = new OpenLayers.Size();
        sz.h = this.zoomStopHeight * this.map.getNumZoomLevels();
        sz.w = this.zoomStopWidth;
        var div = null;
        
        if (OpenLayers.Util.alphaHack()) {
            var id = this.id + "_" + this.map.id;
            div = OpenLayers.Util.createAlphaImageDiv(id, centered,
                                      new OpenLayers.Size(sz.w, 
                                              this.zoomStopHeight),
                                      imgLocation + "panzoombar_zoombar.png", 
                                      "absolute", null, "crop");
            div.style.height = sz.h + "px";
        } else {
            div = OpenLayers.Util.createDiv(
                        'OpenLayers_Control_PanZoomBar_Zoombar' + this.map.id,
                        centered,
                        sz,
                        imgLocation+"panzoombar_zoombar.png");
        }
        
        this.zoombarDiv = div;
        
        this.divEvents = new OpenLayers.Events(this, div, null, true, 
                                                {includeXY: true});
        this.divEvents.on({
            "mousedown": this.divClick,
            "mousemove": this.passEventToSlider,
            "dblclick": this.doubleClick,
            "click": this.doubleClick
        });
        
        this.div.appendChild(div);

        this.startTop = parseInt(div.style.top);
        this.div.appendChild(slider);

        this.map.events.register("zoomend", this, this.moveZoomBar);

        centered = centered.add(0, 
            this.zoomStopHeight * this.map.getNumZoomLevels());
        return centered; 
    },

    moveZoomBar:function() {
        var newTop = 
            ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) * 
            this.zoomStopHeight + this.startTop;
        this.slider.style.top = (newTop - 1) + "px";
    },

    buttonDown: function (evt) {
        if (!OpenLayers.Event.isLeftClick(evt)) {
            return;
        }

        switch (this.action) {
        case "zoomstart":
        	this.map.zoomStart();
            break;
        }

        OpenLayers.Control.PanZoom.prototype.buttonDown.apply(this, arguments);
    }

});

OpenLayers.Control.MousePositionUMAT = OpenLayers.Class(OpenLayers.Control, {
    lastXy: null,
    numDigits: 0,
    elemX: "",
    elemY: "",
    inputX: null,
    inputY: null,

    /**
     * Method: destroy
     */
     destroy: function() {
         if (this.map) {
             this.map.events.unregister('mousemove', this, this.redraw);
         }
         OpenLayers.Control.prototype.destroy.apply(this, arguments);
     },

    /**
     * Method: draw
     * {DOMElement}
     */    
    draw: function() {
        OpenLayers.Control.prototype.draw.apply(this, arguments);

        this.inputX = document.getElementById(this.elemX);
        this.inputY = document.getElementById(this.elemY);
        
        this.redraw();
        return this.div;
    },
   
    /**
     * Method: redraw  
     */
    redraw: function(evt) {

        var lonLat;

        if (evt == null) {
            lonLat = new OpenLayers.LonLat(0, 0);
        } else {
            if (this.lastXy == null ||
                Math.abs(evt.xy.x - this.lastXy.x) > this.granularity ||
                Math.abs(evt.xy.y - this.lastXy.y) > this.granularity)
            {
                this.lastXy = evt.xy;
                return;
            }

            lonLat = this.map.getLonLatFromPixel(evt.xy);
            if (!lonLat) { 
                // map has not yet been properly initialized
                return;
            }    
            if (this.displayProjection) {
                lonLat.transform(this.map.getProjectionObject(), 
                                 this.displayProjection );
            }      
            this.lastXy = evt.xy;
            
        }
        
        var digits = parseInt(this.numDigits);
        if (this.inputX != null) {
        	this.inputX.value = lonLat.lon.toFixed(digits);
        }
        if (this.inputY != null) {
          this.inputY.value = lonLat.lat.toFixed(digits);
        }

    },

    /** 
     * Method: setMap
     */
    setMap: function() {
        OpenLayers.Control.prototype.setMap.apply(this, arguments);
        this.map.events.register( 'mousemove', this, this.redraw);
    },     

    CLASS_NAME: "OpenLayers.Control.MousePositionUMAT"
});

OpenLayers.Control.ScaleUMAT = OpenLayers.Class(OpenLayers.Control, {
   
    input_id: null,
    input: null,
/*    
    initialize: function(element, options) {
    	this.input = document.getElementById(element);
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
    },
*/
    draw: function() {
        OpenLayers.Control.prototype.draw.apply(this, arguments);
        this.input = document.getElementById(this.input_id);
        this.map.events.register( 'moveend', this, this.updateScale);
        this.updateScale();
        return this.div;
    },
   
    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) {
            scale = Math.round(scale / 1000000) + "M";
        } else {
            scale = Math.round(scale);
        }    

        if (this.input != null) {
        	this.input.value = OpenLayers.i18n("scale", {'scaleDenom':scale});
        	this.input.value = scale;
        }
    }, 

    CLASS_NAME: "OpenLayers.Control.ScaleUMAT"
});

