/*
 * jQuery Infinite Carousel
 * @author admin@catchmyfame.com - http://www.catchmyfame.com
 * @version 2.0.2
 * @date June 12, 2010
 * @category jQuery plugin
 * @copyright (c) 2009 admin@catchmyfame.com (www.catchmyfame.com)
 * @license CC Attribution-Share Alike 3.0 - http://creativecommons.org/licenses/by-sa/3.0/
 */

(function($){
    $.fn.extend({ 
        infiniteCarousel: function(options)
        {
            var defaults = 
            {
                elementWidth: 940, 
                elementHeight: 410, 
                transitionSpeed: 800,
                displayTime: 6000,
                textholderHeight: .25,
                displayProgressBar: false,
                displayThumbnails: false,
                customThumbnails: true,
                displayThumbnailNumbers: false,
                displayThumbnailBackground: false,
                thumbnailWidth: '20px',
                thumbnailHeight: '20px',
                thumbnailFontSize: '.7em',
                easeLeft: 'linear',
                easeRight: 'linear',
                imagePath: '/images/layout/carousel/',
                inView: 1,
                padding: '0px',
                advance: 1,
                showControls: true,
                autoHideControls: false,
                autoHideCaptions: false,
                autoStart: false,
                prevNextInternal: true,
                onSlideStart: function(){},
                onSlideEnd: function(){},
                onPauseClick: function(){},
                showCaptions: false
            };
        var options = $.extend(defaults, options);
    
            return this.each(function() {
            var randID = Math.round(Math.random()*100000000);
            var o=options;
            var obj = $(this);
            var autopilot = o.autoStart;

            var numElements = $('li', obj).length; // Number of elements

            if(o.inView > numElements-1) o.inView=numElements-1; // check to make sure inview isnt greater than the number of images. inview should be at least two less than numElements (otherwise hinting wont work and animating left may catch a flash), but one less can work
            /*$('p', obj).hide();*/ // Hide any text paragraphs in the carousel
            $(obj).css({'position':'relative'}).width((o.elementWidth*o.inView)+(o.inView*parseInt(o.padding)*2)).height(o.elementHeight+(parseInt(o.padding)*2)); //,'overflow':'hidden'
            $('ul', obj).css({'list-style':'none','margin':'0','padding':'0','position':'relative'}).width(o.elementWidth*numElements);
            $('li', obj).css({'display':'inline','float':'left','padding':o.padding});

            // Move rightmost image over to the left
            $('li:last', obj).prependTo($('ul', obj));
            $('ul', obj).css('left',-o.elementWidth-(parseInt(o.padding)*2)+'px').width(9999);

            
            if(o.showControls)
            {
                
                arrowsTop = ((o.elementHeight/2)-15)+parseInt(o.padding);
                html = '<div id="btn_rt'+randID+'" style="position:absolute;left:-51px;z-index:400;cursor:pointer;border:none;width:102px;height:51px;background:url('+o.imagePath+'next.png) no-repeat 0 0"></div>';
                (o.prevNextInternal) ? $('#carousel-next').append(html):$('#'+wrapID).append(html);
                
                html = '<div id="btn_lt'+randID+'" style="position:absolute;z-index:400;cursor:pointer;border:none;width:102px;height:51px;background:url('+o.imagePath+'previous.png) no-repeat 0 0"></div>';
                (o.prevNextInternal) ? $('#carousel-prev').append(html):$('#'+wrapID).append(html);

                $('#btn_rt'+randID).click(function(){
                    forcePrevNext('next');
                }).hover(function(){$(this).animate({left:0},250)},function(){$(this).animate({left:-51},250)});
                
                $('#btn_lt'+randID).click(function(){
                    forcePrevNext('prev');
                }).hover(function(){$(this).animate({left:-51},250)},function(){$(this).animate({left:0},250)});
                
            }
            
            
            if(o.customThumbnails)
            {
                function thumbclick(event)
                {
                    target_num = this.id.split('_'); // we want target_num[1]
                    
                    if(viewable[0] != target_num[1])
                    {
                        status='pause';
                        clearTimeout(clearInt);
                        autopilot = 0;
                        
                        // Unbind the thumbnail click event until the transition has ended
                        $('#carousel-thumbs div.thumb').css({'cursor':'default'}).unbind('click'); 
                    }
                    
                    if(target_num[1] > viewable[0])
                    {
                        diff = target_num[1] - viewable[0];
                        moveLeft(diff);
                    }
                    if(target_num[1] < viewable[0])
                    {
                        diff = viewable[0]- target_num[1];
                        moveRight(diff);
                    }
                }

                var viewable = []; // track which images are being displayed
                var unviewable = []; // track which images are being displayed
                
                for(i=0;i<=numElements-1;i++)
                {
                    if(i<=o.inView) $('#thumb_' + i).css({'background-color':'#999999'});
                    unviewable.push(i+1);
                }
                // Initialize viewable/unviewable arrays
                for(i=1;i<=o.inView;i++) viewable.push(unviewable.shift());

                /*$('#carousel-thumbs div.thumb').hover(function(){$(this).animate({'opacity':1},150)},function(){if(viewable[0]!=this.id.split('_')[1]) $(this).animate({'opacity':.65},250)});*/ // add hover to thumbs
                // Assign click handler for the thumbnails. Normally the format $('.thumb') would work but since it's outside of our object (obj) it would get called multiple times
                $('#carousel-thumbs div.thumb').bind('click', thumbclick); // We use bind instead of just plain click so that we can repeatedly remove and reattach the handler
                
            }
            
            function forcePrevNext(dir)
            {
                o.onPauseClick.call(this);
                $('#btn_rt'+randID).unbind('click');
                $('#btn_lt'+randID).unbind('click');
                setTimeout(function(){$('#play_pause_btn'+randID).css('background-position','0 -16px')},o.transitionSpeed-1);
                autopilot = 0;
                $('#progress'+randID).stop().fadeOut();
                status='pause';
                clearTimeout(clearInt);
                (dir=='prev') ? moveRight():moveLeft();
                $('#play_pause_btn'+randID).unbind('click');
                setTimeout(function(){
                        $('#play_pause_btn'+randID).bind('click',function(){forceStart();});
                        $('#btn_rt'+randID).bind('click',function(){forcePrevNext('next')});
                        $('#btn_lt'+randID).bind('click',function(){forcePrevNext('prev')});
                    },o.transitionSpeed);
            }


            function preMove()
            {
                
                // Fade out play/pause/left/right
                if(o.showControls && o.prevNextInternal)
                {
                    $('#play_pause_btn'+randID).fadeOut(200);
                    /*$('#btn_lt'+randID).fadeOut(200);
                    $('#btn_rt'+randID).fadeOut(200);*/
                }
                if(o.customThumbnails) for(i=1;i<=numElements;i++) $('#thumb_'+i).css({'background-color':'#ccc'});
            }

            function postMove()
            {
                if(o.showControls && o.prevNextInternal)
                {
                    $('#play_pause_btn'+randID).fadeIn(200);
                    /*$('#btn_lt'+randID).fadeIn(200);
                    $('#btn_rt'+randID).fadeIn(200);*/
                }
                
                
                if(o.customThumbnails) for(i=0;i<viewable.length;i++) $('#thumb_'+viewable[i]).css({'background-color':'#999999'});
                if(o.customThumbnails) $('#carousel-thumbs div.thumb').unbind('click').bind('click', thumbclick).css({'cursor':'pointer'});
                
            }

            function moveLeft(dist)
            {
                if(dist==null) dist=o.advance;
                preMove();
                
                if(o.customThumbnails)
                {
                    for(i=1;i<=dist;i++){
                        viewable.push(unviewable.shift());
                        unviewable.push(viewable.shift());
                    }
                }
                
                
                if(o.displayTime == 0){clearInterval(clearInt);} // If running a contonuous show with no display time, fist clear the interval. Then below, recursively call moveLeft
                $('li:lt('+dist+')', obj).clone(true).insertAfter($('li:last', obj)); // Copy the first image (offscreen to the left) to the end of the list (offscreen to the right)
                o.onSlideStart.call(this,viewable,'left');
                $('ul', obj).animate({left:-o.elementWidth*(dist+1)-(parseInt(o.padding)*(dist+1))*2},o.transitionSpeed,o.easeLeft,function(){ // Animate the entire list to the left
                    $('li:lt('+dist+')', obj).remove(); // When the animation finishes, remove the first image (on the left). It has already been copied to the end of the list (right)
                    $(this).css({'left':-o.elementWidth-parseInt(o.padding)*2});
                    if(o.displayProgressBar && autopilot) startProgressBar();
                    postMove();
                    if(o.displayTime == 0){moveLeft();}
                });
            }
            function moveRight(dist)
            {
                if(dist==null) dist=o.advance;
                preMove();
                
                if(o.customThumbnails)
                {
                    for(i=1;i<=dist;i++){
                        viewable.unshift(unviewable.pop());
                        unviewable.unshift(viewable.pop());
                    }
                }
                
                $('li:gt('+(numElements-(dist+1))+')', obj).clone(true).insertBefore($('li:first', obj)); // Copy rightmost (last) li and insert it after the first li
                o.onSlideStart.call(this,viewable,'right');
                $('ul', obj).css('left',-(o.elementWidth*(dist+1))-(parseInt(o.padding)*((dist+1)*2)))
                    .animate({left:-o.elementWidth-(parseInt(o.padding)*2)},o.transitionSpeed,o.easeRight,function(){
                        $('li:gt('+(numElements-1)+')', obj).remove();
                        postMove();
                    });
            }

            // Kickoff the show
            if(autopilot)
            {
                var clearInt = setInterval(function(){moveLeft();},o.displayTime+o.transitionSpeed);
                if(o.displayProgressBar) startProgressBar(o.displayTime+o.transitionSpeed);
            } else {status='pause';$('#play_pause_btn'+randID).css({'background-position':'0 -16px'});}
        });
    }
    });
})(jQuery);
