(function () {

  window.CanvasSlideshow = function (options) {
    var hasCanvas = false;

    //  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 : [10, 3];
    options.origImages           = options.hasOwnProperty('origImages') ? options.origImages : {};
    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] : [10, 3];
    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;
    /**
     * 移除canvas
     */
    this.removeCanvas = function () {
      let indexCanvas =  document.getElementById("indexCanvas");
      let parentDiv = document.getElementById("index-body");
      if(indexCanvas && parentDiv){
        indexCanvas.height=0;
        renderer.view.clearRect(0,0,renderer.view.style.width  ,renderer.view.style.height);
        renderer.view = null;
        parentDiv.removeChild(indexCanvas);
        // document.body.removeChild(indexCanvas);

      }
    };
    /// ---------------------------
    //  INITIALISE PIXI
    /// ---------------------------
    this.initPixi = function () {
      let indexCanvas =  document.getElementById("indexCanvas");
      let parentDiv = document.getElementById("index-body");
      if(indexCanvas && parentDiv){
        // document.body.removeChild(indexCanvas);
        parentDiv.removeChild(document.getElementById("indexCanvas"));
      }
      // Add canvas to the HTML
      parentDiv.appendChild(renderer.view);
      // document.body.appendChild(renderer.view);
      renderer.view.setAttribute("id","indexCanvas");
      hasCanvas = true;
      // Add child container to the main container
      stage.addChild(slidesContainer);
      // Enable Interactions
      stage.interactive = true;
      console.log(renderer.view.style);

      // Fit renderer to the screen
      if (options.fullScreen === true) {
        renderer.view.style.objectFit       = 'cover';
        renderer.view.style.width           = '92%';
        renderer.view.style.height          = 'calc(100% - 64px - 50px)';
        renderer.view.style.top             = '64px';
        renderer.view.style.left            = '4%';
        renderer.view.style.position        = 'absolute';
        renderer.view.style.webkitTransform = 'translate( 0%, 0% ) scale(1)';
        renderer.view.style.transform       = 'translate( 0%, 0% ) scale(1)';
        renderer.view.style.zIndex="0";

      } 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;
      }
      const ratioHeight = window.screen.height/754;
      const ratioWidth = window.screen.width/1100;
      let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth;
      console.log("ratio:"+ratio);
      displacementSprite.scale.x = ratio;
      displacementSprite.scale.y = ratio;

      displacementSprite.scale.x = 1.2;
      displacementSprite.scale.y = 1.2;

      // displacementSprite.position.x = 400;
      // displacementSprite.position.y = 400;

      // PIXI tries to fit the filter bounding box to the renderer so we optionally bypass
      displacementFilter.autoFit = options.displaceAutoFit;
      stage.addChild(displacementSprite);
    };

    var imageList=[];

    /// ---------------------------
    //  LOAD SLIDES TO CANVAS
    /// ---------------------------
    this.loadPixiSprites = function (sprites) {
      imageList = [];
      var rSprites = options.sprites;
      var rTexts   = options.texts;
      var origImages = options.origImages;

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

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

        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) {
          const ratioHeight = window.screen.height/1691;
          const ratioWidth = window.screen.width/1256;
          let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth;
          image.width = renderer.width ;
          image.height = renderer.height;
          // image.scale.x = ratio;
          // image.scale.y = ratio;
         /* scaleX = renderer.width/origImages.get(sprites[i]).width;
          scaleY = renderer.height/origImages.get(sprites[i]).height;
          console.log(scaleX + "|" + scaleY);
          image.scale.x = scaleX;
          image.scale.y = scaleY;*/
          image.position.x = renderer.width / 2;
          image.position.y = renderer.height / 2;
          image.anchor.set(0.5);

          // image.x = renderer.width / 2;
          // image.y = renderer.height / 2;
        }
        if (i !== 0) {
          TweenMax.set(image, { alpha: 0 });
        }
        imageList.push(image);
        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() * 10;
            displacementSprite.scale.set(baseTimeline.progress() * 3);
          }
        }
      });
      var baseTimelineFrom = new TimelineMax({
        onComplete:  function () {
        }, onUpdate: function () {
          if (options.wacky === true) {
            displacementSprite.rotation += baseTimeline.progress() * 10;
            displacementSprite.scale.set(baseTimeline.progress() * 3);
          }
        }
      });
      baseTimelineFrom.clear();
      baseTimeline.clear();

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

      baseTimelineFrom
      // .to(displacementFilter.scale, 1, { x: options.displaceScale[0], y: options.displaceScale[1] })
      .to(slideImages[that.currentIndex], 1.5, { alpha: 0 });
      baseTimeline
      // .to(displacementFilter.scale, 1, {
      //   x: options.displaceScaleTo[0],
      //   y: options.displaceScaleTo[1]
      // })
      .to(slideImages[newIndex], 1.5, { alpha: 1 });

    };


    /// ---------------------------
    //  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 );
          // that.loadPixiSprites(options.pixiSprites);
          // console.log("http://localhost:8080/#/index");
          // console.log("renderer.width:"+renderer.width);
          // console.log("renderer.height："+renderer.height);
          for(let idx in imageList){
            /*let itemImg = imageList[idx];
            itemImg.width = renderer.width ;
            itemImg.height = renderer.height;
            const ratio = window.screen.height/754;
            itemImg.scale.x = ratio;
            itemImg.scale.y = ratio;
            itemImg.position.x = renderer.width / 2;
            itemImg.position.y = renderer.height / 2;*/
          }
        });
        // 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 + ''
          });
        };

        slidesContainer.pointerout = 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);
          }

        };

      }

    }

    /// ---------------------------
    //  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


  };

})();
