jQuery.carousel = function(container) {
    
    var ie6 = false;
    /*@cc_on
        @if (@_jscript_version < 5.7)
            ie6 = true;
        @end
    @*/
    
    //containers
    var carouselSelector = container;
    var listSelector = '.bottom ul';
    var scrollerClass = 'scroller';
    var containerClass = 'container';
    var leftClass = 'left';
    var rightClass = 'right';
    var displaySelector = '.display';
    var pageSelector = '.page';
    
    //config
    var horizontalItems = 4;
    
    var scrollerSelector = '.' + scrollerClass;
    var containerSelector = '.' + containerClass;
    var lastListSelector = listSelector + ':last';
    var leftSelector = '.' + leftClass;
    var rightSelector = '.' + rightClass;
    var controlsSelector = leftSelector + ', ' + rightSelector;
    
    //filtering
    $.carousel.filter = function(selector) {
        var selector = selector;
        $(carouselSelector).each(function() {
            $(this).data('carousel').filter(selector);
        });
    };
    
    $(carouselSelector).each(function() {

        var self = $(this);
		var totalItems = self.find(listSelector + ' li').length;
        
        //persistent data
        var persist = {scroll: 0};
        self.data('carousel', new function() {
            
            //filtering
            var filter = '*';
            this.filter = function(selector) {
                filter = selector;
                self.find(listSelector + ' li').not(filter).hide();
                self.find(listSelector).find(filter).show();
                updateLayout();
                updateScroll();
            }
            
            //expanding
			self.find(displaySelector).find('span').replaceWith('<ul><li class="selected">4</li></ul>');			
			if (totalItems > 4){
				self.find(displaySelector).find('ul').append('<li>8</li>');
			}			
			if (totalItems > 8){
				self.find(displaySelector).find('ul').append('<li>16</li>');
			}
			if (totalItems > 16){
				self.find(displaySelector).find('ul').append('<li>20</li>');
			}            
            self.find(displaySelector).find('li').click(function() {
                var self = $(this);
                if (!self.hasClass('selected')) {
                    self.parent().children('li').removeClass('selected');
                    self.addClass('selected');
                    updateLayout(parseInt($(this).text()));
                }
            });

            //wrap list in carousel
            self.find(listSelector).each(function() {
                var list = $(this);
                $(this).after('<div class="' + containerClass + '"><div class="' + scrollerClass + '"></div></div>');
                $(this).next(containerSelector).children(scrollerSelector)[0].appendChild(this);
            });
            
            //add controls
            var itemHeight = self.find(listSelector + '>*').outerHeight({margin: true});
            self.find(containerSelector)
                .before('<div class="' + leftClass + '">&lt;</div><div class="' + rightClass + '">&gt;</div>');
            if (!ie6) self.find(controlsSelector).css({
                height: itemHeight
            });
            
            //carousel scrolling
            var scroll = 0;
            var scrollStep = self.find(listSelector + '>*').outerWidth({margin: true});
            var steps = horizontalItems;
            self.find(controlsSelector).click(function() {
                var control = $(this);
                if (!control.hasClass('disabled')) {
                    if (control.hasClass(rightClass)) {
                        scroll -= scrollStep*steps;
                    } else {
                        scroll += scrollStep*steps;
                    }
                    updateScroll();
                }
            });
       
            //update scroll bounds
            var visibleItems = horizontalItems;
            function updateScroll() {
                var scrollMax;
                if (visibleItems > horizontalItems) {
                    scrollMax = (self.find(listSelector + ':visible').length * horizontalItems - horizontalItems) * scrollStep;
                } else {
                    scrollMax = (self.find(listSelector).children(filter).length - horizontalItems) * scrollStep;
                }
                scroll = Math.min(Math.max(scroll, -scrollMax), 0);
				self.find(scrollerSelector).animate({marginLeft: scroll});
				if (totalItems <= 4 || (scroll == -scrollMax)) {
					self.find(rightSelector).hide();
                } else {
                    self.find(rightSelector).show();
                }
                if (scroll == 0) {
                    self.find(leftSelector).hide();
                } else {
                    self.find(leftSelector).show();
                }
                //update paging
                var start = 0;
                if (visibleItems > horizontalItems) {
                    var page = parseInt(-scroll / (horizontalItems*scrollStep));
                    start = page * visibleItems;
                } else {
                    start = parseInt(-scroll / scrollStep);
                }
                var end = Math.min(totalItems, start + visibleItems);
                var text = (start + 1) + ' - ' + end + ' (' + totalItems + ')'
                //self.find(pageSelector).text(text);
            }
            
            var singleRowSpecialCase = true;
            if (ie6) singleRowSpecialCase = false;
            
            //update layout
            var updateLayout = this.updateLayout = function(n) {
                if (!n) n = visibleItems;
                visibleItems = n;
                var existingGalleries = self.find(listSelector);
                var thumbs = self.find(listSelector + '>*');
                if (singleRowSpecialCase && visibleItems == horizontalItems) {
                    self.find(lastListSelector).after('<ul></ul>');
                    for (var i = 0; i < thumbs.length; i++) {
                        self.find(lastListSelector).append(thumbs[i]);
                    }
                    existingGalleries.remove();
                } else {
                    //split gallery into blocks of visibleItems
                    var filteredThumbs = thumbs.filter(filter);
                    var length = thumbs.length;
                    for (var i = 0; i < length;) {
                        self.find(lastListSelector).after('<ul></ul>');
                        var target = i + visibleItems;
                        for (var j = i; j < length && j < target; j++) {
                            self.find(lastListSelector).append(thumbs[j]);
                            if ($.inArray(thumbs[j], filteredThumbs) == -1) {
                                target ++;
                            }
                        } 
                        if (self.find(lastListSelector + '>*').length == 0) {
                            self.find(lastListSelector).remove();
                        } else if ($(lastListSelector).children(filter).length == 0) {
                            self.find(lastListSelector).hide();
                        }
                        i = target;
                    }
                    existingGalleries.remove();
                    //resize gallery blocks
                    self.find(listSelector).animate({
                        width: self.find(containerSelector).innerWidth(),
                        height: itemHeight * (visibleItems / horizontalItems)
                    });
                }
                //resize scroller
                var h = itemHeight * (visibleItems / horizontalItems);
                self.find(scrollerSelector).animate({height: h});
                self.find('.bottom').animate({height: h});
                //update scroll
                updateScroll();
                //scale navigation arrows
                if (!ie6) self.find(controlsSelector).each(function() {
                    if ($(this).css('display') != 'none') {
                        $(this).animate({
                            height: h,
                            lineHeight: h
                        });
                    } else {
                        $(this).css({
                            display: 'none',
                            height: h,
                            lineHeight: h
                        });
                    }
                });
            };
            updateLayout();
            
        });
            
    });
}


$(function() {

    //apply gallery
    $.carousel('.carousel');
    
    //filtering
    $('#filter').change(function() {
        $.carousel.filter($(this).val());
    });    
    
    //wallpaper hover effect for ie6
    /*@cc_on
        @if (@_jscript_version < 5.7)
            $('.carousel .bottom li>div').hover(function() {
                $(this).addClass('hover');
            }, function() {
                $(this).removeClass('hover');
            });
        @end
    @*/
});