Ext.ns('Ext.ux');

Ext.ux.SlideShow = Ext.extend(Ext.util.Observable, 
{
	ajaxRequestClassName:	null,
	ajaxRequestMethod:		null,
	autoLoad: 				null,
	activeSlide: 			0,
	autoPlay:				false,
	cls:					'GUI_Slide',
	customNavigationIndex:	false,
	debug:					false,
	freezeOnHover: 			true,
	navigationShown:		false,
	interval: 				5,
	transitionDuration:		1,
	pauseOnNavigate: 		false,
	slideShowWidth:			160,
	slideShowHeight: 		500,
	slideOrientation:		'horizontal',
	showContextMenu:		false,
	showSlideInfo:			false,
	showNavigation:			true,
    showNavigationOnHover: 	false,
	showNavigationIndex:	false,
	itemSelector: 			'div.slideItem',
    loadedImages:			null,
	loadingMessage:			'cargando...',
	wrap: 					false,
	tpl:					null,
    tplFileName:			null,
    tplMapping:				'{id: slide.id, src: slide.src, title: slide.title, link: slide.link}',
 
    constructor: function(elId, config) 
    {
        config = config || {};
        Ext.apply(this, config);

        Ext.ux.SlideShow.superclass.constructor.call(this, config);
        
        this.addEvents(
            'beforeprev',
            'prev',
            'beforenext',
            'next',
            'change',
            'play',
            'pause',
            'freeze',
            'unfreeze'
        );

        this.el 			= Ext.get(elId);
        this.els 			= [];
		this.slides			= [];
		this.images			= [];
		this.loadedImages	= new Number(0);
		
		if(this.autoPlay) 
		{
            this.wrap = true;
        };
		
        if(this.autoLoad == null)
        {
        	this.initMarkup();
            //this.preloadImages();
        }
        else
        {
        	this.load(this.autoLoad);
        }
    },

	/**
	 * inicializa la estructura del scroll
	 */
    initMarkup: function() 
    {  		  
    	if(this.debug) console.log("fn(0) initMarkup...");
    	this.slideShowSize 		= 0;
    	this.slideShowWidth 	= this.slideShowWidth || this.el.getWidth(true);
        this.slideShowWidth 	= this.slideShowWidth || this.el.getHeight(true);
    
    	var dh 				= Ext.DomHelper;
        var items			= this.el.select(this.itemSelector);
        
       	// añade el contenedor del scroll
        this.els.container 		= dh.append(this.el, {cls: this.cls + '_Container'}, true);
        this.els.container.setStyle({width: this.slideWidth + 'px', height: this.slideHeight + 'px'});
        
        // añade el contenedor deslizable del scroll
        this.els.slideShowWrap	= dh.append(this.els.container, {cls: this.cls + '_SlidesWrap'}, true).hide();
        
        // agregamos el bloque con el mensaje de cargando
   		this.els.loading		= dh.append(this.els.container, '<div class="' + this.cls + '_Loading">' + this.loadingMessage + '</div>', true);
   		
      	// añade el contenedor con los elementos de navegación del slide
   		if(this.slideOrientation == "horizontal")
   		{
   			if(this.debug) console.log("agrega botones a la derecha e izquierda");
   			this.els.navigationAreaLeft		= dh.append(this.els.container, {cls: this.cls + '_NavigationArea_Left'}, true);
   			this.els.navigationPrev			= dh.append(this.els.navigationAreaLeft, {cls: this.cls + '_Navigation_Prev'}, true).hide();
   	        this.els.navigationPrevBtn		= dh.append(this.els.navigationPrev, {tag: 'a', href: '#'}, true);
   			
   	   		this.els.navigationAreaRight	= dh.append(this.els.container, {cls: this.cls + '_NavigationArea_Right'}, true);
   	   		this.els.navigationNext 		= dh.append(this.els.navigationAreaRight, {cls: this.cls + '_Navigation_Next'}, true).hide();
   	   		this.els.navigationNextBtn		= dh.append(this.els.navigationNext, {tag: 'a', href: '#'}, true);
   		}
   		else
   		{
   			if(this.debug) console.log("agrega botones arriba y abajo");
   			this.els.navigationAreaTop		= dh.append(this.els.container, {cls: this.cls + '_NavigationArea_Top'}, true);
   			this.els.navigationPrev			= dh.append(this.els.navigationAreaTop, {cls: this.cls + '_Navigation_Prev'}, true).hide();
   			this.els.navigationPrevBtn		= dh.append(this.els.navigationPrev, {tag: 'a', href: '#'}, true);
   			
   			this.els.navigationAreaBottom	= dh.append(this.els.container, {cls: this.cls + '_NavigationArea_Bottom'}, true);
   	   		this.els.navigationNext 		= dh.append(this.els.navigationAreaBottom, {cls: this.cls + '_Navigation_Next'}, true).hide();
   	   		this.els.navigationNextBtn		= dh.append(this.els.navigationNext, {tag: 'a', href: '#'}, true);
   		}
   		
   		// añade el contenedor para la navegación por índices
   		if(this.showNavigationIndex) this.els.navigationIndex	= dh.append(this.els.container, {cls: this.cls + '_NavigationIndex'}, true).hide();
   		
   		//añade el contenedor para la información del slide
   		if(this.showSlideInfo) this.els.slideInfo 				= dh.append(this.els.container, {cls: this.cls + '_SlideInfo'}, true).hide();
   		
   		// añade el contenedor para el menú contextual
   		this.els.contextMenu		= dh.append(this.els.container, {cls: this.cls + '_ContextMenu'}, true).hide();
        
        /* Se añade la clase _Element a cada elemento de la galeria y se inicializa el arreglo slides */
        items.appendTo(this.els.slideShowWrap).each(function(item) 
        {        
        	item = item.wrap({cls: this.cls + '_SlideItem'});
        	this.slides.push(item);
        }, this);
        
        /* Se inicializa el tamaño del slide */
        this.slideShowSize = this.slides.length;
        
    	this.el.clip();
    	
    }, // END initMarkup
    
    /**
     * inicializa los eventos del slide
     */
    initEvents: function()
    {
    	if(this.debug) console.log("fn(5) initEvents...");
    	
   		// le asigna un evento al buton de navgacion prev cuando se presiona
    	this.els.navigationPrev.on('click', function(ev) 
    	{
    		ev.preventDefault();
    		var target = ev.getTarget();
      		target.blur(); 
    		this.prev();
    	}, this);
    	
    	// le asigna un evento al buton de navgacion next cuando se presina
    	this.els.navigationNext.on('click', function(ev) 
    	{
    		ev.preventDefault();
    		var target = ev.getTarget();
      		target.blur(); 
    		this.next();
    	}, this);
    	
    	// para la  cuando se pone el puntero sobre el slide
    	if(this.freezeOnHover) 
    	{
            this.els.container.on('mouseenter', function()
            {
                if(this.playing) 
                {
                    this.fireEvent('freeze', this.slides[this.activeSlide]);
                    Ext.TaskMgr.stop(this.playTask);
                }
            }, this);
            this.els.container.on('mouseleave', function()
            {
                if(this.playing) 
                {
                    this.fireEvent('unfreeze', this.slides[this.activeSlide]);
                    Ext.TaskMgr.start(this.playTask);
                }
            }, this, {buffer: (this.interval/2) * 1000});
        };
        
        // muestra los botones de navegación cuando el puntero esta sobre el componente
        if(this.showNavigationOnHover) 
        {
        	if(this.debug) console.log("showNavigationOnHover...");
            this.els.container.on('mouseenter', function()
            {
                if(!this.navigationShown) 
                {
                	if(this.debug) console.log("showNavigation");
                    this.navigationShown = true;
                    
                    if(this.activeSlide > 0)
                    {
                    	this.els.navigationPrev.fadeIn(
                    	{
                    		duration: .5
						});
                    }
                    if(this.activeSlide < (this.slideShowSize - 1))
                    {
                    	this.els.navigationNext.fadeIn(
                    	{
                    		duration: .5
                    	});
                    }
                }
            }, this);

            this.els.container.on('mouseleave', function()
            {
                if(this.navigationShown) 
                {
                	if(this.debug) console.log("hideNavigation");
                    this.navigationShown = false;
                    
                    this.els.navigationPrev.fadeOut(
                    {
                    	duration: .5
                    });
                    this.els.navigationNext.fadeOut(
                    {
                    	duration: .5
                    });
                }
            }, this);
        }
        
        // el ancho de cada uno de los elementos del slide definido en la hoja de estilo
		this.els.slideElementWidth 	= this.slides[0].dom.offsetWidth;
		//console.log("elementWidth: " + this.els.slideElementWidth);
		
		// el largo de cada uno de los elementos del slide definido en la hoja de estilo
		this.els.slideElementHeight = this.slides[0].dom.offsetHeight;
		//console.log("elementHeight: " + this.els.slideElementHeight);
		
		// el ancho total del slide (ancho del elemento por numero de elementos)
		this.els.slideTotalWidth 	= (this.els.slideElementWidth * this.slideShowSize);
		//console.log("totalWidth: " + this.els.slideTotalWidth);
		
		// el ancho total del slide (largo del elemento por numero de elementos, solo para el caso vertical)
		this.els.slideTotalHeight 	= (this.els.slideElementHeight * this.slideShowSize);
		//console.log("totalHeight: " + this.els.slideTotalWidth);
  		
  		// altura del contenedor
  		this.els.wrapperHeight 		= this.el.getHeight();
  		//console.log("wrapperHeight: " + this.els.wrapperHeight);
  		
  		// ancho del contenedor
  		this.els.wrapperWidth 		= this.el.getWidth();
  		//console.log("totalHeight: " + this.els.slideTotalWidth);
  		
    	switch(this.slideOrientation)
    	{
    		case 'vertical':
    		{
    			this.initVerticalSlide();
    			break;
    		}
    		case 'horizontal':
    		{    		
    			this.initHorizontalSlide();
    			break;
			}    			
    	}
    	
    }, // END initEvents
    
	/**
	 * revisa que hayan cargado todas las imagenes antes de ejecutar el scroll
	 */
	preloadImages: function()
	{		
    	if(this.debug) console.log("fn(4) preloadImages...");

		var imageStore	= [];
		
	    for(var i = 0; i < this.slideShowSize; i++)
    	{
    		var imageObj = this.slides[i].child('div.slideItem img', true);
    	
    		if (imageObj.width > 0)
    		{
    			imageStore[i]			= new Image();
    			imageStore[i].onLoad 	= this.onLoadImage(imageObj);
    			imageStore[i].src		= imageObj.src;
    		}	
    	}
	    
	    if(this.debug) console.log("loadedImages: " + this.loadedImages + " slideLength: " + this.slideShowSize);
	    
	    //if (this.loadedImages == this.slideShowSize)
	    //{	    	
	    	if(this.debug) console.log("se cargaron todas las imagenes...");
	    	var task = new Ext.util.DelayedTask(function()
	    	{
	    		this.initEvents();
	    		this.els.loading.hide();
	    		this.els.slideShowWrap.show();
	    	}, this);
	    	
	    	task.delay(1000);
	    //}
	   
	}, // END preloadImages
	
	/**
	 * Agrega el objeto imagen a el arreglo de datos images e incrementa el número de imagenes cargadas
	 */
	onLoadImage: function(imageObj)
	{
		this.images.push(imageObj);
		this.loadedImages++;
		
	}, // END onLoadImage
	
	/**
	 * Realiza una solicitud de información para actualiza el componente
	 */
	load: function(args)
	{
		if(this.debug) console.log("fn(1) load...");
		
		this.initMarkup();
		
		Ext.Ajax.request({
		   	url: 	'Intranet/IApplicationGateway.php',
			method:	'POST',
			params: { 
				args:		args,
				className:	this.ajaxRequestClassName,
				method:		this.ajaxRequestMethod,
				serialize: 	'',						
				task: 		"executeClassMethod"
			},
		   	success: function(result, request)
		   	{
				this.loadSuccess(result.responseText);
		   	},
			failure: function(result, request) 
			{
		     	alert('server-side failure with status code ' + response.status);
		   	},
		   	scope: this
		});
	
		      	
	}, // END of function
	
	/**
	 * Reinicializa la información del componente con los datos recibidos de la petición
	 */
	loadSuccess: function(response)
	{
		if(this.debug) console.log("fn(2) loadSuccess...");
		
		var data 	= Ext.decode(response).data;
		this.clear();
		
		if(this.tpl == null)
		{
			Ext.Ajax.request(
			{
				url: 		'assets/templates/' + this.tplFileName,
				method:		'POST',
				scope:		this,
				success: 	function(result, request)
				{
					var cmp 	= Ext.get(this.el);
					
					this.tpl	= new Ext.Template(result.responseText);
					this.tpl.compile();
					
					Ext.each(data, function(slide)
					{						
						var tplMapping = eval('(' + this.tplMapping + ')');
						this.tpl.append(cmp, tplMapping);
					}, this);
					
					this.initMarkup();
			        this.preloadImages();
				}
			});
		}
		else
		{
			var cmp 	= Ext.get(this.el);
			
			Ext.each(data, function(slide)
			{
				var tplMapping = eval('(' + this.tplMapping + ')');
				this.tpl.append(cmp, tplMapping);
			}, this);
					
			this.initMarkup();
			this.preloadImages();
		}
	}, // END of function 
    
    /**
     * muestra el elemento anterior del slide
     */
    prev: function() 
    {
		if(this.debug) console.log("fn() prev...");
        if (this.fireEvent('beforeprev') === false) {
            return;
        }
        if(this.pauseOnNavigate) 
        {
            this.pause();
        }
        this.setSlide(this.activeSlide - 1);

        this.fireEvent('prev', this.activeSlide);        
        return this; 
    }, // END prev
    
    /**
     * muestra el siguiente elemento del slide
     */
    next: function() 
    {
    	if(this.debug) console.log("fn() next...");
        if(this.fireEvent('beforenext') === false) 
        {
            return;
        }
        if(this.pauseOnNavigate) 
        {
            this.pause();
        }
        this.setSlide(this.activeSlide + 1);
        this.fireEvent('next', this.activeSlide);        
        return this;         
    }, // END next
    
    /**
     * Comienza la reproduccíon de slides
     */
    play: function() 
    {
    	if(this.debug) console.log("fn() play...");
        if(!this.playing) 
        {
            this.playTask = this.playTask || {
                run: function() {
                    this.playing = true;
                    this.setSlide(this.activeSlide+1);
                },
                interval: this.interval*1000,
                scope: this
            };
            
            this.playTaskBuffer = this.playTaskBuffer || new Ext.util.DelayedTask(function() {
                Ext.TaskMgr.start(this.playTask);
            }, this);

            this.playTaskBuffer.delay(this.interval*1000);
            this.playing = true;
            this.fireEvent('play');
        }        
        return this;
    }, // END of function

    /**
     * Reinicializa las variables del componente para una actualización de datos
     */
    clear: function() 
    {
    	if(this.debug) console.log("fn(3) clear...");
    	this.el.update('');
        this.els.slideShowWrap.update('');
        
        this.images			= [];
        this.slides	 		= [];
        this.slideShowSize 	= 0;
        this.loadedImages	= new Number(0);
        return this;
    }, // END of function
    
    /**
     * Actualiza la información del slide
     */
    refresh: function() 
    {
    	if(this.debug) console.log("fn() refresh...");
        this.slideSize = this.slideShowSize;
        this.els.slideShowWrap.setWidth(this.els.slideTotalWidth);
        if(this.slideSize > 0) 
        {
            this.activeSlide = 0;
            this.setSlide(0, true);
        }                
        return this;        
    }, // END of function
    
    /**
     * Establece el slide actua a mostrar en el componente
     */
	setSlide: function(index, initial)
	{
    	if(this.debug) console.log("fn() setSlide(" + index + "), (" + initial + ")");
    	
    	if(!this.wrap && !this.slides[index]) 
        {
            return;
        }
        else if(this.wrap) 
        {
            if(index < 0) 
            {
                index = this.slideShowSize - 1;
            }
            else if(index > (this.els.totalSlides - 1)) 
            {
                index = 0;
            }
        }
        
        if(!this.slides[index]) 
        {
            return;
        }    
        
    	// Muestra las flechas de navegacion si está definido en this.showNavigation
        if(this.showNavigation && (this.showNavigationOnHover == false))
    	{
    		// Se muestran los botones de navegación sólo si hay más de un slide
    		if(this.els.totalSlides > 1)
    		{
				// oculta el botón prev cuando estamos en el primer slide
				if(index == 0)
				{
					this.els.navigationPrev.fadeOut(
		      		{
		    			duration: .5
					});
					
					this.els.navigationNext.fadeIn(
		      		{
		    			duration: .5
					});
				}
		
				// muestra el botón prev si no estamos en slide 0
				if(index > 0)
				{
					this.els.navigationPrev.fadeIn(
		      		{
		    			duration: .5
					});
				}
				
				// oculta el botón next cuando estamos en el último slide
				if(index == (this.els.totalSlides - 1))
				{
					this.els.navigationNext.fadeOut(
		      		{
		    			duration: .5
					});
				}
    		}
    	}
    	
        if(this.showSlideInfo) this._hideSlideInfo(index);
    	
  		// arreglo de datos con la distancia existente desde el origen del documento (0,) hasta la posición del contenedor
  		this.els.wrapperOffset 		= Ext.getBody().getOffsetsTo(this.els.container);

		// distancia en x desde el origen del documento al contenedor
		this.els.wrapperOffsetX 	= Math.abs(this.els.wrapperOffset[0]);
		//console.log("wrapperOffsetX: " + this.els.wrapperOffsetX);
		
		// distancia en y desde el origen del documento al contenedor
  		this.els.wrapperOffsetY 	= Math.abs(this.els.wrapperOffset[1]);
  		//console.log("wrapperOffsetY: " + this.els.wrapperOffsetY);
    	
    	
    	switch(this.slideOrientation)
    	{
    		case 'vertical':
    		{    	        
    			var x	= this.els.wrapperOffsetX + this.els.slideShowWrapOffsetLeft;
    			var y	= (index * this.els.maxElsPerSlide * this.els.slideElementHeight) - (this.els.initTop);
    			
    			if(this.debug) console.log("x: " + x + " y: " + y + " activeSlide: " + index + " maxElsPerSlide: " + this.els.maxElsPerSlide + " slideElementHeight: " + this.els.slideElementHeight);
    	    	
    	    	var moveTask	= new Ext.util.DelayedTask(function()
    	           				{
    	               				this.els.slideShowWrap.moveTo(x, -y, {duration: this.transitionDuration});
    	           				}, this);
    	            		
    	    	var showTask	= new Ext.util.DelayedTask(function()
    	         				{
    	              				this.els.slideShowWrap.setOpacity(1, {duration: this.transitionDuration / 2});
    	              				// cambia el estilo del índice de navegación para indicar el slide actual 
    	              		        if(this.showNavigationIndex)
    	              		    	{
    	              		        	if(this.customNavigationIndex)
    	              		    		{
    	              		        		Ext.select('div.navLink').removeClass(this.cls + '_NavigationIndexActive');
    	              		        		Ext.select('div.navIndex_' + index).addClass(this.cls + '_NavigationIndexActive');	
    	              		    		}
    	              		    	}
    	          				}, this);
    	            		
    	    	this.els.slideShowWrap.setOpacity(.5, {duration: this.transitionDuration / 2});
    	
    	    	moveTask.delay((this.transitionDuration / 2) * 1000);
    	            		
    	    	showTask.delay((this.transitionDuration) * 1000);
    	    	
    	    	this.activeSlide = index;
    	    	
    			break;
    		}
    		case 'horizontal':
    		{    		
    			var x 			= (index * this.els.maxElsPerSlide * this.els.slideElementWidth) - (this.els.initLeft);
    	    	var y			= this.els.wrapperOffsetY + this.els.slideShowWrapOffsetTop;
    	        
    	    	if(this.debug) console.log("x: " + x + " y: " + y + " activeSlide: " + index + " maxElsPerSlide: " + this.els.maxElsPerSlide + " slideElementWidth: " + this.els.slideElementWidth);
    	    	
    	    	var moveTask	= new Ext.util.DelayedTask(function()
    	           				{
    	               				this.els.slideShowWrap.moveTo(-x, y, {duration: this.transitionDuration});
    	           				}, this);
    	            		
    	    	var showTask	= new Ext.util.DelayedTask(function()
    	         				{
    	              				this.els.slideShowWrap.setOpacity(1, {duration: this.transitionDuration / 2});
    	              				// cambia el estilo del índice de navegación para indicar el slide actual 
    	              		        if(this.showNavigationIndex)
    	              		    	{
    	              		        	if(this.customNavigationIndex)
    	              		    		{
    	              		        		Ext.select('div.navLink').removeClass(this.cls + '_NavigationIndexActive');
    	              		        		Ext.select('div.navIndex_' + index).addClass(this.cls + '_NavigationIndexActive');	
    	              		    		}
    	              		    	}
    	              		        
    	              		        
    	              		        this._showSlideInfo();
    	              		        
    	              		        
    	          				}, this);
    	            		
    	    	this.els.slideShowWrap.setOpacity(.5, {duration: this.transitionDuration / 2});
    	
    	    	moveTask.delay((this.transitionDuration / 2) * 1000);
    	            		
    	    	showTask.delay((this.transitionDuration) * 1000);
    	    	
    	    	this.activeSlide = index;
    	    	
    			break;
			}    			
    	}
    	 		
	    	    
        
	}, // END setSlide

	/**
	 * oculta el slide
	 */
	hide: function()
	{
		this.els.slideWrap.hide();
	}, // END function
	
	/**
	 * muestra el slide
	 */
	show: function()
	{
		this.els.slideWrap.show();
	}, // END function
	
	/**
	 * inicializa un scrollHorizontal
	 */
	initHorizontalSlide: function()
	{			
		if(this.debug) console.log("fn(6) initHorizontalSlide...");
		
		// posición inicial del scroller en y con referencia al origen del documento y al contenedor
  		this.els.initLeft			= this.el.getLeft();
  		//console.log("initLeft: " + this.els.initLeft);
  		
  		// número máximo de elementos que aparecen por slide
  		this.els.maxElsPerSlide 	= Math.round(this.els.wrapperWidth / this.els.slideElementWidth);
  		if(this.debug) console.log("maxElsPerSlide: " + this.els.maxElsPerSlide);
  		
  		// establece el ancho del slide que contiene los elementos
  		this.els.slideShowWrap.setWidth(this.els.slideTotalWidth);
  		
  		// El offset del slideWrap (por si fue posicionado de forma absoluta respecto al contenedor)
  		this.els.slideShowWrapOffsetTop		= this.els.slideShowWrap.dom.offsetTop;
  		//console.log("slideWrapOffsetTop: " + this.els.slideWrapOffsetTop);
  		
  		// El offset del slideWrap (por si fue posicionado de forma absoluta respecto al contenedor)
  		this.els.slideShowWrapOffsetLeft	= this.els.slideShowWrap.dom.offsetLeft;
  		//console.log("slideWrapOffsetLeft: " + this.els.slideWrapOffsetLeft);
  		
  		// establece el numero total de slides en el componente, un slide puede tener uno o más elementos  		
  		this.els.totalSlides 	= Math.ceil(this.slideShowSize / this.els.maxElsPerSlide);
  		if(this.debug) console.log("totalHorizontalSlides: " + this.els.totalSlides);
  		
    	this.els.slideShowWrap.slideIn('r', 
        {
    		easing: 'easeOut',
    		duration: 2
		});
		
    	if(this.showNavigation && (this.showNavigationOnHover == false))
    	{	
    		if(this.els.totalSlides > 1)
    		{
    			this.els.navigationNext.fadeIn(
    			{
    				duration: 3
    			});
    		}
    	}
    	
    	// muestra el div slideInfo si esta definido
    	if(this.showSlideInfo)
    	{	
    		this.els.slideInfo.fadeIn(
    		{
    			duration: 3
    		});
    	}
    	
    	// muestra los índices de navegación si está definido
    	if(this.showNavigationIndex)
    	{	
    		var dh 		= Ext.DomHelper;
    		var indexes = [];
    		
    		if(this.customNavigationIndex)
    		{
    			for(var i = 0; i < this.slideShowSize; i++)
        		{
        			indexes[i] = dh.append(this.els.navigationIndex, '<a href="#"><div class="navLink navIndex_'+ i +'"></div</a>', true);
        		}
    			// Agrega la clase para indicar el indice con el slide actual
    	    	Ext.select('div.navIndex_0').addClass(this.cls + '_NavigationIndexActive');
    		}
    		else
    		{
    			for(var i = 0; i < this.slideShowSize; i++)
        		{
        			indexes[i] = dh.append(this.els.navigationIndex, '<a href="#">' + (i + 1) + '</a>', true);
        		}
    		}
    		
    		Ext.each(indexes, function(item, index)
    				{
    					item.on('click', function(ev)
    							{
    	    						ev.preventDefault();
    	    						this.setSlide(index);
    							}, this);
    				}, this);
    		
    		this.els.navigationIndex.fadeIn(
    	    		{
    	    	  		duration: 3
    	    		});
    	}
    	
    	if(this.showSlideInfo) this._hideSlideInfo(0);
    	
    	// comienza la reproducción automática del slide
    	if(this.interval && this.autoPlay) 
    	{
           this.play();
        };
  		
	}, // END initHorizontalScroll

	/**
	 * inicializa un scrollVertical
	 */
	initVerticalSlide: function()
	{
		if(this.debug) console.log("fn(6) initVerticalSlide...");
		
		// posición inicial del scroller en y con referencia al origen del documento y al contenedor
  		this.els.initLeft			= this.el.getLeft();
  		//console.log("initLeft: " + this.els.initLeft);
  		
  		// posición inicial del scroller en y con referencia al origen del documento y al contenedor
  		this.els.initTop			= this.el.getTop();
  		//console.log("initTop: " + this.els.initTop);
  		
  		// número máximo de elementos que aparecen por slide
  		this.els.maxElsPerSlide 	= Math.round(this.els.wrapperHeight / this.els.slideElementHeight);
  		//console.log("maxElsPerSlide: " + this.els.maxElsPerSlide);
  		
  		// establece el ancho del slide que contiene los elementos
  		this.els.slideShowWrap.setHeight(this.els.slideTotalHeight);
  		
  		// El offset del slideWrap (por si fue posicionado de forma absoluta respecto al contenedor)
  		this.els.slideShowWrapOffsetTop		= this.els.slideShowWrap.dom.offsetTop;
  		//console.log("slideWrapOffsetTop: " + this.els.slideWrapOffsetTop);
  		
  		// El offset del slideWrap (por si fue posicionado de forma absoluta respecto al contenedor)
  		this.els.slideShowWrapOffsetLeft	= this.els.slideShowWrap.dom.offsetLeft;
  		//console.log("slideWrapOffsetLeft: " + this.els.slideWrapOffsetLeft);
  		
  		// establece el numero total de slides en el componente, un slide puede tener uno o más elementos  		
  		this.els.totalSlides 	= Math.ceil(this.slideShowSize / this.els.maxElsPerSlide);
    	if(this.debug) console.log("totalVerticalSlides: " + this.els.totalSlides);
  		
    	this.els.slideShowWrap.slideIn('t', 
        {
    		easing: 'easeOut',
    		duration: 2
		});
		
    	if(this.showNavigation && (this.showNavigationOnHover == false))
    	{
    		if(this.els.totalSlides > 1)
    		{
    			this.els.navigationNext.fadeIn(
    			{
    				duration: 3
    			});
    		}
    	}
    	
    	// muestra los índices de navegación si está definido
    	if(this.showNavigationIndex)
    	{	
    		var dh 		= Ext.DomHelper;
    		var indexes = [];
    		
    		if(this.customNavigationIndex)
    		{
    			for(var i = 0; i < this.slideShowSize; i++)
        		{
        			indexes[i] = dh.append(this.els.navigationIndex, '<a href="#"><div class="navLink navIndex_'+ i +'"></div</a>', true);
        		}
    			// Agrega la clase para indicar el indice con el slide actual
    	    	Ext.select('div.navIndex_0').addClass(this.cls + '_NavigationIndexActive');
    		}
    		else
    		{
    			for(var i = 0; i < this.slideShowSize; i++)
        		{
        			indexes[i] = dh.append(this.els.navigationIndex, '<a href="#">' + (i + 1) + '</a>', true);
        		}
    		}
    		
    		Ext.each(indexes, function(item, index)
    				{
    					item.on('click', function(ev)
    							{
    	    						ev.preventDefault();
    	    						this.setSlide(index);
    							}, this);
    				}, this);
    		
    		this.els.navigationIndex.fadeIn(
    	    		{
    	    	  		duration: 3
    	    		});
    	}
    	
    	// comienza la reproducción automática del slide
    	if(this.interval && this.autoPlay) 
    	{
           this.play();
        };	
	}, // END initVerticalScroll
	
	/****************************************************************
	 * Métodos P R I V A D O S
	 ****************************************************************/
	
	/**
	 * Oculta el panel con la información del slide
	 */
	_hideSlideInfo: function(index)
	{
		if(this.debug) console.log("fn(" + index + ") _hideSlideInfo...");
		
        if(this.showSlideInfo)
	   	{		
	   		this.els.slideInfo.fadeOut(
	   		{
	   			duration: this.transitionDuration
	   		});
	   	}
        
        var dh 			= Ext.DomHelper;
    	var slideInfo	= this.slides[index].child('div.slideItem div.' + this.cls + '_SlideInfo', true).innerHTML || ''; 
    	
    	var updateTask	= new Ext.util.DelayedTask(function()
					{
						this.els.slideInfo.update(slideInfo);
					}, this);
	
    	updateTask.delay((this.transitionDuration) * 1000);
    	
	}, // END of function
	
	/**
	 * Muestra el panel con la información del slide
	 */
	_showSlideInfo: function()
	{
	    if(this.showSlideInfo)
	    {	
	    	this.els.slideInfo.fadeIn(
	    	{
	    		duration: this.transitionDuration
	    	});
	    }
	} // END of function
	
});
