/**
 * 画布上各组件的通用对象，主要是各部件的通用函数，
 * 例如组件的缩放、平移、上移、下移、删除等
 */
import Event from './libs/event'
import Util from './libs/util'
import Source from './source'
import getDefaultProperties from './constants/default_properties'
import cloneDeep from 'lodash/cloneDeep'
import { convert2geojson } from 'admin-tools'

class Layer extends Event {
  constructor(layer, scene) {
    super()
    this.id = layer.id
    this.type = layer.type
    this.name = layer.name
    this.layer = layer
    this._scene = scene
    this.rendered = false
  }

  render() {
    this.setAction()
    this.setShape()
    this.setStyle()
    this._scene.addLayer(this.layerInstance)
    this.rendered = true
  }

  /**
   * 根据source选项值获取组件的数据，并监听source.load事件，触发视图更新
   */
  setSource() {
    this.off('source.load')
    let source = this.layer.source
    if (!source || Object.keys(source).length === 0) {
      return
    }
    this.sourceInstance = new Source(this.layer.id, source, this)
    this.once('source.load', ({ data }) => {
      let source = this.layer.source
      // 行政区划的点数据和线段数据需要由引擎进行空间化
      if (
        source.parser &&
        source.parser.type === 'admin' &&
        source.parser.dataType !== 'polygon'
      ) {
        data = convert2geojson(data, source.parser)
      }
      let options = this._getSourceOptions(source)
      if (!this.rendered) {
        this.layerInstance.source(data, options)
        this.render()
      } else {
        this.layerInstance.setData(data, options)
      }
    })
  }

  setAction() {
    let { action } = this._mergeProperties()
    this.layerInstance.active(action.hover)
    this.layerInstance.select(action.select)
  }

  remove() {
    this._scene.removeLayer(this.layerInstance)
  }

  show() {
    this.layerInstance.show()
  }

  hide() {
    this.layerInstance.hide()
  }

  fitBounds() {
    this.layerInstance.fitBounds({
      padding: 100
    })
  }

  setIndex(index) {
    this.layerInstance.setIndex(index)
  }

  _mergeProperties() {
    let defaultProperties = getDefaultProperties(this.type)
    let { scale, shape, style, action } = this.layer
    let newProperties = Util.mergeObjs(cloneDeep(defaultProperties), {
      scale: scale || {},
      shape: shape || {},
      style: style || {},
      action: action || {}
    })
    return newProperties
  }

  _getSourceOptions(source) {
    let parser = {}
    if (source.parser) {
      let { type, dataType } = source.parser
      // 行政区划映射点和线段由引擎转为geojson数据
      if (type === 'admin' && dataType !== 'polygon') {
        parser = {
          type: 'geojson'
        }
      } else {
        parser = Object.assign(cloneDeep(source.parser), {
          type: source.type
        })
      }
    }
    let options = { parser }
    if (source.cluster) {
      // 点数据聚合
      let { enable, radius, minZoom, maxZoom } = source.cluster
      options.cluster = enable || false
      options.clusterOptions = {
        radius: radius || 40,
        minZoom: minZoom || 0,
        maxZoom: maxZoom || 16
      }
    }
    return options
  }
}

export default Layer
