/*global jQuery*/
(function (window) {
    "use strict";
    var $ = window.jQueryFixed ? window.jQueryFixed : window.jQuery,
		view = {};

    view = {
        imageGallery: {

            delay: 5000,

            runTimesSpeed: 100,

            animSpeed: "slow",

            controls: {
                "default": {
                    next: "<a href=\"/\">Next</a>",
                    previous: "<a href=\"/\">Previous</a>",
                    playPause: {
                        play: "Play",
                        pause: "Pause",
                        html: "<a href=\"/\">[text]</a>"
                    }
                },

                "custom": {
                    /*next : "<a href=\"/\">Nästa</a>",
                    previous : "<a href=\"/\">Föregående</a>",*/
                    playPause: {
                    /*play : "Spela upp",
                    pause : "Vänta ett tag",
                    html : "<a href=\"/\">[text]</a>"*/
                }
            },

            playPause: function playPause(ctrls, gallery) {

                var next = view.imageGallery.controls.custom.next ? view.imageGallery.controls.custom.next : view.imageGallery.controls["default"].next,
                        previous = view.imageGallery.controls.custom.previous ? view.imageGallery.controls.custom.previous : view.imageGallery.controls["default"].previous,
                        playPauseText = view.imageGallery.controls.custom.playPause.pause ? view.imageGallery.controls.custom.playPause.pause : view.imageGallery.controls["default"].playPause.pause,
                        wrapPlayPause = view.imageGallery.controls.custom.playPause.html ? view.imageGallery.controls.custom.playPause.html : view.imageGallery.controls["default"].playPause.html,
                        insertPlayPause = wrapPlayPause.replace(/\[text\]/, playPauseText);

                if (!view.imageGallery.controls.use) {
                    view.imageGallery.controls.use = {
                        play: view.imageGallery.controls.custom.playPause.play ? view.imageGallery.controls.custom.playPause.play : view.imageGallery.controls["default"].playPause.play,
                        pause: view.imageGallery.controls.custom.playPause.pause ? view.imageGallery.controls.custom.playPause.pause : view.imageGallery.controls["default"].playPause.pause
                    };
                }

                ctrls.append("<ul class=\"playPauseList\"><li class=\"previous\">" + previous + "</li><li class=\"playPause\">" + insertPlayPause + "</li><li class=\"next\">" + next + "</li></ul>");
            },

            indicator: function indicator(ctrls, gallery) {
                ctrls.append(function () {

                    var ul = document.createElement("ul"),
                            slides = gallery.find("> ul li"),
                            i = 0,
                            l = slides.length,
                            addLi = function (i) {

                                var li = document.createElement("li"),
                                    a = document.createElement("a"),
                                    s = document.createElement("span");

                                a.href = "/";
                                a.className = "slide" + i;
                                //a.innerHTML = parseInt(i + 1, 10);

                                s.className = "slide" + i;
                                // s.innerHTML = parseInt(i + 1, 10);

                                li.appendChild(a);
                                li.appendChild(s);

                                //prevent href from triggering in IE
                                window.jQuery(a).click(function (e) {
                                    e.preventDefault();
                                });

                                if (!i) {
                                    li.className = "currentSlide";
                                }

                                return li;
                            };

                    ul.className = "indicator";

                    for (i = 0; i < l; i += 1) {
                        ul.appendChild(addLi(i));
                    }

                    return ul; //"<ul><li><a href=\"/\">test</a></li></ul>";
                });
            },

            add: function add(ctrls, gallery) {

                // get custom and/or default controls
                var isPP = ctrls.hasClass("playPauseCtrls"),
                        isInd = ctrls.hasClass("indicator");

                if (isPP) {
                    // add the markup [ previous | playPause | next ]
                    view.imageGallery.controls.playPause(ctrls, gallery);

                    // previous
                    ctrls.find(".previous").click(function (e) {
                        e.stopPropagation();

                        view.imageGallery.previous(gallery);
                    });

                    // playPause
                    ctrls.find(".playPause").click(function (e) {
                        e.stopPropagation();

                        view.imageGallery.playPause(gallery, this);
                    });

                    // next
                    ctrls.find(".next").click(function (e) {
                        e.stopPropagation();

                        view.imageGallery.next(gallery);
                    });
                }

                if (isInd) {
                    // add more markup [slide indicatior]
                    view.imageGallery.controls.indicator(ctrls, gallery);

                    // show numbered slide
                    ctrls.find("[class^=slide]").click(function (e) {
                        e.stopPropagation();

                        if (!$(this.parentNode).hasClass("currentSlide")) {
                            view.imageGallery.showSlide(gallery, this);
                        }
                    });
                }

                // if there are any <a>:  preventDefault
                gallery.find("a").click(function (e) {
                    e.preventDefault();
                });
            }
        },

        showSlide: function showSlide(gallery, that) {

            if (gallery.hasClass("play")) {
                view.imageGallery.playPause(gallery, gallery.find(".playPause").get(0));
            }

            var fade = gallery.hasClass("fade"),
                    slide = (function () {
                        return parseInt(that.className.match(/(^|\s)slide\d+(\s|$)/).toString().replace(/\D/g, ""), 10);
                    } ());

            if (fade) {
                view.imageGallery.fade.apply(gallery.get(0), [slide]);
            } else {

                if (slide > gallery.data("galleryStore").currentSlide) {
                    view.imageGallery.next(gallery, ((slide - gallery.data("galleryStore").currentSlide) - 1));
                } else {
                    view.imageGallery.previous(gallery, ((gallery.data("galleryStore").currentSlide - slide) - 1));
                }

            }
        },

        setCurrentSlide: function setCurrentSlide() {
            var that = this,
                    fade = that.hasClass("fade"),
                    carousel = that.data("carousel"),
                    lis = null,
                    i = 0,
                    l = 0;

            if (fade) {
                that.data("galleryStore").currentSlide = that.find("> ul > li:last-child").data("slide");
            } else if (!fade && carousel === "noCarousel") {

                lis = that.find("> ul > li");
                l = lis.length;

                for (i = 0; i < l; i += 1) {

                    if (lis[i].offsetLeft === parseInt(lis[i].parentNode.offsetLeft.toString().replace(/^\-/, ""), 10)) {
                        that.data("galleryStore").currentSlide = that.find("> ul > li:nth-child(" + parseInt(i + 1, 10) + ")").data("slide");
                        break;
                    }
                }

            } else {
                that.data("galleryStore").currentSlide = that.find("> ul > li:first-child").data("slide");
            }

            that.find(".indicator li").removeClass("currentSlide");

            that.find(".indicator li:nth-child(" + parseInt(that.data("galleryStore").currentSlide + 1, 10) + ")").addClass("currentSlide");
        },

        next: function next(gallery, runTimes) {

            if (gallery.data("tweening") && !runTimes && runTimes !== 0) {
                return;
            }

            gallery.data("tweening", true);

            var ul = gallery.find("> ul"),
                    ulWidth = ul.width(),
                    slides = gallery.find("> ul > li"),
                    slideWidth = slides.width(),
                    speed = (runTimes || (runTimes !== undefined && typeof runTimes === "number")) ? view.imageGallery.runTimesSpeed : (gallery.data("galleryStore").tweenSpeed ? gallery.data("galleryStore").tweenSpeed : view.imageGallery.animSpeed),
                    cLeft = ul.css("left"),
                    nLeft = parseInt(parseInt(cLeft, 10) - parseInt(slideWidth, 10), 10),
                    slide = function slide() {

                        ul.animate({
                            left: nLeft + "px"
                        }, speed, function () {
                            if (gallery.data("carousel") !== "noCarousel") {
                                var firstLi = ul.find("li:first").get(0),
                                    ulElem = ul.get(0);

                                ulElem.appendChild(firstLi);
                                ul.css("left", 0);

                            }

                            view.imageGallery.setCurrentSlide.apply(gallery);

                            gallery.data("tweening", false);

                            if (runTimes) {
                                view.imageGallery.next(gallery, (runTimes - 1));
                            }

                        });
                    };

            if (gallery.data("carousel") === "noCarousel" && (nLeft === -ulWidth)) {
                nLeft = 0;
            }

            if (gallery.data("tween") === "fade") {
                view.imageGallery.fade.apply(gallery.get(0), ["next"]);
            } else {
                slide();
            }

        },
        previous: function previous(gallery, runTimes) {

            if (gallery.data("tweening") && !runTimes && runTimes !== 0) {
                return;
            }

            gallery.data("tweening", true);

            var ul = gallery.find("> ul"),
                    slides = gallery.find("> ul > li"),
                    slideWidth = slides.width(),
                    speed = (runTimes || (runTimes !== undefined && typeof runTimes === "number")) ? view.imageGallery.runTimesSpeed : (gallery.data("galleryStore").tweenSpeed ? gallery.data("galleryStore").tweenSpeed : view.imageGallery.animSpeed),
                    getLeft = ul.css("left"),
                    cLeft = (getLeft === "auto") ? "0px" : getLeft,
                    nLeft = parseInt(parseInt(cLeft, 10) + parseInt(slideWidth, 10), 10),

                    slide = function slide() {

                        if ((parseInt(cLeft, 10) === 0) && (gallery.data("carousel") !== "noCarousel")) {

                            ul.prepend(ul.find("li:last").get(0)).css("left", "-" + slideWidth + "px");

                            ul.animate({
                                left: 0
                            }, speed, function () {
                                view.imageGallery.setCurrentSlide.apply(gallery);

                                if (runTimes) {
                                    view.imageGallery.previous(gallery, (runTimes - 1));
                                }

                                gallery.data("tweening", false);
                            });
                        } else {
                            ul.animate({
                                left: nLeft
                            }, speed, function () {
                                view.imageGallery.setCurrentSlide.apply(gallery);

                                if (runTimes) {
                                    view.imageGallery.previous(gallery, (runTimes - 1));
                                }

                                gallery.data("tweening", false);

                            });
                        }
                    };

            console.log("cLeft = ", cLeft, ul.get(0).offsetLeft);

            if ((gallery.data("carousel") === "noCarousel") && (parseInt(cLeft, 10) >= 0)) {
                nLeft = "-" + parseInt(parseInt(slideWidth, 10) * (slides.length - 1), 10) + "px";
            }

            if (gallery.data("tween") === "fade") {
                view.imageGallery.fade.apply(gallery.get(0), ["previous"]);
            } else {
                slide();
            }

        },
        playPause: function playPause(gallery, that) {
            var g = $(gallery),
                    delay = g.data("galleryStore").tweenDelay ? g.data("galleryStore").tweenDelay : view.imageGallery.delay,
                    galleryStore = g.data("galleryStore"),
                    togglePlayPause = function (playPause, that) {
                        var playPauseElem = g.find(".playPause").get(0),
                            toHTML = "",
                            fromHTML = "",
                            replaceText = function (fromHTML, toHTML) {
                                var all = that.getElementsByTagName("*"),
                                    i = 0,
                                    l = all.length,
                                    re = new RegExp("^" + fromHTML + "$"),
                                    ih = "";

                                for (i = 0; i < l; i += 1) {
                                    ih = all[i].innerHTML;

                                    if ((re).test(ih)) {
                                        all[i].innerHTML = toHTML;
                                        break;
                                    }
                                }
                            };

                        if (playPauseElem) {

                            if (playPause === "pause") {

                                fromHTML = view.imageGallery.controls.use.pause;
                                toHTML = view.imageGallery.controls.use.play;

                            } else if (playPause === "play") {
                                fromHTML = view.imageGallery.controls.use.play;
                                toHTML = view.imageGallery.controls.use.pause;
                            }

                            if (that) {
                                replaceText(fromHTML, toHTML);
                            }
                        }
                    };

            if (!g.hasClass("play")) {
                g.addClass("play");

                if (g.hasClass("pause")) {
                    view.imageGallery.next(g);
                }

                g.removeClass("pause");

                togglePlayPause("play", that);

                galleryStore.iv = setInterval(function () {
                    view.imageGallery.next(g);
                }, delay);

            } else {
                clearInterval(galleryStore.iv);

                g.addClass("pause");
                g.removeClass("play");

                togglePlayPause("pause", that);
            }
        },

        setUlWidth: function setUlWidth() {
            var that = this,
                    t = $(that),
                    ul = t.find("ul"),
                    lis = t.find("li"),
                    ulWidth = 0,
                    i = 0,
                    l = lis.length;

            lis.css("width", function () {
                var t = $(this),
                        marginLeft = parseInt(t.css("margin-left"), 10) ? parseInt(t.css("margin-left"), 10) : 0,
                        marginRight = parseInt(t.css("margin-right"), 10) ? parseInt(t.css("margin-right"), 10) : 0,
                        paddingLeft = parseInt(t.css("padding-left"), 10) ? parseInt(t.css("padding-left"), 10) : 0,
                        paddingRight = parseInt(t.css("padding-right"), 10) ? parseInt(t.css("padding-right"), 10) : 0,
                        width = this.offsetWidth - parseInt(marginLeft + marginRight + paddingLeft + paddingRight, 10);

                return width + "px";
            });

            for (i = 0; i < l; i += 1) {
                ulWidth += lis[i].offsetWidth;
            }

            ul.css("width", ulWidth + "px");
        },

        fade: function fade(dir) {

            var that = this,
                    t = $(that),
                    slides = t.data("slides"),
                    currentSlide = t.data("galleryStore").currentSlide,
                    nextSlide = (typeof dir === "number") ? dir : ((dir === "previous") ? (currentSlide - 1) : parseInt(currentSlide + 1, 10)),
                    speed = t.data("galleryStore").tweenSpeed ? t.data("galleryStore").tweenSpeed : view.imageGallery.animSpeed,
                    currentReady = false,
                    nextReady = false;

            if (!t.data("first")) {

                t.find("> ul > li:not(:first-child)").css({
                    position: "absolute",
                    top: 0,
                    left: 0,
                    opacity: 0
                });

                t.data("first", true);


            } else {

                if (!slides[nextSlide] && dir === "next") {
                    nextSlide = 0;
                } else if (!slides[nextSlide] && dir === "previous") {
                    nextSlide = (slides.length - 1);
                }

                slides[nextSlide].parentNode.appendChild(slides[nextSlide]);

                $(slides[nextSlide]).animate({
                    opacity: 1
                }, speed, function () {
                    $(this).css("position", "relative");

                    nextReady = true;
                });

                $(slides[currentSlide]).animate({
                    opacity: 0
                }, speed, function () {
                    $(this).css({
                        position: "absolute",
                        top: 0,
                        left: 0
                    });
                    currentReady = true;
                });

                view.imageGallery.setCurrentSlide.apply(t);

                $.runWhenExists(function () {
                    return (currentReady && nextReady);
                }, function () {
                    t.data("tweening", false);
                });
            }


        },

        init: function init() {
            var imageGalleries = $(".imageGallery");

            imageGalleries.normalize().each(function () {
                var that = this,
                        t = $(that),
                        carousel = t.hasClass("noCarousel") ? "noCarousel" : "carousel",
                        tween = t.hasClass("fade") ? "fade" : "slide",
                        customSpeed = parseInt(t.find("input[type=hidden][id$=tweenSpeed]").val(), 10),
                        customDelay = parseInt(t.find("input[type=hidden][id$=tweenDelay]").val(), 10),
                        storeSlides = [];

                t.data("carousel", carousel);
                t.data("tween", tween);

                if (customDelay < customSpeed) {
                    customDelay += customSpeed;
                }

                t.find("> ul > li").each(function (i) {
                    $(this).data("slide", i);
                    storeSlides.push(this);
                });

                t.data("slides", storeSlides);

                /* --- store gallery specific vars --- */
                if (!view.imageGallery.galleries) {
                    view.imageGallery.galleries = {};
                    view.imageGallery.galleries.length = 0;
                }

                view.imageGallery.galleries[view.imageGallery.galleries.length] = {
                    iv: null,
                    currentSlide: 0
                };


                /* -- custom speed -- */

                if (customSpeed && parseInt(customSpeed, 10)) {
                    view.imageGallery.galleries[view.imageGallery.galleries.length].tweenSpeed = parseInt(customSpeed, 10);
                }

                /* -- /custom speed -- */

                /* -- custom delay --*/

                if (customDelay) {

                    if (parseInt(customDelay, 10)) {
                        view.imageGallery.galleries[view.imageGallery.galleries.length].tweenDelay = parseInt(customDelay, 10);
                    } else if ((/^(fast|slow)$/i).test(customDelay)) {
                        view.imageGallery.galleries[view.imageGallery.galleries.length].tweenDelay = customDelay;
                    }
                }
                /* -- /custom delay --*/

                t.data("galleryStore", view.imageGallery.galleries[view.imageGallery.galleries.length]);

                view.imageGallery.galleries.length += 1;

                /* --- /store gallery specific vars --- */

                if (tween === "fade") {
                    view.imageGallery.fade.apply(that);
                } else {
                    view.imageGallery.setUlWidth.call(this);
                }

                t.find(".indicator").each(function () {
                    var ctrls = $(this);
                    view.imageGallery.controls.add(ctrls, t);
                });

                t.find(".playPauseCtrls").each(function () {
                    var ctrls = $(this);
                    view.imageGallery.controls.add(ctrls, t);
                });

                if (tween === "slide") {
                    t.find("> ul").css("left", 0);
                }

                view.imageGallery.playPause(this);
            });
        }
    }
};

$.extendView(view);

} (window));
