import { LayerView } from '@mapgis/webclient-common'
import ApplyLayerUpdateUtil from './support/ApplyLayerUpdateUtil'
class IGSDocLayerView extends LayerView {
  /**
   * 添加图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onAdd(event) {
    const layer = this.layer
    const innerView = this.innerView
    this.innerLayer = null
    const MapDocLayer = L.TileLayer.extend({
      options: {
        layers: null,
        filters: null,
        style: null,
        // 图像类型:jpg,png,gif
        f: null,
        // 动态投影参数,设置地图文档在服务器端重新投影所需的空间参考系对象
        proj: null,
        guid: null,
        cache: false,
        // keepCache设置为true时,会首先从客户端缓存中取瓦片,否则不从客户端缓存中提取
        keepCache: true,
        tileSize: 256,
        attribution: 'Zondy Map doc Data'
      },
      initialize(options) {
        this.url = options.url
        L.TileLayer.prototype.initialize.apply(this, arguments)
        L.setOptions(this, options)
        L.stamp(this)
      },
      /**
       * @private
       * @function Zondy.Map.MapDocLayer.prototype.onAdd
       * @description 添加矢量地图文档。
       * @param map - {L.map} 待添加的矢量地图文档参数
       */
      onAdd(map) {
        this._crs = map.options.crs
        this._initLayerUrl()
        L.TileLayer.prototype.onAdd.call(this, map)
      },
      /**
       * @private
       * @function Zondy.Map.MapDocLayer.prototype.getTileUrl
       * @description 根据行列号获取瓦片地址
       * @param coords - {Object} 行列号
       * @return {String} 瓦片地址
       */
      getTileUrl(coords) {
        const tileBounds = this._tileCoordsToBounds(coords)
        const nw = this._crs.project(tileBounds.getNorthWest())
        const se = this._crs.project(tileBounds.getSouthEast())
        let params = `&bbox=${nw.x},${se.y},${se.x},${nw.y}`
        if (!this.options.keepCache) {
          params += `&temp=${Math.random()}`
        }
        return this._layerUrl + encodeURI(params)
      },
      _initLayerUrl() {
        const me = this
        let layerUrl = `${me.url}?`
        layerUrl += encodeURI(me._initAllRequestParams().join('&'))
        this._layerUrl = layerUrl
      },
      _initAllRequestParams() {
        const me = this
        const options = me.options || {}
        const params = []
        const f = options.f || 'png'
        params.push(`f=${f}`)
        let tileSize = this.options.tileSize
        if (!(tileSize instanceof L.Point)) {
          tileSize = L.point(tileSize, tileSize)
        }
        params.push(`w=${tileSize.x}`)
        params.push(`h=${tileSize.y}`)
        if (options.layers) {
          params.push(`layers=${options.layers}`)
        }
        if (options.filters) {
          params.push(`filters=${options.filters}`)
        }
        if (options.style) {
          params.push(`style=${JSON.stringify(options.style)}`)
        }
        const guid =
          options.guid || parseInt(String(Math.random() * 1000000000))
        params.push(`guid=${guid}`)
        if (options.proj) {
          params.push(`proj=${options.proj}`)
        }
        if (options.cache !== undefined && options.isAntialiasing !== null) {
          params.push(`cache=${options.cache}`)
        }
        if (options.update !== undefined && options.isAntialiasing !== null) {
          params.push(`update=${options.update}`)
        }
        if (options.mode) {
          params.push(`mode=${options.mode}`)
        }
        if (
          options.isAntialiasing !== undefined &&
          options.isAntialiasing !== null
        ) {
          params.push(`isAntialiasing=${options.isAntialiasing}`)
        }
        return params
      },
      redraw() {
        if (this._map) {
          this._removeAllTiles()
          this._update()
        }
        return this
      },
      refreshMap(guid) {
        if (guid !== null) {
          this.options.guid = guid
        }
        this._initLayerUrl()
        this.redraw()
      }
    })
    this.innerLayer = new MapDocLayer({
      url: layer.url
    }).addTo(innerView)
    this.innerLayer.commonLayerId = layer.id
    return Promise.resolve(this)
  }
  /**
   * 移除图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onRemove(event) {
    this.innerView.removeLayer(this.innerLayer)
    return Promise.resolve(this)
  }
  /**
   * 更新图层视图
   * @param {LayerViewUpdateEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onUpdate(event) {
    const _layer = this.innerLayer
    ApplyLayerUpdateUtil.applyUpdate(this.view, this.layer, _layer, event)
    return Promise.resolve(this)
  }
}
export default IGSDocLayerView