(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
            itemResize: true
        }, 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;
            }
            else {
                $(options.btnPrev).addClass(options.btnDisabled); // Set previous button to initial disabled
            }

            if (options.zoomFeature) {
                $(options.items + ":nth-child(" + oCurrent + ")", oContainer).addClass(options.featureItemClass).find("*").addClass(options.featureItemClass);
                $(oElement).addClass(options.featureContainerClass);
                var oItemFeatureSize = $(options.items + ":nth-child(" + (oCurrent + 1) + ")", oContainer).width(); // Items width
            }
            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

            if (options.itemResize) {
                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("-");
                    }
                });
            }

            $("#secondary-nav ul li a").click(function() {
                if (!$(this).parent().hasClass("current")) {
                    var jumpTo = $('#secondary-nav ul li').index($(this).parent()) + 1;
                    runScroll(null, jumpTo);
                    $("#secondary-nav ul li").removeClass("current");
                    $(this).parent().addClass("current");
                }
            });

            function runScroll(direction, jump) {
                if (!oScrolling) {
                    oScrolling = true; // Set scrolling to true, to prevent queuing
                    if (direction && !jump) {
                        oAnimationResult = direction + "=" + oItemOuterSize + "px";
                    }
                    else if (!direction && jump) {
                        if (jump == 1) {
                            oAnimationResult = "0px";
                        }
                        else {
                            oAnimationResult = "-" + (jump - 1) * oItemOuterSize + "px";
                        }
                    }
                    oContainer.animate({ "left": oAnimationResult }, options.speed, function() {
                        oScrolling = false; // Set scrolling to finished
                        if (direction == "+" && !jump) {
                            oCurrent--; // Change current number
                        }
                        else if (direction == "-" && !jump) {
                            oCurrent++; // Change current number
                        }
                        else if (!direction && jump) {
                            oCurrent = jump;
                        }
                        if (!options.infinite) { // If not inifite
                            if (oCurrent == (oItemsLength)) { //If current is at end
                                $(options.btnNext).addClass(options.btnDisabled); // Disable
                                $(options.btnPrev).removeClass(options.btnDisabled);
                            }
                            else if (oCurrent == 1) { // If current is at beginning
                                $(options.btnPrev).addClass(options.btnDisabled); // Disable
                                $(options.btnNext).removeClass(options.btnDisabled);
                            }
                            else {
                                $(options.btnPrev + "," + options.btnNext).removeClass(options.btnDisabled); // Remove any disabled links
                            }
                        }
                        else {
                            if (direction == "+") {
                                $(options.items, oContainer).last().clone().prependTo(oContainer);
                                $(options.items, oContainer).last().remove();
                                var oContainerPosition = parseInt($(oContainer).css("left")) - parseInt(oItemOuterSize);
                                $(oContainer).css({ "left": oContainerPosition + "px" });
                            }
                            else if (direction == "-") {
                                $(options.items, oContainer).first().clone().appendTo(oContainer);
                                $(options.items, oContainer).first().remove();
                                var oContainerPosition = parseInt($(oContainer).css("left")) + parseInt(oItemOuterSize);
                                $(oContainer).css({ "left": oContainerPosition + "px" });
                            }
                        }
                    });
                    if (options.zoomFeature) {
                        if (direction == "+") {
                            $(options.items + "." + options.featureItemClass, oContainer).removeClass(options.featureItemClass, options.speed).prev().addClass(options.featureItemClass, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).children("img").animate({ bottom: "0" }, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).prev().children("img").animate({ bottom: "-140px" }, options.speed);
                        }
                        else if (direction == "-") {
                            $(options.items + "." + options.featureItemClass, oContainer).removeClass(options.featureItemClass, options.speed).next().addClass(options.featureItemClass, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).children("img").animate({ bottom: "0" }, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).next().children("img").animate({ bottom: "-140px" }, options.speed);
                        }
                        else if (!direction && jump) {
                            $(options.items + "." + options.featureItemClass, oContainer).removeClass(options.featureItemClass, options.speed);
                            $(options.items + ":nth-child(" + jump + ")", oContainer).addClass(options.featureItemClass, options.speed);
                            $(options.items + "." + options.featureItemClass, oContainer).children("img").animate({ bottom: "0" }, options.speed);
                            $(options.items + ":nth-child(" + jump + ")", oContainer).children("img").animate({ bottom: "-140px" }, options.speed);
                        }
                    }
                    if (direction == "+") {
                        var oCategory = $(options.items + "." + options.featureItemClass, oContainer).prev().attr("data-category");
                    }
                    else if (direction == "-") {
                        var oCategory = $(options.items + "." + options.featureItemClass, oContainer).next().attr("data-category");
                    }
                    $("#secondary-nav ul li").removeClass("current");
                    $("#secondary-nav ul li a:contains(" + oCategory + ")").parent().addClass("current");
                }
                return false;
            }

        });

    };

})(jQuery);
