/**
 * me 滚动条模块
 * @author wzs
 */

var $win = $(window),
  $body = $('body'),
  $container = $('body'),
  isMobi = window.isMobi = (function() {
    var winW = $win.width();
    var threshold = 720;
    var onResize = function() {
      winW = $win.width();
      if (winW <= threshold) {
        $container.removeAttr('style');
      } else {
        $container.height($win.height() - 70 - 15 - 20 * 2);
      }
    };
    onResize();
    $win.on('resize', onResize);
    return function() {
      return winW <= threshold;
    };
  })();;
(function(win, $) {

  'use strict';

  //定时检测内容高度作为补充
  var list = [];
  setInterval(function() {
    for (var i = 0, item; item = list[i]; i++) {
      item.checkHeightWidth();
    }
  }, 1000);

  /**
   * 页面滚动
   * @param {Element} _this
   * @constructor
   */
  var Scroller = function(_this) {
    this.$e = {
      container: $(_this), //主容器
      inner: null, //正文内容
      barY: null, //垂直滚动条外层
      boxY: null, //垂直滚动条
      sliderY: null, //垂直滑块
      barX: null, //水平滚动条外层
      boxX: null, //水平滚动条
      sliderX: null //水平滑块
    };
    this._data = {
      xRolling: this.$e.container.attr('data-x-rolling') == 'true',
      maxTop: 0, //最大top值
      barH: 0, //滚动条高度
      sliderH: 0, //滑块高度
      contentH: 0, //内容高度
      containerH: 0, //容器高度
      contentHLast: 0, //上次内容高度
      barW: 0, //滚动条宽度
      sliderW: 0, //滑块宽度
      contentW: 0, //内容宽度
      containerW: 0, //容器宽度
      contentWLast: 0 //上次内容宽度
    };
    this._init();
  };

  /**
   * 初始化
   * @private
   */
  Scroller.prototype._init = function() {
    var that = this;
    var barHtml = '<div class="scrollbar scrollbar-y" onselectstart="return false"><div><i></i></div></div>';
    barHtml += this._data.xRolling ?
      '<div class="scrollbar scrollbar-x" onselectstart="return false"><div><i></i></div></div>' : '';
    this.$e.container.append(barHtml);
    //获取元素
    this.$e.barY = this.$e.container.find('.scrollbar-y');
    this.$e.boxY = this.$e.barY.children('div');
    this.$e.sliderY = this.$e.barY.find('i');
    if (this._data.xRolling) {
      this.$e.barX = this.$e.container.find('.scrollbar-x');
      this.$e.boxX = this.$e.barX.children('div');
      this.$e.sliderX = this.$e.barX.find('i');
    }
    this.$e.inner = this.$e.container.children('.scroller-inner');
    //绑定事件
    this._onWinResize();
    $(win).on('resize', function() {
      that._onWinResize();
      that.checkHeightWidth();
    });
    this.$e.container.on('scrollbar', function() {
      that.checkHeightWidth();
    });
    this.$e.inner.on({
      'click': function() {
        that.checkHeightWidth();
      },
      'scroll': function() {
        that._reScroll();
      }
    });
    this.checkHeightWidth();
    this._bindAction();
  };

  /**
   * 滑块操作
   * @private
   */
  Scroller.prototype._bindAction = function() {
    var that = this;
    var onDrag = false;
    var _y = 0,
      top = 0,
      _x = 0,
      left = 0;
    this.$e.body = $('body');
    this.$e.boxY.on({
      'mousedown': function(e) {
        onDrag = 'y';
        that.$e.body.attr('onselectstart', 'return false');
        that.$e.barY.addClass('active');
        _y = e.pageY;
        top = parseFloat(that.$e.sliderY.css('top'));
      }
    });
    if (this._data.xRolling) {
      this.$e.boxX.on({
        'mousedown': function(e) {
          onDrag = 'x';
          that.$e.body.attr('onselectstart', 'return false');
          that.$e.barX.addClass('active');
          _x = e.pageX;
          left = parseFloat(that.$e.sliderX.css('left'));
        }
      });
    }
    $(win.document).on({
      'mousemove': function(e) {
        if (onDrag == 'y') {
          that.scrollYTo(top + e.pageY - _y);
        } else if (onDrag == 'x') {
          that.scrollXTo(left + e.pageX - _x);
        }
      },
      'mouseup': function() {
        that.$e.body.removeAttr('onselectstart', 'return false')
          .children('aside').show();
        if (onDrag == 'y') {
          that.$e.barY.removeClass('active');
        } else if (onDrag == 'x') {
          that.$e.barX.removeClass('active');
        }
        onDrag = false;
      }
    });
  };

  /**
   * 尺寸缩放
   * @private
   */
  Scroller.prototype._onWinResize = function() {
    if (isMobi()) {
      //console.log(this.$e.inner)
      //this.$e.inner.removeAttr('style').removeClass('on');
      this.$e.inner.addClass('on');
    } else {
      this.$e.inner.css({
        width: this.$e.container.width() + 30,
        paddingRight: 13,
      }).addClass('on');
    }
  };

  /**
   * 重设滑块大小
   * @private
   */
  Scroller.prototype._resize = function() {
    var that = this;
    this._data.containerH = this.$e.inner.height();
    //当内容高度小于等于容器时，不显示滚动条
    if (this._data.contentH <= this._data.containerH) {
      this._data.contentH = this._data.containerH;
      this.$e.barY.addClass('off');
    } else {
      this.$e.barY.removeClass('off');
    }
    //设置滑块大小
    this._data.barH = this.$e.boxY.height();
    this._data.sliderH = this._data.containerH / that._data.contentH * this._data.barH;
    this.$e.sliderY.height(this._data.sliderH);
    //计算最大高度
    this._data.maxTop = (this._data.barH - this._data.sliderH) / this._data.barH * this._data.contentH + 1;
    //水平方向
    if (this._data.xRolling) {
      this._data.containerW = this.$e.inner.width();
      //当内容宽度不超过容器时，不显示滚动条
      if (this._data.contentW <= this._data.containerW) {
        this._data.contentW = this._data.containerW;
        this.$e.barX.addClass('off');
      } else {
        this.$e.barX.removeClass('off');
      }
      //设置滑块大小
      this._data.barW = this.$e.boxX.width();
      this._data.sliderW = this._data.containerW / that._data.contentW * this._data.barW;
      this.$e.sliderX.width(this._data.sliderW);
    }
  };

  /**
   * 重设滑块顶部距离
   * @private
   */
  Scroller.prototype._reScroll = function() {
    var that = this;
    var top1 = this.$e.inner.scrollTop();
    var barTop = top1 / this._data.contentH * this._data.barH;
    //限制滑动边界 (由事件触发的滚动不会向上过界)
    if (barTop + this._data.sliderH >= this._data.barH) {
      barTop = this._data.barH - this._data.sliderH;
      this.$e.sliderY.css('top', barTop);
      this.$e.inner.scrollTop(this._data.maxTop);
    } else {
      this.$e.sliderY.css('top', barTop);
    }
    //水平方向
    if (this._data.xRolling) {
      var barLeft = this.$e.inner.scrollLeft() / this._data.contentW * this._data.barW;
      //水平方向没有鼠标滚动事件
      this.$e.sliderX.css('left', barLeft);
    }
  };

  /**
   * 垂直滚动到某位置
   * @param {Number} num
   * @public
   */
  Scroller.prototype.scrollYTo = function(num) {
    var barTop = num;
    barTop = barTop < 0 ? 0 : barTop;
    barTop = barTop + this._data.sliderH > this._data.barH ? this._data.barH - this._data.sliderH : barTop;
    this.$e.sliderY.css('top', barTop);
    this.$e.inner.scrollTop(barTop / this._data.barH * this._data.contentH);
  };

  /**
   * 水平滚动到某位置
   * @param {Number} num
   * @public
   */
  Scroller.prototype.scrollXTo = function(num) {
    var barLeft = num;
    barLeft = barLeft < 0 ? 0 : barLeft;
    barLeft = barLeft + this._data.sliderW > this._data.barW ? this._data.barW - this._data.sliderW : barLeft;
    this.$e.sliderX.css('left', barLeft);
    this.$e.inner.scrollLeft(barLeft / this._data.barW * this._data.contentW);
  };

  /**
   * 检查高度宽度
   * @public
   */
  Scroller.prototype.checkHeightWidth = function() {
    var that = this;
    this._data.contentH = 0;
    this._data.contentW = 0;
    this.$e.inner.children('.scroller-content').each(function() {
      that._data.contentH += $(this).outerHeight();
      that._data.contentW += $(this).outerWidth();
    });
    //修正 webkit 中滚动条本身占位
    if (/webkit/.test(navigator.userAgent.toLowerCase())) {
      that._data.contentH += 15;
    }
    //如果高度未改变不进行操作
    if (this._data.contentH == this._data.contentHLast && this._data.contentW == this._data.contentWLast) {
      return;
    } else {
      this._data.contentHLast = this._data.contentH;
      this._data.contentWLast = this._data.contentW;
    }
    this._resize();
    this._reScroll();
  };

  //注册到 jQuery
  $.extend($.fn, {
    scrollbar: function() {
      return this.each(function() {
        list.push(new Scroller(this));
      });
    }
  });

})(window, jQuery);
