/* jQuery Carousel 0.9.2
Copyright 2008-2009 Thomas Lanciaux and Pierre Bertet.
This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
; (function($) {
    $.fn.carousel = function(params) {
        var params = $.extend({
            direction: "horizontal",
            skipItems: 1,
            pagination: false,
            paginationPosition: "inside",
            nextBtn: '<a role="button">Next</a>',
            prevBtn: '<a role="button">Previous</a>',
            btnsPosition: "inside",
            nextBtnInsert: "appendTo",
            prevBtnInsert: "prependTo",
            template: false,
            columns: 1,
            prevBtnInsertFn: false,
            emptyNotDisplay: true,
            autoSlide: false,
            showRepeated: false,
            autoSlideInterval: 3000,
            delayAutoSlide: false,
            combinedClasses: false,
            effect: "slide",
            slideEasing: "swing",
            animSpeed: "normal",
            equalWidths: "true",
            verticalMargin: 0,
            maxInnerHeight: 00,
            maxInnerWidth: 00,
            callback: function() { },
            useAddress: false,
            adressIdentifier: "carousel",
            tabLabel: function(tabNum) { return tabNum; }
        }, params);
        if (params.btnsPosition == "outside") {
            params.prevBtnInsert = "insertBefore";
            params.nextBtnInsert = "insertAfter";
        }
        return this.each(function() {
            var env = { $elts: {}, params: params, launchOnLoad: [], that: $(this), stop: false };
            env.$elts.carousel = $(this).addClass("js");

            if (!env.params.template || env.params.columns < 1)
                env.params.columns = 1;

            env.$elts.content = $(this).children();
            env.$elts.wrap = env.$elts.content.wrap('<div class="carousel-wrap"></div>').parent().css({ overflow: "hidden", position: "relative" });

            env.steps = { first: 0, list: env.$elts.content.children(), itemsShift: 0 };
            env.steps.count = env.steps.list.length;
            env.steps.last = env.steps.count - 1;
            if (env.steps.count < 1) {
                if (env.params.emptyNotDisplay)
                    $(this).remove();
                env = null;
                return;
            }
            if ($.isFunction(env.params.prevBtnInsertFn)) {
                env.$elts.prevBtn = env.params.prevBtnInsertFn(env.$elts);
            }
            else {
                env.$elts.prevBtn = $(params.prevBtn)[params.prevBtnInsert](env.$elts.carousel);
            }
            if ($.isFunction(env.params.nextBtnInsertFn)) {
                env.$elts.nextBtn = env.params.nextBtnInsertFn(env.$elts);
            }
            else {
                env.$elts.nextBtn = $(params.nextBtn)[params.nextBtnInsert](env.$elts.carousel);
            }
            env.$elts.nextBtn.addClass("carousel-control next carousel-next");
            env.$elts.prevBtn.addClass("carousel-control previous carousel-previous");
            if (env.params.pagination) {
                initPagination(env);
            }

            env.onClick = function() { goToStep(env, getRelativeStep(env, ($(this).is(".next") ? "next" : "prev"))); };
            env.onHover = function() { $(this).toggleClass("hover"); };

            initAddress(env);
            showItems(env);
            env.$elts.content.css({ position: "absolute", "top": 0 });
            if ($.browser.msie) {
                $("body").append('<div id="IEData" style="display:none;" />');
                $("#IEData").append(env.$elts.content.children());
            }

            env.$elts.content.html("");

            env.timeOut = null;

            env.contList = [env.$elts.content, env.$elts.content.clone()];
            env.contList[1].removeAttr("id");
            env.contList[0].parent().append(env.contList[1]);
            env.contShow = 0;
            secondListDraw(env, env.contShow);

            this.resize = function() {
                if (env.timeOut)
                    clearTimeout(env.timeOut);
                env.timeOut = window.setTimeout(function() {
                    env.$elts.wrap.css({ height: "100%", width: "100%" });
                    showItems(env);
                    env.contList[1].remove();
                    env.contList[1] = env.$elts.content.clone();
                    env.contList[1].removeAttr("id");
                    env.contList[0].parent().append(env.contList[1]);
                    secondListDraw(env);
                }, 600)
            };

            this.env = env;
        });
    };

    function showItems(env) {
        env.showWidth = env.that.outerWidth(); //$(".carousel-wrap").outerWidth();
        env.showHeight = env.that.outerHeight(); // $(".carousel-wrap").outerHeight();
        if (!env.itemWidth) {
            env.shiftWidth = env.shiftHeight = env.itemWidth = env.itemHeight = 0;
            var $item;
            env.steps.list.each(function(i) {
                i++;
                if (env.params.template) {
                    if (i % env.params.columns == 1 || env.params.columns == 1) {
                        $item = $(env.params.template);
                        env.$elts.content.append($item);
                    }
                    $item.append(this);
                }
                else
                    $item = $(this);
                if (i % env.params.columns == 0 || i == env.steps.count) {
                    $itemHeight = $item.outerHeight(true);
                    if ($itemHeight > env.itemHeight)
                        env.itemHeight = $itemHeight;
                    $itemWidth = $item.outerWidth(true);
                    if ($itemWidth > env.itemWidth)
                        env.itemWidth = $itemWidth;
                    $itemHeight = $item.outerHeight();
                    if ($itemHeight > env.shiftHeight)
                        env.shiftHeight = $itemHeight;
                    $itemWidth = $item.outerWidth();
                    if ($itemWidth > env.shiftWidth)
                        env.shiftWidth = $itemWidth;
                    if (env.params.template)
                        $item.remove();
                }
            });
            if (env.params.verticalMargin > 0)
                env.shiftHeight += env.params.verticalMargin;

            if (!env.params.template) {
                env.steps.list.height(env.shiftHeight);
                env.steps.list.width(env.shiftWidth);
            }
        }
        env.hideItems = env.params.skipItems;
        if (env.params.direction == "vertical")
            env.dispItems = Math.floor(env.showHeight / env.itemHeight + 1);
        else
            env.dispItems = Math.max(Math.floor(env.showWidth / env.itemWidth + 1), env.params.maxInnerWidth);

        env.params.showRepeated = env.params.showRepeated || env.dispItems <= Math.floor(env.steps.count / env.params.columns);
        if (!env.params.showRepeated) {
            env.dispItems = Math.ceil(env.steps.count / env.params.columns);
            env.hideItems = 0;
        }

        if (env.params.direction == "vertical") {
            env.contentWidth = env.itemWidth;
            env.contentHeight = env.itemHeight * (env.dispItems + env.hideItems * 2);
            if (env.params.showRepeated && env.contentHeight < env.params.maxInnerHeight)
                env.hideItems = Math.floor((env.params.maxInnerHeight / env.itemHeight - env.dispItems) / 2);
        }
        else {
            env.contentWidth = env.itemWidth * (env.dispItems + env.hideItems * 2);
            if (env.params.showRepeated && env.contentWidth < env.params.maxInnerWidth)
                env.hideItems = Math.floor((env.params.maxInnerWidth / env.itemWidth - env.dispItems) / 2);
            env.contentHeight = env.itemHeight;
        }


        env.$elts.content.width(env.contentWidth);
        env.$elts.content.height(env.contentHeight);

        env.$elts.content.parent().css({ height: Math.max(env.itemHeight, env.showHeight) + "px",
            width: Math.max(env.itemWidth, env.showWidth) + "px"
        });

        initButtonsEvents(env);

        $.each(env.launchOnLoad, function(i, fn) { fn(); });
    }

    function getItem(env, i, isChange) {
        var step = env.steps;
        i = step.first + i;
        if (i < 0)
            i = step.count - Math.abs(i % step.count)
        else
            i = i % step.count;
        if (isChange)
            step.first = i;
        return $(step.list[i]).clone();
    }

    function secondListDraw(env, number) {
        var step = env.steps;
        var cont = env.contList[(number ? env.contShow : 1 - env.contShow)];
        cont.html("");
        cont.height(env.contentHeight);
        if (env.params.direction == "vertical")
            cont.css("top", -(env.itemHeight * env.hideItems) + "px");
        else
            cont.css("left", -(env.itemWidth * env.hideItems) + "px");
        var item;
        for (var i = -env.hideItems; i < env.dispItems + env.hideItems; i++) {
            if (env.params.template) {
                item = $(env.params.template);
                for (var j = 0; j < env.params.columns; j++) {
                    var pos = i * env.params.columns + j;
                    if (env.params.showRepeated || pos < step.count)
                        item.append(getItem(env, pos));
                    else
                        break;
                }
                item.height(env.shiftHeight);
                item.width(env.shiftWidth);
            } else
                item = getItem(env, i);
            cont.append(item);
        }

        if (!number) {
            env.contList[(env.contShow)].html("");
            env.contList[(env.contShow)].height(0);
        }
        if (env.params.autoSlide) {
            stopAutoSlide(env)
            env.autoSlideTimeout = window.setTimeout(
            function() { goToStep(env, getRelativeStep(env, "next")); },
            env.params.autoSlideInterval);
        }
        env.stop = false;
    }

    function replaceList(env, step) {
        if (env.contList[env.contShow].html() > " ")
            secondListDraw(env);
        env.contShow = 1 - env.contShow;
        getItem(env, -step * env.params.columns, true);

    }

    function initButtonsEvents(env) {
        if (env.params.showRepeated)
            env.$elts.nextBtn.add(env.$elts.prevBtn).bind("click", env.onClick).hover(env.onHover);
        else
            env.$elts.nextBtn.add(env.$elts.prevBtn).unbind("click", env.onClick);
    };

    function initPagination(env) {
        env.$elts.pagination = $('<div class="center-wrap"><div class="carousel-pagination"><p></p></div></div>')
               [((env.params.paginationPosition == "outside") ? "insertAfter" : "appendTo")](env.$elts.carousel).find("p");
        env.$elts.paginationBtns = $([]);
        env.$elts.content.find("li").each(function(i) {
            if (i % env.params.dispItems == 0) {
                env.$elts.paginationBtns = env.$elts.paginationBtns.add($('<a role="button"><span>' + env.params.tabLabel(env.$elts.paginationBtns.length + 1) +
                    '</span></a>').data("firstStep", i));
            }
        });
        env.$elts.paginationBtns.each(function() {
            $(this).appendTo(env.$elts.pagination);
        });
        env.$elts.paginationBtns.slice(0, 1).addClass("active");
        env.launchOnLoad.push(function() {
            env.$elts.paginationBtns.click(function(e) {
                goToStep(env, $(this).data("firstStep"));
            });
        }
             );

    };
    function initAddress(env) {
        if (env.params.useAddress && $.isFunction($.fn.address)) {
            $.address.init(function(e) {
                var pathNames = $.address.pathNames();
                if (pathNames[0] === env.params.adressIdentifier && !!pathNames[1]) {
                    goToStep(env, pathNames[1] - 1);
                }
                else {
                    $.address.value('/' + env.params.adressIdentifier + '/1');
                }
            }).change(function(e) {
                var pathNames = $.address.pathNames();
                if (pathNames[0] === env.params.adressIdentifier && !!pathNames[1]) {
                    goToStep(env, pathNames[1] - 1);
                }
            });
        }
        else {
            env.params.useAddress = false;
        }
    };

    function goToStep(env, step) {
        if (env.stop)
            return;
        env.params.callback(step);
        replaceList(env, step);
        transition(env, step);
        if (env.params.useAddress) {
            $.address.value('/' + env.params.adressIdentifier + '/' + (step + 1));
        }
    };

    function getRelativeStep(env, position) {
        if (position == "prev")
            return env.params.skipItems;
        else
            return -env.params.skipItems;
    };

    function transition(env, step) {
        env.stop = true;
        stopAutoSlide(env);
        step = env.hideItems - step;
        switch (env.params.effect) {
            case "no":
                if (env.params.direction == "vertical") {
                    env.contList[env.contShow].css("top", -(env.itemHeight * step) + "px");
                }
                else {
                    env.contList[env.contShow].css("left", -(env.itemWidth * step) + "px");
                }
                secondListDraw(env);
                break;
            case "fade":
                if (env.params.direction == "vertical") {
                    env.contList[env.contShow].hide().css("top", -(env.itemHeight * step) + "px").fadeIn(env.params.animSpeed, function() { secondListDraw(env); });
                }
                else {
                    env.contList[env.contShow].hide().css("left", -(env.itemWidth * step) + "px").fadeIn(env.params.animSpeed, function() { secondListDraw(env); });
                }
                break;
            default:
                if (env.params.direction == "vertical") {
                    env.contList[env.contShow].stop().animate({ top: -(env.itemHeight * step) + "px" }, env.params.animSpeed, env.params.slideEasing, function() { secondListDraw(env); });
                }
                else {
                    env.contList[env.contShow].stop().animate({ left: -(env.itemWidth * step) + "px" }, env.params.animSpeed, env.params.slideEasing, function() { secondListDraw(env); });
                }
                break;
        }
    };

    function stopAutoSlide(env) {
        if (env.autoSlideTimeout)
            clearTimeout(env.autoSlideTimeout);
    };

})(jQuery);
