$.fn.infiniteCarousel = function () {


    function repeat(str, num) {
        return new Array( num + 1 ).join( str );
    };

    return this.each(function () {
        //var $wrapper = $('> div', this).css({'overflow': 'visible'}),
        var $wrapper = $('> div', this).css('overflow', 'hidden'),
            $slider = $wrapper.find('> ul'),
            $items = $slider.find('> li'),
            $single = $items.filter(':first'),

            singleWidth = $single.outerWidth(),
            visible = Math.ceil($wrapper.innerWidth() / singleWidth), // note: doesn't include padding or border
            currentPage = 1,
            pages = Math.ceil($items.length / visible);

            //$wrapper.css('overflow', 'visible'),
        // 2. Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
        $items.filter(':first').before($items.slice(- visible).clone().addClass('cloned'));
        $items.filter(':last').after($items.slice(0, visible).clone().addClass('cloned'));
        $items = $slider.find('> li'); // reselect

        // 3. Set the left position to the first 'real' item
        $wrapper.scrollLeft(singleWidth * visible);
        if ($.browser.msie) reApplyPNGFilter();

        // 4. paging function
        function gotoPage(page) {
            var dir = page < currentPage ? -1 : 1,
                n = Math.abs(currentPage - page),
                left = singleWidth * dir * visible * n;

            $wrapper.filter(':not(:animated)').animate({
                scrollLeft : '+=' + left
            }, 1500, function () {
                if (page == 0) {
                     $wrapper.animate({
                        scrollLeft : singleWidth * visible * pages
                    }, 400);
                    //$wrapper.scrollLeft(singleWidth * visible * pages);
                    page = pages;
                } else if (page > pages) {
                    //$wrapper.scrollLeft(singleWidth * visible);
                    $wrapper.animate({
                        scrollLeft : singleWidth * visible
                    }, 400);
                    // reset back to start position
                    page = 1;
                };

                currentPage = page;
            });

            return false;
        };


        $wrapper.after('<a href="#" class="arrow back">&lt;</a><a href="#" class="arrow forward">&gt;</a>');

        // 5. Bind to the forward and back buttons
        $('a.back', this).click(function () {
            
            return gotoPage(currentPage - 1);
        });

        $('a.forward', this).click(function () {
            return gotoPage(currentPage + 1);
        });

        // create a public interface to move to a specific page
        $(this).bind('goto', function (event, page) {
            gotoPage(page);
        });
    });
};

function reApplyPNGFilter() {
    $('li.cloned ins img.png').each(function() {
        $img = $(this);
        var filter   = ['progid:DXImageTransform.Microsoft.AlphaImageLoader(src="',
        $img.attr('alt'), '", sizingMethod="crop")'].join('');
        $img.get(0).runtimeStyle.filter = filter;
        $img.attr('src', '/css/obj/transparent.gif?carousel')
    });    
    
    $('li ins img.png').each(function() { $(this).attr('alt', ''); });
};


$(document).ready(function () { $('.infinitecarousel').infiniteCarousel(); });
