function googleMapClass(datosMapa)
{
	var objeto = this;
	
	var idContenedorMapa = datosMapa.contenedor;
	objeto.contenedorMapa = jQuery('#'+idContenedorMapa);//atributo con el objeto 'div' que contendrá el mapa
	
	objeto.latitud = datosMapa.latMapa;//atributo con la latitud  original del centro del mapa
	objeto.longitud = datosMapa.longMapa;//atributo con la longitud original del centro del mapa
	objeto.tituloMapa = datosMapa.tituloMapa;//atributo con el título del mapa
	objeto.zoomMapa = datosMapa.zoomMapa;//zoom inicial del mapa
	
	//si se pasa como propiedad de datosMapa, streetView = true, crearemos una instancia del gestor de streetview
	//si se pasa false, o no existe la propiedad, no habrá street view.
	objeto.streetViewActivo = datosMapa.streetView || false;
	objeto.gestorStreetView = {};

	//atributo que contiene un objeto con los límites del mapa en formato LatLngBounds
	objeto.limitesMapaLatLng = "";
	//atributo que contiene un objeto con los límites del mapa como un array de 4 valores
	//ordenados de la siguiente forma: norte, sur, este, oeste
	objeto.limitesMapa = [];
	
	/*
	//metodo que actua como escuchador del evento mapaCargado
	//ejemplo equivalente a usar directamente bind de la forma tradicional
	objeto.bind = jQuery().bind;
	objeto.mapaCargado2 = function(listener) {
		objeto.bind('mapaCargado',listener);
	}
	*/
	
	//metodo que establece el atributo con los limites del mapa
	objeto.setLimitesMapa = function(punto)
	{
		//el parametro punto que se pasa al método es una instancia de LatLngBounds
		//para construir un nuevo LatLngBounds, hay que pasar el punto inferior izquierdo
		//y el punto superior derecho
		var noreste = punto.getNorthEast();
		var suroeste = punto.getSouthWest();
		objeto.limitesMapaLatLng = new google.maps.LatLngBounds(suroeste,noreste);
		
		//guardamos los valores individuales máximos y mínimos en un array
		var norte = noreste.lat();
		var sur = suroeste.lat();
		var este = noreste.lng();
		var oeste = suroeste.lng();
		objeto.limitesMapa = [norte,sur,este,oeste];
	}
	
	//metodo que devuelve un objeto con los límites del mapa
	objeto.getLimitesMapa = function(instanciaMapa)
	{
		var limites =  instanciaMapa.getBounds();
		return limites;
	}
	
	//metodo que amplia la extensión del mapa para contener el marcador que se le pasa
	//si dicho marcador se encuentra fuera del área del mapa
	objeto.extiendeLimitesMapa = function extiendeLimitesMapa(idMarcador)
	{
		
		//extraemos el marcador del array de marcadores
		var marcador = objeto.marcadores[idMarcador];
			
		//obtenemos las coordenadas del marcador como objeto LatLng
		var marcadorLatLng = marcador.marcadorIcono.getPosition();
		
		//obtenemos los limites del mapa actualmente como LatLngBounds
		var limitesLatLng = objeto.getLimitesMapa(instanciaMapa);
		
		if (limitesLatLng.contains(marcadorLatLng))
		{
			return false;
		}
		else
		{		
			limitesLatLng.extend(marcadorLatLng);
			instanciaMapa.fitBounds(limitesLatLng);
			objeto.setLimitesMapa(limitesLatLng);
		}
	}
	
	//metodo que comprueba, a partir de todos los marcadores cuyos id's se pasen como parámetro
	//las coordenadas mínimas y máximas, inferior izquierda y superior derecha
	//para establecer los límites del mapa
	objeto.calculaLimitesMapa = function(idMarcadores)
	{
		//arrays para las coordenadas x e y
		var lat = [];
		var lng = [];
		
		//variable que almacenará todos los id's que se vayan a procesar
		var arrayIdMarcadores = [];
		
		//si el parámetro es un array con varios id's
		if  ( typeof(idMarcadores) == 'object')
		{
		    jQuery(idMarcadores).each(function(n)
			{
				arrayIdMarcadores.push(idMarcadores[n]);
			});
		}
		//si el parámetro es solo un id
		else
		{
			arrayIdMarcadores[0] = idMarcadores;
		}
		
		var numMarcadores = arrayIdMarcadores.length - 1;
		var num;
		
		for (num in arrayIdMarcadores)
		{
			//extraemos el marcador del array de marcadores
			var marcador = objeto.marcadores[arrayIdMarcadores[num]];
			
			//obtenemos las coordenadas del marcador como objeto LatLng
			var marcadorLatLng = marcador.marcadorIcono.getPosition();
			//extraemos la latitud y longitud como números mediante los métodos correspondientes
			var marcadorLat = marcadorLatLng.lat();
			var marcadorLng = marcadorLatLng.lng();
			
			//comprobamos si las coordenadas de este marcador están dentro o fuera de los límites
			//si están fuera, almacenamos los valores
			lat.push(marcadorLat);
			lng.push(marcadorLng);
			
			//una vez que terminamos de procesar el último marcador
			//llamamos al método del mapa que cambia los límites
			//y actualizamos los límites del mapa
			if(num == numMarcadores)
			{
			
				var maxEste = Math.max.apply(null,lng);
				var minOeste = Math.min.apply(null,lng);
				var minSur = Math.min.apply(null,lat);
				var maxNorte = Math.max.apply(null,lat);
			
				var limiteSO = new google.maps.LatLng(minSur,minOeste);
				var limiteNE = new google.maps.LatLng(maxNorte,maxEste);
				var limitesLatLng = new google.maps.LatLngBounds(limiteSO,limiteNE); 
				//instanciaMapa.panToBounds(limitesLatLng);
				instanciaMapa.fitBounds(limitesLatLng);
				objeto.setLimitesMapa(limitesLatLng);
			}
			
		};
		
	}
	
	objeto.marcadores = {};//atributo para establecer un array con todos los marcadores del mapa
	objeto.idMarcadorActivo = "";//atributo que contiene el id del marcador activo, si es que hay alguno
	objeto.idMarcadoresVisibles = "";//atributo que contiene un array con los id's de los marcadores actualmente visibles
	
	var anchoMapa = '';
	var altoMapa = '';
	
	//establecemos las medidas del contenedor del mapa, si se pasan como parámetros, y si no, 
	//calculando las medidas del propio contenedor
	if (datosMapa.ancho) {
		anchoMapa = datosMapa.ancho;
	}
	else {
		anchoMapa = objeto.contenedorMapa.width();
	}
	
	if (datosMapa.alto) {
		altoMapa = datosMapa.alto;
	}
	else {
		altoMapa = objeto.contenedorMapa.height();
	}
	
	var instanciaMapa = "";//variable privada que contendrá el objeto mapa, instancia de GMap
	objeto.mapaCargado = false;//variable bandera para indicar si se ha creado la instancia del mapa o no
	
	//método publico para obtener la instancia del mapa desde el exterior
	objeto.getInstanciaMapa = function()
	{
		return instanciaMapa;
	}
	
	objeto.centroMapa = new google.maps.LatLng(objeto.latitud,objeto.longitud);//variable con el objeto GLatLng para el centro original del mapa
	
	objeto.getCentroMapa = function()
	{
		return objeto.centroMapa;
	}
	
	
	//objeto literal con las opciones de inicialización del mapa
	var opcionesMapa = {
		zoom: objeto.zoomMapa,
		center: objeto.centroMapa,
		navigationControl: true,
		scaleControl: true,
		scrollwheel:false,
		navigationControlOptions: {style: google.maps.NavigationControlStyle.DEFAULT},
		mapTypeId: google.maps.MapTypeId.ROADMAP      
	}

	//método que crea la instancia del mapa, y establece los parametros de inicio
	inicializaMapa = function()
	{
		establecerContenedorMapa();
		instanciaMapa = new google.maps.Map(document.getElementById(idContenedorMapa),opcionesMapa);
			
		//si el mapa ha de contener gestor de streetview, crearemos la isntancia
		if (objeto.streetViewActivo == true)
		{
			objeto.gestorStreetView = new gestorStreetView(instanciaMapa,'pano',objeto.centroMapa);
			instanciaMapa.setStreetView(objeto.gestorStreetView.estritViuf);
		}

		//establecemos un nivel máximo de zoom para el mapa
		google.maps.event.addListener(instanciaMapa, 'zoom_changed', function() {
		  if (instanciaMapa.getZoom() > 19) {
			instanciaMapa.setZoom(19);
		  }
		
		}); 
		
		//establecemos el evento click para mostrar streetview
		objeto.streetViewEventClick = google.maps.event.addListener(instanciaMapa, 'click', function(event) {
			var puntoClick = event.latLng;
			objeto.gestorStreetView.procesarPunto(puntoClick);
		}); 
		
		//no hay evento load para el mapa, así que usamos el evento 'bounds_changed'
		//que supuestamente se dispara cuando los límites del mapa están definidos
		//para obtener los límites primero, y después almacenarlos en el atributo correspondiente
		google.maps.event.addListener(instanciaMapa,'bounds_changed',function() 
		{ 
			var limitesMapa = objeto.getLimitesMapa(instanciaMapa);
			objeto.setLimitesMapa(limitesMapa);
			
		    //añadimos al objeto instancia mapa un evento propio para poder 'escuchar' el momento en que se haya cargado el mapa
			//puesto que el evento bounds_changed de la instancia del mapa se puede repetir cada vez que éste cambie
			//el evento 'mapaCargado' solo puede lanzarse cuando el mapa se cree por vez primera
			if (objeto.mapaCargado == false) 
			{   
			    //una vez inicializado el mapa, creamos un marcador para el centro original
				var datosMarcadorCentro = 
				{
					id:'centroMapa',
					coordenadas:objeto.centroMapa
				}
				
				objeto.marcadores['centroMapa'] = new gestorMarcador(instanciaMapa,datosMarcadorCentro);
				jQuery(objeto).trigger('mapaCargado');
					
				objeto.mapaCargado = true;
			}
			
		});

	}
	
	//función que establece el ancho y alto del contenedor del mapa
	function establecerContenedorMapa()
	{
		objeto.contenedorMapa.css('width',anchoMapa);
		objeto.contenedorMapa.css('height',altoMapa);
		//nos aseguramos que el div que contiene el mapa esté visible
		objeto.contenedorMapa.css('display','block')
	}
	
	this.reescalarMapa = function() {
		 	google.maps.event.trigger(instanciaMapa, 'resize');
	}
	

	//metodo de la clase googleMapClass para crear marcadores
	objeto.crearMarcadores = function(datosMarcador)
	{
		var idMarcador = datosMarcador.id;
		var mapa = objeto.getInstanciaMapa();
		var marcador = new gestorMarcador(mapa,datosMarcador);
			
		//guardamos el marcador en el array de marcadores
		objeto.marcadores[datosMarcador.id] = marcador;
		
		//escuchador para el evento click en el marcador sobre el mapa
		google.maps.event.addListener(marcador.marcadorIcono, 'click', function() 
		{
				//comprobamos si se ha activado algún marcador previamente
				//y si es así, cerramos la ventana de información si estuviera abierta
				if (objeto.idMarcadorActivo)
				{
					objeto.marcadores[objeto.idMarcadorActivo].ventanaInfo.close();
				}
				
				marcador.ventanaInfo.open(instanciaMapa,marcador.marcadorIcono);
				objeto.idMarcadorActivo = marcador.id;
				
				var posicionMarcador = marcador.marcadorIcono.getPosition()

				objeto.gestorStreetView.procesarPunto(posicionMarcador);
							
		});
		
		//escuchador para el evento 'visible_change' en el marcador sobre el mapa
		//que se dispara cada vez que un icono se muestra u oculta
		google.maps.event.addListener(marcador, 'visible_changed', function() 
		{
			objeto.actualizarMarcadoresVisibles();
			if(objeto.idMarcadoresVisibles.length > 0)
			{
				objeto.calculaLimitesMapa(objeto.idMarcadoresVisibles);
			}
		});
		
		//escuchador para el evento 'drag_end' en el marcador sobre el mapa
		//que se dispara cada vez el icono deja de ser arrastrado sobre el mapa
		google.maps.event.addListener(marcador.marcadorIcono, 'dragend', function() 
		{
			var nuevaPosicion = marcador.marcadorIcono.getPosition();
			jQuery(marcador).trigger('marcador_cambio_posicion',[nuevaPosicion]);
			
		});
		
		//ampliamos los límites del mapa para que contenga el Marker recién creado
		objeto.extiendeLimitesMapa(datosMarcador.id);
		
		return idMarcador;
		
	};
	
	//metodo de la clase googleMapClass para borrar marcadores
	//si no se pasa un id de marcador, o un array de marcadores,
	//se eliminaran todos los marcadores del mapa
	objeto.borrarMarcadores = function(idMarcador)
	{
		if (!!idMarcador)
		{
			objeto.marcadores[idMarcador].borrarMarker();
		}
		else 
		{
			for (marcador in objeto.marcadores)
			{
				objeto.marcadores[marcador].borrarMarker();
			}
		}
	};
	
	//metodo de la clase googleMapClass para mostrar los marcadores
	objeto.mostrarMarcadores = function(idMarcador)
	{
		var marcador = objeto.marcadores[idMarcador];
		marcador.marcadorIcono.setVisible(true);
		return true;
	}
		
	//metodo de la clase googleMapClass para ocultar los marcadores
	objeto.ocultarMarcadores = function(idMarcador)
	{
		var marcador = objeto.marcadores[idMarcador];
		marcador.marcadorIcono.setVisible(false);
		return false;
	}
	
	//metodo de la clase googleMapClass para alternar el estado de visibilidad de los marcadores
	//el parametro 'modo' nos permite variar funcionamiento, entre alternar los estados o forzarlos
	objeto.mostrarOcultarMarcadores = function(idMarcador,modo)
	{
		var marcador = objeto.marcadores[idMarcador];
		//obtenemos la visibilidad del marcador como booleano
		var esVisible = marcador.marcadorIcono.getVisible();
		
		var estado = "";
		
		switch(modo)
		{
			case 'alternar':
			alternarVisibilidad();
			break;
			
			case 'mostrar':
			forzarVisible();
			break;
			
			case 'ocultar':
			forzarOculto();
			break;
			
			default:
			alternarVisibilidad();
			break;
			
		}
		
		function alternarVisibilidad()
		{
			//si el marcador está visible
			if (esVisible == true)
			{
				estado = objeto.ocultarMarcadores(idMarcador);
			}
			//si está oculto
			else
			{
				estado = objeto.mostrarMarcadores(idMarcador);
			}
			
		}
		
		function forzarVisible()
		{
			estado = objeto.mostrarMarcadores(idMarcador);
		}
		
		function forzarOculto()
		{
			estado = objeto.ocultarMarcadores(idMarcador);
		}

		//devolvemos el valor del estado
		return estado;
		
	};
	
	//metodo que nos devuelve un array con los id's de los marcadores visibles actualmente
	objeto.actualizarMarcadoresVisibles = function actualizarMarcadoresVisibles()
	{
		objeto.idMarcadoresVisibles = [];
		jQuery(objeto.marcadores).each(function()
		{
			var marcador = this.marcadorIcono;
			var estado = marcador.getVisible();
			if(estado == true)
			{
				objeto.idMarcadoresVisibles.push(this.id);
			}
		});
			
	}//actualizarMarcadoresVisibles
	
	//metodo para simular click en un marcador y abrir la ventana de información
	objeto.clickMarcador = function(idMarcador)
	{
		//comprobamos si hay alguna ventana abierta y la cerramos
		var marcadorActivo = objeto.marcadores[objeto.idMarcadorActivo];
		if (!!marcadorActivo && !!marcadorActivo.ventanaInfo)
		{
			marcadorActivo.ventanaInfo.close()
		}
		
		//instancia del Marcador
		var marcador = objeto.marcadores[idMarcador];
	    //disparamos el evento click en el marker del mapa, 
		//correspondiente al atributo marcadorIcono deo objeto Marcador
		google.maps.event.trigger(marcador.marcadorIcono,'click'); 
		//actualizamos el atributo de la Clase del gestor de mapas que indica el id del marcador activo
		objeto.idMarcadorActivo = idMarcador;
	}
	
	
	

	//si creamos la instancia pasando como parámetro al constructor el objeto con los datos necesarios
	//para crear un mapa, llamamos al método que crea el objeto mapa
	if(datosMapa) 
	{
		inicializaMapa();
	}
	
						   
}//googleMapClass




