﻿var priorityCarousel = {
    // CSS3 Touch Support
    Support: {
        CSSAnimation: function () {

            if (!this._result) { // check if CSS transform and trasisions supported. 
                this._result = ($('html').hasClass('csstransitions') && $('html').hasClass('csstransforms')); // Cache response for speed.
            }

            return this._result;
        },

        getTranlate3D: function (elm) { // read the translate/translate3D rule of an element
            var props = ['WebkitTransform', 'Transform', 'MozTransform'],
                l = props.length,
                computedStyle = window.getComputedStyle(elm),
                comps;

            while (l--) { // find the correct vendor prefix
                if (computedStyle[props[l]]) {
                    comps = computedStyle[props[l]].split(',');
                };
            }

            return {
                x: parseInt(comps[comps.length - 2], 10) // find the x value
            };
        }
    },

    BaseCarousel: {

        head: 0, // first visible item
        enabled: false,

        create: function (root) {
            var self = this;

            $.extend(self, {
                root: root,
                wrap: root.find('.items'),
                nextBtn: root.find('.next'),
                prevBtn: root.find('.prev'),
                lastBtn: root.find('.last-item'),
                firstBtn: root.find('.first-item'),
                carouselNav: root.find('.carousel-nav div')
            });

            this.items = self.wrap.children();

            if (self.items.length > self.config.visibleItems) {
                this.enabled = true;
            };

            this.nextBtn.bind('click', function (e) {
                e.preventDefault();

                self.seekTo(self.head + 1);
            });

            this.prevBtn.bind('click', function (e) {
                e.preventDefault();

                self.seekTo(self.head - 1);
            });

            this.lastBtn.bind('click', function (e) {
                e.preventDefault();

                self.seekTo(self.items.length);
            });

            this.firstBtn.bind('click', function (e) {
                e.preventDefault();

                self.seekTo(0);
            });

            this.wrap.bind('webkitTransitionEnd OTransitionEnd transitionend', function (e) { // for browsers with CSS Transitions support
                self.onSeek();
            });

            self.wrap.bind('touchstart touchmove touchend', function (e) {
                if (self.handlers[e.type]) {
                    self.handlers[e.type].apply(this, [e, self]);
                }
            });

            root.addClass('enabled');
            this.toggleButtons();

            // If .page-total exists we update the text indicator 
            if (this.carouselNav.length) {
                this.carouselNav.find('.page-total').html((self.head + 1) + ' of ' + self.items.length)

                if ((self.head + 1) == self.items.length) {
                    this.carouselNav.hide();
                }
            }
        },

        tail: function () { // last visible item
            return this.head + (this.config.visibleItems - 1);
        },

        headItem: function (item) {
            return this.items.eq(this.head);
        },

        tailItem: function () {
            return this.items.eq(this.tail());
        },

        toggleButtons: function () { // show or hide buttons based on position of carousel
            this.prevBtn.toggleClass('disabled', this.head === 0);
            this.firstBtn.toggleClass('disabled', this.head === 0);
            this.nextBtn.toggleClass('disabled', (this.tail() + 1) >= this.items.length);
            this.lastBtn.toggleClass('disabled', (this.tail() + 1) >= this.items.length);
        },

        isItemVisible: function (item) {
            var self = this,
                n = self.items.index(item);

            return (n >= self.head && n <= self.tail());
        },

        handlers: {
            touchstart: function (e, self) { // store intial position and time
                this._start = {
                    posX: priorityCarousel.Support.getTranlate3D(this).x,
                    touchX: e.originalEvent.targetTouches[0].clientX,
                    time: (new Date).getTime()
                };

                $(this).addClass('touching'); // switch on a class to remove the animation duration
            },

            touchend: function (e, self) { // determine where to place the carousel at the end of a swipe
                $(this).removeClass('touching');

                var time = (new Date).getTime(),
                    deltaD = e.originalEvent.changedTouches[0].clientX - this._start.touchX;
                v = deltaD / (time - this._start.time);

                if (Math.abs(v) > self.config.swipeThreshold) { // if velocity is over swipThreshold, skip to next or previous
                    deltaD < 0 ? self.seekTo(self.head + self.config.visibleItems) : self.seekTo(self.head - 1);
                } else { // snap to the nearest item
                    var n = Math.abs(priorityCarousel.Support.getTranlate3D(this).x) / self.config.itemWidth,
                        index = Math.round(n);

                    self.seekTo(index, null, true);
                };

                this._start = false;
            },

            touchmove: function (e, self) {
                if (this._start) { // only track after the touch has started
                    var delta = this._start.touchX - e.originalEvent.targetTouches[0].clientX,
                        newX;

                    if (Math.abs(delta) > 10) { // prevent vertical scrolling 
                        e.preventDefault();
                    };

                    newX = this._start.posX - delta;

                    if (newX < 0 && newX > -((self.items.length - 1) * self.config.itemWidth)) {
                        $(this).css('webkitTransform', 'translate3d(' + newX + 'px, 0, 0)');
                    };
                }
            }
        },

        onSeek: function () {
            this.toggleButtons();
        },

        seekToItem: function (item, duration, force) {
            var self = this;
            return self.seekTo(self.items.index(item), duration, force);
        },

        seekTo: function (n, duration, force) {
            var self = this,
                duration = duration || self.config.animationDuration;

            if (!this.enabled) { return false; }

            if (!force && n === this.head) { // no need to seek if n is already at head position; if force is truthy do it anyway
                return false;
            }

            if (n < 0) {
                n = 0;
            };

            if ((n + self.config.visibleItems) > self.items.length) {
                n = self.items.length - self.config.visibleItems;
            }

            var newPosition = -(n * self.config.itemWidth) + 'px';

            if (priorityCarousel.Support.CSSAnimation()) {
                this.wrap.css({
                    'webkitTransform': 'translate3d(' + newPosition + ', 0px, 0)',
                    'MozTransform': 'translate(' + newPosition + ', 0px)',
                    'transform': 'translate(' + newPosition + ', 0px)'
                });
            } else {
                this.wrap.animate({
                    'left': newPosition
                }, {
                    'complete': function () {
                        self.onSeek();
                    },
                    'duration': duration
                });
            }

            this.head = n;

            // If .page-total exists we update the text indicator 
            if (this.carouselNav.length) {
                this.carouselNav.find('.page-total').html((this.head + 1) + ' of ' + self.items.length)
            }
        }
    },

    BusinessCarousel: {
        config: {
            animationDuration: 250,
            visibleItems: 4,
            itemWidth: 221,
            touchFriction: 0.075,   // adjust speed of swiping on touch devices
            swipeThreshold: 100
        },

        init: function (root, delegate) {
            var self = this;

            self.delegate = delegate;

            $.extend(this, priorityCarousel.BaseCarousel);
            self.create(root);

            return this;
        }
    },

    MomentsCarousel: {
        config: {
            animationDuration: 250,
            visibleItems: 1,
            itemWidth: 882,
            touchFriction: 0.075,   // adjust speed of swiping on touch devices
            swipeThreshold: 100
        },

        init: function (root, delegate) {
            var self = this;

            self.delegate = delegate;

            $.extend(this, priorityCarousel.BaseCarousel);
            self.create(root);

            return this;
        }
    },

    MomentsFeaturedCarousel: {
        config: {
            animationDuration: 250,
            visibleItems: 2,
            itemWidth: 441,
            touchFriction: 0.075,   // adjust speed of swiping on touch devices
            swipeThreshold: 100
        },

        init: function (root, delegate) {
            var self = this;

            self.delegate = delegate;

            $.extend(this, priorityCarousel.BaseCarousel);
            self.create(root);

            return this;
        }
    }
}

jQuery(function ($) {
    if($('#BusinessInner').length){
        priorityCarousel.BusinessCarousel.init($('.carousel-container'));
    }

    priorityCarousel.MomentsFeaturedCarousel.init($('#moments-featured-carousel'));
    priorityCarousel.MomentsCarousel.init($('#moments-carousel'));
});
