(function ($) {
    $.fn.setup_slider = function (variables) {
        return this.each(function (i) {
            // default global vars
            var config = {
                animatePause: true,
                autoPlay: true,
                changeSpeed: 600,
                controls: true,
                controlText: {
                    play: 'Play',
                    pause: 'Pause',
                    next: 'Next',
                    previous: 'Previous'
                },
                effect: 'fade',
                hoverPause: true,
                links: true,
                speed: 9000
            };
            // merge default global variables with custom variables, modifying 'config'
            if (variables) $.extend(true, config, variables);
            var content = $(this);
            var original_width = content.parent().width();
            var children = content.find(":first").children();
            var t_height = FindMaxHeight(children);
            var t_width = FindCummlativeWidth(children);
            var no_child_height = 0;
            content.css({ width: t_width + "px", position: "relative", left: "0" });
            children.css({ float: "left", display: "block" });
            content.parent().css({ position: "absolute", width: original_width + "px", overflow: "hidden" });
            var children_count = children.length;
            var current_child_count = 0;
            var endChild = EndChildCount(children, original_width, t_width);

            if (variables.show_controls) {
                AddControls();
            }
            if (variables.show_numbers) {
                AddNumbers(children);
            }
            no_child_height += CalculateHeight();
            var timeout_id = setTimeout(ScrollLeft, variables.speed);
            if (variables.variable_height) {
                if (children.length > 0) {
                    var t_height = $(children[current_child_count]).outerHeight(true);
                    content.parent().parent().css({ position: "relative", height: (t_height + no_child_height) + "px" });
                }
            }
            else {
                content.parent().parent().css({ height: (t_height + no_child_height) + "px" });
                children.css({});
            }

            function CalculateHeight() {
                children.css({ display: "none" });
                var a = content.parent().outerHeight(true) - content.parent().height();
                children.css({ display: "block" });
                return a;
            }

            function ScrollLeft() {
                current_child_count++;
                if (current_child_count > endChild) {
                    current_child_count = 0;
                }
                var width = $(children[current_child_count]).outerWidth(true);
                if (config.effect === "scroll_left") {
                    if (current_child_count === 0) {
                        content.animate({ "left": "0px" }, "slow");
                    }
                    else {
                        content.animate({ "left": "-=" + width + "px" }, "slow");
                    }
                }
                else if (config.effect === "none") {
                    if (current_child_count === 0) {
                        content.css({ "left": "0px" });
                    }
                    else {
                        var left = content.css("left");
                        left = left.replace(/[^(0-9)]/g, "");
                        left = (left * 1) + width;
                        content.css({ "left": -left + "px" });
                    }
                }
                if (variables.variable_height) {
                    content.parent().parent().css({ height: ($(children[current_child_count]).outerHeight(true) + no_child_height) + "px" });
                }
                timeout_id = setTimeout(ScrollLeft, variables.speed);
            }

            function FindMaxHeight(c) {
                var a = 0;
                for (var b = 0; b < c.length; b++) {
                    if (c.height() > a) {
                        a = c.height();
                    }
                }
                return a;
            }

            function FindMaxWidth(c) {
                var a = 0;
                for (var b = 0; b < c.length; b++) {
                    if (c.width() > a) {
                        a = c.width();
                    }
                }
                return a;
            }

            function FindCummlativeWidth(c) {
                var a = 0;
                for (var b = 0; b < c.length; b++) {
                    a += $(c[b]).outerWidth(true);
                }
                return a;
            }

            function FindWidthToSelected(c, i) {
                var w = 0;
                for (var j = 0; j < i; j++) {
                    w += $(c[j]).outerWidth(true);
                }
                var diff = $(c[j]).outerWidth(true) - $(c[j]).innerWidth();
                return w + diff;
            }

            function EndChildCount(c, w, cw) {
                var a = 0;
                var i = c.length;
                var d = cw - w;
                while (i > 0 && a < d) {
                    i--;
                    var wt = $(c[i]).outerWidth(true);
                    a += wt;
                }
                return c.length - i;
            }

            function AddControls() {
                content.parent().append("<div id=\"controls\"><a>Play</a><a>Pause</a><a>Previous</a><a>Next</a></div>");
                for (var i = 0; i < children.length; i++) {
                    var p_top = $(children[i]).css("margin-top");
                    p_top = p_top.replace(/[^(0-9)]/g, "");
                    p_top = (p_top * 1) + $("#controls", content.parent()).outerHeight(true);
                    $(children[i]).css({ marginTop: p_top + "px" });
                }
                AddControlsClickBehaviour($("#controls", content.parent()));
                HideControl($("#controls", content.parent()).children(), "Play");
            }

            function AddNumbers(c) {
                var s = "<div id=\"numbers\">";
                for (var i = 0; i < c.length; i++) {
                    s += "<a>" + (i + 1) + "</a>";
                }
                s += "</div>";
                content.parent().append(s);
                var n_height = $("#numbers", content.parent()).outerHeight(true);
                no_child_height += n_height;
                AddNumbersClickBehaviour($("#numbers", content.parent()));
            }

            function ManualScroll(l) {
                if (config.effect === "scroll_left") {
                    content.animate({ "left": -l + "px" }, "slow");
                }
                else if (config.effect === "none") {
                    content.css({ left: -l + "px" });
                }
            }

            function AddNumbersClickBehaviour(e) {
                e.children().each(function () {
                    $(this).click(function () {
                        clearTimeout(timeout_id);
                        current_child_count = ($(this).text() - 1);
                        var c = current_child_count;
                        if (c > endChild) {
                            c = endChild;
                        }
                        var left = FindWidthToSelected(children, c);
                        ManualScroll(left);
                        HideControl($("#controls", content.parent()).children(), "Pause");
                        ShowControl($("#controls", content.parent()).children(), "Play");
                    });
                });
            }

            function AddControlsClickBehaviour(e) {
                e.children().each(function () {
                    $(this).click(function () {
                        switch ($(this).text()) {
                            case "Play":
                                HideControl($("#controls", content.parent()).children(), "Play");
                                ShowControl($("#controls", content.parent()).children(), "Pause");
                                ScrollLeft();
                                break;
                            case "Pause":
                                HideControl($("#controls", content.parent()).children(), "Pause");
                                ShowControl($("#controls", content.parent()).children(), "Play");
                                clearTimeout(timeout_id);
                                break;
                            case "Next":
                                HideControl($("#controls", content.parent()).children(), "Pause");
                                ShowControl($("#controls", content.parent()).children(), "Play");
                                clearTimeout(timeout_id);
                                var c = ++current_child_count;
                                if (c > endChild) {
                                    c = 0;
                                    current_child_count = 0;
                                }
                                if (variables.variable_height) {
                                    var t_height = $(children[current_child_count]).outerHeight(true);
                                    content.parent().parent().css({ position: "relative", height: (t_height + no_child_height) + "px" });
                                }
                                var left = FindWidthToSelected(children, c);
                                ManualScroll(left);
                                break;
                            case "Previous":
                                HideControl($("#controls", content.parent()).children(), "Pause");
                                ShowControl($("#controls", content.parent()).children(), "Play");
                                clearTimeout(timeout_id);
                                var c = --current_child_count;
                                if (c < 0) {
                                    c = endChild;
                                    current_child_count = c;
                                }
                                if (variables.variable_height) {
                                    var t_height = $(children[current_child_count]).outerHeight(true);
                                    content.parent().parent().css({ position: "relative", height: (t_height + no_child_height) + "px" });
                                }
                                var left = FindWidthToSelected(children, c);
                                ManualScroll(left);
                                break;
                        }
                    });
                });
            }

            function HideControl(c, n) {
                var found = false;
                for (var i = 0; i < c.length && !found; i++) {
                    if ($(c[i]).text() === n) {
                        $(c[i]).css({ display: "none" });
                        found = true;
                    }
                }
            }

            function ShowControl(c, n) {
                var found = false;
                for (var i = 0; i < c.length && !found; i++) {
                    if ($(c[i]).text() === n) {
                        $(c[i]).css({ display: "inline-block" });
                        found = true;
                    }
                }
            }

        });
    };
})(jQuery);