/*
* 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 =
			{
			    transitionSpeed: 800,
			    displayTime: 6000,
			    textholderHeight: .25,
			    displayProgressBar: false,
			    displayThumbnails: true,
			    displayThumbnailNumbers: false,
			    displayThumbnailBackground: true,
			    thumbnailWidth: '12px',
			    thumbnailHeight: '12px',
			    thumbnailFontSize: '.7em',
			    easeLeft: 'linear',
			    easeRight: 'linear',
			    imagePath: '/Storage/Images/',
			    inView: 1,
			    padding: '0px',
			    advance: 1,
			    showControls: true,
			    autoHideControls: false,
			    autoHideCaptions: false,
			    autoStart: true,
			    prevNextInternal: true,
			    enableKeyboardNav: true,
			    onSlideStart: function () { },
			    onSlideEnd: function () { },
			    onPauseClick: function () { }
			};
            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 numImages = $('img', obj).length; // Number of images
                var imgHeight = $('img:first', obj).height();
                var imgWidth = $('img:first', obj).width();

                if (o.inView > numImages - 1) o.inView = numImages - 1; // check to make sure inview isnt greater than the number of images. inview should be at least two less than numimages (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', 'overflow': 'hidden' }).width((imgWidth * o.inView) + (o.inView * parseInt(o.padding) * 2)).height(imgHeight + (parseInt(o.padding) * 2)); //,'overflow':'hidden'
                $('ul', obj).css({ 'list-style': 'none', 'margin': '0', 'padding': '0', 'position': 'relative' }).width(imgWidth * numImages);
                $('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', -imgWidth - (parseInt(o.padding) * 2) + 'px').width(9999);

                // Build progress bar
                //if (o.displayProgressBar) {
                //    $(obj).append('<div id="progress' + randID + '" class="ic-progress-bar" style="position:absolute;bottom:0;background:#bbb;left:0;z-index:1"></div>');
                //    $('#progress' + randID).width('100%').height(5).css('opacity', '.6');
                //}

                // Animate progress bar
                //function startProgressBar(barTime) {
                //    barTime = (barTime == null) ? o.displayTime : barTime;
                //    $('#progress' + randID).width('100%').height(5);
                //    $('#progress' + randID).animate({ 'width': 0 }, barTime);
                //}

                // JCH, ITF - Build text and thumbnails holder
                $(obj).after('<div id="textThumbnailHolder" style="margin-top:-10px; width:' + imgWidth + 'px; height:70px;"></div>');

                // Build textholder div(s) as wide as one image and as tall as the textholderHeight option
                var containerBorder = parseInt($(obj).css('border-bottom-width')) + parseInt($(obj).css('border-top-width'));
                if (isNaN(containerBorder)) containerBorder = 0; // IE returns NaN for $(obj).css('border-bottom-width')
                var containerPaddingLeft = parseInt($(obj).css('padding-left')); // Normally we'd do both left and right but only left matters here
                for (i = 1; i <= o.inView; i++) {
                    $("#textThumbnailHolder").append('<div id="textholder' + randID + '_' + i + '" class="textholder" style="float:left; width:510px; padding:10px; color:#fff;"></div>');
                    if (!o.autoHideCaptions) showtext($('li:eq(' + i + ') p', obj).html(), i);
                }
                var textholderPadding = parseInt($('#textholder' + randID + '_1').css('padding-left')) + parseInt($('#textholder' + randID + '_1').css('padding-right'));
                if (textholderPadding > 0) $('.textholder', obj).width(imgWidth - textholderPadding);

                function showtext(t, i) {
                    if (autopilot) {
                        //$('#minmax' + randID + '_' + i).hide();
                        //$('#close' + randID + '_' + i).hide();
                    }
                    if (t != null) {
                        $('#textholder' + randID + '_' + i).html(t); // Change textholder content
                        //$('#textholder' + randID + '_' + i).stop().animate({ marginBottom: '0px' }, 500); // Raise textholder
                    }
                }

//                function showminmax() {
//                    if (!autopilot) {
//                        $('.minmax', obj).fadeIn(250);
//                        $('.close', obj).fadeIn(250);
//                    }
//                }

                function hideCaption() { $('.textholder', obj).stop().animate({ marginBottom: (-imgHeight * o.textholderHeight - containerBorder - 1) + 'px' }, o.transitionSpeed) }

                if (o.displayThumbnails) {
                    function thumbclick(event) {
                        target_num = this.id.split('_'); // we want target_num[1]
                        if (viewable[0] != target_num[1]) {
                            status = 'pause';
                            $('#progress' + randID).stop().fadeOut();
                            clearTimeout(clearInt);
                            $('#thumbs' + randID + ' div').css({ 'cursor': 'default' }).unbind('click'); // Unbind the thumbnail click event until the transition has ended
                            autopilot = 0;
                            setTimeout(function () { $('#play_pause_btn' + randID).css('background-position', '0 -16px') }, o.transitionSpeed);
                            $('#play_pause_btn' + randID).unbind('click').bind('click', function () { forceStart(); });
                        }
                        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
                    // Build thumbnail viewer and thumbnail divs
                    $("#textThumbnailHolder").append('<div style="overflow:auto;position:relative;height:55px;"><div id="thumbs' + randID + '" style="position:absolute;bottom:0px;right:0px;padding:10px;"></div></div>');
                    for (i = 0; i <= numImages - 1; i++) {
                        thumb = $('img:eq(' + (i + 1) + ')', obj).attr('src');
                        $('#thumbs' + randID).append('<div class="thumb" id="thumb' + randID + '_' + (i + 1) + '" style="cursor:pointer;background-color:#7a7b7b;display:inline;float:left;width:' + o.thumbnailWidth + ';height:' + o.thumbnailHeight + ';line-height:' + o.thumbnailHeight + ';padding:0;overflow:hidden;margin-right:4px;">' + (i + 1) + '</div>');
                        if (i <= o.inView) $('#thumb' + randID + '_' + i).css({ 'background-color': '#fff' });
                        unviewable.push(i + 1);
                    }
                    // Initialize viewable/unviewable arrays
                    for (i = 1; i <= o.inView; i++) viewable.push(unviewable.shift());

                    // Next two lines are a special case to handle the first list element which was originally the last
                    thumb = $('img:first', obj).attr('src');
                    $('#thumb' + randID + '_' + numImages).css({ 'background-color': '#7b7a7a' });
                    
                    $('#thumbs' + randID + ' div.thumb').hover(function () { $(this).css({ 'background-color': '#ccc' }) }, function () { if (viewable[0] != this.id.split('_')[1]) $(this).css({ 'background-color': '#7b7a7a' }) }); // 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
                    $('#thumbs' + randID + ' div').bind('click', thumbclick); // We use bind instead of just plain click so that we can repeatedly remove and reattach the handler

                    if (!o.displayThumbnailNumbers) $('#thumbs' + randID + ' div').text('');
                    if (!o.displayThumbnailBackground) $('#thumbs' + randID + ' div').css({ 'background-image': 'none' });
                }

                if (o.showControls) {
                    // Pause/play button(img)
                    html = '<div id="play_pause_btn' + randID + '" style="cursor:pointer;position:absolute;top:3px;right:3px;border:none;width:16px;height:16px;background:url(/Storage/Images/caro-playpause.gif) no-repeat 0 0"></div>';
                    $(obj).append(html);
                    var status = 'play';
                    $('#play_pause_btn' + randID).css('opacity', .5).hover(function () { $(this).animate({ opacity: '1' }, 250) }, function () { $(this).animate({ opacity: '.5' }, 250) });
                    $('#play_pause_btn' + randID).click(function () {
                        status = (status == 'play') ? 'pause' : 'play';
                        (status == 'play') ? forceStart() : forcePause();
                    });

                    if (!o.prevNextInternal) {
                        wrapID = $(obj).attr('id') + 'Wrapper';
                        $(obj).wrap('<div id="' + wrapID + '"></div>').css('margin', '0 auto');
                        $('#' + wrapID).css('position', 'relative').width(($(obj).width() + 40 + parseInt($(obj).css('padding-left')) + parseInt($(obj).css('padding-right'))));
                    }

                    // Prev/next button(img)
                    arrowsTop = ((imgHeight / 2) - 15) + parseInt(o.padding);
                    html = '<div id="btn_rt' + randID + '" style="position:absolute;right:0px;top:' + arrowsTop + 'px;cursor:pointer;border:none;width:22px;height:68px;background:url(/Storage/Images/caro-rgt.png) no-repeat 0 0"></div>';
                    html += '<div id="btn_lt' + randID + '" style="position:absolute;left:0px;top:' + arrowsTop + 'px;cursor:pointer;border:none;width:22px;height:68px;background:url(/Storage/Images/caro-lft.png) no-repeat 0 0"></div>';
                    (o.prevNextInternal) ? $(obj).append(html) : $('#' + wrapID).append(html);

                    $('#btn_rt' + randID).css('opacity', .5).click(function () {
                        forcePrevNext('next');
                    }).hover(function () { $(this).animate({ opacity: '1' }, 250) }, function () { $(this).animate({ opacity: '.5' }, 250) });
                    $('#btn_lt' + randID).css('opacity', .5).click(function () {
                        forcePrevNext('prev');
                    }).hover(function () { $(this).animate({ opacity: '1' }, 250) }, function () { $(this).animate({ opacity: '.5' }, 250) });

                    if (o.autoHideControls && o.prevNextInternal) {
                        function showcontrols() {
                            $('#play_pause_btn' + randID).stop().animate({ top: '3px', right: '3px' }, 250);
                            $('#btn_rt' + randID).stop().animate({ top: arrowsTop + 'px', right: '2px' }, 250);
                            $('#btn_lt' + randID).stop().animate({ top: arrowsTop + 'px', left: '2px' }, 250);
                        }
                        function hidecontrols() {
                            $('#play_pause_btn' + randID).stop().animate({ top: -16 - containerBorder + 'px', right: -16 - containerBorder + 'px' }, 250);
                            $('#btn_rt' + randID).stop().animate({ right: '-16px' }, 250);
                            $('#btn_lt' + randID).stop().animate({ left: '-16px' }, 250);
                        }
                        $(obj).hover(showcontrols, hidecontrols);
                        hidecontrols();
                    }
                    if (o.autoHideCaptions) {
                        var isHover;
                        function autoShowCap() { isHover = true; for (i = 1; i <= o.inView; i++) showtext($('li:eq(' + i + ') p', obj).html(), i); }
                        function autoHideCap() { isHover = false; hideCaption(); }
                        $(obj).hover(autoShowCap, autoHideCap);
                        hideCaption();
                    }
                }

                function keyBind() {
                    if (o.enableKeyboardNav) {
                        $(document).keydown(function (event) {
                            if (event.keyCode == 39) {
                                forcePrevNext('next');
                                $(document).unbind('keydown');
                            }
                            if (event.keyCode == 37) {
                                forcePrevNext('prev');
                                $(document).unbind('keydown');
                            }
                            if (event.keyCode == 80 || event.keyCode == 111) forcePause();
                            if (event.keyCode == 83 || event.keyCode == 115) {
                                forceStart();
                                $(document).unbind('keydown');
                            }
                        });
                    }
                }

                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 forcePause() {
                    $('#play_pause_btn' + randID).unbind('click'); // unbind the click, wait for transition, then reenable
                    if (autopilot) {
                        o.onPauseClick.call(this);
                        $('#play_pause_btn' + randID).fadeTo(250, 0, function () { $(this).css({ 'background-position': '0 -16px', 'opacity': '.5' }); }).animate({ opacity: .5 }, 250);
                        autopilot = 0;
                        //showminmax();
                        $('#progress' + randID).stop().fadeOut();
                        clearTimeout(clearInt);
                        setTimeout(function () { $('#play_pause_btn' + randID).bind('click', function () { forceStart(); }) }, o.transitionSpeed);
                    }
                }

                function forceStart() {
                    $('#play_pause_btn' + randID).unbind('click'); // unbind the click, wait for transition, then reenable
                    if (!autopilot) {
                        setTimeout(function () { $('#play_pause_btn' + randID).css('background-position', '0 0') }, o.transitionSpeed - 1);
                        autopilot = 1;
                        moveLeft();
                        clearInt = setInterval(function () { moveLeft(); }, o.displayTime + o.transitionSpeed);
                        setTimeout(function () { $('#play_pause_btn' + randID).bind('click', function () { forcePause(); }) }, o.transitionSpeed);
                    }
                }

                function preMove() {
                    hideCaption();
                    // 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.displayThumbnails) for (i = 1; i <= numImages; i++) $('#thumb' + randID + '_' + i).css({ 'background-color': '#7a7b7b' });
                }

                function postMove() {
                    if (o.showControls && o.prevNextInternal) {
                        $('#play_pause_btn' + randID).fadeIn(200);
                        $('#btn_lt' + randID).fadeIn(200);
                        $('#btn_rt' + randID).fadeIn(200);
                    }
                    keyBind();
                    if (o.autoHideCaptions && isHover) autoShowCap();
                    if (o.displayThumbnails) for (i = 0; i < viewable.length; i++) $('#thumb' + randID + '_' + viewable[i]).css({ 'background-color': '#fff' });
                    if (!o.autoHideCaptions) for (i = 1; i <= o.inView; i++) showtext($('li:eq(' + i + ') p', obj).html(), i);
                    if (o.displayThumbnails) $('#thumbs' + randID + ' div').unbind('click').bind('click', thumbclick).css({ 'cursor': 'pointer' });
                    ary = [];
                    for (x = 1; x <= o.inView; x++) { ary.push($('img:eq(' + x + ')', obj).attr('src')) }
                    o.onSlideEnd.call(this, ary);
                }

                function moveLeft(dist) {
                    if (dist == null) dist = o.advance;
                    preMove();
                    if (o.displayThumbnails) {
                        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: -imgWidth * (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': -imgWidth - 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.displayThumbnails) {
                        for (i = 1; i <= dist; i++) {
                            viewable.unshift(unviewable.pop());
                            unviewable.unshift(viewable.pop());
                        }
                    }
                    $('li:gt(' + (numImages - (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', -(imgWidth * (dist + 1)) - (parseInt(o.padding) * ((dist + 1) * 2)))
					.animate({ left: -imgWidth - (parseInt(o.padding) * 2) }, o.transitionSpeed, o.easeRight, function () {
					    $('li:gt(' + (numImages - 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' }); }
                keyBind();
            });
        }
    });
})(jQuery);
