(function() {
  var SOURCES = window.TEXT_VARIABLES.sources;
  window.Lazyload.js(SOURCES.jquery, function() {
    function swiper(options) {
      var $window = $(window), $root = this, $swiperWrapper, $swiperSlides, $swiperButtonPrev, $swiperButtonNext,
        initialSlide, animation, onChange, onChangeEnd,
        rootWidth, count, preIndex, curIndex, translateX, CRITICAL_ANGLE = Math.PI / 3;

      function setOptions(options) {
        var _options = options || {};
        initialSlide = _options.initialSlide || 0;
        animation = _options.animation === undefined && true;
        onChange = onChange || _options.onChange;
        onChangeEnd = onChangeEnd || _options.onChangeEnd;
      }

      function init() {
        $swiperWrapper = $root.find('.swiper__wrapper');
        $swiperSlides = $root.find('.swiper__slide');
        $swiperButtonPrev = $root.find('.swiper__button--prev');
        $swiperButtonNext = $root.find('.swiper__button--next');
        animation && $swiperWrapper.addClass('swiper__wrapper--animation');
        calc(true);
      }

      function preCalc() {
        rootWidth = $root.width();
        count = $swiperWrapper.children('.swiper__slide').length;
        if (count < 2) {
          $swiperButtonPrev.addClass('d-none');
          $swiperButtonNext.addClass('d-none');
        }
        curIndex = initialSlide || 0;
        translateX = getTranslateXFromCurIndex();
      }

      var calc = (function() {
        var preAnimation, $swiperSlide, $preSwiperSlide;
        return function (needPreCalc, params) {
          needPreCalc && preCalc();
          var _animation = (params && params.animation !== undefined) ? params.animation : animation;
          if (preAnimation === undefined || preAnimation !== _animation) {
            preAnimation = _animation ? $swiperWrapper.addClass('swiper__wrapper--animation') :
              $swiperWrapper.removeClass('swiper__wrapper--animation');
          }
          if (preIndex !== curIndex) {
            ($preSwiperSlide = $swiperSlides.eq(preIndex)).removeClass('active');
            ($swiperSlide = $swiperSlides.eq(curIndex)).addClass('active');
            onChange && onChange(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
            if (onChangeEnd) {
              if (_animation) {
                setTimeout(function() {
                  onChangeEnd(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
                }, 400);
              } else {
                onChangeEnd(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
              }
            }
            preIndex = curIndex;
          }
          $swiperWrapper.css('transform', 'translate(' + translateX + 'px, 0)');
          if (count > 1) {
            if (curIndex <= 0) {
              $swiperButtonPrev.addClass('disabled');
            } else {
              $swiperButtonPrev.removeClass('disabled');
            }
            if (curIndex >= count - 1) {
              $swiperButtonNext.addClass('disabled');
            } else {
              $swiperButtonNext.removeClass('disabled');
            }
          }
        };
      })();

      function getTranslateXFromCurIndex() {
        return curIndex <= 0 ? 0 : - rootWidth * curIndex;
      }

      function moveToIndex(index ,params) {
        preIndex = curIndex;
        curIndex = index;
        translateX = getTranslateXFromCurIndex();
        calc(false, params);
      }

      function move(type) {
        var nextIndex = curIndex, unstableTranslateX;
        if (type === 'prev') {
          nextIndex > 0 && nextIndex--;
        } else if (type === 'next') {
          nextIndex < count - 1 && nextIndex++;
        }
        if (type === 'cur') {
          moveToIndex(curIndex, { animation: true });
          return;
        }
        unstableTranslateX = translateX % rootWidth !== 0;
        if (nextIndex !== curIndex || unstableTranslateX) {
          unstableTranslateX ? moveToIndex(nextIndex, { animation: true }) : moveToIndex(nextIndex);
        }
      }

      setOptions(options);
      init();
      preIndex = curIndex;

      $swiperButtonPrev.on('click', function(e) {
        e.stopPropagation();
        move('prev');
      });
      $swiperButtonNext.on('click', function(e) {
        e.stopPropagation();
        move('next');
      });
      $window.on('resize', function() {
        calc(true, { animation: false });
      });

      (function() {
        var pageX, pageY, velocityX, preTranslateX = translateX, timeStamp, touching;
        function handleTouchstart(e) {
          var point = e.touches ? e.touches[0] : e;
          pageX = point.pageX;
          pageY = point.pageY;
          velocityX = 0;
          preTranslateX = translateX;
        }
        function handleTouchmove(e) {
          if (e.touches && e.touches.length > 1) {
            return;
          }
          var point = e.touches ? e.touches[0] : e;
          var deltaX = point.pageX - pageX;
          var deltaY = point.pageY - pageY;
          velocityX = deltaX / (e.timeStamp - timeStamp);
          timeStamp = e.timeStamp;
          if (e.cancelable && Math.abs(Math.atan(deltaY / deltaX)) < CRITICAL_ANGLE) {
            touching = true;
            translateX += deltaX;
            calc(false, { animation: false });
          }
          pageX = point.pageX;
          pageY = point.pageY;
        }
        function handleTouchend() {
          touching = false;
          var deltaX = translateX - preTranslateX;
          var distance = deltaX + velocityX * rootWidth;
          if (Math.abs(distance) > rootWidth / 2) {
            distance > 0 ? move('prev') : move('next');
          } else {
            move('cur');
          }
        }
        $swiperWrapper.on('touchstart', handleTouchstart);
        $swiperWrapper.on('touchmove', handleTouchmove);
        $swiperWrapper.on('touchend', handleTouchend);
        $swiperWrapper.on('touchcancel', handleTouchend);

        (function() {
          var pressing = false, moved = false;
          $swiperWrapper.on('mousedown', function(e) {
            pressing = true; handleTouchstart(e);
          });
          $swiperWrapper.on('mousemove', function(e) {
            pressing && (e.preventDefault(), moved = true, handleTouchmove(e));
          });
          $swiperWrapper.on('mouseup', function(e) {
            pressing && (pressing = false, handleTouchend(e));
          });
          $swiperWrapper.on('mouseleave', function(e) {
            pressing && (pressing = false, handleTouchend(e));
          });
          $swiperWrapper.on('click', function(e) {
            moved && (e.stopPropagation(), moved = false);
          });
        })();

        $root.on('touchmove', function(e) {
          if (e.cancelable & touching) {
            e.preventDefault();
          }
        });
      })();

      return {
        setOptions: setOptions,
        previous: function(){
          move('prev');
        },
        next: function(){
          move('next');
        },
        refresh: function() {
          calc(true, { animation: false });
        }
      };
    }
    $.fn.swiper = swiper;
  });
})();
