;
(function ($, window, document, undefined) {
    'use strict';

    Foundation.libs.clearing = {
        name: 'clearing',

        version: '5.5.0',

        settings: {
            templates: {
                viewing: '<a href="#" class="clearing-close">&times;</a>' +
                '<div class="visible-img" style="display: none"><div class="clearing-touch-label"></div><img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' +
                '<p class="clearing-caption"></p><a href="#" class="clearing-main-prev"><span></span></a>' +
                '<a href="#" class="clearing-main-next"><span></span></a></div>'
            },

            // comma delimited list of selectors that, on click, will close clearing,
            // add 'div.clearing-blackout, div.visible-img' to close on background click
            close_selectors: '.clearing-close, div.clearing-blackout',

            // Default to the entire li element.
            open_selectors: '',

            // Image will be skipped in carousel.
            skip_selector: '',

            touch_label: '',

            // event initializers and locks
            init: false,
            locked: false
        },

        init: function (scope, method, options) {
            var self = this;
            Foundation.inherit(this, 'throttle image_loaded');

            this.bindings(method, options);

            if (self.S(this.scope).is('[' + this.attr_name() + ']')) {
                this.assemble(self.S('li', this.scope));
            } else {
                self.S('[' + this.attr_name() + ']', this.scope).each(function () {
                    self.assemble(self.S('li', this));
                });
            }
        },

        events: function (scope) {
            var self = this,
                S = self.S,
                $scroll_container = $('.scroll-container');

            if ($scroll_container.length > 0) {
                this.scope = $scroll_container;
            }

            S(this.scope)
                .off('.clearing')
                .on('click.fndtn.clearing', 'ul[' + this.attr_name() + '] li ' + this.settings.open_selectors,
                function (e, current, target) {
                    var current = current || S(this),
                        target = target || current,
                        next = current.next('li'),
                        settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'),
                        image = S(e.target);

                    e.preventDefault();

                    if (!settings) {
                        self.init();
                        settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
                    }

                    // if clearing is open and the current image is
                    // clicked, go to the next image in sequence
                    if (target.hasClass('visible') &&
                        current[0] === target[0] &&
                        next.length > 0 && self.is_open(current)) {
                        target = next;
                        image = S('img', target);
                    }

                    // set current and target to the clicked li if not otherwise defined.
                    self.open(image, current, target);
                    self.update_paddles(target);
                })

                .on('click.fndtn.clearing', '.clearing-main-next',
                function (e) {
                    self.nav(e, 'next')
                })
                .on('click.fndtn.clearing', '.clearing-main-prev',
                function (e) {
                    self.nav(e, 'prev')
                })
                .on('click.fndtn.clearing', this.settings.close_selectors,
                function (e) {
                    Foundation.libs.clearing.close(e, this)
                });

            $(document).on('keydown.fndtn.clearing',
                function (e) {
                    self.keydown(e)
                });

            S(window).off('.clearing').on('resize.fndtn.clearing',
                function () {
                    self.resize()
                });

            this.swipe_events(scope);
        },

        swipe_events: function (scope) {
            var self = this,
                S = self.S;

            S(this.scope)
                .on('touchstart.fndtn.clearing', '.visible-img', function (e) {
                    if (!e.touches) {
                        e = e.originalEvent;
                    }
                    var data = {
                        start_page_x: e.touches[0].pageX,
                        start_page_y: e.touches[0].pageY,
                        start_time: (new Date()).getTime(),
                        delta_x: 0,
                        is_scrolling: undefined
                    };

                    S(this).data('swipe-transition', data);
                    e.stopPropagation();
                })
                .on('touchmove.fndtn.clearing', '.visible-img', function (e) {
                    if (!e.touches) {
                        e = e.originalEvent;
                    }
                    // Ignore pinch/zoom events
                    if (e.touches.length > 1 || e.scale && e.scale !== 1) return;

                    var data = S(this).data('swipe-transition');

                    if (typeof data === 'undefined') {
                        data = {};
                    }

                    data.delta_x = e.touches[0].pageX - data.start_page_x;

                    if (Foundation.rtl) {
                        data.delta_x = -data.delta_x;
                    }

                    if (typeof data.is_scrolling === 'undefined') {
                        data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
                    }

                    if (!data.is_scrolling && !data.active) {
                        e.preventDefault();
                        var direction = (data.delta_x < 0) ? 'next' : 'prev';
                        data.active = true;
                        self.nav(e, direction);
                    }
                })
                .on('touchend.fndtn.clearing', '.visible-img', function (e) {
                    S(this).data('swipe-transition', {});
                    e.stopPropagation();
                });
        },

        assemble: function ($li) {
            var $el = $li.parent();

            if ($el.parent().hasClass('carousel')) {
                return;
            }

            $el.after('<div id="foundationClearingHolder"></div>');

            var grid = $el.detach(),
                grid_outerHTML = '';

            if (grid[0] == null) {
                return;
            } else {
                grid_outerHTML = grid[0].outerHTML;
            }

            var holder = this.S('#foundationClearingHolder'),
                settings = $el.data(this.attr_name(true) + '-init'),
                data = {
                    grid: '<div class="carousel">' + grid_outerHTML + '</div>',
                    viewing: settings.templates.viewing
                },
                wrapper = '<div class="clearing-assembled"><div>' + data.viewing +
                    data.grid + '</div></div>',
                touch_label = this.settings.touch_label;

            if (Modernizr.touch) {
                wrapper = $(wrapper).find('.clearing-touch-label').html(touch_label).end();
            }

            holder.after(wrapper).remove();
        },

        open: function ($image, current, target) {
            var self = this,
                body = $(document.body),
                root = target.closest('.clearing-assembled'),
                container = self.S('div', root).first(),
                visible_image = self.S('.visible-img', container),
                image = self.S('img', visible_image).not($image),
                label = self.S('.clearing-touch-label', container),
                error = false;

            // Event to disable scrolling on touch devices when Clearing is activated
            $('body').on('touchmove', function (e) {
                e.preventDefault();
            });

            image.error(function () {
                error = true;
            });

            function startLoad() {
                setTimeout(function () {
                    this.image_loaded(image, function () {
                        if (image.outerWidth() === 1 && !error) {
                            startLoad.call(this);
                        } else {
                            cb.call(this, image);
                        }
                    }.bind(this));
                }.bind(this), 100);
            }

            function cb(image) {
                var $image = $(image);
                $image.css('visibility', 'visible');
                // toggle the gallery
                body.css('overflow', 'hidden');
                root.addClass('clearing-blackout');
                container.addClass('clearing-container');
                visible_image.show();
                this.fix_height(target)
                    .caption(self.S('.clearing-caption', visible_image), self.S('img', target))
                    .center_and_label(image, label)
                    .shift(current, target, function () {
                        target.closest('li').siblings().removeClass('visible');
                        target.closest('li').addClass('visible');
                    });
                visible_image.trigger('opened.fndtn.clearing')
            }

            if (!this.locked()) {
                visible_image.trigger('open.fndtn.clearing');
                // set the image to the selected thumbnail
                image
                    .attr('src', this.load($image))
                    .css('visibility', 'hidden');

                startLoad.call(this);
            }
        },

        close: function (e, el) {
            e.preventDefault();

            var root = (function (target) {
                    if (/blackout/.test(target.selector)) {
                        return target;
                    } else {
                        return target.closest('.clearing-blackout');
                    }
                }($(el))),
                body = $(document.body), container, visible_image;

            if (el === e.target && root) {
                body.css('overflow', '');
                container = $('div', root).first();
                visible_image = $('.visible-img', container);
                visible_image.trigger('close.fndtn.clearing');
                this.settings.prev_index = 0;
                $('ul[' + this.attr_name() + ']', root)
                    .attr('style', '').closest('.clearing-blackout')
                    .removeClass('clearing-blackout');
                container.removeClass('clearing-container');
                visible_image.hide();
                visible_image.trigger('closed.fndtn.clearing');
            }

            // Event to re-enable scrolling on touch devices
            $('body').off('touchmove');

            return false;
        },

        is_open: function (current) {
            return current.parent().prop('style').length > 0;
        },

        keydown: function (e) {
            var clearing = $('.clearing-blackout ul[' + this.attr_name() + ']'),
                NEXT_KEY = this.rtl ? 37 : 39,
                PREV_KEY = this.rtl ? 39 : 37,
                ESC_KEY = 27;

            if (e.which === NEXT_KEY) this.go(clearing, 'next');
            if (e.which === PREV_KEY) this.go(clearing, 'prev');
            if (e.which === ESC_KEY) this.S('a.clearing-close').trigger('click').trigger('click.fndtn.clearing');
        },

        nav: function (e, direction) {
            var clearing = $('ul[' + this.attr_name() + ']', '.clearing-blackout');

            e.preventDefault();
            this.go(clearing, direction);
        },

        resize: function () {
            var image = $('img', '.clearing-blackout .visible-img'),
                label = $('.clearing-touch-label', '.clearing-blackout');

            if (image.length) {
                this.center_and_label(image, label);
                image.trigger('resized.fndtn.clearing')
            }
        },

        // visual adjustments
        fix_height: function (target) {
            var lis = target.parent().children(),
                self = this;

            lis.each(function () {
                var li = self.S(this),
                    image = li.find('img');

                if (li.height() > image.outerHeight()) {
                    li.addClass('fix-height');
                }
            })
                .closest('ul')
                .width(lis.length * 100 + '%');

            return this;
        },

        update_paddles: function (target) {
            target = target.closest('li');
            var visible_image = target
                .closest('.carousel')
                .siblings('.visible-img');

            if (target.next().length > 0) {
                this.S('.clearing-main-next', visible_image).removeClass('disabled');
            } else {
                this.S('.clearing-main-next', visible_image).addClass('disabled');
            }

            if (target.prev().length > 0) {
                this.S('.clearing-main-prev', visible_image).removeClass('disabled');
            } else {
                this.S('.clearing-main-prev', visible_image).addClass('disabled');
            }
        },

        center_and_label: function (target, label) {
            if (!this.rtl) {
                target.css({
                    marginLeft: -(target.outerWidth() / 2),
                    marginTop: -(target.outerHeight() / 2)
                });

                if (label.length > 0) {
                    label.css({
                        marginLeft: -(label.outerWidth() / 2),
                        marginTop: -(target.outerHeight() / 2) - label.outerHeight() - 10
                    });
                }
            } else {
                target.css({
                    marginRight: -(target.outerWidth() / 2),
                    marginTop: -(target.outerHeight() / 2),
                    left: 'auto',
                    right: '50%'
                });

                if (label.length > 0) {
                    label.css({
                        marginRight: -(label.outerWidth() / 2),
                        marginTop: -(target.outerHeight() / 2) - label.outerHeight() - 10,
                        left: 'auto',
                        right: '50%'
                    });
                }
            }
            return this;
        },

        // image loading and preloading

        load: function ($image) {
            var href;

            if ($image[0].nodeName === 'A') {
                href = $image.attr('href');
            } else {
                href = $image.closest('a').attr('href');
            }

            this.preload($image);

            if (href) return href;
            return $image.attr('src');
        },

        preload: function ($image) {
            this
                .img($image.closest('li').next())
                .img($image.closest('li').prev());
        },

        img: function (img) {
            if (img.length) {
                var new_img = new Image(),
                    new_a = this.S('a', img);

                if (new_a.length) {
                    new_img.src = new_a.attr('href');
                } else {
                    new_img.src = this.S('img', img).attr('src');
                }
            }
            return this;
        },

        // image caption

        caption: function (container, $image) {
            var caption = $image.attr('data-caption');

            if (caption) {
                container
                    .html(caption)
                    .show();
            } else {
                container
                    .text('')
                    .hide();
            }
            return this;
        },

        // directional methods

        go: function ($ul, direction) {
            var current = this.S('.visible', $ul),
                target = current[direction]();

            // Check for skip selector.
            if (this.settings.skip_selector && target.find(this.settings.skip_selector).length != 0) {
                target = target[direction]();
            }

            if (target.length) {
                this.S('img', target)
                    .trigger('click', [current, target]).trigger('click.fndtn.clearing', [current, target])
                    .trigger('change.fndtn.clearing');
            }
        },

        shift: function (current, target, callback) {
            var clearing = target.parent(),
                old_index = this.settings.prev_index || target.index(),
                direction = this.direction(clearing, current, target),
                dir = this.rtl ? 'right' : 'left',
                left = parseInt(clearing.css('left'), 10),
                width = target.outerWidth(),
                skip_shift;

            var dir_obj = {};

            // we use jQuery animate instead of CSS transitions because we
            // need a callback to unlock the next animation
            // needs support for RTL **
            if (target.index() !== old_index && !/skip/.test(direction)) {
                if (/left/.test(direction)) {
                    this.lock();
                    dir_obj[dir] = left + width;
                    clearing.animate(dir_obj, 300, this.unlock());
                } else if (/right/.test(direction)) {
                    this.lock();
                    dir_obj[dir] = left - width;
                    clearing.animate(dir_obj, 300, this.unlock());
                }
            } else if (/skip/.test(direction)) {
                // the target image is not adjacent to the current image, so
                // do we scroll right or not
                skip_shift = target.index() - this.settings.up_count;
                this.lock();

                if (skip_shift > 0) {
                    dir_obj[dir] = -(skip_shift * width);
                    clearing.animate(dir_obj, 300, this.unlock());
                } else {
                    dir_obj[dir] = 0;
                    clearing.animate(dir_obj, 300, this.unlock());
                }
            }

            callback();
        },

        direction: function ($el, current, target) {
            var lis = this.S('li', $el),
                li_width = lis.outerWidth() + (lis.outerWidth() / 4),
                up_count = Math.floor(this.S('.clearing-container').outerWidth() / li_width) - 1,
                target_index = lis.index(target),
                response;

            this.settings.up_count = up_count;

            if (this.adjacent(this.settings.prev_index, target_index)) {
                if ((target_index > up_count) && target_index > this.settings.prev_index) {
                    response = 'right';
                } else if ((target_index > up_count - 1) && target_index <= this.settings.prev_index) {
                    response = 'left';
                } else {
                    response = false;
                }
            } else {
                response = 'skip';
            }

            this.settings.prev_index = target_index;

            return response;
        },

        adjacent: function (current_index, target_index) {
            for (var i = target_index + 1; i >= target_index - 1; i--) {
                if (i === current_index) return true;
            }
            return false;
        },

        // lock management

        lock: function () {
            this.settings.locked = true;
        },

        unlock: function () {
            this.settings.locked = false;
        },

        locked: function () {
            return this.settings.locked;
        },

        off: function () {
            this.S(this.scope).off('.fndtn.clearing');
            this.S(window).off('.fndtn.clearing');
        },

        reflow: function () {
            this.init();
        }
    };

}(jQuery, window, window.document));
