/*
	Lens by HTML5 UP
	html5up.net | @ajlkn
	Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/

var main = (function ($) {
    var _ = {

        /**
         * Settings.
         * @var {object}
         */
        settings: {

            // Preload all images.
            preload: false,

            // Slide duration (must match "duration.slide" in _vars.scss).
            slideDuration: 500,

            // Layout duration (must match "duration.layout" in _vars.scss).
            layoutDuration: 750,

            // Thumbnails per "row" (must match "misc.thumbnails-per-row" in _vars.scss).
            thumbnailsPerRow: 2,

            // Side of main wrapper (must match "misc.main-side" in _vars.scss).
            mainSide: 'right'

        },

        /**
         * Window.
         * @var {jQuery}
         */
        $window: null,

        /**
         * Body.
         * @var {jQuery}
         */
        $body: null,

        /**
         * Main wrapper.
         * @var {jQuery}
         */
        $main: null,

        /**
         * Thumbnails.
         * @var {jQuery}
         */
        $thumbnails: null,

        /**
         * Viewer.
         * @var {jQuery}
         */
        $viewer: null,

        /**
         * Toggle.
         * @var {jQuery}
         */
        $toggle: null,

        /**
         * Nav (next).
         * @var {jQuery}
         */
        $navNext: null,

        /**
         * Nav (previous).
         * @var {jQuery}
         */
        $navPrevious: null,

        /**
         * Slides.
         * @var {array}
         */
        slides: [],

        /**
         * Current slide index.
         * @var {integer}
         */
        current: null,

        /**
         * Lock state.
         * @var {bool}
         */
        locked: false,

        /**
         * Keyboard shortcuts.
         * @var {object}
         */
        keys: {

            // Escape: Toggle main wrapper.
            27: function () {
                _.toggle();
            },

            // Up: Move up.
            38: function () {
                _.up();
            },

            // Down: Move down.
            40: function () {
                _.down();
            },

            // Space: Next.
            32: function () {
                _.next();
            },

            // Right Arrow: Next.
            39: function () {
                _.next();
            },

            // Left Arrow: Previous.
            37: function () {
                _.previous();
            }

        },

        /**
         * Initialize properties.
         */
        initProperties: function () {

            // Window, body.
            _.$window = $(window);
            _.$body = $('body');

            // Thumbnails.
            _.$thumbnails = $('#thumbnails');

            // Viewer.
            _.$viewer = $(
                '<div id="viewer">' +
                '<div class="inner">' +
                '<div class="nav-next"></div>' +
                '<div class="nav-previous"></div>' +
                '<div class="toggle"></div>' +
                '</div>' +
                '</div>'
            ).appendTo(_.$body);

            // Nav.
            _.$navNext = _.$viewer.find('.nav-next');
            _.$navPrevious = _.$viewer.find('.nav-previous');

            // Main wrapper.
            _.$main = $('#main');

            // Toggle.
            $('<div class="toggle"></div>')
                .appendTo(_.$main);

            _.$toggle = $('.toggle');

            // IE<9: Fix viewer width (no calc support).
            if (skel.vars.IEVersion < 9)
                _.$window
                    .on('resize', function () {
                        window.setTimeout(function () {
                            _.$viewer.css('width', _.$window.width() - _.$main.width());
                        }, 100);
                    })
                    .trigger('resize');

        },

        /**
         * Initialize events.
         */
        initEvents: function () {

            // Window.

            // Remove is-loading-* classes on load.
            _.$window.on('load', function () {

                _.$body.removeClass('is-loading-0');

                window.setTimeout(function () {
                    _.$body.removeClass('is-loading-1');
                }, 100);

                window.setTimeout(function () {
                    _.$body.removeClass('is-loading-2');
                }, 100 + Math.max(_.settings.layoutDuration - 150, 0));

            });

            // Disable animations/transitions on resize.
            var resizeTimeout;

            _.$window.on('resize', function () {

                _.$body.addClass('is-loading-0');
                window.clearTimeout(resizeTimeout);

                resizeTimeout = window.setTimeout(function () {
                    _.$body.removeClass('is-loading-0');
                }, 100);

            });

            // Viewer.

            // Hide main wrapper on tap (<= medium only).
            _.$viewer.on('touchend', function () {

                if (skel.breakpoint('medium').active)
                    _.hide();

            });

            // Touch gestures.
            _.$viewer
                .on('touchstart', function (event) {

                    // Record start position.
                    _.$viewer.touchPosX = event.originalEvent.touches[0].pageX;
                    _.$viewer.touchPosY = event.originalEvent.touches[0].pageY;

                })
                .on('touchmove', function (event) {

                    // No start position recorded? Bail.
                    if (_.$viewer.touchPosX === null
                        || _.$viewer.touchPosY === null)
                        return;

                    // Calculate stuff.
                    var diffX = _.$viewer.touchPosX - event.originalEvent.touches[0].pageX,
                        diffY = _.$viewer.touchPosY - event.originalEvent.touches[0].pageY;
                    boundary = 20,
                        delta = 50;

                    // Swipe left (next).
                    if ((diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta))
                        _.next();

                    // Swipe right (previous).
                    else if ((diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)))
                        _.previous();

                    // Overscroll fix.
                    var th = _.$viewer.outerHeight(),
                        ts = (_.$viewer.get(0).scrollHeight - _.$viewer.scrollTop());

                    if ((_.$viewer.scrollTop() <= 0 && diffY < 0)
                        || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {

                        event.preventDefault();
                        event.stopPropagation();

                    }

                });

            // Main.

            // Touch gestures.
            _.$main
                .on('touchstart', function (event) {

                    // Bail on xsmall.
                    if (skel.breakpoint('xsmall').active)
                        return;

                    // Record start position.
                    _.$main.touchPosX = event.originalEvent.touches[0].pageX;
                    _.$main.touchPosY = event.originalEvent.touches[0].pageY;

                })
                .on('touchmove', function (event) {

                    // Bail on xsmall.
                    if (skel.breakpoint('xsmall').active)
                        return;

                    // No start position recorded? Bail.
                    if (_.$main.touchPosX === null
                        || _.$main.touchPosY === null)
                        return;

                    // Calculate stuff.
                    var diffX = _.$main.touchPosX - event.originalEvent.touches[0].pageX,
                        diffY = _.$main.touchPosY - event.originalEvent.touches[0].pageY;
                    boundary = 20,
                        delta = 50,
                        result = false;

                    // Swipe to close.
                    switch (_.settings.mainSide) {

                        case 'left':
                            result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
                            break;

                        case 'right':
                            result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
                            break;

                        default:
                            break;

                    }

                    if (result)
                        _.hide();

                    // Overscroll fix.
                    var th = _.$main.outerHeight(),
                        ts = (_.$main.get(0).scrollHeight - _.$main.scrollTop());

                    if ((_.$main.scrollTop() <= 0 && diffY < 0)
                        || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {

                        event.preventDefault();
                        event.stopPropagation();

                    }

                });
            // Toggle.
            _.$toggle.on('click', function () {
                _.toggle();
            });

            // Prevent event from bubbling up to "hide event on tap" event.
            _.$toggle.on('touchend', function (event) {
                event.stopPropagation();
            });

            // Nav.
            _.$navNext.on('click', function () {
                _.next();
            });

            _.$navPrevious.on('click', function () {
                _.previous();
            });

            // Keyboard shortcuts.

            // Ignore shortcuts within form elements.
            _.$body.on('keydown', 'input,select,textarea', function (event) {
                event.stopPropagation();
            });

            _.$window.on('keydown', function (event) {

                // Ignore if xsmall is active.
                if (skel.breakpoint('xsmall').active)
                    return;

                // Check keycode.
                if (event.keyCode in _.keys) {

                    // Stop other events.
                    event.stopPropagation();
                    event.preventDefault();

                    // Call shortcut.
                    (_.keys[event.keyCode])();

                }

            });

        },

        /**
         * Initialize viewer.
         */
        initViewer: function () {

            // Bind thumbnail click event.
            _.$thumbnails
                .on('click', '.thumbnail', function (event) {

                    var $this = $(this);

                    // Stop other events.
                    event.preventDefault();
                    event.stopPropagation();

                    // Locked? Blur.
                    if (_.locked)
                        $this.blur();

                    // Switch to this thumbnail's slide.
                    _.switchTo($this.data('index'));

                });

            // Create slides from thumbnails.
            _.$thumbnails.children()
                .each(function () {

                    var $this = $(this),
                        $thumbnail = $this.children('.thumbnail'),
                        s;

                    // Slide object.
                    s = {
                        $parent: $this,
                        $slide: null,
                        $slideImage: null,
                        $slideCaption: null,
                        url: $thumbnail.attr('href'),
                        loaded: false
                    };

                    // Parent.
                    $this.attr('tabIndex', '-1');

                    // Slide.

                    // Create elements.
                    s.$slide = $('<div class="slide"><div class="caption"></div><div class="image"></div></div>');

                    // Image.
                    s.$slideImage = s.$slide.children('.image');

                    // Set background stuff.
                    s.$slideImage
                        .css('background-image', '')
                        .css('background-position', ($thumbnail.data('position') || 'center'));

                    // Caption.
                    s.$slideCaption = s.$slide.find('.caption');

                    // Move everything *except* the thumbnail itself to the caption.
                    $this.children().not($thumbnail)
                        .appendTo(s.$slideCaption);

                    // Preload?
                    if (_.settings.preload) {

                        // Force image to download.
                        var $img = $('<img src="' + s.url + '" />');

                        // Set slide's background image to it.
                        s.$slideImage
                            .css('background-image', 'url(' + s.url + ')');

                        // Mark slide as loaded.
                        s.$slide.addClass('loaded');
                        s.loaded = true;

                    }

                    // Add to slides array.
                    _.slides.push(s);

                    // Set thumbnail's index.
                    $thumbnail.data('index', _.slides.length - 1);

                });

        },

        /**
         * Initialize stuff.
         */
        init: function () {

            // IE<10: Zero out transition delays.
            if (skel.vars.IEVersion < 10) {

                _.settings.slideDuration = 0;
                _.settings.layoutDuration = 0;

            }

            // Skel.
            skel.breakpoints({
                xlarge: '(max-width: 1680px)',
                large: '(max-width: 1280px)',
                medium: '(max-width: 980px)',
                small: '(max-width: 736px)',
                xsmall: '(max-width: 480px)'
            });

            // Everything else.
            _.initProperties();
            _.initViewer();
            _.initEvents();

            // Initial slide.
            window.setTimeout(function () {

                // Show first slide if xsmall isn't active or it just deactivated.
                skel.on('-xsmall !xsmall', function () {

                    if (_.current === null)
                        _.switchTo(0, true);

                });

            }, 0);

        },

        /**
         * Switch to a specific slide.
         * @param {integer} index Index.
         */
        switchTo: function (index, noHide) {

            // Already at index and xsmall isn't active? Bail.
            if (_.current == index
                && !skel.breakpoint('xsmall').active)
                return;

            // Locked? Bail.
            if (_.locked)
                return;

            // Lock.
            _.locked = true;

            // Hide main wrapper if medium is active.
            if (!noHide
                && skel.breakpoint('medium').active
                && skel.vars.IEVersion > 8)
                _.hide();

            // Get slides.
            var oldSlide = (_.current !== null ? _.slides[_.current] : null),
                newSlide = _.slides[index];

            // Update current.
            _.current = index;

            // Deactivate old slide (if there is one).
            if (oldSlide) {

                // Thumbnail.
                oldSlide.$parent
                    .removeClass('active');

                // Slide.
                oldSlide.$slide.removeClass('active');

            }

            // Activate new slide.

            // Thumbnail.
            newSlide.$parent
                .addClass('active')
                .focus();

            // Slide.
            var f = function () {

                // Old slide exists? Detach it.
                if (oldSlide)
                    oldSlide.$slide.detach();

                // Attach new slide.
                newSlide.$slide.appendTo(_.$viewer);

                // New slide not yet loaded?
                if (!newSlide.loaded) {

                    window.setTimeout(function () {

                        // Mark as loading.
                        newSlide.$slide.addClass('loading');

                        // Wait for it to load.
                        $('<img src="' + newSlide.url + '" />').on('load', function () {
                            //window.setTimeout(function() {

                            // Set background image.
                            newSlide.$slideImage
                                .css('background-image', 'url(' + newSlide.url + ')');

                            // Mark as loaded.
                            newSlide.loaded = true;
                            newSlide.$slide.removeClass('loading');

                            // Mark as active.
                            newSlide.$slide.addClass('active');

                            // Unlock.
                            window.setTimeout(function () {
                                _.locked = false;
                            }, 100);

                            //}, 1000);
                        });

                    }, 100);

                }

                // Otherwise ...
                else {

                    window.setTimeout(function () {

                        // Mark as active.
                        newSlide.$slide.addClass('active');

                        // Unlock.
                        window.setTimeout(function () {
                            _.locked = false;
                        }, 100);

                    }, 100);

                }

            };

            // No old slide? Switch immediately.
            if (!oldSlide)
                (f)();

            // Otherwise, wait for old slide to disappear first.
            else
                window.setTimeout(f, _.settings.slideDuration);

        },

        /**
         * Switches to the next slide.
         */
        next: function () {

            // Calculate new index.
            var i, c = _.current, l = _.slides.length;

            if (c >= l - 1)
                i = 0;
            else
                i = c + 1;

            // Switch.
            _.switchTo(i);

        },

        /**
         * Switches to the previous slide.
         */
        previous: function () {

            // Calculate new index.
            var i, c = _.current, l = _.slides.length;

            if (c <= 0)
                i = l - 1;
            else
                i = c - 1;

            // Switch.
            _.switchTo(i);

        },

        /**
         * Switches to slide "above" current.
         */
        up: function () {

            // Fullscreen? Bail.
            if (_.$body.hasClass('fullscreen'))
                return;

            // Calculate new index.
            var i, c = _.current, l = _.slides.length, tpr = _.settings.thumbnailsPerRow;

            if (c <= (tpr - 1))
                i = l - (tpr - 1 - c) - 1;
            else
                i = c - tpr;

            // Switch.
            _.switchTo(i);

        },

        /**
         * Switches to slide "below" current.
         */
        down: function () {

            // Fullscreen? Bail.
            if (_.$body.hasClass('fullscreen'))
                return;

            // Calculate new index.
            var i, c = _.current, l = _.slides.length, tpr = _.settings.thumbnailsPerRow;

            if (c >= l - tpr)
                i = c - l + tpr;
            else
                i = c + tpr;

            // Switch.
            _.switchTo(i);

        },

        /**
         * Shows the main wrapper.
         */
        show: function () {

            // Already visible? Bail.
            if (!_.$body.hasClass('fullscreen'))
                return;

            // Show main wrapper.
            _.$body.removeClass('fullscreen');

            // Focus.
            _.$main.focus();

        },

        /**
         * Hides the main wrapper.
         */
        hide: function () {

            // Already hidden? Bail.
            if (_.$body.hasClass('fullscreen'))
                return;

            // Hide main wrapper.
            _.$body.addClass('fullscreen');

            // Blur.
            _.$main.blur();

        },

        /**
         * Toggles main wrapper.
         */
        toggle: function () {

            if (_.$body.hasClass('fullscreen'))
                _.show();
            else
                _.hide();

        },

    };
    return _;
})(jQuery);
main.init();