<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- Created by 虎牙 on 17/07/28. -->

<template>
  <div class="slide-nav" ref="wrapper">
    <slot></slot>
  </div>
</template>

<style scoped>
  .slide-nav {
    position: absolute;
    z-index: 1000;
  }

</style>

<script>
  const DOM = weex.requireModule('dom');
  const Animation = weex.requireModule('animation');
  const OFFSET_ACCURACY = 10;
  const SCALE = weex.config.env.platform.toLowerCase() === 'web' ? 2 : 1;

  function _toNum (str) {
    return typeof str === 'number' ? str : parseFloat((str || '').replace(/px$/i, ''));
  }

  function _getHeight (element, callback) {
    if (!element) {
      return;
    }
    if (element.__cacheHeight) {
      element.__cacheHeight && callback && callback(element.__cacheHeight);
    } else {
      DOM.getComponentRect(element, (res) => {
        let height = (parseFloat(res && res.size && res.size.height) || 0) / SCALE;
        height && callback && callback((element.__cacheHeight = height));
      });
    }
  }

  export default {

    props: {
      position: {
        'type': String,
        'default': 'top'
      },

      height: [String, Number]
    },

    data () {
      return {
        visible: true
      }
    },

    watch: {
      visible (newVal) {
        newVal ? this._slideIn() : this._slideOut();
      }
    },

    created () {
      this._height = _toNum(this.height) || 0;
      this._isBottom = this.position === 'bottom';
      this._direction = this._isBottom ? 1 : -1;
    },

    methods: {

      _slideOut () {
        this.getHeight((height) => {
          this.$emit('slideOut');
          this.slideY(height * this._direction * SCALE, () => {
            this.$emit('slideOutEnd');
          });
        });
      },

      _slideIn () {
        this.getHeight((height) => {
          this.$emit('slideIn');
          this.slideY(0, () => {
            this.$emit('slideInEnd');
          });
        });
      },

      getHeight (callback) {
        return _getHeight(this.$refs.wrapper, callback);
      },

      slideOut () {
        this.visible = false;
      },

      slideIn () {
        this.visible = true;
      },

      slideY (y, callback) {
        Animation.transition(this.$refs.wrapper, {
          styles: { transform: 'translateY(' + y + 'px)' },
          duration: 150, //ms
          timingFunction: 'ease',
          delay: 0 //ms
        }, callback);
      }
    },

    handleTouchStart (e) {
      let touch = e.changedTouches[0];
      this._touchParams = {
        pageY: touch.screenY,
        startY: touch.screenY,
        lastPageY: touch.screenY,
        timeStamp: e.timeStamp,
        direction: -1
      };
    },

    handleTouchMove (e, bottomNav) {
      let tp = this._touchParams;
      let touch = e.changedTouches[0];
      let offsetY;

      // 安卓下滚动的时候经常不触发touchstart事件
      if (!tp || tp.hasEnd) {
        return (this._touchParams = {
          pageY: touch.screenY,
          startY: touch.screenY,
          lastPageY: touch.screenY,
          timeStamp: e.timeStamp,
          direction: -1
        });
      }

      offsetY = touch.screenY - tp.pageY;

      tp.lastPageY = tp.pageY;
      tp.lastDirection = tp.direction;
      tp.direction = offsetY > 0 ? 1 : -1;

      if (tp.lastDirection !== tp.direction) {
        tp.startY = tp.lastPageY;
      }

      tp.pageY = touch.screenY;
      tp.offsetY = tp.pageY - tp.startY;

      if (!this.__scrollable && bottomNav) {
        if (tp.offsetY <= -OFFSET_ACCURACY) {
          bottomNav.slideOut();
        } else if (tp.offsetY >= OFFSET_ACCURACY) {
          bottomNav.slideIn();
        }
      }
    },

    handleTouchEnd () {
      let tp = this._touchParams;
      tp && (tp.hasEnd = true);
    },

    handleScroll (e, scroller, topNav, bottomNav, startThreshold, moveThreshold = 5) {
      let scrollY = e.contentOffset.y;
      let nav = topNav || bottomNav;
      let scrollFn = (maxScrollY) => {
        if (-scrollY > maxScrollY) {
          return;
        }
        maxScrollY = Math.abs(maxScrollY);
        if (Math.abs(scrollY) < startThreshold) {
          if (Math.abs(scrollY) >= maxScrollY - OFFSET_ACCURACY) {
            let tp = this._touchParams;
            if (!tp) {
              return;
            }
            let offsetY = tp.offsetY;
            if (offsetY < -OFFSET_ACCURACY) {
              bottomNav && bottomNav.slideOut();
            } else if (offsetY > OFFSET_ACCURACY) {
              bottomNav && bottomNav.slideIn();
            }
          } else {
            topNav && topNav.slideIn();
            bottomNav && bottomNav.slideIn();
          }
        } else {
          let tp = this._touchParams;
          if (!tp) {
            return;
          }
          let offsetY = tp.offsetY;
          if (Math.abs(offsetY) >= moveThreshold) {
            if (offsetY > 0) {
              topNav && topNav.slideIn();
              bottomNav && bottomNav.slideIn();
            } else {
              topNav && topNav.slideOut();
              bottomNav && bottomNav.slideOut();
            }
          }
        }
      };

      let maxScrollYCheck = (maxScrollY) => {
        if (!this.__scrollable) {
          return;
        }
        if (startThreshold) {
          scrollFn(maxScrollY);
        } else {
          nav.getHeight((navHeight) => {
            startThreshold = navHeight;
            scrollFn(maxScrollY);
          });
        }
      };

      if (!nav) {
        return;
      }

      _getHeight(scroller, (scrollerHeight) => {
        let maxScrollY = e.contentSize.height - scrollerHeight;
        this.__scrollable = maxScrollY >= OFFSET_ACCURACY;

        if (bottomNav) {
          bottomNav.getHeight((height) => {
            this.__scrollable = maxScrollY >= height;
            maxScrollYCheck(maxScrollY);
          });
        } else {
          maxScrollYCheck(maxScrollY);
        }
      });
    }
  }
</script>
