/*
 * 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.
 */

import { scrollable, list as listMixin } from './mixins'

function getScroller (weex) {
  const {
    extractComponentStyle,
    createEventMap
  } = weex

  return {
    name: 'weex-scroller',
    mixins: [scrollable, listMixin],
    props: {
      scrollDirection: {
        type: [String],
        default: 'vertical',
        validator (value) {
          return ['horizontal', 'vertical'].indexOf(value) !== -1
        }
      },
      scrollable: {
        type: [Boolean],
        default: true
      }
    },
    computed: {
      wrapperClass () {
        const classArray = ['weex-scroller', 'weex-scroller-wrapper', 'weex-ct']
        if (this.scrollDirection === 'horizontal') {
          classArray.push('weex-scroller-horizontal')
        }
        else {
          classArray.push('weex-scroller-vertical')
        }
        if (!this.scrollable) {
          classArray.push('weex-scroller-disabled')
        }
        return classArray.join(' ')
      }
    },

    methods: {
      createChildren (h) {
        const slots = this.$slots.default || []
        this._cells = slots.filter(vnode => {
          if (!vnode.tag || !vnode.componentOptions) return false
          return true
        })
        return [
          h('article', {
            ref: 'inner',
            staticClass: 'weex-scroller-inner weex-ct'
          }, this._cells)
        ]
      }
    },

    render (createElement) {
      this.weexType = 'scroller'

      /* istanbul ignore next */
      // if (process.env.NODE_ENV === 'development') {
      //   validateStyles('scroller', this.$vnode.data && this.$vnode.data.staticStyle)
      // }

      this._cells = this.$slots.default || []
      this.$nextTick(() => {
        this.updateLayout()
      })

      return createElement('main', {
        ref: 'wrapper',
        attrs: { 'weex-type': 'scroller' },
        on: createEventMap(this, {
          scroll: this.handleScroll,
          touchstart: this.handleTouchStart,
          touchmove: this.handleTouchMove,
          touchend: this.handleTouchEnd
        }),
        staticClass: this.wrapperClass,
        staticStyle: extractComponentStyle(this)
      }, this.createChildren(createElement))
    }
  }
}

export default {
  init (weex) {
    weex.registerComponent('scroller', getScroller(weex))
  }
}
