// Utils
import mixins from "../../../lib/utils/mixins";
import { isDef } from "../../../lib/utils";
import { raf } from "../../../lib/utils/raf";
import { off, on } from "../../../lib/utils/event";
import { getElementTop, getScrollEventTarget, getScrollTop, setScrollTop } from "../../../lib/utils/scroll"; // Mixins

import Touchable from "../../../lib/mixins/touchable";
export default mixins(Touchable).extend({
  name: 'w-tabs',
  model: {
    prop: 'active'
  },
  props: {
    sticky: Boolean,
    swipeable: Boolean,
    animated: Boolean,
    color: String,
    background: String,
    titleActiveColor: String,
    titleInactiveColor: String,
    ellipsis: {
      type: Boolean,
      default: true
    },
    lineWidth: {
      type: Number,
      default: null
    },
    lineHeight: {
      type: Number,
      default: null
    },
    active: {
      type: [Number, String],
      default: 0
    },
    type: {
      type: String,
      default: 'line'
    },
    duration: {
      type: Number,
      default: 0.2
    },
    swipeThreshold: {
      type: Number,
      default: 4
    },
    offsetTop: Number
  },
  data: function data() {
    return {
      inited: false,
      tabs: [],
      position: '',
      currentActive: 0,
      lineStyle: {
        backgroundColor: this.color
      },
      events: {
        resize: false,
        sticky: false,
        swipeable: false
      }
    };
  },
  computed: {
    // whether the nav is scrollable
    scrollable: function scrollable() {
      return this.tabs.length > this.swipeThreshold || !this.ellipsis;
    },
    wrapStyle: function wrapStyle() {
      switch (this.position) {
        case 'top':
          return {
            top: this.offsetTop + 'px',
            position: 'fixed'
          };

        case 'bottom':
          return {
            top: 'auto',
            bottom: 0
          };

        default:
          return null;
      }
    },
    navStyle: function navStyle() {
      return {
        borderColor: this.color,
        background: this.background
      };
    }
  },
  watch: {
    active: function active(val) {
      if (val !== this.currentActive) {
        this.correctActive(val);
      }
    },
    color: function color() {
      this.setLine();
    },
    tabs: function tabs() {
      this.correctActive(this.currentActive || this.active);
      this.scrollIntoView();
      this.setLine();
    },
    currentActive: function currentActive() {
      this.scrollIntoView();
      this.setLine(); // scroll to correct position

      if (this.position === 'top' || this.position === 'bottom') {
        setScrollTop(window, getElementTop(this.$el));
      }
    },
    sticky: function sticky() {
      this.handlers(true);
    },
    swipeable: function swipeable() {
      this.handlers(true);
    }
  },
  mounted: function mounted() {
    this.onShow();
  },

  /* istanbul ignore next */
  activated: function activated() {
    this.onShow();
  },

  /* istanbul ignore next */
  deactivated: function deactivated() {
    this.handlers(false);
  },
  beforeDestroy: function beforeDestroy() {
    this.handlers(false);
  },
  methods: {
    onShow: function onShow() {
      var _this = this;

      this.$nextTick(function () {
        _this.inited = true;

        _this.handlers(true);

        _this.scrollIntoView(true);
      });
    },
    // whether to bind sticky listener
    handlers: function handlers(bind) {
      var events = this.events;
      var sticky = this.sticky && bind;
      var swipeable = this.swipeable && bind; // listen to window resize event

      if (events.resize !== bind) {
        events.resize = bind;
        (bind ? on : off)(window, 'resize', this.setLine, true);
      } // listen to scroll event


      if (events.sticky !== sticky) {
        events.sticky = sticky;
        var scrollEl = getScrollEventTarget(this.$el);
        (sticky ? on : off)(scrollEl, 'scroll', this.onScroll, true);
        this.onScroll();
      } // listen to touch event


      if (events.swipeable !== swipeable) {
        events.swipeable = swipeable;
        var content = this.$refs.content;
        var action = swipeable ? on : off;
        action(content, 'touchstart', this.touchStart);
        action(content, 'touchmove', this.touchMove);
        action(content, 'touchend', this.onTouchend);
        action(content, 'touchcancel', this.onTouchend);
      }
    },
    // watch swipe touch end
    onTouchend: function onTouchend() {
      var direction = this.direction,
          deltaX = this.deltaX,
          currentActive = this.currentActive;
      var minSwipeDistance = 50;
      /* istanbul ignore else */

      if (direction === 'horizontal' && this.offsetX >= minSwipeDistance) {
        if (deltaX > 0 && currentActive !== 0) {
          this.setCurActive(currentActive - 1);
        } else if (deltaX < 0 && currentActive !== this.tabs.length - 1) {
          this.setCurActive(currentActive + 1);
        }
      }
    },
    // adjust tab position
    onScroll: function onScroll() {
      var scrollTop = getScrollTop(window) + this.offsetTop;
      var elTopToPageTop = getElementTop(this.$el);
      var elBottomToPageTop = elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight;

      if (scrollTop > elBottomToPageTop) {
        this.position = 'bottom';
      } else if (scrollTop > elTopToPageTop) {
        this.position = 'top';
      } else {
        this.position = '';
      }
    },
    // update nav bar style
    setLine: function setLine() {
      var _this2 = this;

      this.$nextTick(function () {
        var tabs = _this2.$refs.tabs;

        if (!tabs || !tabs[_this2.currentActive] || _this2.type !== 'line') {
          return;
        }

        var tab = tabs[_this2.currentActive];
        var lineWidth = _this2.lineWidth,
            lineHeight = _this2.lineHeight;
        var width = isDef(lineWidth) ? lineWidth : tab.offsetWidth;
        var left = tab.offsetLeft + (tab.offsetWidth - width) / 2;
        var lineStyle = {
          width: "".concat(width, "px"),
          backgroundColor: _this2.color,
          transform: "translateX(".concat(left, "px)"),
          transitionDuration: "".concat(_this2.duration, "s")
        };

        if (isDef(lineHeight)) {
          lineStyle.height = "".concat(lineHeight, "px");
          lineStyle.borderRadius = "".concat(lineHeight, "px");
        }

        _this2.lineStyle = lineStyle;
      });
    },
    // correct the value of active
    correctActive: function correctActive(active) {
      active = +active;
      var exist = this.tabs.some(function (tab) {
        return tab.index === active;
      });
      var defaultActive = (this.tabs[0] || {}).index || 0;
      this.setCurActive(exist ? active : defaultActive);
    },
    setCurActive: function setCurActive(active) {
      active = this.findAvailableTab(active, active < this.currentActive);

      if (active !== this.currentActive) {
        this.$emit('input', active);

        if (this.currentActive !== null) {
          this.$emit('change', active, this.tabs[active].title);
        }

        this.currentActive = active;
      }
    },
    findAvailableTab: function findAvailableTab(active, reverse) {
      var diff = reverse ? -1 : 1;
      var index = active;

      while (index >= 0 && index < this.tabs.length) {
        if (!this.tabs[index].disabled) {
          return index;
        }

        index += diff;
      }

      return index;
    },
    // emit event when clicked
    onClick: function onClick(index) {
      var _this$tabs$index = this.tabs[index],
          title = _this$tabs$index.title,
          disabled = _this$tabs$index.disabled;

      if (disabled) {
        this.$emit('disabled', index, title);
      } else {
        this.setCurActive(index);
        this.$emit('click', index, title);
      }
    },
    // scroll active tab into view
    scrollIntoView: function scrollIntoView() {
      var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (!this.scrollable || !this.$refs.tabs) {
        return;
      }

      var tab = this.$refs.tabs[this.currentActive];
      var nav = this.$refs.nav;
      var scrollLeft = nav.scrollLeft,
          navWidth = nav.offsetWidth;
      var offsetLeft = tab.offsetLeft,
          tabWidth = tab.offsetWidth;
      this.scrollTo(nav, scrollLeft, offsetLeft - (navWidth - tabWidth) / 2, immediate);
    },
    // animate the scrollLeft of nav
    scrollTo: function scrollTo(el, from, to, immediate) {
      if (immediate) {
        el.scrollLeft += to - from;
        return;
      }

      var count = 0;
      var frames = Math.round(this.duration * 1000 / 16);

      var animate = function animate() {
        el.scrollLeft += (to - from) / frames;
        /* istanbul ignore next */

        if (++count < frames) {
          raf(animate);
        }
      };

      animate();
    },
    // render title slot of child tab
    renderTitle: function renderTitle(el, index) {
      var _this3 = this;

      this.$nextTick(function () {
        var title = _this3.$refs.title[index];
        title.parentNode && title.parentNode.replaceChild(el, title);
      });
    },
    getTabStyle: function getTabStyle(item, index) {
      var style = {};
      var color = this.color;
      var active = index === this.currentActive;
      var isCard = this.type === 'card';

      if (color && isCard) {
        style.borderColor = color;

        if (!item.disabled && !active) {
          style.color = color;
        } else if (!item.disabled && active) {
          style.backgroundColor = color;
        }
      }

      var titleColor = active ? this.titleActiveColor : this.titleInactiveColor;

      if (titleColor) {
        style.color = titleColor;
      }

      return style;
    }
  },
  render: function render() {
    var _this4 = this;

    var h = arguments[0];
    var type = this.type,
        scrollable = this.scrollable;
    var Nav = this.tabs.map(function (tab, index) {
      return h("div", {
        "key": index,
        "ref": "tabs",
        "refInFor": true,
        "class": {
          'wv-tab': true,
          'wv-tab--active': index === _this4.currentActive,
          'wv-tab--disabled': tab.disabled
        },
        "style": _this4.getTabStyle(tab, index),
        "on": {
          "click": function click() {
            _this4.onClick(index);
          }
        }
      }, [h("span", {
        "class": "wv-ellipsis",
        "ref": "title",
        "refInFor": true
      }, [tab.title])]);
    });
    return h("div", {
      "class": ['wv-tabs', "wv-tabs--".concat(type)]
    }, [h("div", {
      "ref": "wrap",
      "style": this.wrapStyle,
      "class": {
        'wv-tabs__wrap': true,
        'wv-tabs__wrap--scrollable': scrollable,
        'wv-hairline--top-bottom': type === 'line'
      }
    }, [h("div", {
      "ref": "nav",
      "class": ['wv-tabs__nav', "wv-tabs__nav--".concat(type)],
      "style": this.navStyle
    }, [type === 'line' && h("div", {
      "class": "wv-tabs__line",
      "style": this.lineStyle
    }), Nav])]), h("div", {
      "class": "wv-tabs__content",
      "ref": "content"
    }, [this.$slots.default])]);
  }
});
//# sourceMappingURL=WTabs.js.map