<template>
    <div class="wrap" :style="wrapStyle">
        <div class="select-area" v-if="isShowIndicator" :style="indicatorStyle"></div>
        <text class="item-label" v-if="label" :style="labelStyle">{{label}}</text>
        <scroller @touchstart="handleStart" @touchend="handleEnd" ref="scroller" class="scroller" :style="scrollerStyle" append="tree" offset-accuracy="10" :show-scrollbar="false" @scroll="scroll">
            <div v-for="(item, index) in calcListArray" :key="index" ref="item">
                <text class="list-item" :style="itemStyle" v-bind:class="item['classes']">{{item.value}}</text>
            </div>
        </scroller>
    </div>
</template>
<script>
const dom = weex.requireModule('dom');

export default {
  props: {
    listArray: {
      type: Array,
      default: function () {
        return [];
      }
    },
    itemIndex: {
      type: Number,
      default: null
    },
    wrapHeight: {
      type: Number,
      default: 350
    },
    wrapWidth: {
      type: Number,
      default: 750
    },
    isShowIndicator: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    },
    labelOffset: {
      type: Number,
      default: null
    },
    align: {
      type: String,
      default: 'center' // 'center'/'left'
    }
  },
  computed: {
    wrapStyle() {
      return {
        width: this.wrapWidth,
        height: this.wrapHeight
      };
    },
    selectedItemTop() {
      return Math.floor((this.wrapHeight / this.itemHeight) / 2) * this.itemHeight;
    },
    indicatorStyle() {
      return {
        top: this.selectedItemTop + 'px',
        width: this.wrapWidth,
        height: this.itemHeight + 2
      };
    },
    labelStyle() {
      return {
        top: this.selectedItemTop + 'px',
        left: this.labelOffset ? this.labelOffset : ((this.wrapWidth / 2) + 50),
        width: this.wrapWidth / 2,
        height: this.itemHeight
      };
    },
    scrollerStyle() {
      return {
        width: this.wrapWidth,
        height: this.wrapHeight
      };
    },
    itemStyle() {
      return {
        width: this.wrapWidth
      };
    },
    calcListArray() {
      let result = [];
      result = this.listArray.map((item, index) => {
        item['classes'] = [];
        if (this.align == 'left' && this.label) {
          item['classes'].push('list-item-left');
        }
        if (index == 0) {
          item['classes'].push('first-item');
        } else if (index == this.listArray.length - 1) {
          item['classes'].push('last-item');
        }

        if (index == this.itemIndex - 2) {
          item['classes'].push('first-visible-item');
        } else if (index == this.itemIndex - 1) {
          item['classes'].push('second-visible-item');
        } else if (index == this.itemIndex) {
          item['classes'].push('selected-item');
        } else if (index == this.itemIndex + 1) {
          item['classes'].push('second-last-visible-item');
        } else if (index == this.itemIndex + 2) {
          item['classes'].push('first-last-visible-item');
        }

        return item;
      });

      return result;
    }
  },
  data() {
    return {
      isInit: false,
      itemHeight: 70,
      index: this.itemIndex,
      handler: null,
      intervalHandler: null
    };
  },
  watch: {
    itemIndex(value) {
      this.index = value;
    }
  },
  methods: {
    scroll(event) {
      if (!this.isInit) return;
      // 计算当前滚动到的下标
      this.itemIndex = Math.abs(Math.round((event.contentOffset.y || 0) / this.itemHeight));
      // 处理滚动超过边界时，不触发scrollEnd的问题 2019-08-02 Ken Added Start***
      if (weex.config.env.platform == 'android') {
        if (this.handler) {
          clearTimeout(this.handler);
        }
        this.handler = setTimeout(() => {
          this.handleEnd(event);
        }, 500);
      }
      // 处理滚动超过边界时，不触发scrollEnd的问题 2019-08-02 Ken Added End***
    },
    handleEnd(e) {
      if (!this.isInit) return;
      // 计算当前滚动到的下标
      setTimeout(() => {
        this.scrollToIndexItem(this.itemIndex);
        this.$emit('onChange', this.listArray[this.itemIndex]);
      }, 400);
    },
    scrollToIndexItem(index, animated = true) {
      const el = this.$refs.item[index];
      if (el) {
        dom.getComponentRect(el, (options) => {
          if (options.result && options.size.bottom) {
            dom.scrollToElement(el, { animated: animated, offset: index == 0 ? 0 : (-this.selectedItemTop) });
            this.isInit = true;
          } else {
            setTimeout(() => this.scrollToIndexItem(index, animated), 100);
          }
        });
      }
    }
  },
  mounted() {
    if (this.itemIndex != null) {
      this.scrollToIndexItem(this.itemIndex, false);
    }
  }
};
</script>

<style>
.wrap {
    position: relative;
    flex-direction: row;
    background-color: #ffffff;
}
.scroller {
    flex: 1;
    align-content: center;
    align-items: center;
    background-color: transparent;
}
.item-label {
    position: absolute;
    height: 70px;
    line-height: 70px;
    font-family: PingFangSC-Regular;
    opacity: 0.6;
    font-size: 40px;
    color: #1E2E37;
    text-align: left;
}
.list-item {
    height: 70px;
    line-height: 70px;
    font-family: PingFangSC-Regular;
    opacity: 0.3;
    font-size: 40px;
    color: #1E2E37;
    text-align: center;
}
.list-item-left {
    text-align: left;
}
.first-item {
    margin-top: 140px;
}
.last-item {
    margin-bottom: 140px;
}
.first-visible-item {
    opacity: 0.1;
    font-size: 40px;
}
.second-visible-item {
    opacity: 0.3;
    font-size: 40px;
}
.second-last-visible-item {
    opacity: 0.3;
    font-size: 40px;
}
.first-last-visible-item {
    opacity: 0.1;
    font-size: 40px;
}
.selected-item {
    opacity: 1;
    color: #1E2E37;
    font-size: 48px;
}
.select-area {
    position: absolute;
    left: 0px;
    border-top-color: #e5e5e5;
    border-top-width: 1px;
    border-bottom-color: #e5e5e5;
    border-bottom-width: 1px;
}
</style>
