/********************************************************************************
 COPYRIGHT(C):  IAAA-2003
 PROYECTO:      Búsquedas
 ARCHIVO:       CoordinatesBoxCriterionQueryBuilder.js
 CREACION:      25-02-03 ocantan
 ULTIMA MODIF:
 LENGUAJE:      Javascript
 PLATAFORMA:    Windows 95-NT, debe funcionar en todas
 REQUERIM.:
 DESCRIPCION:   Componente para la construcción de consultas(queries) bajo el
                criterio de coordenadas.
 HISTORIA:      06-03-03 ocantan Creación.
								22-12-04 rubenm Versión accediendo a proxy de visualizador
								26-04-05 rubenm Adaptación a nueva versión controller/proxy
								14-12-05 claborda. Variación del criterio para incluirlo 
													en zona común de memoria para todos los JSP.
								19-10-06 claborda. Dividir la función borrarCampos() en dos:
													borrarCampos() y inicializarCampos() para poder
													inicializar los campos sin necesidad de recargar el
													cliente de visualización.
*******************************************************************************/


 /**
  *   Constructor.
  * @param name nombre.
  * @return nueva instancia de la clase.
  */
 function CoordinatesCriterionQueryBuilder(name, config, contexto, containingDocument, myPath)
 {
	this._name = name;

	// contexto de la aplicación. Obtenido del fichero web.xml
	this._contexto = contexto;

	// config: Array de etiquetas del criterio de cuadro de texto.
	this._config = config;
	
	// Nombre de la ventana donde cargamos el visualizador.
	// Aunque el objeto criterio está creado en el JSP padre,
	// la ventana se abre en el JSP hijo.
	this._windowName = "";
	
	this._containingDocument = containingDocument;
 	this._mypath = myPath;
	
	this._undefinedValue = null;
	this._background = "";
	this._filterBuilder = new FilterBuilderToolkitObject();
	this._wmsClientProxy = null;
	this._defaultSRS = this._config._srs || "EPSG:4326";
	this._extent = null;
	
	this._title = this._config._title; 
	this._norte = config._norte;
	this._oeste = config._oeste;
	this._sur = config._sur;
	this._este = config._este;
	
	this._currentNorth = null;
	this._currentSouth = null;
	this._currentWest = null;
	this._currentEast = null;
	
	// Variables que guardan las coordenadas introducidas por el usuario.
        // Usadas para el refinamiento de consulta, stateString...
	this._north = null;
	this._south = null;
	this._west = null;
	this._east = null;
	
	this._srs2datum = new Array();
	this._srs2datum["EPSG:4230"] = "ED50";
	this._srs2datum["EPSG:4326"] = "WGS84";
	this._srs2datum["EPSG:23028"] = "ED50 / UTM zone 28N";	
	this._srs2datum["EPSG:23029"] = "ED50 / UTM zone 29N";	
	this._srs2datum["EPSG:23030"] = "ED50 / UTM zone 30N";	
	this._srs2datum["EPSG:23031"] = "ED50 / UTM zone 31N";
	
	this._loadedLayerName = "";
	
	// Parámetros que se le pasan al visualizador (idioma, etc.)
	this._userParams = "";
 }

 CoordinatesCriterionQueryBuilder.prototype.setContainingDocument = function(document) {
 	this._containingDocument = document;
 }
 
 CoordinatesCriterionQueryBuilder.prototype.setPath = function(path) {
 	this._mypath = path;
 }
 
 CoordinatesCriterionQueryBuilder.prototype.setWindowName = function(windowName) {
 	this._windowName = windowName;
 }

 CoordinatesCriterionQueryBuilder.prototype.setLanguage = function(language) {
 	this._language = language;
 }

 /**
  *    Método para generar una consulta por todos los campos de this._searchingAttributes
  *  a partir del texto introducido por el usuario.
  */
 CoordinatesCriterionQueryBuilder.prototype.getQueryTree= function(norte,oeste,sur,este)
 {
   var queryTreeArray = new Array();
   var nextPositionInArray = 0;
   var queryTree = "";

   queryTree =  this._filterBuilder.createFilterByGeomCoordinates(norte, sur, este, oeste);
   return queryTree;
 }

 CoordinatesCriterionQueryBuilder.prototype.getQueryTreeFromGUI = function()
 {
    if (this._wmsClientProxy == null) {
	this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    }

    // eliminamos el extent almacenado actualmente
    this._extent = null;
    // y obtenemos el nuevo
    getVisualizationExtentRec(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
    				consCadPath(this._mypath, this._name) + "._extent",
    				this._defaultSRS,
    				0);
    				
    if (this._extent != null) {

    	var bounds = this._extent.getBounds();
	var oeste = bounds.getX();
	var sur = bounds.getY();
	var este = bounds.getX() + bounds.getWidth();
	var norte = bounds.getY() + bounds.getHeight();

	if (isNaN(norte) || isNaN(oeste) || isNaN(sur) || isNaN(este)) return "";
	
	this._north = norte;
	this._south = sur;
	this._west = oeste;
	this._east = este;
	
	return  this.getQueryTree(norte,oeste,sur,este);
    } else {
    	alert(this._config.getExtentError);
    }	
 }

 CoordinatesCriterionQueryBuilder.prototype.getGUI = function()
 {
    var code = "";
    code = code + '<IFRAME name="VisualizadorInteractivoMinimo" align="center" frameborder=0 scrolling=no';
    code = code + ' class="' + this._config._styleGUI + '"'
    code = code + ' text-align:center"></iframe>' + '\n';
    if (this._config._useRestrictArea) {
    	code = code + '<div class="normal">' + '\n';
    	code = code + '    <input type="checkbox" name="' + this._name + 'CHMapa"/>' + '\n';
    	code = code + '    <span class="intro">' + this._config._restrictArea + '</span>';
    	code = code + '</div>';
    }

    return code;
 }
 
 CoordinatesCriterionQueryBuilder.prototype.restrictAreaChecked = function()
 {
 	if (this._config._useRestrictArea) {
 		var porMapa = this._containingDocument.getElementsByName(this._name + 'CHMapa')[0];
 		return porMapa.checked;
 	}
 	else {
 		return false;
 	}
 }

 /*CoordinatesCriterionQueryBuilder.prototype.getState = function()
 {
    var separator= '@';

    if (this._wmsClientProxy == null) {
	this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    }
    
    // eliminamos el extent almacenado actualmente
    this._extent = null;
    // y obtenemos el nuevo
    getVisualizationExtentRec(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
    				consCadPath(this._mypath, this._name) + "._extent",
    				this._defaultSRS,
    				0);

    if (this._extent != null) {
    	var bounds = this._extent.getBounds();
	var oeste = bounds.getX();
	var sur = bounds.getY();
	var este = bounds.getX() + bounds.getWidth();
	var norte = bounds.getY() + bounds.getHeight();
	
	if (isNaN(norte) || isNaN(oeste) || isNaN(sur) || isNaN(este)) return "";
	
	return "" + norte + separator + oeste + separator + sur + separator + este;
    } else {
    	alert(this._config.getExtentError);
    }	
 }*/

 CoordinatesCriterionQueryBuilder.prototype.setCoordinates = function(north, west, south, east)
 {
 	this._north = north;
 	this._west = west;
 	this._south = south;
 	this._east = east;
 }

 CoordinatesCriterionQueryBuilder.prototype.setState = function()
 {
    if ((this._west != null) && (this._east != null)
	&& (this._north != null) && (this._south != null)) {
    	if (this._config._useRestrictArea) {
    		var porMapa = this._containingDocument.getElementsByName(this._name + 'CHMapa')[0];
    		porMapa.checked = true;
    	}
    }
    if ((this._currentNorth != this._north) && (this._currentWest != this._west)
    	&& (this._currentSouth != this._south) && (this._currentEast != this._east)) {
    	
	this.setExtentSelected(this._north, this._west, this._south, this._east);
    }
 }

 CoordinatesCriterionQueryBuilder.prototype.setBackground = function(background)
 {
    this._background = background;
 }

 // Se encarga de realizar la creación del objeto que muestra el cliente ligero de mapas.
 CoordinatesCriterionQueryBuilder.prototype.showMap = function()
 {
    //var userParams = '';
    if ((this._west != null) && (this._east != null)
			  && (this._north != null) && (this._south != null)) {
		this._userParams = "initMinX=" + this._west
      				+ "&initMinY=" + this._south
      				+ "&initMaxX=" + this._east
      				+ "&initMaxY=" + this._north
      				+ "&initSrs=" + this._defaultSRS;
		this._userParams = this._userParams + "&lang=" + this._language;
    }
    else {
    	this._userParams = "lang=" + this._language;
    }
   
    Controller.openNamedComponent(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
    				this._windowName, 
    				this._config._WMSClientFramePath, 
    				this._userParams, 
    				'');
    //if (this._wmsClientProxy == null) {
    this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    //}
    
    this._currentNorth = this._north;
    this._currentSouth = this._south;
    this._currentEast = this._east;
    this._currentWest = this._west;
 }

 // Encargado de resetear los campos.
 CoordinatesCriterionQueryBuilder.prototype.inicializarCampos = function()
 {
 		if (this._config._useRestrictArea) {
  		var porMapa = this._containingDocument.getElementsByName(this._name + 'CHMapa')[0];
  		porMapa.checked = false;
  	}
  	
  	this._north = null;
		this._south = null;
		this._west = null;
		this._east = null;
 }

 // Se encarga de resetear los campos a vacio y resetear el mapa.
 CoordinatesCriterionQueryBuilder.prototype.borrarCampos = function()
 {
  	if (this._wmsClientProxy == null) {
		this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    }

    // Cargar el extent inicial
    restoreEmbeddedWMSClientRec(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
    				    this._config._WMSClientFramePath,
    				    0, this._windowName);
  
  	this.inicializarCampos();
 }
 
 CoordinatesCriterionQueryBuilder.prototype.setLayer = function(layer)
 {
	if ((this._wmsClientProxy == null) || (!this._wmsClientProxy.checkProxyReady())) {
		this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    	}

	//quitamos la segunda palabra detrás del : (ej:provincias:PROV --> provincias).
	var layer_array = layer.split(":");
	var layerName = layer_array[0];
	if (layerName == 'cuadriculaProv') {	// Catalogos viejos tienen cuadriculaProv en lugar de provincias
		layerName = 'provincias';
	}
	// Si es una capa distinta, la cargamos
	if (this._loadedLayerName != layerName) {
		this.setLayerRec(layerName, 0);
	}
 }
 
 CoordinatesCriterionQueryBuilder.prototype.setLayerRec = function(layer, numRetries)
 {
	if (numRetries < Controller.MAX_N_OF_RETRIES) {
		numRetries++;
		// Condición de fallo
		if ((this._wmsClientProxy == null) || (this._wmsClientProxy == undefined) 
		    || (!this._wmsClientProxy.checkProxyReady())) {
			// Programamos el tiempo de espera
			timeout = numRetries * Controller.TIMEOUT_BASE;
			setTimeout(consCadPath(this._mypath, this._name) + ".setLayerRec(" 
					+ "'" + layer + "',"
					+ numRetries + ")",
			   	timeout);
		} else {
			// Ya está disponible el proxy --> restaurar
			this._wmsClientProxy.facade.disableClient();
			if (this._loadedLayerName != "") {
				// Primero quitar la capa actual
				setLayerVisibility(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
							this._loadedLayerName,
							false);
				this._loadedLayerName = "";
			}
			// Poner nueva capa
			this.setNewLayer(layer);
		}
	} else {
		alert(config.CoordinatesBoxCQB.restoreError);		
	}
 }

 CoordinatesCriterionQueryBuilder.prototype.setNewLayer = function(layer)
 {
 	if ((this._wmsClientProxy == null) || (!this._wmsClientProxy.checkProxyReady())) {
		this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    	}
    	this.setNewLayerRec(layer, 0);
 }
 
 CoordinatesCriterionQueryBuilder.prototype.setNewLayerRec = function(layer, numRetries)
 {
 	// Añadir la nueva capa, si es valida
	if (this.isValidLayer(layer)) {
		if (numRetries < Controller.MAX_N_OF_RETRIES) {
			numRetries++;
			// Condición de fallo
			if ((this._wmsClientProxy == null) || (this._wmsClientProxy == undefined)
			    || (!this._wmsClientProxy.checkProxyReady())) {
				// Programamos el tiempo de espera
				timeout = numRetries * Controller.TIMEOUT_BASE;
				setTimeout(consCadPath(this._mypath, this._name) + ".setNewLayerRec(" 
						+ "'" + layer + "',"
						+ numRetries + ")",
				   	timeout);
			} else {
				// Ya está disponible el proxy --> restaurar
				setLayerVisibility(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
							layer,
							true);
				this._loadedLayerName = layer;
				enableEmbeddedWMSClient(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
							this._config._WMSClientFramePath,
							this._windowName,
							this._userParams);
			}
		} else {
			alert(config.CoordinatesBoxCQB.restoreError);		
		}
	}
	else {
		enableEmbeddedWMSClient(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
					this._config._WMSClientFramePath,
					this._windowName,
					this._userParams);
	}
 }

 CoordinatesCriterionQueryBuilder.prototype.isValidLayer = function(layerName) 
 {
 	for (i = 0; i < this._config.layerNames.length; i++) {
 		if (this._config.layerNames[i] == layerName) {
 			return true;
 		}
 	}
 	return false;
 }
 
 CoordinatesCriterionQueryBuilder.prototype.stateString = function(value)
 {
    	var cadena = "";

	if ((this._west != null) && (this._east != null)
	    && (this._north != null) && (this._south != null)) {	
		var regularExp2 = /-?\d+.?\d{0,3}/;
		cadena += "<b>" + this._title + "</b>:&nbsp;";
		cadena +=  "(" + this._west.toString().match(regularExp2)[0] + "," + this._south.toString().match(regularExp2)[0] + ") ";
		cadena += "(" + this._east.toString().match(regularExp2)[0] + "," + this._north.toString().match(regularExp2)[0] + ")";
		cadena += "&nbsp;(lon-lat, datum " + this._srs2datum[this._defaultSRS] + ")";
		cadena += "<br />";
		return cadena;

    	}
    	else{
		return cadena;
    	}
 }

 CoordinatesCriterionQueryBuilder.prototype.getExtentSelected = function() {

	if ((this._west != null) && (this._east != null)
	    && (this._north != null) && (this._south != null)) {
    		var rectangle = new LinearRing();
    		rectangle.addPoint(this._west, this._south);
    		rectangle.addPoint(this._west, this._north);
    		rectangle.addPoint(this._east, this._north);
    		rectangle.addPoint(this._east, this._south);
    	
    		return rectangle;
    	} else {
    		return null;
    	}
}

CoordinatesCriterionQueryBuilder.prototype.setExtentSelected = function(norte, oeste, sur, este) {
    if (this._wmsClientProxy == null) {
	this._wmsClientProxy = Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO, 
					this._windowName, 
					this._config._WMSClientFramePath,
					this._userParams, 
					consCadPath(this._mypath, this._name) + "._wmsClientProxy");
    }
    if ((oeste != null) && (este != null)
      && (norte != null) && (sur != null)) {
	centerInEmbeddedWMSClientRec(consCadPath(this._mypath, this._name) + "._wmsClientProxy",
					this._config._WMSClientFramePath,
    					norte,
    					oeste,
    					sur,
    					este,
    					this._defaultSRS, 0, this._windowName);
	this._currentNorth = norte;
	this._currentSouth = sur;
	this._currentEast = este;
	this._currentWest = oeste;
    }
}

 // PRIVATE

 // función que da acceso al objeto javaScript identificado
 // por nombre y que está declarado en thePath
function consCadPath(thePath,nombre){
    var k = 0;
    var limite= thePath.length;
    var cadena= "";
    while(k<limite){
      cadena = cadena + thePath[k] + '.';
      k++;
    }
    cadena = cadena + nombre;
    return cadena;
 }

/* Funciones auxiliares para interactuar
  * con el cliente embebido.
  */
 function centerInEmbeddedWMSClientRec(proxyRef, WMSClientFramePath, 
 				       norte, oeste, sur, este, srs, numRetries, windowName) {
	var timeout = 0;
	if (numRetries < Controller.MAX_N_OF_RETRIES) {
		numRetries++;
		var proxy = eval(proxyRef);
		// Condición de fallo
		if ((proxy == null) || (proxy == undefined)) {
			// Programamos el tiempo de espera
			timeout = numRetries * Controller.TIMEOUT_BASE;
			setTimeout("centerInEmbeddedWMSClientRec("
					+ "'" + proxyRef + "',"
					+ "'" + WMSClientFramePath + "',"
					+ norte + ","
					+ oeste + ","
					+ sur + ","
					+ este + ","
					+ "'" + srs + "',"
					+ numRetries + ","
					+ "'" + windowName + "')",
				   timeout);
		} else {
			// Ya está disponible el proxy --> centrar
			proxy.facade.disableClient();
		    	var rectangle = new LinearRing();
		    	rectangle.addPoint(oeste, sur);
		    	rectangle.addPoint(oeste, norte);
		    	rectangle.addPoint(este, norte);
		    	rectangle.addPoint(este, sur);
		    	proxy.facade.setVisualizationExtent(rectangle, srs);
		    	proxy.setIsValid(false);
		    	enableEmbeddedWMSClient(proxyRef, WMSClientFramePath, windowName, this._userParams);
		}
	} else {
		alert(config.CoordinatesBoxCQB.centerError);		
	}
 }
 
 function getVisualizationExtentRec(proxyRef, resultRef, srs, numRetries) {
	var timeout = 0;
	if (numRetries < Controller.MAX_N_OF_RETRIES) {
		numRetries++;
		var proxy = eval(proxyRef);
		// Condición de fallo
		if ((proxy == null) || (proxy == undefined)) {
			// Programamos el tiempo de espera
			timeout = numRetries * Controller.TIMEOUT_BASE;
			setTimeout("getVisualizationExtentRec("
					+ "'" + proxyRef + "',"
					+ "'" + resultRef + "',"
					+ "'" + srs + "',"
					+ numRetries + ")",
				   timeout);
		} else {
			// Ya está disponible el proxy --> obtener extent
			var rectangle = proxy.facade.getVisualizationExtent(srs);
			// Guardo copia del proxy en la referencia que me pasan
			eval(resultRef + "= rectangle");
		    	return rectangle;
		}
	} else {
		alert(config.CoordinatesBoxCQB.getExtentError);		
	}
 }

 function restoreEmbeddedWMSClientRec(proxyRef, WMSClientFramePath, numRetries, windowName) {
	var timeout = 0;
	if (numRetries < Controller.MAX_N_OF_RETRIES) {
		numRetries++;
		var proxy = eval(proxyRef);
		// Condición de fallo
		if ((proxy == null) || (proxy == undefined)) {
			// Programamos el tiempo de espera
			timeout = numRetries * Controller.TIMEOUT_BASE;
			setTimeout("restoreEmbeddedWMSClientRec(" 
					+ "'" + proxyRef + "',"
					+ "'" + WMSClientFramePath + "',"
					+ numRetries + ","
					+ "'" + windowName + "')",
				   timeout);
		} else {
			// Ya está disponible el proxy --> restaurar
			proxy.facade.disableClient();
		    	proxy.facade.restoreClient();
		    	proxy.setIsValid(false);
		    	enableEmbeddedWMSClient(proxyRef, WMSClientFramePath, windowName, this._userParams);
		}
	} else {
		alert(config.CoordinatesBoxCQB.restoreError);		
	}
 }
 
 function setLayerVisibility(proxyRef, layerName, visibility) {
	var timeout = 0;
	var urlWMS = config.Global.layerUrlWMS[layerName.toLowerCase()];
	// Estilos para resultado de busqueda y resultado de busqueda seleccionados
	var styleNameDefault = 'default';
	var styleNameSinIdentificadores = 'sin_identificadores';
	var styleNameSoloIdentificadores = 'solo_identificadores';
	var styleNameSearch = 'SearchStyle';
	var styleNameSelectedSearch = 'SelectedSearchStyle';
	
	var proxy = eval(proxyRef);

	// Ya está disponible el proxy --> restaurar
	proxy.facade.setLayerVisibility(urlWMS, layerName, styleNameDefault, visibility);
	proxy.facade.updateMapClient();
	proxy.setIsValid(false);
 }

   /* Habilitar cliente embebido: permitir hacer zooms, pannings... */
    function enableEmbeddedWMSClient(proxyRef, WMSClientFramePath, windowName, userParams) {
    	try {
    		var proxy = eval(proxyRef);
	    	if ((proxy == null) || (!proxy.checkProxyReady())) {
	    		Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS,
					windowName, 
					WMSClientFramePath,
					userParams, 
					proxyRef);
	    	}
    	} catch (e) {
    		// En principio debería ocurrir sólo si se cerró
    		// el cliente o produjo alguna excepción.
    		// Abrimos de nuevo, obtenemos el proxy
    		// y marcamos que no existe la mapLayer
    		proxy = null;
		Controller.getNamedComponentProxy(Controller._INTERACTIVOMINIMO_CUADRICULAS,
				windowName, 
				WMSClientFramePath,
				userParams, 
				proxyRef);
    	}
    	enableEmbeddedWMSClientRec(proxyRef, 0);
    }

    function enableEmbeddedWMSClientRec(proxyRef, numRetries) {
	var timeout = 0;
	if (numRetries < Controller.MAX_N_OF_RETRIES) {
		numRetries++;
		var proxy = eval(proxyRef);
		// Condición de fallo
		if (proxy == null) {
			// Programamos el tiempo de espera
			timeout = numRetries * Controller.TIMEOUT_BASE;
			setTimeout("enableEmbeddedWMSClientRec(" + numRetries + ")",
				   timeout);
		} else {
			// Ya está disponible el proxy --> ejecutar
	    		proxy.facade.enableClient();
	    		// Después de habilitar el cliente tengo que anular el proxy
	    		// pq la referencia a la ventana ya no es válida
	    		// (da 'Acceso denegado', pourquoi? Ah, qui le sait!)
	    		proxy.setIsValid(false);
		}
	} else {
		alert("Error habilitando cliente");		
	}
    }
    /* FIN Habilitar cliente embebido: permitir hacer zooms, pannings... */
