(function($) {
    $.fn.ultimateCarousel = function(options) {
        options = $.extend({
            container: "ul", // Items container
            items: "li", // Items
            visible: 1,
            speed: 200, // Transition speed
            infinite: false, // Infinite carousel
            zoomFeature: false, // Zoom on featured item
            featureItemClass: "feature",
            featureContainerClass: "feature-enabled",
            btnNext: null, // Next button object
            btnPrev: null,  // Previous button object
            btnDisabled: "disabled" // Button disabled CSS class
        }, options || {});


        return this.each(function() {

            //Create initial variables, collections, objects
            var oElement = $(this), oContainer = $(options.container, oElement), oItems = $(options.items, oContainer), oItemsLength = $(oItems).size(), oCurrent = 1;

            var oItemSize = $(oItems).width(); // Items width
            var oItemOuterSize = $(oItems).outerWidth(true); // Items outer width (including padding)
            var oContainerSize = oItemOuterSize * oItemsLength; // Items container width

            if (options.infinite) { // If inifinite carousel set to true
                itemsDuplicateBefore = itemsDuplicateAfter = oItems.clone(); // Get initial items
                oContainer.prepend(itemsDuplicateBefore).append(itemsDuplicateAfter).css({ "left": "-" + oContainerSize + "px" }); // Append, prepend cloned items, set left position
                oCurrent = oItemsLength + 1;


                if ($.browser.msie && parseInt($.browser.version, 10) == "7") {
                    var itemLi = 1;
                    $(options.items, oElement).each(function() {
                        var itemLiIndex = 2000 - itemLi;
                        $(this).css("z-index", itemLiIndex.toString());
                        itemLi++;
                    });
                }

            }
            else {
                $(options.btnPrev).addClass(options.btnDisabled); // Set previous button to initial disabled
            }

            if (options.zoomFeature) {
                $(options.items + ":nth-child(" + oCurrent + ")", oContainer).addClass(options.featureItemClass);
                $(oElement).addClass(options.featureContainerClass);
                var oItemSize = $(options.items + ":nth-child(" + oCurrent + ")", oContainer).width(); // Items width
                var oItemOuterSize = $(options.items + ":nth-child(" + oCurrent + ")", oContainer).outerWidth(true); // Items outer width (including padding)
                $(options.items + ":nth-child(" + oCurrent + ") img", oContainer).load(function() {
                    oItemFeatureHeight = $(options.items + ":nth-child(" + oCurrent + ") img", oContainer).height();
                    oItemResetHeight = $(options.items + ":nth-child(" + (oCurrent + 1) + ") img", oContainer).height();
                });
            }
            if (options.zoomFeature && options.infinite) {
                var oItemSize = $(options.items + ":nth-child(" + oCurrent + ")", oContainer).width(); // Items width
                var oItemOuterSize = $(options.items + ":nth-child(" + oCurrent + ")", oContainer).outerWidth(true); // Items outer width (including padding)
                var oContainerSize = oItemOuterSize * oItemsLength; // Items container width			
                oContainer.css({ "left": "-" + oContainerSize + "px" });
            }

            var oItems = $(options.items, oContainer), oItemsLength = $(oItems).size(), oScrolling = false; // Reset variables, collections, objects

            oItems.css({ "width": oItemSize + "px" }); // Set width of items

            if (options.btnPrev) { // Previous button click
                $(options.btnPrev).click(function() {
                    if (!$(this).hasClass(options.btnDisabled)) { // If not disabled
                        runScroll("+");
                    }
                });
            }

            if (options.btnNext) {
                $(options.btnNext).click(function() {
                    if (!$(this).hasClass(options.btnDisabled)) { // If disabled
                        runScroll("-");
                    }
                });
            }

            function runScroll(direction) {
                if (!oScrolling) {
                    oScrolling = true; // Set scrolling to true, to prevent queuing
                    oContainer.animate({ "left": direction + "=" + oItemOuterSize + "px" }, options.speed, function() {
                        oScrolling = false; // Set scrolling to finished
                        if (direction == "+") {
                            oCurrent--; // Change current number
                        }
                        else if (direction == "-") {
                            oCurrent++; // Change current number
                        }
                        if (!options.infinite) { // If not inifite
                            if (oCurrent == (oItemsLength - (options.visible - 1))) { //If current is at end
                                $(options.btnNext).addClass(options.btnDisabled); // Disable
                            }
                            else if (oCurrent == 1) { // If current is at beginning
                                $(options.btnPrev).addClass(options.btnDisabled); // Disable
                            }
                            else {
                                $(options.btnPrev + "," + options.btnNext).removeClass(options.btnDisabled); // Remove any disabled links
                            }
                        }
                        else {
                            if (direction == "+") {
                                var itemLiIndex = 2000 + itemLi;
                                $(options.items, oContainer).last().clone().prependTo(oContainer).css("z-index", itemLiIndex.toString());
                                $(options.items, oContainer).last().remove();
                                var oContainerPosition = parseInt($(oContainer).css("left")) - parseInt(oItemOuterSize);
                                $(oContainer).css({ "left": oContainerPosition + "px" });
                                itemLi++;
                            }
                            else if (direction == "-") {
                                var itemLiIndex = 2000 - itemLi;
                                $(options.items, oContainer).first().clone().appendTo(oContainer).css("z-index", itemLiIndex.toString());
                                $(options.items, oContainer).first().remove();
                                var oContainerPosition = parseInt($(oContainer).css("left")) + parseInt(oItemOuterSize);
                                $(oContainer).css({ "left": oContainerPosition + "px" });
                                itemLi++;
                            }
                        }
                    });
                    if (options.zoomFeature) {
                        if (direction == "+") {
                            $(options.items + "." + options.featureItemClass + " img", oContainer).animate({ "height": oItemResetHeight + "px" }, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).removeClass(options.featureItemClass, options.speed).prev().addClass(options.featureItemClass, options.speed).children("img").animate({ "height": oItemFeatureHeight + "px" }, options.speed);
                        }
                        else if (direction == "-") {
                            $(options.items + "." + options.featureItemClass + " img", oContainer).animate({ "height": oItemResetHeight + "px" }, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).removeClass(options.featureItemClass, options.speed).next().addClass(options.featureItemClass, options.speed).children("img").animate({ "height": oItemFeatureHeight + "px" }, options.speed);

                        }
                    }
                }
                return false;
            }

        });

    };

})(jQuery);
