function PhotoGallerySlider(settings){

	var objeto = this;

	//propiedades de la imagen dinámica
	this.imagenSup = settings.imagenSup;//imagen superior que se usa almacenar la imagen actual y realizar el fundido
	this.imagenInf = settings.imagenInf;//imagen inferior que se usar para almacenar la nueva imagen
	
	
	//propiedades del slider 
	this.titSliderWrapper = settings.titSliderWrapper; //contenedor del titulo de la imagen y del slider
	this.contTitulo = settings.contTitulo; //contenedor del título y del botón de más información
	this.abrirCerrarTitulo = jQuery('.slider_interruptor',this.contTitulo);//contenedor del boton que abre y cierra el slider
	this.abrirCerrarTituloImg = jQuery('.slider_interruptor_img',this.abrirCerrarTitulo);//imagen del boton que abre y cierra el slider
	this.sliderWrapper = settings.sliderWrapper; //contenedor del slider y de los botones
	this.contSlider = settings.contSlider;//ul que contiene las miniaturas y hará de carrusel
	
	this.numMin = 5;//propiedad que almacena el número de miniaturas por defecto que se ven en el carrusel
	this.sepMin = 10;//propiedad con los márgenes de las miniaturas por defecto, pues el metodo width solo devuelve ancho+padding+border
	
	if (settings.numMin)
	{ 
	this.numMin = settings.numMin
	}
	
	if (settings.sepMin)
	{ 
	this.sepMin = settings.sepMin
	}
	
	//propiedades bandera para controlar el estado del objeto durante las transiciones de imágenes y eventos
	var sliderAbierto = true; //bandera para comprobar el estado del slider, que puede visible u oculto
	this.imagenCambiando = false;//bandera que se pone a true cuando la imágen dinámica está cambiando
	
	//marcadores globales
	this.i = 0;//variable contador i que almacenará el valor de la miniatura activa actualmente	
	
	
	
	//inicializamos el slider
	this.slider = new Slider(this.contSlider);
	this.slider.activaSlider();
		
	//añadimos al boton de abrir y el evento click que ejecutara el metodo correspondiente
	this.abrirCerrarTitulo.click(function(e)
	{
		e.preventDefault();
		animaTitulo();
	});


	//*************metodo que mostrará y ocultará el slider al pasar con el ratón sobre la zona del título*********************
	function animaTitulo(){

		//propiedades privadas del método animaTítulo 
		var alturaWrapper = objeto.titSliderWrapper.height();
		var alturaTitulo = objeto.contTitulo.height();
		var alturaSlider = objeto.contSlider.height();
		var alturaAbierto = alturaTitulo + alturaSlider;
		var alturaCerrado = alturaTitulo;
		var lapsoAnimacion = 500;
		
		
		//eventos que dispararán los métodos correspodientes para abrir y cerrar el título
        if (sliderAbierto == false)
		{
			  objeto.titSliderWrapper.animate({ 
					height:alturaAbierto
			  }, lapsoAnimacion );
			  
			  //al abrir y cerrar el slider, se desplaza la imagen del boton en vertical 
			  //en vez de simplemente sustituir el icono de abrir por el de cerrar y vicecersa
			  objeto.abrirCerrarTituloImg.animate({
					bottom:0
			  }, lapsoAnimacion);

			  sliderAbierto = true;
		}
		else if (sliderAbierto == true) 
		{
			  objeto.titSliderWrapper.animate(
			  { 
			    height:alturaCerrado
			  }, lapsoAnimacion );
			  
  			  objeto.abrirCerrarTituloImg.animate({
					bottom:-27
			  }, lapsoAnimacion);
			  
			  sliderAbierto = false;
		}
		else  
		{
			  return false;
		}

	};//animaTitulo()

	
	
	
	//***************************************metodo para crear y animar el slider*****************************************//
	
	function Slider(container) {
	
		var minSlider = jQuery('li',container);//propiedad con los li's que contienen las miniaturas
		var picEls = minSlider.length;//calculamos el número de imágenes que tiene el slider
		var enlacesSlider = jQuery('a',container);//objeto que contiene los enlaces del slider
		
		var thumbs = 5;//número de diapositivas que se ven en el carrusel en cada momento
		var anchoMiniatura = 110;//ancho de cada diapositiva
		var easeFunc = "easeInOutExpo";//tipo de transición en el desplazamiento del slider	
		var timer = 4000;//tiempo para la ejecución de cada cambio de imagen
				
		var botonRetroceder = new Boton('#vt_slider_cont_retrocede','bwd');//boton para retroceder
		var botonAvanzar = new Boton('#vt_slider_cont_avanza','fwd');	//boton para avanzar	
		
		var elemento = minSlider.eq(0);//propiedad que contiene el elemento seleccionado actualmente

		//para que los métodos sean visibles al exterior, públicos, usamos this para declararlos
		this.activaSlider = function activaSlider() {
		
			//declaramos las propiedades privadas del slider
			var anchoSlider = 0;//variable con el ancho del slider
			
			//método que calculará el ancho del slider; si el ancho es mayor que el del contenedor, 
			//llamará a los métodos que animan el slider y ponen en 'marcha' los botones
			function calculaAncho() 
			{
				//para cada miniatura, vamos sumando el ancho del elemento más el margen establecido
				minSlider.each(function(i,el)
				{
					//variable local que almacena el ancho de cada miniatura
					var anchoTmp = jQuery(el).width();
					//jquery no puede obtener las dimensiones de elementos que están ocultos
					//en el caso de que el ancho que devuelva sea 0,
					//clonaremos cada elemento, lo haremos visible temporalmente fuera de la pantalla
					//y una vez obtenidas las dimensiones, lo eliminaremos del documento
					if (anchoTmp == 0)
					{
						var clonEl = jQuery(el).clone();
						clonEl.css({'position':'absolute','left':'10000px','display':'block'}).appendTo('body');
						anchoTmp = clonEl.width();
						clonEl.remove();
					}
					anchoSlider = anchoSlider + anchoTmp + objeto.sepMin;
				});
				
				container.width(anchoSlider).css('visibility','visible');
				
			};
			
			calculaAncho();
			
			//si hay más miniaturas que el número que se ven en el carrusel, activaremos los botones
			if (picEls > thumbs) { 
				compruebaBotones('inicio');
			}
			
			cambiaIndice(0,false);
		
		}//activaSlider
		
		
		//añadimos a los enlaces del slider el evento click
		enlacesSlider.bind('click',miniaturaClick);
		
		function miniaturaClick(event) {
			event.preventDefault();
			//siempre que la variable global imagenCambiando sea 'false'
			//y por tanto, las imágenes no estén en proceso de fundido y actualización
			if (objeto.imagenCambiando == false)
			{
			//enviamos el enlace a la función que usará su href y title para cargar las imágenes
			
			var enlace = jQuery(this);
			objeto.cambiaImagen(enlace);
						
			//cambiaremos la variable global i con la posición del elemento actual, para indicar al slider en que miniatura nos encontramos
			var tmpIndice = jQuery(enlacesSlider).index(enlace);
			cambiaIndice(tmpIndice,false);
			}
			else
			{
				return false;
			}
			
			
		}
		
		//metodo que actualiza el valor del índice de la miniatura actual y la activa en el slider
		//en caso de que el segundo parametro sea true, llamaremos al método que cambia la imagen dinámica
		function cambiaIndice(indice,simulaclick)
		{

			//metodo que determina el li que contiene la miniatura seleccionada actualmente
			function actualizaElemento(indice) {
			
				elemento = objeto.contSlider.find("li").eq(indice);
				
				//si el parametro simulaclick es true, quiere decir que el slider se ha desplazado
				//mediante los botones, por lo que además de actualizar el elemento,
				//hay que llamar al metodo del objeto que cambia la imagen
				if (simulaclick == true)
				{
					var enlace = jQuery('a',elemento);
					objeto.cambiaImagen(enlace);
				}
				
			}
			
			//funcion para marcar la miniatura en la que nos encontramos
			//el marcado se realiza cambiando el color de borde del div que hay dentro del li
			//el parametro que se envía a la función, es el objeto jquery con el li seleccionado
			function marcaMiniatura(elemento)
			{
				//puesto que el parametro elemento contiene el li, tenemos que buscar el primer div hijo 
				//hay uno para la imagen, y otro para el título
				jQuery('div:first',elemento).css('border','5px solid #00830c');
				//y a cada primer div hijo de los otros li's hermanos en el slider, les ponemos el borde inactivo
				jQuery(elemento).siblings('li').children('div:first-child').css('border','5px solid white');
			}
			
			//establecemos el valor del indice global de la miniatura actual
			objeto.i = indice;
						
			//establecemos el elemento actual que corresponde al li seleccionado
			actualizaElemento(indice);
			
			//marcamos el borde la miniatura
			marcaMiniatura(elemento);	
			
			//comprobamos el estado que deben tener los botones en función de la miniatura que esté activa
			//por ejemplo, desactivar el boton de retroceder si estamos en la primera miniatura (indice = 0)
			compruebaBotones(indice);
		}
		

		//metodo que desplaza el slider cuando se hace click en un botón
		//el método debe recoger el valor del elemento actual, y en función de si el desplazamiento
		//es hacia delante o hacia atrás, buscar el elemento correspondiente, activar la miniatura
		//y cambiar la imagen dinámica, simulando el evento click en la propia miniatura
		this.mueveSlider = function mueveSlider(direccion)
		{
			//variable que recoge la dirección en que se moverá el slider, correspondiente al botón pulsado
			var direccion = direccion;
			
			//variable que determinará la posición del carrusel relativa al borde izquierdo
			//el primer movimiento de avance lo situará a -550px de la izquierda, -1100px el segundo, etc.
			//para volver a su posición inicial, se pondrá a 0
			var desplazamiento = 0;
			
			//variable que almacenará el valor actual del indice global de la miniatura seleccionada
			var tmpIndice = objeto.i;
			
			switch(direccion)
			{
				case 'fwd':
				if (tmpIndice < picEls-1) 
				{
					tmpIndice++;
					desplazamiento = -((tmpIndice)*anchoMiniatura);
					
					//si vamos hacia delante, movemos la página en los múltiplos del número de miniaturas
					//si son 5 por página, se moverá en la miniatura 4, 9, 14, etc...
					if ((tmpIndice) % thumbs == 0) 
					{
					objeto.contSlider.animate({left:desplazamiento}, 500, easeFunc);	
					}
				}
				else 
				{
					tmpIndice = 0;
					objeto.contSlider.animate({left:0}, 500, easeFunc);
				}
				break;
				
				case 'bwd':
				if (tmpIndice > 0) 
				{
					
					//si vamos hacia atrás, usaremos la posición actual, antes de pasar a la siguiente
					//es decir, si estamos en la 5 y vamos a pasar a la 4, tenemos que desplazar el slider
					//por lo que es más cómodo usar la i actual y una vez calculado del desplazamiento, 
					//establecer el valor del nuevo i
					
					//el desplazamiento en la primera página se hace en la miniatura 5, y en este caso, el slider
					//debe estar en la posición 0 desde la izquierda
					desplazamiento = -(tmpIndice-5)*anchoMiniatura;
					if ((tmpIndice % thumbs) == 0) 
					{
						objeto.contSlider.animate({left:desplazamiento}, 500, easeFunc);	
					}
					
					//una vez desplazado el slider, establecemos el nuevo valor de la miniatura actual
					tmpIndice--;
				}
				else 
				{
					tmpIndice = 0;
				}
				break;
			}
			
			cambiaIndice(tmpIndice,true);
	
		}//mueveSlider
		
		
		//método de slider que activará o desactivará los botones de avanzar y retroceder en función de i
		//en este caso, simplemente sirve para desactivar el botón de retroceder cuando estamos en la primera miniatura
		//pero podría servir para desactivar la última si se parara el slider en la última, en vez de retroceder hasta el principio
		//o para desactivar los dos botones cuando la imagen grande esté cambiando
		function compruebaBotones(caso)
		{
			switch (caso)
			{
				case 'inicio':
					botonAvanzar.activarBoton();
				break;
				case 0:
					if (botonRetroceder.activo == true)
					{
						botonRetroceder.desActivarBoton();
					}
				break;
				case 1:
					if (botonRetroceder.activo == false)
					{
						botonRetroceder.activarBoton();
					}
				default:
					if (botonRetroceder.activo == false)
					{
						botonRetroceder.activarBoton();
					}
				break;
			}
		}
		

	}//creaSlider
	
	
	function Boton(idboton,direccion){
			
		//la clase recibe el id del botón
		//para poder manejarlo, creamos una propiedad privada donde almacenamos el correspondiente objeto jQuery
		var objetoBoton = jQuery(idboton);
		//la propiedad del boton que indica si es para avanzar o retroceder
		this.direccion = direccion;
		//la propiedad del boton que indica si está activo o no
		this.activo = false;
				
		//al activar el botón, debe indicarse la dirección que hará moverse el slider en el parámetro dirección
		//así como el estado del botón, true para activarlo, false para desactivarlo
				
		//declaramos el método mediante this para hacerlo visible al exterior, es decir, público
		this.activarBoton = function activarBoton() 
		{
			objetoBoton.bind('click.mueveslider',clickBoton).css('cursor','pointer');
			this.activo = true;
		}	
				
		this.desActivarBoton = function desactivarBoton()
		{
			objetoBoton.unbind('click.mueveslider').css('cursor','default');
			this.activo = false;
		}
		
		var clickBoton = function(event)
		{
			event.preventDefault();
			if (objeto.imagenCambiando == false)
			{
				objeto.slider.mueveSlider(direccion);
			}	
			else
			{
				return false;
			}
		}
		
	}//boton
	
	
	//metodo para hacer click en el slider de forma automática
	//el temporizador hace que el slider vaya hacia delante solamente
	//por eso asignamos al propio boton de avanzar el temporizador
	//la función ejecuta un click sobre el botón pasados 5s desde la llamada
	function autoslide(modo)
	{
		switch(modo)
		{
			case 'play':
			//si activamos el autoslide, ponemos en marcha un temporizador que llamará a la función
			//para cambiar de imagen cada segundo
			botonAvanzar.everyTime(timer,"disparadorslider",function()
			{
				//si la imagen se ha cargado y ha terminado de moverse, cargamos la siguiente
				if (objeto.imagenCambiando == false)
				{
						disparaSlider();
				}
			});
			break;
			case 'stop':
			//paramos el temporizador que lanza el vento
			botonAvanzar.stopTime("disparadorslider");
			break;
		}
		
		
		function disparaSlider()
		{
			botonAvanzar.oneTime("1s", "autoslide", function() 
			{
				jQuery(botonAvanzar).trigger("click.mueveslider");			
			});	
		}
		
		//eventos para detener el modo automatico 	
		botonAvanzar.bind("mouseup", function()
		{
			botonAvanzar.stopTime("disparadorslider");
		});
		botonRetroceder.bind("mouseup", function()
		{
			botonAvanzar.stopTime("disparadorslider");	
		});
		jQuery(".sp_foto_link").bind("mouseup", function()
		{
			botonAvanzar.stopTime("disparadorslider");
		});
		
	}//autoslide

	


	//**************************** metodo que cambia una imagen por otra****************************************//

	//El script trabaja con dos imágenes superpuestas
	//La superior se utiliza para almacenar la imagen actual 
	//y hacer el fundido a la imagen inferior que alberga la nueva imagen

	//El funcionamiento básico consiste en:

	//Partir de dos imagenes que contienen la la misma imagen; la superior está oculta y la inferior se muestra
	//Cuando el usuario hace click o se desplaza el slider
	//Se hace visible la imagen superior con la imagen actual (las dos imagenes siguen siendo iguales)
	//Cargar la imagen nueva en la imagen inferior (ahora la superior tiene la vieja y la inferior la nueva)
	//Una vez detectado el evento load, hacer el fundido de la superior 
	//Una vez que la superior se ha ocultado, se sustituye la imagen por la nueva (ahora vuelven a tener la misma imagen)



	//el parametro enlace contiene la url de la nueva imagen así como el titulo
	this.cambiaImagen = function cambiaImagen(enlace) 
	{
		var enlace = enlace;
		
				
		//almacenamos la imagen de la diapositiva que seleccionamos
		var nuevaImagen = enlace.attr('href');
		var nuevoTitulo = enlace.attr('title');
		
		//variables con las imagenes y sus contenedores
		var contImagenSup = objeto.imagenSup.parent();
		var contImagenInf = objeto.imagenInf.parent();
		
		contImagenSup = jQuery(contImagenSup);
		contImagenInf = jQuery(contImagenInf);
		
		//si la bandera que marca la transición está inactiva, realizamos el fundido
		if (objeto.imagenCambiando == false )
		{
			//establecemos la bandera como activa para evitar que se interrumpa el fundido
			objeto.imagenCambiando = true;
			
			//mostramos el contenedor
			//con la imagen superior haciendo un fundido instantáneo
			contImagenSup.fadeIn('fast',function()
			{
			
				//cargamos la imagen de la miniatura seleccionada en la imagen inferior
				objeto.imagenInf.load(function()
				{	
					//una vez cargada, fundimos la imagen superior haciendola desaparecer
					contImagenSup.fadeOut(1200, function()
					{
						//y una vez oculta, cargamos la nueva imagen
						objeto.imagenSup.attr("src",objeto.imagenInf.attr('src'));
						objeto.imagenSup.attr('alt',objeto.imagenInf.attr('alt'));
						objeto.imagenCambiando = false;
										
					});
				
				}).attr('src',nuevaImagen).attr('alt',nuevoTitulo);
			
			});
			
			
		}
		else 
		{
			return false;
		}
		
		//sustituimos el titulo de la imagen
		jQuery('#titulo_imagen_portada_txt').text(nuevoTitulo);
		
		
		
		
		//*******************************************metodo que sirve para centrar imagenes************************************/

		//actualmente no se usa puesto que las imagenes van en un div contenedor y se centran con css
		function centraImagen(img) 
		{
			//para centrar las imágenes tenemos que crear una imagen virtual que tendrá el mismo origen que la imagen que queremos centrar
			//debido a que en firefox, chrome, etc, jquery comprueba el valor del ancho antes de que la imagen haya cargado, devolviendo 0
			var img = img;
			var srcImg = img.attr('src');
			
			//esta variable corresponderá a la imagen virtual
			var tmpImg = new Image(); 
			
			//una vez que esta imagen haya cargado, comprobandolo mediante el evento load, llamamos a la función que calcula los anchos
			jQuery(tmpImg).load(function()
			{
				calculaAnchos();
			}).attr('src',srcImg);
			
			//una vez seguros de que la imagen haya cargado completamente, es indistinto aplicar los métodos para el ancho a la imagen 
			//original o a la virtual
			function calculaAnchos()
			{
				var anchoImg = img.width();
				var anchoCont = img.parent().width();
				var espacioLat = 0;
				
					if (anchoImg == 0)
					{
						anchoImg = img.width();
					}
					else
					{
				
						if (anchoCont > anchoImg)
						{
							espacioLat = (anchoCont - anchoImg) / 2;
						}
						else
						{
							espacioLat = 0;
						}
					}
					
					//alert(anchoCont+ ' '+anchoImg+' '+espacioLat);
					
					//ahora sí, aplicamos la posición correspondiente a las medidas obtenidas
					img.css({'left':espacioLat,'visibility':'visible'});

					
			}//calculaAnchos

		}//centraimagen
		
		
	};//cambiaImagen


	
	
}//fin de la clase
