{
    // Helper vars and functions.
    const extend = function(a, b) {
        for( let key in b ) {
            if( b.hasOwnProperty( key ) ) {
                a[key] = b[key];
            }
        }
        return a;
    };

    // from http://www.quirksmode.org/js/events_properties.html#position
    const getMousePos = function(ev) {
        let posx = 0;
        let posy = 0;
        if (!ev) ev = window.event;
        if (ev.pageX || ev.pageY) 	{
            posx = ev.pageX;
            posy = ev.pageY;
        }
        else if (ev.clientX || ev.clientY) 	{
            posx = ev.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy = ev.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }
        return { x : posx, y : posy };
    };

    const TiltObj = function(el, options) {
        this.el = el;
        this.options = extend({}, this.options);
        extend(this.options, options);
        this.DOM = {};
        this.DOM.img = this.el.querySelector('.content__img');
        this.DOM.title = this.el.querySelector('.content__title');
        this._initEvents();
    }

    TiltObj.prototype.options = {
        movement: {
            img : { translation : {x: -40, y: -40} },
            title : { translation : {x: 20, y: 20} },
        }
    };

    TiltObj.prototype._initEvents = function() {
        this.mouseenterFn = (ev) => {
            anime.remove(this.DOM.img);
            anime.remove(this.DOM.title);
        };

        this.mousemoveFn = (ev) => {
            requestAnimationFrame(() => this._layout(ev));
        };

        this.mouseleaveFn = (ev) => {
            requestAnimationFrame(() => {
                anime({
                          targets: [this.DOM.img, this.DOM.title],
                          duration: 1500,
                          easing: 'easeOutElastic',
                          elasticity: 400,
                          translateX: 0,
                          translateY: 0
                      });
        });
        };

        this.el.addEventListener('mousemove', this.mousemoveFn);
        this.el.addEventListener('mouseleave', this.mouseleaveFn);
        this.el.addEventListener('mouseenter', this.mouseenterFn);
    };

    TiltObj.prototype._layout = function(ev) {
        // Mouse position relative to the document.
        const mousepos = getMousePos(ev);
        // Document scrolls.
        const docScrolls = {left : document.body.scrollLeft + document.documentElement.scrollLeft, top : document.body.scrollTop + document.documentElement.scrollTop};
        const bounds = this.el.getBoundingClientRect();
        // Mouse position relative to the main element (this.DOM.el).
        const relmousepos = { x : mousepos.x - bounds.left - docScrolls.left, y : mousepos.y - bounds.top - docScrolls.top };

        // Movement settings for the animatable elements.
        const t = {
            img: this.options.movement.img.translation,
            title: this.options.movement.title.translation,
        };

        const transforms = {
            img : {
                x: (-1*t.img.x - t.img.x)/bounds.width*relmousepos.x + t.img.x,
                y: (-1*t.img.y - t.img.y)/bounds.height*relmousepos.y + t.img.y
            },
            title : {
                x: (-1*t.title.x - t.title.x)/bounds.width*relmousepos.x + t.title.x,
                y: (-1*t.title.y - t.title.y)/bounds.height*relmousepos.y + t.title.y
            }
        };
        this.DOM.img.style.WebkitTransform = this.DOM.img.style.transform = 'translateX(' + transforms.img.x + 'px) translateY(' + transforms.img.y + 'px)';
        this.DOM.title.style.WebkitTransform = this.DOM.title.style.transform = 'translateX(' + transforms.title.x + 'px) translateY(' + transforms.title.y + 'px)';
    };

    const DOM = {};
    DOM.svg = document.querySelector('.morph');
    DOM.shapeEl = DOM.svg.querySelector('path');
    DOM.contentElems = Array.from(document.querySelectorAll('.album_animation_content-wrap'));
    DOM.contentLinks = Array.from(document.querySelectorAll('.content__link'));
    DOM.footer = document.querySelector('.album_animation_content-wrap:last-child');
    DOM.porfolioItem = document.querySelectorAll('.album_animation_content-wrap');
    const contentElemsTotal = DOM.contentElems.length;

    var color1 = DOM.svg.hasAttribute("data-color1") ? DOM.svg.getAttribute("data-color1") : '#ad8580';
    var color2 = DOM.svg.hasAttribute("data-color2") ? DOM.svg.getAttribute("data-color2") : '#FEC58E';
    var color3 = DOM.svg.hasAttribute("data-color3") ? DOM.svg.getAttribute("data-color3") : '#bfb37c';
    var color4 = DOM.svg.hasAttribute("data-color4") ? DOM.svg.getAttribute("data-color4") : '#1e71bf';
    var color5 = DOM.svg.hasAttribute("data-color5") ? DOM.svg.getAttribute("data-color5") : '#44b7a3';
    var color6 = DOM.svg.hasAttribute("data-color6") ? DOM.svg.getAttribute("data-color6") : '#4b66b3';
    let colors = [color1, color2, color3, color4, color5, color6];

    let shapes = [
        {
            path: 'M 262.9,252.2 C 210.1,338.2 212.6,487.6 288.8,553.9 372.2,626.5 511.2,517.8 620.3,536.3 750.6,558.4 860.3,723 987.3,686.5 1089,657.3 1168,534.7 1173,429.2 1178,313.7 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            pathAlt: 'M 262.9,252.2 C 210.1,338.2 273.3,400.5 298.5,520 323.7,639.6 511.2,537.2 620.3,555.7 750.6,577.8 872.2,707.4 987.3,686.5 1102,665.6 1218,547.8 1173,429.2 1128,310.6 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            scaleX: 1.3,
            scaleY: 1.8,
            rotate: 70,
            tx: 0,
            ty: -100,
            fill: {
                color: colors[1],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                },
                svg: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                }
            }
        },
        {
            path: 'M 415.6,206.3 C 407.4,286.6 438.1,373.6 496.2,454.8 554.3,536.1 497,597.2 579.7,685.7 662.4,774.1 834.3,731.7 898.5,653.4 962.3,575 967.1,486 937.7,370 909.3,253.9 937.7,201.5 833.4,105.4 729.3,9.338 602.2,13.73 530.6,41.91 459,70.08 423.9,126.1 415.6,206.3 Z',
            pathAlt: 'M 415.6,206.3 C 407.4,286.6 415.5,381.7 473.6,462.9 531.7,544.2 482.5,637.6 579.7,685.7 676.9,733.8 826.2,710.7 890.4,632.4 954.2,554 926.8,487.6 937.7,370 948.6,252.4 937.7,201.5 833.4,105.4 729.3,9.338 602.2,13.73 530.6,41.91 459,70.08 423.9,126.1 415.6,206.3 Z',
            scaleX: 1.9,
            scaleY: 1,
            rotate: 0,
            tx: 0,
            ty: 100,
            fill: {
                color: colors[2],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                },
                svg: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                }
            }
        },
        {
            path: 'M 383.8,163.4 C 335.8,352.3 591.6,317.1 608.7,420.8 625.8,524.5 580.5,626 647.3,688 714,750 837.1,760.5 940.9,661.5 1044,562.3 1041,455.8 975.8,393.6 909.8,331.5 854.2,365.4 784.4,328.1 714.6,290.8 771.9,245.2 733.1,132.4 694.2,19.52 431.9,-25.48 383.8,163.4 Z',
            pathAlt: 'M 383.8,163.4 C 345.5,324.9 591.6,317.1 608.7,420.8 625.8,524.5 595.1,597 647.3,688 699.5,779 837.1,760.5 940.9,661.5 1044,562.3 1068,444.4 975.8,393.6 884,342.8 854.2,365.4 784.4,328.1 714.6,290.8 820.3,237.2 733.1,132.4 645.9,27.62 422.1,1.919 383.8,163.4 Z',
            scaleX: 1.9,
            scaleY: 1.1,
            rotate: 40,
            tx: -100,
            ty: 200,
            fill: {
                color: colors[3],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                },
                svg: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                }
            }
        },
        {
            path: 'M 262.9,252.2 C 210.1,338.2 212.6,487.6 288.8,553.9 372.2,626.5 511.2,517.8 620.3,536.3 750.6,558.4 860.3,723 987.3,686.5 1089,657.3 1168,534.7 1173,429.2 1178,313.7 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            pathAlt: 'M 262.9,252.2 C 210.1,338.2 273.3,400.5 298.5,520 323.7,639.6 511.2,537.2 620.3,555.7 750.6,577.8 872.2,707.4 987.3,686.5 1102,665.6 1218,547.8 1173,429.2 1128,310.6 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            scaleX: 1.5,
            scaleY: 2,
            rotate: -20,
            tx: 0,
            ty: -50,
            fill: {
                color: colors[4],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                },
                svg: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                }
            }
        },
        {
            path: 'M 262.9,252.2 C 210.1,338.2 212.6,487.6 288.8,553.9 372.2,626.5 511.2,517.8 620.3,536.3 750.6,558.4 860.3,723 987.3,686.5 1089,657.3 1168,534.7 1173,429.2 1178,313.7 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            pathAlt: 'M 262.9,252.2 C 210.1,338.2 273.3,400.5 298.5,520 323.7,639.6 511.2,537.2 620.3,555.7 750.6,577.8 872.2,707.4 987.3,686.5 1102,665.6 1218,547.8 1173,429.2 1128,310.6 1096,189.1 995.1,130.7 852.1,47.07 658.8,78.95 498.1,119.2 410.7,141.1 322.6,154.8 262.9,252.2 Z',
            scaleX: 1.3,
            scaleY: 1,
            rotate: -70,
            tx: 0,
            ty: 150,
            fill: {
                color: colors[5],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                },
                svg: {
                    duration: 1000,
                    easing: 'easeInOutQuad'
                }
            }
        },
        {
            path: 'M 415.6,206.3 C 407.4,286.6 438.1,373.6 496.2,454.8 554.3,536.1 497,597.2 579.7,685.7 662.4,774.1 834.3,731.7 898.5,653.4 962.3,575 967.1,486 937.7,370 909.3,253.9 937.7,201.5 833.4,105.4 729.3,9.338 602.2,13.73 530.6,41.91 459,70.08 423.9,126.1 415.6,206.3 Z',
            pathAlt: 'M 415.6,206.3 C 407.4,286.6 415.5,381.7 473.6,462.9 531.7,544.2 482.5,637.6 579.7,685.7 676.9,733.8 826.2,710.7 890.4,632.4 954.2,554 926.8,487.6 937.7,370 948.6,252.4 937.7,201.5 833.4,105.4 729.3,9.338 602.2,13.73 530.6,41.91 459,70.08 423.9,126.1 415.6,206.3 Z',
            scaleX: 2,
            scaleY: 1,
            rotate: 0,
            tx: 0,
            ty: 100,
            fill: {
                color: colors[6],
                duration: 500,
                easing: 'linear'
            },
            animation: {
                path: {
                    duration: 2000,
                    easing: 'easeOutElastic',
                    elasticity: 400
                },
                svg: {
                    duration: 2000,
                    easing: 'easeOutQuad'
                }
            }
        }
    ];
    let step,
        colorsLength = colors.length;

    if(DOM.porfolioItem.length) {
        for (let i = 0; i < DOM.porfolioItem.length - colorsLength + 1; i++) {
            colors.push(colors[i]);
            shapes.push(shapes[i]);
        }
    }

    const initShapeLoop = function(pos) {
        pos = pos || 0;
        anime.remove(DOM.shapeEl);
        anime({
            targets: DOM.shapeEl,
            easing: 'linear',
            d: [{value: shapes[pos].pathAlt, duration:1500}, {value: shapes[pos].path, duration:1500}],
            loop: true,
            fill: {
                value: shapes[pos].fill.color,
                duration: shapes[pos].fill.duration,
                easing: shapes[pos].fill.easing
            },
            direction: 'alternate'
        });
    };

    const initShapeEl = function() {
        anime.remove(DOM.svg);
        anime({
            targets: DOM.svg,
            duration: 1,
            easing: 'linear',
            scaleX: shapes[0].scaleX,
            scaleY: shapes[0].scaleY,
            translateX: shapes[0].tx+'px',
            translateY: shapes[0].ty+'px',
            rotate: shapes[0].rotate+'deg'
        });

        initShapeLoop();
    };

    const createScrollWatchers = function() {
        DOM.contentElems.forEach((el,pos) => {
            const scrollElemToWatch = pos ? DOM.contentElems[pos] : DOM.footer;
        pos = pos ? pos : contentElemsTotal;
        const watcher = scrollMonitor.create(scrollElemToWatch,-350);

        watcher.enterViewport(function() {
            step = pos;

            anime.remove(DOM.shapeEl);
            anime({
                targets: DOM.shapeEl,
                duration: shapes[pos].animation.path.duration,
                easing: shapes[pos].animation.path.easing,
                elasticity: shapes[pos].animation.path.elasticity || 0,
                d: shapes[pos].path,
                fill: {
                    value: shapes[pos].fill.color,
                    duration: shapes[pos].fill.duration,
                    easing: shapes[pos].fill.easing
                },
                complete: function() {
                    initShapeLoop(pos);
                }
            });

            anime.remove(DOM.svg);
            anime({
                targets: DOM.svg,
                duration: shapes[pos].animation.svg.duration,
                easing: shapes[pos].animation.svg.easing,
                elasticity: shapes[pos].animation.svg.elasticity || 0,
                scaleX: shapes[pos].scaleX,
                scaleY: shapes[pos].scaleY,
                translateX: shapes[pos].tx+'px',
                translateY: shapes[pos].ty+'px',
                rotate: shapes[pos].rotate+'deg'
            });
        });

        watcher.exitViewport(function() {
            const idx = !watcher.isAboveViewport ? pos-1 : pos+1;

            if( idx <= contentElemsTotal && step !== idx ) {
                step = idx;
                anime.remove(DOM.shapeEl);
                anime({
                    targets: DOM.shapeEl,
                    duration: shapes[idx].animation.path.duration,
                    easing: shapes[idx].animation.path.easing,
                    elasticity: shapes[idx].animation.path.elasticity || 0,
                    d: shapes[idx].path,
                    fill: {
                        value: shapes[idx].fill.color,
                        duration: shapes[idx].fill.duration,
                        easing: shapes[idx].fill.easing
                    },
                    complete: function() {
                        initShapeLoop(idx);
                    }
                });

                anime.remove(DOM.svg);
                anime({
                    targets: DOM.svg,
                    duration: shapes[idx].animation.svg.duration,
                    easing: shapes[idx].animation.svg.easing,
                    elasticity: shapes[idx].animation.svg.elasticity || 0,
                    scaleX: shapes[idx].scaleX,
                    scaleY: shapes[idx].scaleY,
                    translateX: shapes[idx].tx+'px',
                    translateY: shapes[idx].ty+'px',
                    rotate: shapes[idx].rotate+'deg'
                });
            }
        });
    });
    };

    const init = function() {
        imagesLoaded(document.body, () => {
            initShapeEl();
            createScrollWatchers();
            Array.from(document.querySelectorAll('.content--layout')).forEach(el => new TiltObj(el));
        });
    }

    init();
};


;(function ($, window, document, undefined) {
    'use strict';
    $(window).on('load resize', function () {
        if ($('.main-album-anim-wrap').length && $('#footer').hasClass('fix-bottom')) {
            var footerHeight = $('#footer').outerHeight();
            $('.main-album-anim-wrap').css('padding-bottom', footerHeight + 'px');
        }
    });
})(jQuery, window, document);