/*
 * jQuery Rotate Images Alpha
 * http://www.entijuana.es
 *
 * Copyright 2011, Hermes Andreu
 * Free to use and abuse under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Creates a slideshow from an array of photos preloading in the background the next images
 * 
 * March 2011 - Pick random effect from specified set of effects by toronegro 
 * 
 */

(function($){
                        
    $.fn.preloadSlide = function(options){
        // override defaults with specified option
        var settings = $.extend({}, $.fn.preloadSlide.defaults, options),                   
            
			tokenId = Math.floor(Math.random()*1000000).toString(16),           
            readyToLoad=true,      
			total=settings.imageArray.length,
			indexPosition=settings.startImage-1; //current position of the index in the array of images
        if(indexPosition<0){
            indexPosition+=total;
        }     
        var navigationDirection=1, // 1 forward, -1 backward. Increment of the index in the array of images
			imageBufferId="#JRIimageBufferId"+tokenId,
			clickHandler='JRIprocessClick'+tokenId,
			$imageBuffer=null,
			$slideContainer=this.eq(0),
			checkLoadTimer=setInterval(function(){
            updateImageBuffer();
        },500);
        var nextIsAvailable=false;     // advance is only possible if it is true 
        var windowToken='JRItoken'+tokenId;
        eval('window.'+windowToken+'={id:"'+tokenId+'"};');
        var loadHandler=function(){};
        var firstInterval=true;
        
        //
        //console.log(settings.imageArray) ;
        initPreloadSlide();                        
               
        function initPreloadSlide(){
            //create the hidden image buffer
            $('body').append('<div id="'+imageBufferId.substring(1)+'" style="display:none;"></div>');
            $imageBuffer=$(imageBufferId);
            $slideContainer.append('<div class="pl-loading">&nbsp;</div>');                              
          

            //handles button clicking or interval launch
            $(document).bind(clickHandler, function(e){
                var oldWidth=0;
                var newWidth=0;
                var oldHeight =0;
                var newHeight=0;
                
                $('.pl-loading',$slideContainer).fadeOut('fast');
                //  console.log("fading out loader for "+windowToken);
                $('.imageContainer.current',$slideContainer).removeClass('current').addClass('oldCurrent');
                indexPosition+=navigationDirection;
                if(indexPosition>=total){
                    indexPosition=0;
                }else if (indexPosition<0){
                    indexPosition=total-1;
                }
                 
                //We clean any past style definition from animations etc
                $('.imageContainer[index="'+indexPosition+'"] img',$imageBuffer).removeAttr('style');
                $('.clear', $slideContainer).remove();
                //and begin the show
				var initialImageCss={opacity:0};
				if(settings.width){
					initialImageCss.width=settings.width+'px';
				}if(settings.height){
					initialImageCss.width=settings.height+'px';
				}

                
                $('.imageContainer[index="'+indexPosition+'"]',$imageBuffer).removeAttr('style').addClass('current').stop(true,true).css({
                    opacity:0
                }).appendTo($slideContainer).delay(100).animate({
                    opacity:1
                },settings.transitionSpeed,function(){                    
                    $('.imageContainer.oldCurrent',$slideContainer).removeClass('oldCurrent').trigger('fadeOutNow');
                    var $elem=$(this);
                    if ($.browser.msie ) {
                        $elem[0].style.removeAttribute('filter');
                    }
                    
                });
                //   console.log ("Is the next on stage really? "+$('.imageContainer[index="'+indexPosition+'"]',$slideContainer).length);
                $slideContainer.append('<div class="clear"></div>');
                $('.imageContainer.current img',$slideContainer).removeClass('wider');                
                //check for image aspect vs container aspect and add or not a class to fit the image in the container
                if($('.imageContainer.current img',$slideContainer).width()>$slideContainer.width()){
                    $('.imageContainer.current img',$slideContainer).addClass('wider');
                }else{
                    $('.imageContainer.current img',$slideContainer).removeClass('wider');
                }
                //we measure old and new dimensions
                oldWidth=$('.imageContainer.oldCurrent img',$slideContainer).width();
                newWidth=$('.imageContainer.current img',$slideContainer).width();
                oldHeight =$('.imageContainer.oldCurrent img',$slideContainer).height();
                newHeight=$('.imageContainer.current img',$slideContainer).height();
                if(typeof adjustCaption=='function')   {
                    adjustCaption();
                }          
                //and if animateFadeAspect is true, we animate it
                if((settings.animateFadeAspect)&&(!$('body').hasClass('fullscreen'))){
                    // console.log(newWidth+" más pequeña que "+oldWidth);
                    $('.imageContainer.oldCurrent img',$slideContainer).css({
                        width:oldWidth,
                        height:oldHeight
                    });
                    $('.imageContainer.oldCurrent',$slideContainer).stop(true,true).css({
                        width:oldWidth,
                        marginLeft:Math.floor(-oldWidth/2),
                        "text-indent":0,
                        height:oldHeight,
                        // backgroundColor:"red",
                        textAlign:"left"
                    }).animate({
                        width:newWidth,
                        marginLeft:Math.floor(-newWidth/2),
                        "text-indent":Math.ceil((newWidth-oldWidth)/2),
                        height:newHeight
                    },'fast');
                }
       
            });
                
            $('#'+settings.nextButtonId+' a').click(function(e){
                if(settings.autoSlideshowTime!=false){                    
                    window.clearInterval(window[windowToken].autoSlideshowTime);
                    window[windowToken].autoSlideshowTime=window.setInterval(function(){                   
                        if(nextIsAvailable){
                            nextIsAvailable=!nextIsAvailable;
                            $(document).trigger(clickHandler);
                        }
                    },settings.autoSlideshowTime);
                }
                //  console.log("click");
                if(!$(this).hasClass('disabled')){
                    $(this).addClass('disabled');
                    navigationDirection=1;      
                    $(document).trigger(clickHandler);
                }
                else{
            //  console.log("disabled button");
            }
            });
                
         
            $('#'+settings.prevButtonId+' a').click(function(e){
                if(settings.autoSlideshowTime!=false){
                    window.clearInterval(window[windowToken].autoSlideshowTime);
                    window[windowToken].autoSlideshowTime=window.setInterval(function(){                   
                        if(nextIsAvailable){
                            nextIsAvailable=!nextIsAvailable;
                            $(document).trigger(clickHandler);
                        }
                    },settings.autoSlideshowTime);
                }
               
            
                
                
                // console.log("click");
                if(!$(this).hasClass('disabled')){
                    $(this).addClass('disabled');
                    navigationDirection=-1;      
                    $(document).trigger(clickHandler);
                }
                else{
            //  console.log("disabled button");
            }
            });
            
            if(settings.autoSlideshowTime!=false){ 
                window[windowToken].firstInterval=window.setTimeout(function(){
                    if(nextIsAvailable){
                        nextIsAvailable=!nextIsAvailable;
                        $(document).trigger(clickHandler);
                    }
                    window[windowToken].autoSlideshowTime=window.setInterval(function(){
                        if(nextIsAvailable){
                            nextIsAvailable=!nextIsAvailable;
                            $(document).trigger(clickHandler);
                        }
                    },settings.autoSlideshowTime);
                },settings.autoSlideshowTime+settings.initialDelay);
            }
        }
        // function called at short intervals that checks if the loader is ready
        // and then loads the next image 
        function updateImageBuffer(){
            var indexRaw=0; //used when calculating next and previous indexes for preloading
            var zero=true; //used when calculating next and previous indexes for preloading
            var one=true; //used when calculating next and previous indexes for preloading
            var two=false;  //used when calculating next and previous indexes for preloading
            var nextImageIndex=indexPosition;
                
            if(readyToLoad){
                if(settings.preloadedImages>total){
                    settings.preloadedImages = total;               
                }
                one=true;
                zero=true;
                indexRaw=0;
                for(var i=0;i<settings.preloadedImages;i++){
                    //it adds "nexts" and "prevs" evenly.  
                    if(indexRaw>0){
                        if(!one){
                            indexRaw=-indexRaw;
                        }else{                           
                            one=false;
                        }
                    }else if(indexRaw<0){
                        indexRaw=-indexRaw+1;
                    }else if(indexRaw==0){
                        if(!zero){
                            indexRaw=1;
                        }else{
                            zero=false;
                        }
                    }
                    
                    nextImageIndex=indexPosition+indexRaw;
                    if(nextImageIndex>=total){
                        nextImageIndex-=(total-1);
                    }else if(nextImageIndex<0){
                        nextImageIndex+=(total);
                    }                   
                    //if the next index is present neither in the buffer nor in the container  then we create the tag in the buffer, load the image, and break the for
                    if(($('.imageContainer[index="'+nextImageIndex+'"]',$slideContainer).length==0)&&($('.imageContainer[index="'+nextImageIndex+'"]',$imageBuffer).length==0)){ 
                        readyToLoad=false;
                        if(!settings.modelName){
                                                        
                        }else{
                            // create the image
                            if(!settings.createImageTags){
                                $imageBuffer.append('<div class="imageContainer" index="'+nextImageIndex+'">'+settings.imageArray[nextImageIndex][settings.modelName][settings.fileNameField]+'</div>');                   
                            }else{
                                $imageBuffer.append('<div class="imageContainer" index="'+nextImageIndex+'"><img src="'+settings.imageArray[nextImageIndex][settings.modelName][settings.fileNameField]+'"></div>');                    
                            } 
                            
                            //create the caption if specified                                    
                            if(!settings.createCaptionTags){                              
                                $(imageBufferId+' imageContainer[index="'+nextImageIndex+'"]').append(settings.imageArray[nextImageIndex][settings.modelName][settings.captionField]);         
                                linkTitle= $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"]').text();
                            }else{
                                //console.log('creating caption: '+settings.captionField +settings.imageArray[nextImageIndex][settings.modelName][settings.captionField]);
                                $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"]').append('<div class="slideImageCaption">'+settings.imageArray[nextImageIndex][settings.modelName][settings.captionField]+'</div>');          
                                linkTitle=settings.imageArray[nextImageIndex][settings.modelName][settings.captionField];
                            }
                                
                            console.log('link title from text: '+$(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"]').text());
                            console.log('link title from vars: '+settings.imageArray[nextImageIndex][settings.modelName][settings.captionField]);
                            //create the links if specified in both the image and the caption
                            if(settings.linkField){
                                $(imageBufferId+' imageContainer[index="'+nextImageIndex+'"] img').wrap('<a href="'+settings.imageArray[nextImageIndex][settings.modelName][settings.linkField]+'" title="'+linkTitle+'" target="_top">');
                                var t=$(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"] .slideImageCaption').html();
                                $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"] .slideImageCaption').html('<a href="'+settings.imageArray[nextImageIndex][settings.modelName][settings.linkField]+'" title="'+linkTitle+'" target="_top">'+t+'</a>');
                             
                            } 
							//position the caption if specified
							if(settings.captionFieldPosition 
								&& ((typeof settings.captionFieldPosition.left != "undefined") 
								|| (typeof settings.captionFieldPosition.right != "undefined")
								|| (typeof settings.captionFieldPosition.top != "undefined")
								|| (typeof settings.captionFieldPosition.bottom != "undefined")
								)){
									$('.slideImageCaption').css(settings.captionFieldPosition);
								}
							
                        }
                    
                       
                        // handle image loading                      
                        $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"] img').removeAttr('width').removeAttr('height').one('load',function(e){
                            loadHandler($(this)) 
                        })
                        
                        //adding imageContainer class
                        if(settings.imageContainerClass){
                            $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"]').addClass(settings.imageContainerClass);
                            if ($.browser.msie){
                                $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"] .nivo-caption').addClass('noOpacity');
                            }
                        }
                        
                        // attaching fadeOut function, which makes an image disappear and be stored in its image buffer
                        $(imageBufferId+' .imageContainer[index="'+nextImageIndex+'"]').bind('fadeOutNow',function(e){
                           
                            //                            $(this).stop(true,true).animate({
                            //                                opacity:0
                            //                            },'fast',function(){
                            //                                $(this).appendTo($imageBuffer);
                            //                            })
							
                            $(this).stop(true,true).css({
                                opacity:0
                            }).appendTo($imageBuffer);
                        });                        
                        
                        break;                                        
                    }                
                }
                //remove disabled class in buttons, which happens when both next and pervious images are in the buffer                
                if(i>2){
                    if(settings.nextButtonId){
                        $('#'+settings.nextButtonId+' a, #'+settings.prevButtonId+' a').removeClass('disabled');
                    }
                    nextIsAvailable=true;
                }else{
                    if(settings.nextButtonId){
                        if(!$('#'+settings.nextButtonId+' a.disabled, #'+settings.prevButtonId+' a.disabled').length){
                            $('#'+settings.nextButtonId+' a, #'+settings.prevButtonId+' a').addClass('disabled');
                        }
                    }
                    nextIsAvailable=false;
                }
                
            }
        }
        
        //after the image has been loaded:
        loadHandler = function($e){
            if(settings.linkField){
                $parent= $e.parent().parent();
            }else{
                $parent= $e.parent()
            }
            $parent.attr('loaded','loaded').css({
                opacity:0
            });                               
            readyToLoad=true;
            //inmediately place the first image loaded
            // console.log (windowToken+": loadHandler:  ------------------------------- "+$slideContainer.attr('id'));
            //  console.log (windowToken+": slideContainer length:" +  $('.imageContainer',$slideContainer).length+' : '+($('.imageContainer',$slideContainer).length==0?"true":"false"));
            //    console.log (windowToken+": imageBuffer length:" +  $('.imageContainer',$imageBuffer).length+' : '+($('.imageContainer',$imageBuffer).length>1?"true":"false"));
            //checking for an empty container and a more than 1 buffer:";
            if(($('.imageContainer',$slideContainer).length==0)&&(($('.imageContainer',$imageBuffer).length>1))){
                //       console.log ("+++++++++++++++++++++++++++++ Yes!!! Triggering "+clickHandler);
                $(document).trigger(clickHandler);
				//$(document).trigger()
            }
        }
    }
        
	jQuery.event.special.newImage = {
		setup: function(data, namespaces) {
			var elem = this;
		},

		teardown: function(namespaces) {
			var elem = this;
		}
	};	
		
        
    $.fn.preloadSlide.defaults = {
        /**
     * Max number of preloaded images (will create hidden divs with them)
     * @var int
     */
        preloadedImages: 7,
		
        /**
     * Array with the images to display
     * @var array
     */
        imageArray: null,
        /**
     * Wether image tags are already in the  array or should the plugin create them instead
     * @var boolean
     */
        createImageTags: false,
        /**
     * prefix to prepend to the images in case the image tags are not previously created
     * @var string|boolean
     */
        basePath:false,		
        /**
     * Model name if the image array comes as imageArray[n].modelName.fileNameField
     * @var string|boolean
     */
        modelName: false,		
        /**
     * File name field if the image array comes as imageArray[n].modelName.fileNameField
     * @var string|boolean
     */
        fileNameField: 'thumb',		
        /**
     * Caption field if the image array comes as imageArray[n].modelName.captionField
     * @var string|boolean
     */
        captionField: false,
        /**
     * Link field if the image array comes as imageArray[n].modelName.linkField. 
     * If present each image will link to the specified URL
     * @var string|boolean 
     */
        linkField: false,
        /**
     * Wether caption tags are already in the  array or should the plugin create them instead
     * @var boolean
     */
        createCaptionTags: true,
        /**
     *  time interval for auto slideshow (milliseconds). If false
     * @var number|boolean
     */
        autoSlideshowTime:1500,            
        /**
     *  ids for navigation buttons 
     * @var string|boolean
     */
        nextButtonId:false,
        prevButtonId:false,
        /**
     *  class to add to the imageContainers
     * @var string|boolean
     */
        imageContainerClass:false,
        /**
     *  it will animate the size of the container box to match the dimensions of the new image for a better transition
     *  It only makes sense if images come in different proportions
     * @var boolean
     */
        animateFadeAspect:false,
        /**
     *  transition speed. Accepts typical speed values: 'fast', 'slow', number in milliseconds...
     *  @var string|number
     */
        transitionSpeed:'normal',
        /**
     *  first image to be displayed from the array
     *  @var  number
     */
        startImage:0,
        /**
     *  additional delay to apply only to the first image after it has been loaded
     *  @var  number
     */
        initialDelay:0,
		
	   /**
     *  force the container to have a specific width
     *  @var  number width in pixels or false 
     */
        width:false,	
	
	/**
     *  force the container to have a specific height
     *  @var  number height in pixels or false
     */
        height:false	
                       
    };
                

})(jQuery);
        


