import DataUtils from '../utils/DataUtils';
import VerifyUtils from '../utils/VerifyUtils';
import LayerProvider from '../geog/LayerProvider';
import GeoJsonProvider from '../geog/GeoJsonProvider';

/**
 * 定义注记图层
 * @alias AnnotationLayer
 *
 * @summary <用于注记图层加载>
 */
export default class AnnotationLayer {
  /**
   * 构造函数
   * @param {Object} options -图层选项
   */
  constructor(options) {
    // 默认数据源ID
    this._defaultSourceId = 'point_annotation';
    // 数据源是否存在
    this._hasSource = true;

    /**
     * 地图对象
     * @type {Object}
     */
    this._map = options.map;

    /**
     * 最小缩放层级
     * @type {Number}
     */
    this._minzoom = DataUtils.default(options.minzoom, 10);

    /**
     * 字段名
     * @type {String}
     */
    this._fieldName = DataUtils.default(options.field, 'name');

    /**
     * 符号位置
     * @type {String}
     *
     * @summery <取值：point、line、line-center>
     */
    this._placement = DataUtils.default(options.placement, 'point');

    /**
     * 符号间距
     * @type {Number}
     *
     * @summery <在options.placement==='line'时生效>
     */
    this._spacing = DataUtils.default(options.spacing, 250);

    /**
     * 文本大小
     * @type {Number}
     */
    this._textSize = DataUtils.default(options.textSize, 15);

    /**
     * 文本偏移
     * @type {Array}
     */
    this._textOffset = DataUtils.default(options.textOffset, [0, 0]);

    /**
     * 文本旋转角度(顺时针)
     * @type {Number|Array}
     */
    this._textRotate = DataUtils.default(options.textRotate, 0);

    /**
     * 文本可移动的锚点
     * @type {Array}
     */
    this._variableAnchor = DataUtils.default(options.variableAnchor, ['center']);

    /**
     * 文本径向偏移
     * @type {Number}
     */
    this._radialOffset = DataUtils.default(options.radialOffset, 0);

    /**
     * 图标是否环绕文字
     * @type {Boolean}
     */
    this._around = DataUtils.default(options.around, false);

    /**
     * 过滤条件数组
     * @type {Array}
     */
    this._filter = DataUtils.default(options.filter, undefined);

    /**
     * 数据源ID
     * @type {String}
     */
    this._sourceId = DataUtils.default(options.sourceId, this._defaultSourceId);

    /**
     * 图层ID
     * @type {String}
     */
    this._layerId = DataUtils.default(options.layerId, this._sourceId);

    // 样式属性数组
    this._styleProperties = [];
  }

  /** 公有方法 **/
  /**
   * 设置数据
   * @param {Object|String|Array} data -GeoJSON要素集/查询语句/过滤条件(点位)数组
   *
   * @summary <data参数：
   *   Object - GeoJson要素/要素集
   *   String - cql_filter查询语句
   *   Array - 图层过滤条件数组(如：['==', field, value]) or 点位数组(包含longitude, latitude字段)
   * >
   */
  setData(data) {
    // 加载图层
    if (!this.hasLayer()) {
      this.loadLayer();
    }
    // 隐藏图层
    this.showLayer(false);

    let fc = null;
    if (VerifyUtils.isGeoJsonFC(data)) {
      // GeoJSON要素集合
      fc = data;
    } else if (VerifyUtils.isGeoJsonFeature(data)) {
      // GeoJSON要素
      fc = GeoJsonProvider.getEmptyFC();
      fc.features = [data];
    } else if (VerifyUtils.isArray(data)) {
      if (data.length > 1 && VerifyUtils.isString(data[0])) {
        // 设置筛选器
        this._map.setFilter(this._layerId, data);
      } else {
        // 数组转GeoJSON对象
        fc = GeoJsonProvider.data2PointFC(data);
      }
    } else if (VerifyUtils.isString(data)) {
      // 查询语句
      if (this._hasSource) {
        const source = this._map.getSource(this._sourceId);
        fc = source._data + (data ? "&cql_filter=" + data : '');
      }
    }

    fc = fc || GeoJsonProvider.getEmptyFC();

    // 更新数据源
    this._map.getSource(this._sourceId).setData(fc);
    // 显示图层
    this.showLayer(true);
  }

  /**
   * 设置筛选器
   * @param {Array} filter -筛选器
   */
  setFilter(filter) {
    if (!this.hasLayer()) return;

    // 空数组
    if (VerifyUtils.isArray(filter) && filter.length === 0) {
      filter = null;
    }

    let newFilter = null;
    /*
    if (this._filter) {
      newFilter = ['all', this._filter];
    }
    */
    if (this._filter) {
      if (this._filter.length === 1) {
        newFilter = ['all', this._filter];
      } else {
        newFilter = [].concat(this._filter);
      }
    }

    if (filter) {
      if (!newFilter) {
        newFilter = filter;
      } else {
        newFilter.push(filter);
      }
    }

    // 设置筛选器
    this._map.setFilter(this._layerId, newFilter);
  }

  /**
   * 设置绘制属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setPaintProperty(name, value) {
    if (!this.hasLayer()) {
      this._styleProperties.push({style: 'paint', name: name, value: value});
      return;
    }

    this._map.setPaintProperty(this._layerId, name, value);
  }

  /**
   * 设置布局属性
   * @param {String} name -属性名称
   * @param {String|Object} value -属性值
   */
  setLayoutProperty(name, value) {
    if (!this.hasLayer()) {
      this._styleProperties.push({style: 'layout', name: name, value: value});
      return;
    }

    this._map.setLayoutProperty(this._layerId, name, value);
  }

  /**
   * 加载图层
   */
  loadLayer() {
    if (this.hasLayer()) return;

    const map = this._map;

    const sourceId = this._sourceId;
    const layerId = this._layerId;
    // 判断数据源是否存在
    this._hasSource = LayerProvider.hasSource(map, sourceId);
    if (!this._hasSource) {
      // 添加数据源
      map.addSource(sourceId, {
        type: "geojson",
        data: GeoJsonProvider.getEmptyFC()
      });
    }

    // 自定义字体颜色
    let textColor = map._customStyle ? map._customStyle.textColor : '#F8F8FF';
    //let textHaloWidth = map._customStyle ? map._customStyle.textHaloWidth : 0.1;

    map.addLayer({
      type: "symbol",
      id: layerId,
      source: sourceId,
      minzoom: this._minzoom,
      layout: {
        "symbol-placement": this._placement,
        "symbol-spacing": this._spacing,
        "symbol-avoid-edges": true,
        "text-offset": this._textOffset,
        "text-field": "{" + this._fieldName + "}",
        "text-size": this._textSize,
        "text-font": ["Microsoft YaHei"],
        "text-max-width": 32,
        "text-rotate": this._textRotate,
        "text-rotation-alignment": "map",
        "text-variable-anchor": this._variableAnchor,
        "text-radial-offset": this._radialOffset,
        'text-justify': 'auto',
        visibility: "none"
      },
      paint: {
        "text-color": textColor,
        //"text-halo-color": "#8B8B8B",
        //"text-halo-width": textHaloWidth,
      }
    });

    // 图标环绕文组
    if (this._around) {
      map.setLayoutProperty(layerId, 'icon-text-fit', 'both');
    }

    // 设置自定义样式
    if (this._styleProperties.length > 0) {
      this._styleProperties.forEach(prop => {
        switch (prop.style) {
          case 'paint':
            map.setPaintProperty(layerId, prop.name, prop.value);
            break;
          case 'layout':
            map.setLayoutProperty(layerId, prop.name, prop.value);
            break;
          default:
            break;
        }
      });
    }

    // 设置筛选器
    if (this._filter) {
      map.setFilter(this._layerId, this._filter);
    }
  }

  /**
   * 显示/隐藏图层
   * @param {Boolean} isShow -是否显示图层
   */
  showLayer(isShow) {
    LayerProvider.showLayer(this._map, this._layerId, isShow);
  }

  /**
   * 判断图层是否已加载
   *
   * @returns {Boolean}
   */
  hasLayer() {
    return LayerProvider.hasLayer(this._map, this._layerId);
  }

  /**
   * 移除图层
   */
  removeLayer() {
    LayerProvider.removeLayer(this._map, this._layerId);
  }

  /**
   * 移除数据源
   */
  removeSource() {
    LayerProvider.removeSource(this._map, this._sourceId);
  }
}
