/// <reference path="jquery-1.4.2.min.js" />

// TODO: Find a better solution for some selectors.
// TODO: Clean up the code.

var container;

(function ($) {

    var containerWidth;

    $.fn.slider = function (params) {

        var defaults = {
            itemWidth: 100,
            itemsToDisplay: 3,
            itemsToMove: 1,
            leftButtonControl: ".leftButton",
            rightButtonControl: ".rightButton",
            leftButtonInactive: "",
            rightButtonInactive: "",
            jumperClass: "",
            slideSpeed: 500,
            mode: "forcePage",
            excludeElements: "",
            pagingContainer: ""
        };

        var config = $.extend(defaults, params);
        container = $(this);        

        if (container.length > 1) {
            $(container).nextUntil(config.rightButtonControl).hide();

            if (config.pagingContainer.length) {
                $(config.pagingContainer).children().click(switchToPage).data("container", $(this));
            }
        }

        if (config.jumperClass.length > 0)
        {
            $j($j(config.jumperClass).parent().get(0)).find("> *").addClass("active");
        }

        // Register click events.
        // [PP]
        $(config.jumperClass).data("container", $(this)).click(jumpTo);
        $(config.leftButtonControl).data("container", $(this)).click(moveLeft);
        $(config.rightButtonControl).data("container", $(this)).click(moveRight);

        if (config.leftButtonInactive) {
            $(config.leftButtonControl).children("img").attr("temp", $(config.leftButtonControl).children("img").attr("src"));
            $(config.leftButtonControl).children("img").attr("src", config.leftButtonInactive);
        }

        if (config.rightButtonInactive)
            $(config.rightButtonControl).children("img").attr("temp", $(config.rightButtonControl).children("img").attr("src"));

        container.each(function (index, element) {

            container.data("config", config);

            container.data("position" + index, 1);
            container.data("jumperPosition" + index, 1);

            var childCount;
            // Set container width.
            // [PP]
            if (config.excludeElements.length) {
                childCount = $(this).children(":not(" + config.excludeElements + ")").length;
            }
            else {
                childCount = $(this).children().length;
            }

            containerWidth = childCount * config.itemWidth;

            $(this).css("width", containerWidth + "px");
            $(this).css("position", "relative");
        });

        // Create a wrapper for the container.
        // [PP]
        var wrapper = $("<div />");
        wrapper.css("width", config.itemWidth * config.itemsToDisplay + "px");
        wrapper.css("overflow", "hidden");
        wrapper.css("position", "relative");

        wrapper.insertAfter(container.get(0));

        // Move container to wrapper.
        // [PP]
        container.appendTo(wrapper);
    };

    var switchToPage = function () {
        var index = $(this).index();
        var container = $(this).data("container");

        

        container.hide();
        $(container.get(index)).show();

        var config = container.data("config");
        var childCount = container.children(":visible").length;

        if (config.itemsToMove > 1) {
            var newVal = childCount;
        }
        else {
            var newVal = childCount - config.itemsToDisplay;
        }

        if (config.rightButtonInactive && !(container.data("position" + index) + config.itemsToMove - 1 < newVal)) {
            $(config.rightButtonControl).children("img").attr("src", config.rightButtonInactive);
        }
        else if (config.rightButtonInactive){
            $(config.rightButtonControl).children("img").attr("src", $(config.rightButtonControl).children("img").attr("temp"));
        }
        if (config.leftButtonInactive && !(container.data("position" + index) > config.itemsToMove)) {
            $(config.leftButtonControl).children("img").attr("src", config.leftButtonInactive);
        }
        else if (config.leftButtonInactive){
            $(config.leftButtonControl).children("img").attr("src", $(config.leftButtonControl).children("img").attr("temp"));
        }
    }

    var moveLeft = function () {
        var container = $(this).data("container");
        var config = container.data("config");
        var containerIndex = container.children(":visible").parent().index();

        var activeJumper = $(config.jumperClass + ".active").parent().prev().children("a");

        if (container.data("position" + containerIndex) > config.itemsToMove) {

            $(config.jumperClass).each(function () {
                $(this).removeClass("active");
            });
            $(activeJumper).addClass("active");
            container.data("jumperPosition" + containerIndex, container.data("jumperPosition" + containerIndex) - 1);

            container.data("position" + containerIndex, container.data("position" + containerIndex) - config.itemsToMove);
            animate("+", container, containerIndex);
        }
    }

    var moveRight = function () {   
        var container = $(this).data("container");
        var config = container.data("config");
        var containerIndex = container.children(":visible").parent().index();
        
        var childCount = $(container[containerIndex]).children().length;
        var activeJumper = $(config.jumperClass + ".active").parent().next().children("a");

        if (config.itemsToMove > 1) {
            var newVal = childCount;
        }
        else {
            var newVal = childCount - config.itemsToDisplay;
        }        

        if (config.mode == "forcePage") {
            if (container.data("position" + containerIndex) + config.itemsToMove - 1 < newVal) {
                $(config.jumperClass).each(function () {
                    $(this).removeClass("active");
                });
                $(activeJumper).addClass("active");
                container.data("jumperPosition" + containerIndex, container.data("jumperPosition" + containerIndex) + 1);

                container.data("position" + containerIndex, container.data("position" + containerIndex) + config.itemsToMove);
                animate("-", container, containerIndex, childCount, newVal);
            }
        }
        else if (config.mode == "seamless") {
            // TODO
            // [PP]
        }
    }

    var animate = function (operator, activeContainer, containerIndex, childCount, newVal, newLeft) {
        var config = activeContainer.data("config");

        activeContainer.children(":visible").parent().animate({
            left: operator + "=" + (newLeft != null ? newLeft : config.itemsToMove * config.itemWidth)
        }, config.slideSpeed);
        if (config.rightButtonInactive && !(activeContainer.data("position" + containerIndex) + config.itemsToMove - 1 < newVal) && operator != "+") {
            $(config.rightButtonControl).children("img").attr("src", config.rightButtonInactive);
        }
        else if (config.rightButtonInactive){
            $(config.rightButtonControl).children("img").attr("src", $(config.rightButtonControl).children("img").attr("temp"));
        }
        if (config.leftButtonInactive && !(activeContainer.data("position" + containerIndex) > config.itemsToMove)) {
            $(config.leftButtonControl).children("img").attr("src", config.leftButtonInactive);
        }
        else if (config.leftButtonInactive){
            $(config.leftButtonControl).children("img").attr("src", $(config.leftButtonControl).children("img").attr("temp"));
        }
    }

    $.fn.slider.SlideExtern = function(slider, index) {
        jumpTo(slider, index + 1 );
    }

    var jumpTo = function (slider, index) {
        
        var sliderContainer;
        var sliderIndex;

        if (slider.length > 0) {
            sliderContainer = slider;
            sliderIndex = index;
        }
        else {
            sliderContainer = this;
            sliderIndex = $(this).parent().index() + 1;
        }

        var container = $(sliderContainer).data("container");
        var config = container.data("config");
        var containerIndex = container.children(":visible").parent().index();

        var childCount = $j(container[containerIndex]).children().length;

        if (config.itemsToMove > 1) {
            var newVal = childCount;
        }
        else {
            var newVal = childCount - config.itemsToDisplay;
        }
        
        var newLeft = ((container.data("jumperPosition" + containerIndex) - (sliderIndex)) * config.itemsToMove) * config.itemWidth;
        
        $(config.jumperClass).each(function () {
            $(config.jumperClass).removeClass("active");
        });
        $(sliderContainer).addClass("active");

        if (newLeft >= 0) {
            container.data("position" + containerIndex, container.data("position" + containerIndex) - (newLeft / config.itemWidth));
            container.data("jumperPosition" + containerIndex, container.data("jumperPosition" + containerIndex) - (newLeft / config.itemWidth / config.itemsToMove));
            animate("+", container, containerIndex, childCount, newVal, newLeft);
        }
        else {
            container.data("position" + containerIndex, container.data("position" + containerIndex) + ((newLeft / config.itemWidth) * -1));
            container.data("jumperPosition" + containerIndex, container.data("jumperPosition" + containerIndex) + ((newLeft / config.itemWidth / config.itemsToMove) * -1));
            animate("-", container, containerIndex, childCount, newVal, newLeft * -1);
        }
    }

    var getActiveContainerIndex = function () {        
        var activeContainer = container.children(":visible").parent();
        return activeContainer.index();
    }

    var getConfig = function(element) {
        return element.data("container").data("config");
    }

})(jQuery);
