$.fn.infiniteCarousel = function () {
	
	var inited = false;

    function repeat(str, num) {
        return new Array( num + 1 ).join( str );
    }
  
    return this.each(function () {
    	
        var $wrapper = $('> div', this).css('overflow', 'hidden'),
            $slider = $wrapper.find('> ul'),
            $items = $slider.find('> li'),
            $single = $items.filter(':first'),
            // $uid = 
            
            singleWidth = $single.outerWidth(),
            visible = Math.ceil($wrapper.innerWidth() / singleWidth), // note: doesn't include padding or border
            
            currentPage = 1,
            pages = Math.ceil($items.length / visible);    
            total = $items.length;       
            

        // 1. Pad so that 'visible' number will always be seen, otherwise create empty items
        if (($items.length % visible) != 0) {
            $slider.append(repeat('<li class="empty" />', visible - ($items.length % visible)));
            $items = $slider.find('> li');
        }

        // 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);
        
        // 4. paging function
        function gotoPage(page) {
			// alert(page);
			
            var dir = page < currentPage ? -1 : 1, 
				n = Math.abs(currentPage - page), 
				left = singleWidth * dir * visible * n;

			// currentPage = page = 1;
			// Si la direction est en avant et que le total est inférieur à la page demandée
            if( dir > 0 && pages < page) return; //'false >> ' + (total - (visible * currentPage)) + ' >> ' + left + ' >> ' + n + ' >> ' + dir ;
			
			// Si la direction est en errière et que le total est inférieur à la page demandée
			if( dir < 0 && page < 1) return;
			
            $wrapper.filter(':not(:animated)').animate({
                scrollLeft : '+=' + left
            }, 500, function () {
				
                if (page == 0) {
                    $wrapper.scrollLeft(singleWidth * visible * pages);
                    page = pages;
                } else if (page > pages) {
                    $wrapper.scrollLeft(singleWidth * visible);
                    // reset back to start position
                    page = 1;
                } 

                currentPage = page;
                
                if(currentPage < pages) var avr = " av";
                else var avr = "";
                
				// Si la page est supérieur à 1, on peut activer le bouton retour
                if(currentPage > 1) var avl = " av";
                else var avl = "";
                
				$('.back', $wrapper.parents('.panel-wrapper')).removeClass('av').addClass(avl);
                $('.forward', $wrapper.parents('.panel-wrapper')).removeClass('av').addClass(avr);				
			});
            return currentPage;
        }

        if(total - (visible * currentPage) > 0) var avr = " av";
        else var avr = "";
        
        if(currentPage > 1) var avl = " av";
        else var avl = "";
        
        
		var prev_btn = '<p class="arrow back ' + avl + ' inifiniteControl">&gt;</p>';
		var next_btn = '<p class="arrow forward ' + avr +' inifiniteControl">&lt</p>';
        if(inited == false) {
        	$wrapper.parents('.panel-wrapper').find('.slide-indicator p').before( next_btn + prev_btn);
        	inited == true;
        }
        

        // 5. Bind to the forward and back buttons
		$('.back', $wrapper.parents('.panel-wrapper')).bind('click', function(){
			return gotoPage(currentPage - 1);
		});

        $('.forward.av', $wrapper.parents('.panel-wrapper')).bind('click', function () {
            return gotoPage(currentPage + 1);
        });
        
        // create a public interface to move to a specific page
        $(this).bind('goto', function (event, page) {
            gotoPage(page);
        });
    });
	
};
