(function() {

    window.CanvasSlideshow = function( options ) {



        //  SCOPE
        /// ---------------------------
        var that  =   this;



        //  OPTIONS
        /// ---------------------------
        options                     = options || {};
        options.stageWidth          = options.hasOwnProperty('stageWidth') ? options.stageWidth : 1920;
        options.stageHeight         = options.hasOwnProperty('stageHeight') ? options.stageHeight : 1080;
        options.pixiSprites         = options.hasOwnProperty('sprites') ? options.sprites : [];
        options.centerSprites       = options.hasOwnProperty('centerSprites') ? options.centerSprites : false;
        options.texts               = options.hasOwnProperty('texts') ? options.texts : [];
        options.autoPlay            = options.hasOwnProperty('autoPlay') ? options.autoPlay : true;
        options.autoPlaySpeed       = options.hasOwnProperty('autoPlaySpeed') ? options.autoPlaySpeed : [10, 3];
        options.fullScreen          = options.hasOwnProperty('fullScreen') ? options.fullScreen : true;
        options.displaceScale       = options.hasOwnProperty('displaceScale') ? options.displaceScale : [200, 70];
        options.displacementImage   = options.hasOwnProperty('displacementImage') ? options.displacementImage : '';
        options.navElement          = options.hasOwnProperty('navElement')  ?  options.navElement : document.querySelectorAll( '.scene-nav' );
        options.displaceAutoFit     = options.hasOwnProperty('displaceAutoFit')  ?  options.displaceAutoFit : false;
        options.wacky               = options.hasOwnProperty('wacky') ? options.wacky : false;
        options.interactive         = options.hasOwnProperty('interactive') ? options.interactive : false;
        options.interactionEvent    = options.hasOwnProperty('interactionEvent') ? options.interactionEvent : '';
        options.displaceScaleTo     = ( options.autoPlay === false ) ? [ 0, 0 ] : [ 20, 20 ];
        options.textColor           = options.hasOwnProperty('textColor') ? options.textColor : '#fff';
        options.displacementCenter  = options.hasOwnProperty('displacementCenter') ? options.displacementCenter : false;
        options.dispatchPointerOver = options.hasOwnProperty('dispatchPointerOver') ? options.dispatchPointerOver : false;



        //  PIXI VARIABLES
        /// ---------------------------
        var renderer            = new PIXI.autoDetectRenderer( options.stageWidth, options.stageHeight, { transparent: true });
        var stage               = new PIXI.Container();
        var slidesContainer     = new PIXI.Container();
        var displacementSprite  = new PIXI.Sprite.fromImage( options.displacementImage );
        var displacementFilter  = new PIXI.filters.DisplacementFilter( displacementSprite );



        //  TEXTS
        /// ---------------------------
        var style = new PIXI.TextStyle({
            fill: options.textColor,
            wordWrap: true,
            wordWrapWidth: 400,
            letterSpacing: 20,
            fontSize: 14
        });



        //  SLIDES ARRAY INDEX
        /// ---------------------------
        this.currentIndex = 0;



        /// ---------------------------
        //  INITIALISE PIXI
        /// ---------------------------
        this.initPixi = function() {

            // Add canvas to the HTML
            document.body.appendChild( renderer.view );


            // Add child container to the main container
            stage.addChild( slidesContainer );


            // Enable Interactions
            stage.interactive = true;


            // Fit renderer to the screen
            if ( options.fullScreen === true ) {
                renderer.view.style.objectFit = 'cover';
                renderer.view.style.width     = '100%';
                renderer.view.style.height    = '100%';
                renderer.view.style.top       = '50%';
                renderer.view.style.left      = '50%';
                renderer.view.style.webkitTransform = 'translate( -50%, -50% ) scale(1.2)';
                renderer.view.style.transform = 'translate( -50%, -50% ) scale(1.2)';
            } else {
                renderer.view.style.maxWidth  = '100%';
                renderer.view.style.top       = '50%';
                renderer.view.style.left      = '50%';
                renderer.view.style.webkitTransform = 'translate( -50%, -50% )';
                renderer.view.style.transform = 'translate( -50%, -50% )';
            }


            displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;


            // Set the filter to stage and set some default values for the animation
            stage.filters = [displacementFilter];

            if ( options.autoPlay === false ) {
                displacementFilter.scale.x = 0;
                displacementFilter.scale.y = 0;
            }

            if ( options.wacky === true ) {

                displacementSprite.anchor.set(0.5);
                displacementSprite.x = renderer.width / 2;
                displacementSprite.y = renderer.height / 2;
            }

            displacementSprite.scale.x = 2;
            displacementSprite.scale.y = 2;

            // PIXI tries to fit the filter bounding box to the renderer so we optionally bypass
            displacementFilter.autoFit = options.displaceAutoFit;

            stage.addChild( displacementSprite );

        };



        /// ---------------------------
        //  LOAD SLIDES TO CANVAS
        /// ---------------------------
        this.loadPixiSprites = function( sprites ) {


            var rSprites = options.sprites;
            var rTexts   = options.texts;

            for ( var i = 0; i < rSprites.length; i++ ) {

                var texture   = new PIXI.Texture.fromImage( sprites[i] );
                var image     = new PIXI.Sprite( texture );

                if ( rTexts ) {
                    var richText = new PIXI.Text( rTexts[i], style);
                    image.addChild(richText);

                    richText.anchor.set(0.5);
                    richText.x = image.width / 2;
                    richText.y = image.height / 2;
                }

                if ( options.centerSprites === true ) {
                    image.anchor.set(0.5);
                    image.x = renderer.width / 2;
                    image.y = renderer.height / 2;
                }
                // image.transform.scale.x = 1.3;
                // image.transform.scale.y = 1.3;



                if ( i !== 0  ) {
                    TweenMax.set( image, { alpha: 0 } );
                }

                slidesContainer.addChild( image );

            }

        };



        /// ---------------------------
        //  DEFAULT RENDER/ANIMATION
        /// ---------------------------
        if ( options.autoPlay === true ) {

            var ticker = new PIXI.ticker.Ticker();

            ticker.autoStart = options.autoPlay;

            ticker.add(function( delta ) {

                displacementSprite.x += options.autoPlaySpeed[0] * delta;
                displacementSprite.y += options.autoPlaySpeed[1];

                renderer.render( stage );

            });

        }  else {

            var render = new PIXI.ticker.Ticker();

            render.autoStart = true;

            render.add(function( delta ) {
                renderer.render( stage );
            });

        }


        /// ---------------------------
        //  TRANSITION BETWEEN SLIDES
        /// ---------------------------
        var isPlaying   = false;
        var slideImages = slidesContainer.children;
        this.moveSlider = function( newIndex ) {

            isPlaying = true;


            var baseTimeline = new TimelineMax( { onComplete: function () {
                that.currentIndex = newIndex;
                isPlaying = false;
                if ( options.wacky === true ) {
                    displacementSprite.scale.set( 1 );
                }
            },onUpdate: function() {

                if ( options.wacky === true ) {
                    displacementSprite.rotation += baseTimeline.progress() * 0.02;
                    displacementSprite.scale.set( baseTimeline.progress() * 3 );
                }

            } });

            baseTimeline.clear();

            if ( baseTimeline.isActive() ) {
                return;
            }

            // DEMO 4
            baseTimeline
                .to(displacementFilter.scale, 0.8, { x: options.displaceScale[0], y: options.displaceScale[1], ease: Power2.easeIn  })
                .to(slideImages[that.currentIndex], 0.5, { alpha: 0, ease: Power2.easeOut }, 0.4)
                .to(slideImages[newIndex], 0.8, { alpha: 1, ease: Power2.easeOut }, 1)
                .to(displacementFilter.scale, 0.7, { x: options.displaceScaleTo[0], y: options.displaceScaleTo[1], ease: Power1.easeOut }, 0.9 );

        };



        /// ---------------------------
        //  CLICK HANDLERS
        /// ---------------------------
        var nav = options.navElement;

        for ( var i = 0; i < nav.length; i++ ) {

            var navItem = nav[i];

            navItem.onclick = function( event ) {

                // Make sure the previous transition has ended
                if ( isPlaying ) {
                    return false;
                }

                if ( this.getAttribute('data-nav') === 'next' ) {

                    if ( that.currentIndex >= 0 && that.currentIndex < slideImages.length - 1 ) {
                        that.moveSlider( that.currentIndex + 1 );
                    } else {
                        that.moveSlider( 0 );
                    }

                } else {

                    if ( that.currentIndex > 0 && that.currentIndex < slideImages.length ) {
                        that.moveSlider( that.currentIndex - 1 );
                    } else {
                        that.moveSlider( spriteImages.length - 1 );
                    }

                }

                return false;

            }

        }



        /// ---------------------------
        //  INIT FUNCTIONS
        /// ---------------------------

        this.init = function() {


            that.initPixi();
            that.loadPixiSprites( options.pixiSprites );

            /*
            if ( options.fullScreen === true ) {
              window.addEventListener("resize", function( event ){
                scaleToWindow( renderer.view );
              });
              scaleToWindow( renderer.view );
            }
            */


        };




        /// ---------------------------
        //  INTERACTIONS
        /// ---------------------------
        function rotateSpite() {
            displacementSprite.rotation += 0.001;
            rafID = requestAnimationFrame( rotateSpite );
        }

        if ( options.interactive === true ) {

            var rafID, mouseX, mouseY;

            // Enable interactions on our slider
            slidesContainer.interactive = true;
            slidesContainer.buttonMode  = true;

            // HOVER
            if ( options.interactionEvent === 'hover' || options.interactionEvent === 'both'  )  {

                slidesContainer.pointerover = function( mouseData ){
                    mouseX = mouseData.data.global.x;
                    mouseY = mouseData.data.global.y;
                    TweenMax.to( displacementFilter.scale, 1, { x: "+=" + Math.sin( mouseX ) * 100 + "", y: "+=" + Math.cos( mouseY ) * 100 + ""  });
                    rotateSpite();
                };

                slidesContainer.pointerout = function( mouseData ){
                    TweenMax.to( displacementFilter.scale, 1, { x: 0, y: 0 });
                    cancelAnimationFrame( rafID );
                };

            }

            // CLICK
            if ( options.interactionEvent === 'click' || options.interactionEvent === 'both'  ) {

                slidesContainer.pointerup = function( mouseData ){
                    if ( options.dispatchPointerOver === true ) {
                        TweenMax.to( displacementFilter.scale, 1, { x: 0, y: 0, onComplete: function() {
                            TweenMax.to( displacementFilter.scale, 1, { x: 20, y: 20  });
                        } });
                    } else {
                        TweenMax.to( displacementFilter.scale, 1, { x: 0, y: 0 });
                        cancelAnimationFrame( rafID );
                    }

                };

                slidesContainer.pointerdown = function( mouseData ){
                    mouseX = mouseData.data.global.x;
                    mouseY = mouseData.data.global.y;
                    TweenMax.to( displacementFilter.scale, 1, { x: "+=" + Math.sin( mouseX ) * 1200 + "", y: "+=" + Math.cos( mouseY ) * 200 + ""  });
                };

            }

        }


        /// ---------------------------
        //  CENTER DISPLACEMENT
        /// ---------------------------
        if ( options.displacementCenter === true ) {
            displacementSprite.anchor.set(0.5);
            displacementSprite.x = renderer.view.width / 2;
            displacementSprite.y = renderer.view.height / 2;
        }


        /// ---------------------------
        //  START
        /// ---------------------------
        this.init();


        /// ---------------------------
        //  HELPER FUNCTIONS
        /// ---------------------------
        function scaleToWindow( canvas, backgroundColor ) {
            var scaleX, scaleY, scale, center;

            //1. Scale the canvas to the correct size
            //Figure out the scale amount on each axis
            scaleX = window.innerWidth / canvas.offsetWidth;
            scaleY = window.innerHeight / canvas.offsetHeight;

            //Scale the canvas based on whichever value is less: `scaleX` or `scaleY`
            scale = Math.min(scaleX, scaleY);
            canvas.style.transformOrigin = "0 0";
            canvas.style.transform = "scale(" + scale + ")";

            //2. Center the canvas.
            //Decide whether to center the canvas vertically or horizontally.
            //Wide canvases should be centered vertically, and
            //square or tall canvases should be centered horizontally
            if (canvas.offsetWidth > canvas.offsetHeight) {
                if (canvas.offsetWidth * scale < window.innerWidth) {
                    center = "horizontally";
                } else {
                    center = "vertically";
                }
            } else {
                if (canvas.offsetHeight * scale < window.innerHeight) {
                    center = "vertically";
                } else {
                    center = "horizontally";
                }
            }

            //Center horizontally (for square or tall canvases)
            var margin;
            if (center === "horizontally") {
                margin = (window.innerWidth - canvas.offsetWidth * scale) / 2;
                canvas.style.marginTop = 0 + "px";
                canvas.style.marginBottom = 0 + "px";
                canvas.style.marginLeft = margin + "px";
                canvas.style.marginRight = margin + "px";
            }

            //Center vertically (for wide canvases)
            if (center === "vertically") {
                margin = (window.innerHeight - canvas.offsetHeight * scale) / 2;
                canvas.style.marginTop = margin + "px";
                canvas.style.marginBottom = margin + "px";
                canvas.style.marginLeft = 0 + "px";
                canvas.style.marginRight = 0 + "px";
            }

            //3. Remove any padding from the canvas  and body and set the canvas
            //display style to "block"
            canvas.style.paddingLeft = 0 + "px";
            canvas.style.paddingRight = 0 + "px";
            canvas.style.paddingTop = 0 + "px";
            canvas.style.paddingBottom = 0 + "px";
            canvas.style.display = "block";

            //4. Set the color of the HTML body background
            document.body.style.backgroundColor = backgroundColor;

            //Fix some quirkiness in scaling for Safari
            var ua = navigator.userAgent.toLowerCase();
            if (ua.indexOf("safari") != -1) {
                if (ua.indexOf("chrome") > -1) {
                    // Chrome
                } else {
                    // Safari
                    //canvas.style.maxHeight = "100%";
                    //canvas.style.minHeight = "100%";
                }
            }

            //5. Return the `scale` value. This is important, because you'll nee this value
            //for correct hit testing between the pointer and sprites
            return scale;
        } // http://bit.ly/2y1Yk2k


    };

    var spriteImages = document.querySelectorAll( '.slide-item__image' );
    var spriteImagesSrc = [];
    var texts = [];

    for ( var i = 0; i < spriteImages.length; i++ ) {
        var img = spriteImages[i];
        // Set the texts you want to display to each slide
        // in a sibling element of your image and edit accordingly
        if ( img.nextElementSibling ) {
            texts.push(img.nextElementSibling.innerHTML);
        } else {
            texts.push('');
        }
        spriteImagesSrc.push( img.getAttribute('src' ) );
    }
    var imageT = document.querySelector('.disortion-wrap').getAttribute('data-image');
    var initCanvasSlideshow = new CanvasSlideshow({
        sprites: spriteImagesSrc,
        displacementImage: imageT,
        autoPlay: true,
        autoPlaySpeed: [4, 3],
        displaceScale: [5000, 10000],
        interactive: true,
        centerSprites: true,
        interactionEvent: 'click', // 'click', 'hover', 'both'
        displaceAutoFit: false,
        dispatchPointerOver: true // restarts pointerover event after click
    });
})();