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

/**
 * @fileoverview waterfall
 * NOTE: only support full screen width waterfall.
 */

import { scrollable } from './mixins'

const NORMAL_GAP_SIZE = 32
const DEFAULT_COLUMN_COUNT = 1

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

  return {
    name: 'weex-waterfall',
    mixins: [scrollable],
    props: {
      /**
       * specified gap size.
       * value can be number or 'normal'. 'normal' (32px) by default.
       */
      columnGap: {
        type: [String, Number],
        default: 'normal',
        validator (val) {
          if (!val || val === 'normal') {
            return true
          }
          val = parseInt(val)
          return !isNaN(val) && val > 0
        }
      },
      /**
       * the maximum column counts.
       * value can be number or 'auto'. 1 by default.
       */
      columnCount: {
        type: [String, Number],
        default: DEFAULT_COLUMN_COUNT,
        validator (val) {
          val = parseInt(val)
          return !isNaN(val) && val > 0
        }
      },
      /**
       * the mimimum column width.
       * value can be number or 'auto'. 'auto' by default.
       */
      columnWidth: {
        type: [String, Number],
        default: 'auto',
        validator (val) {
          if (!val || val === 'auto') {
            return true
          }
          val = parseInt(val)
          return !isNaN(val) && val > 0
        }
      }
    },

    mounted () {
      this._nextTick()
    },

    updated () {
      this.$nextTick(this._nextTick())
    },

    methods: {
      _createChildren (h, rootStyle) {
        const slots = this.$slots.default || []
        this._headers = []
        this._others = []
        this._cells = slots.filter(vnode => {
          if (!vnode.tag || !vnode.componentOptions) return false
          const tag = vnode.componentOptions.tag
          if (tag === 'refresh' || tag === 'loading') {
            this[`_${tag}`] = vnode
            return false
          }
          if (tag === 'header') {
            this._headers.push(vnode)
            return false
          }
          if (tag !== 'cell') {
            this._others.push(vnode)
            return false
          }
          return true
        })
        this._reCalc(rootStyle)
        this._genColumns(h)
        let children = []
        this._refresh && children.push(this._refresh)
        children = children
          .concat(this._headers)
          .concat(this._others)
        children.push(h('html:div', {
          ref: 'columns',
          staticClass: 'weex-waterfall-inner-columns weex-ct'
        }, this._columns))
        this._loading && children.push(this._loading)
        return [
          h('article', {
            ref: 'inner',
            staticClass: 'weex-waterfall-inner weex-ct'
          }, children)
        ]
      },

      _reCalc (rootStyle) {
        /**
         * NOTE: columnGap and columnWidth can't both be auto.
         * NOTE: the formula:
         *  totalWidth = n * w + (n - 1) * gap
         * 1. if columnCount = n then calc w
         * 2. if columnWidth = w then calc n
         * 3. if columnWidth = w and columnCount = n then calc totalWidth
         *    3.1 if totalWidth < ctWidth then increase columnWidth
         *    3.2 if totalWidth > ctWidth then decrease columnCount
         */
        let width, gap, cnt, ctWidth
        const scale = weex.config.env.scale
        const el = this.$el
        function getCtWidth (width, style) {
          const padding = style.padding
            ? parseInt(style.padding) * 2
            : parseInt(style.paddingLeft || 0) + parseInt(style.paddingRight || 0)
          return width - padding
        }
        if (el && el.nodeType === 1) {  // already mounted
          const cstyle = window.getComputedStyle(el)
          ctWidth = getCtWidth(el.getBoundingClientRect().width, cstyle)
        }
        else {  // not mounted.
          // only support full screen width for waterfall component.
          ctWidth = getCtWidth(document.documentElement.clientWidth, rootStyle)
        }

        gap = this.columnGap
        if (gap && gap !== 'normal') {
          gap = parseInt(gap)
        }
        else {
          gap = NORMAL_GAP_SIZE
        }
        gap = gap * scale

        width = this.columnWidth
        cnt = this.columnCount
        if (width && width !== 'auto') {
          width = parseInt(width) * scale
        }
        if (cnt && cnt !== 'auto') {
          cnt = parseInt(cnt)
        }

        // 0. if !columnCount && !columnWidth
        if (cnt === 'auto' && width === 'auto') {
          if (process.env.NODE_ENV === 'development') {
            console.warn(`[vue-render] waterfall's columnWidth and columnCount shouldn't`
            + ` both be auto at the same time.`)
            cnt = DEFAULT_COLUMN_COUNT
            width = ctWidth
          }
        }
        // 1. if columnCount = n then calc w.
        else if (cnt !== 'auto' && width === 'auto') {
          width = (ctWidth - (cnt - 1) * gap) / cnt
        }
        // 2. if columnWidth = w then calc n.
        else if (cnt === 'auto' && width !== 'auto') {
          cnt = (ctWidth + gap) / (width + gap)
        }
        // 3. if columnWidth = w and columnCount = n then calc totalWidth
        else if (cnt !== 'auto' && width !== 'auto') {
          let totalWidth
          const adjustCountAndWidth = () => {
            totalWidth = cnt * width + (cnt - 1) * gap
            if (totalWidth < ctWidth) {
              width += (ctWidth - totalWidth) / cnt
            }
            else if (totalWidth > ctWidth && cnt > 1) {
              cnt--
              adjustCountAndWidth()
            }
            else if (totalWidth > ctWidth) {  // cnt === 1
              width = ctWidth
            }
          }
          adjustCountAndWidth()
        }
        this._columnCount = cnt
        this._columnWidth = width
        this._columnGap = gap
      },

      _genColumns (createElement) {
        this._columns = []
        const cells = this._cells
        const columnCnt = this._columnCount
        const len = cells.length
        const columnCells = this._columnCells = Array(columnCnt).join('.').split('.').map(function () { return [] })
        // spread cells to the columns using simpole polling algorithm.
        for (let i = 0; i < len; i++) {
          (cells[i].data.attrs || (cells[i].data.attrs = {}))['data-cell'] = i
          columnCells[i % columnCnt].push(cells[i])
        }
        for (let i = 0; i < columnCnt; i++) {
          this._columns.push(createElement('html:div', {
            ref: `column${i}`,
            attrs: {
              'data-column': i
            },
            staticClass: 'weex-ct',
            staticStyle: {
              width: this._columnWidth + 'px',
              marginLeft: i === 0 ? 0 : this._columnGap + 'px'
            }
          }, columnCells[i]))
        }
      },

      _nextTick () {
        this._reLayoutChildren()
      },

      _reLayoutChildren () {
        /**
         * treat the shortest column bottom as the match standard.
         * whichever cell exceeded it would be rearranged.
         * 1. m = shortest column bottom.
         * 2. get all cell ids who is below m.
         * 3. calculate which cell should be in which column.
         */
        const columnCnt = this._columnCount
        const columnDoms = []
        const columnAppendFragments = []
        const columnBottoms = []
        let minBottom = Number.MAX_SAFE_INTEGER
        let minBottomColumnIndex = 0

        // 1. find the shortest column bottom.
        for (let i = 0; i < columnCnt; i++) {
          const columnDom = this._columns[i].elm
          const lastChild = columnDom.lastElementChild
          const bottom = lastChild ? lastChild.getBoundingClientRect().bottom : 0
          columnDoms.push(columnDom)
          columnBottoms[i] = bottom
          columnAppendFragments.push(document.createDocumentFragment())
          if (bottom < minBottom) {
            minBottom = bottom
            minBottomColumnIndex = i
          }
        }

        // 2. get all cell ids who is below m.
        const belowCellIds = []
        const belowCells = {}
        for (let i = 0; i < columnCnt; i++) {
          if (i === minBottomColumnIndex) {
            continue
          }
          const columnDom = columnDoms[i]
          const cellsInColumn = columnDom.querySelectorAll('section.weex-cell')
          const len = cellsInColumn.length
          for (let j = len - 1; j >= 0; j--) {
            const cellDom = cellsInColumn[j]
            const cellRect = cellDom.getBoundingClientRect()
            if (cellRect.top > minBottom) {
              const id = ~~cellDom.getAttribute('data-cell')
              belowCellIds.push(id)
              belowCells[id] = { elm: cellDom, height: cellRect.height }
              columnBottoms[i] -= cellRect.height
            }
          }
        }

        // 3. calculate which cell should be in which column and rearrange them
        //  in the dom tree.
        belowCellIds.sort(function (a, b) { return a > b })
        const cellIdsLen = belowCellIds.length
        function addToShortestColumn (belowCell) {
          // find shortest bottom.
          minBottom = Math.min(...columnBottoms)
          minBottomColumnIndex = columnBottoms.indexOf(minBottom)
          const { elm: cellElm, height: cellHeight } = belowCell
          columnAppendFragments[minBottomColumnIndex].appendChild(cellElm)
          columnBottoms[minBottomColumnIndex] += cellHeight
        }
        for (let i = 0; i < cellIdsLen; i++) {
          addToShortestColumn(belowCells[belowCellIds[i]])
        }
        for (let i = 0; i < columnCnt; i++) {
          columnDoms[i].appendChild(columnAppendFragments[i])
        }
      }
    },

    render (createElement) {
      this.weexType = 'waterfall'
      this._cells = this.$slots.default || []
      this.$nextTick(() => {
        this.updateLayout()
      })
      const mergedStyle = extractComponentStyle(this)
      return createElement('main', {
        ref: 'wrapper',
        attrs: { 'weex-type': 'waterfall' },
        on: createEventMap(this, {
          scroll: this.handleScroll,
          touchstart: this.handleTouchStart,
          touchmove: this.handleTouchMove,
          touchend: this.handleTouchEnd
        }),
        staticClass: 'weex-waterfall weex-waterfall-wrapper weex-ct',
        staticStyle: mergedStyle
      }, this._createChildren(createElement, mergedStyle))
    }
  }
}

export default {
  init (weex) {
    weex.registerComponent('waterfall', getWaterfall(weex))
  }
}
