import _regeneratorRuntime from 'babel-runtime/regenerator';
import _asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _createClass from 'babel-runtime/helpers/createClass';
import _inherits from 'babel-runtime/helpers/inherits';
/**
 * @文件说明: 构建Map.Services地图Web GIS服务图层对象
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-03-20 22:14:55
 */

import BasicMapApi from '../../util/basicMapApiClass';
import omit from 'omit.js';
import { isHttpUrl, isArray, isEmpty, isNumeric, isNotEmptyArray } from '../../../_util/methods-util';
import isPlainObject from 'lodash/isPlainObject';
import XYZTile from './xyzTile';
import VTS from './vts';
import GeoTile from './geoTile';
import WMTS from './wmts';
import ArcgisWMTS from './arcgisWMTS';
import WMS from './wms';
import ArcgisWMS from './arcgisWMS';
import GeoExport from './geoExport';
import ArcgisExport from './arcgisExport';

// 内置地图Web GIS服务的服务类型枚举名
export var mapServicesTypeKeys = ['XYZTile', 'GeoTile', 'VTS', 'WMTS', 'WMS', 'GeoExport', 'ArcgisWMTS', 'ArcgisWMS', 'ArcgisExport'];

// 服务数据源的默认参数选项
export var defaultServicesSourceOptions = {
  // 瓦片的大小
  tileSize: 256,
  // 瓦片的计算方案，可选值：[ xyz | tms ]
  scheme: null,
  // 瓦片类型
  rasterType: null,
  // 瓦片计算偏移量
  zoomOffset: null,
  // 是否拼接代理服务地址
  proxy: true,
  // 瓦片数据源的属性描述
  attribution: null,
  // 瓦片的请求范围
  bounds: null,
  // 瓦片的最小层级
  minzoom: null,
  // 瓦片的最大层级
  maxzoom: null
};

// 服务图层的默认参数选项
export var defaultServicesLayerOptions = {
  // 图层的Layout属性
  layout: null,
  // 图层的Paint属性
  paint: null,
  // 图层的扩展属性，不影响图层的渲染，自定义扩展
  metadata: null,
  // 图层的[source-layer]属性
  sourceLayer: null,
  // 图层的不透明度，范围：0-1
  opacity: 1,
  // 图层的显隐状态，可选项: [ visible | none ]
  visibility: 'visible'
};

// 获取图层的数据源
export var getServicesLayerSource = function getServicesLayerSource(options) {
  var source = {};
  source.type = 'raster';
  source.defaultTileSize = 256;
  source.tileSize && (source.tileSize = options.tileSize);
  if (!isEmpty(options.scheme)) {
    source.scheme = options.scheme === 'tms' ? 'tms' : 'xyz';
  }
  options.rasterType && (source.rasterType = options.rasterType);
  options.attribution && (source.attribution = options.attribution);
  options.bounds && (source.bounds = options.bounds);
  options.minzoom && (source.minzoom = options.minzoom);
  options.maxzoom && (source.maxzoom = options.maxzoom);
  if (!isEmpty(options.zoomOffset) && isNumeric(options.zoomOffset)) {
    source.zoomOffset = parseInt(options.zoomOffset, 10) || 0;
  }
  return source;
};

// 获取服务图层的基础对象
export var getServicesBaseLayer = function getServicesBaseLayer(options) {
  var layer = {};
  layer.type = 'raster';
  layer.layout = options.layout || {};
  layer.paint = options.paint || {};
  if (options.metadata) {
    layer.metadata = { 'layer:meta': options.metadata };
  } else {
    layer.metadata = {};
  }
  options.minzoom && (layer.minzoom = options.minzoom);
  options.maxzoom && (layer.maxzoom = options.maxzoom);
  options.sourceLayer && (layer['source-layer'] = options.sourceLayer);
  var opacity = !isEmpty(options.opacity) && isNumeric(opacity) ? Number(opacity) : 1;
  opacity > 1 && (opacity = 1);
  opacity < 0 && (opacity = 0);
  layer.paint['raster-opacity'] = opacity;
  var visibility = !isEmpty(options.visibility) && options.visibility === 'none' ? 'none' : 'visible';
  layer.layout['visibility'] = visibility;
  return layer;
};

// 效验Services服务的基础属性的有效性
var validateServicesOptions = function validateServicesOptions(id, url, options) {
  if (!id || !url) {
    console.error('WebGIS Services\u670D\u52A1[id]\u3001[url]\u5C5E\u6027\u5FC5\u9700\u8BBE\u5B9A.');
    return;
  }
  var errorUrlMsg = 'WebGIS Services服务[url]属性格式不是一个有效的链接地址.';
  if (isArray(url)) {
    for (var i = 0, len = url.length; i < len; i++) {
      if (!isHttpUrl(url[i])) {
        console.error(errorUrlMsg);
        return;
      }
    }
  } else if (!isHttpUrl(url)) {
    console.error(errorUrlMsg);
    return;
  }

  return {
    id: id,
    name: options && options.name ? String(options.name) : '',
    url: url,
    options: omit(options, ['name'])
  };
};

var Services = function (_BasicMapApi) {
  _inherits(Services, _BasicMapApi);

  _createClass(Services, [{
    key: 'typeKeys',

    /**
     * 获取Web GIS服务的服务类型的名称
     * @readonly
     */
    get: function get() {
      return mapServicesTypeKeys;
    }

    /**
     * Services地图Web GIS服务
     * @param {MapApi} iMapApi 地图Api实例化对象
     */

  }]);

  function Services() {
    var _ref;

    _classCallCheck(this, Services);

    for (var _len = arguments.length, arg = Array(_len), _key = 0; _key < _len; _key++) {
      arg[_key] = arguments[_key];
    }

    return _possibleConstructorReturn(this, (_ref = Services.__proto__ || Object.getPrototypeOf(Services)).call.apply(_ref, [this].concat(arg)));
  }

  /**
   * 获取XYZTile类型服务的图层对象
   * @param {String} id 图层Id名称
   * @param {String} url 服务地址
   * @param {Object} options 解析服务的参数选项
   */


  _createClass(Services, [{
    key: 'getXYZTileLayer',
    value: function getXYZTileLayer(id, url) {
      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

      var result = validateServicesOptions(id, url, options);
      if (!result) {
        return null;
      }
      var xyzTile = new XYZTile(this.iMapApi);
      var layer = xyzTile.getLayer(result.id, result.name, result.url, result.options);
      xyzTile = null;
      return layer;
    }

    /**
     * 获取VTS类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getVTSLayer',
    value: function () {
      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, vts, layer;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context.next = 3;
                  break;
                }

                return _context.abrupt('return', null);

              case 3:
                vts = new VTS(this.iMapApi);
                layer = vts.getLayer(result.id, result.name, result.url, result.options);

                vts = null;
                return _context.abrupt('return', layer);

              case 7:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function getVTSLayer(_x3, _x4) {
        return _ref2.apply(this, arguments);
      }

      return getVTSLayer;
    }()

    /**
     * 获取GeoTile类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getGeoTileLayer',
    value: function () {
      var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, geoTile, layer;
        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context2.next = 3;
                  break;
                }

                return _context2.abrupt('return', null);

              case 3:
                geoTile = new GeoTile(this.iMapApi);
                layer = geoTile.getLayer(result.id, result.name, result.url, result.options);

                geoTile = null;
                return _context2.abrupt('return', layer);

              case 7:
              case 'end':
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      function getGeoTileLayer(_x6, _x7) {
        return _ref3.apply(this, arguments);
      }

      return getGeoTileLayer;
    }()

    /**
     * 获取WMTS类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getWMTSLayer',
    value: function () {
      var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, wmts, layer;
        return _regeneratorRuntime.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context3.next = 3;
                  break;
                }

                return _context3.abrupt('return', null);

              case 3:
                wmts = new WMTS(this.iMapApi);
                layer = wmts.getLayer(result.id, result.name, result.url, result.options);

                wmts = null;
                return _context3.abrupt('return', layer);

              case 7:
              case 'end':
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      function getWMTSLayer(_x9, _x10) {
        return _ref4.apply(this, arguments);
      }

      return getWMTSLayer;
    }()

    /**
     * 获取Arcgis WMTS类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getArcgisWMTSLayer',
    value: function () {
      var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, arcgisWmts, layer;
        return _regeneratorRuntime.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context4.next = 3;
                  break;
                }

                return _context4.abrupt('return', null);

              case 3:
                arcgisWmts = new ArcgisWMTS(this.iMapApi);
                layer = arcgisWmts.getLayer(result.id, result.name, result.url, result.options);

                arcgisWmts = null;
                return _context4.abrupt('return', layer);

              case 7:
              case 'end':
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      function getArcgisWMTSLayer(_x12, _x13) {
        return _ref5.apply(this, arguments);
      }

      return getArcgisWMTSLayer;
    }()

    /**
     * 获取WMS类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getWMSLayer',
    value: function () {
      var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, wms, layer;
        return _regeneratorRuntime.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context5.next = 3;
                  break;
                }

                return _context5.abrupt('return', null);

              case 3:
                wms = new WMS(this.iMapApi);
                layer = wms.getLayer(result.id, result.name, result.url, result.options);

                wms = null;
                return _context5.abrupt('return', layer);

              case 7:
              case 'end':
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      function getWMSLayer(_x15, _x16) {
        return _ref6.apply(this, arguments);
      }

      return getWMSLayer;
    }()

    /**
     * 获取Arcgis WMS类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getArcgisWMSLayer',
    value: function () {
      var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, arcgisWms, layer;
        return _regeneratorRuntime.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context6.next = 3;
                  break;
                }

                return _context6.abrupt('return', null);

              case 3:
                arcgisWms = new ArcgisWMS(this.iMapApi);
                layer = arcgisWms.getLayer(result.id, result.name, result.url, result.options);

                arcgisWms = null;
                return _context6.abrupt('return', layer);

              case 7:
              case 'end':
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      function getArcgisWMSLayer(_x18, _x19) {
        return _ref7.apply(this, arguments);
      }

      return getArcgisWMSLayer;
    }()

    /**
     * 获取GeoExport类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getGeoExportLayer',
    value: function () {
      var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, geoExport, layer;
        return _regeneratorRuntime.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context7.next = 3;
                  break;
                }

                return _context7.abrupt('return', null);

              case 3:
                geoExport = new GeoExport(this.iMapApi);
                layer = geoExport.getLayer(result.id, result.name, result.url, result.options);

                geoExport = null;
                return _context7.abrupt('return', layer);

              case 7:
              case 'end':
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      function getGeoExportLayer(_x21, _x22) {
        return _ref8.apply(this, arguments);
      }

      return getGeoExportLayer;
    }()

    /**
     * 获取Arcgis Export类型服务的图层对象
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getArcgisExportLayer',
    value: function () {
      var _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(id, url) {
        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
        var result, arcgisExport, layer;
        return _regeneratorRuntime.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                result = validateServicesOptions(id, url, options);

                if (result) {
                  _context8.next = 3;
                  break;
                }

                return _context8.abrupt('return', null);

              case 3:
                arcgisExport = new ArcgisExport(this.iMapApi);
                layer = arcgisExport.getLayer(result.id, result.name, result.url, result.options);

                arcgisExport = null;
                return _context8.abrupt('return', layer);

              case 7:
              case 'end':
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      function getArcgisExportLayer(_x24, _x25) {
        return _ref9.apply(this, arguments);
      }

      return getArcgisExportLayer;
    }()

    /**
     * 根据对应内置的Web GIS Service服务类型获取解析的服务图层
     * @param {String} type 内置Web GIS Service服务类型
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     */

  }, {
    key: 'getServicesLayer',
    value: function () {
      var _ref10 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(type, id, url) {
        var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
        return _regeneratorRuntime.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                _context9.t0 = type;
                _context9.next = _context9.t0 === 'XYZTile' ? 3 : _context9.t0 === 'VTS' ? 4 : _context9.t0 === 'GeoTile' ? 5 : _context9.t0 === 'WMTS' ? 6 : _context9.t0 === 'ArcgisWMTS' ? 7 : _context9.t0 === 'WMS' ? 8 : _context9.t0 === 'ArcgisWMS' ? 9 : _context9.t0 === 'GeoExport' ? 10 : _context9.t0 === 'ArcgisExport' ? 11 : 12;
                break;

              case 3:
                return _context9.abrupt('return', this.getXYZTileLayer(id, url, options));

              case 4:
                return _context9.abrupt('return', this.getVTSLayer(id, url, options));

              case 5:
                return _context9.abrupt('return', this.getGeoTileLayer(id, url, options));

              case 6:
                return _context9.abrupt('return', this.getWMTSLayer(id, url, options));

              case 7:
                return _context9.abrupt('return', this.getArcgisWMTSLayer(id, url, options));

              case 8:
                return _context9.abrupt('return', this.getWMSLayer(id, url, options));

              case 9:
                return _context9.abrupt('return', this.getArcgisWMSLayer(id, url, options));

              case 10:
                return _context9.abrupt('return', this.getGeoExportLayer(id, url, options));

              case 11:
                return _context9.abrupt('return', this.getArcgisExportLayer(id, url, options));

              case 12:
                return _context9.abrupt('return', null);

              case 13:
              case 'end':
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      function getServicesLayer(_x27, _x28, _x29) {
        return _ref10.apply(this, arguments);
      }

      return getServicesLayer;
    }()

    /**
     * 根据对应内置的Web GIS Service服务类型自定义数据集合批量获取解析服务图层
     * @param {Array} arrayList 内置Web GIS Service服务类型数据集合数组
     */

  }, {
    key: 'getServicesLayers',
    value: function () {
      var _ref11 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10(arrayList) {
        var _this2 = this;

        var promiseList, result, layers;
        return _regeneratorRuntime.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                if (!isNotEmptyArray(arrayList)) {
                  _context10.next = 10;
                  break;
                }

                promiseList = [];

                arrayList.map(function (item) {
                  if (isPlainObject(item) && item.id && item.url) {
                    var options = item.options || {};
                    options.name = item.name || '';
                    var promise = new Promise(function (resolve) {
                      _this2.getServicesLayer(item.type, item.id, item.url, options).then(function (data) {
                        resolve(data);
                      })['catch'](function () {
                        resolve(null);
                      });
                    });
                    promiseList.push(promise);
                  }
                });

                if (!promiseList.length) {
                  _context10.next = 10;
                  break;
                }

                _context10.next = 6;
                return Promise.all(promiseList).then(function (result) {
                  return result;
                });

              case 6:
                result = _context10.sent;
                layers = [];

                result && result.length && result.map(function (layer) {
                  layer && layers.push(layer);
                });
                return _context10.abrupt('return', layers.length ? layers : null);

              case 10:
                return _context10.abrupt('return', null);

              case 11:
              case 'end':
                return _context10.stop();
            }
          }
        }, _callee10, this);
      }));

      function getServicesLayers(_x30) {
        return _ref11.apply(this, arguments);
      }

      return getServicesLayers;
    }()

    /**
     * 根据对应内置的Web GIS Service服务类型添加图层到地图
     * @param {String} type 内置Web GIS Service服务类型
     * @param {String} id 图层Id名称
     * @param {String} url 服务地址
     * @param {Object} options 解析服务的参数选项
     * @param {String} beforeId 待添加到指定图层(组)Id之前
     * @param {String} layerGroupId 图层组的Id名称
     */

  }, {
    key: 'addServicesLayer',
    value: function () {
      var _ref12 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11(type, id, url) {
        var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
        var beforeId = arguments[4];
        var layerGroupId = arguments[5];
        var layer;
        return _regeneratorRuntime.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                _context11.next = 2;
                return this.getServicesLayer(type, id, url, options);

              case 2:
                layer = _context11.sent;

                if (!layer) {
                  _context11.next = 9;
                  break;
                }

                if (!layerGroupId) {
                  _context11.next = 8;
                  break;
                }

                return _context11.abrupt('return', this.iMapApi.addLayerToGroup(layerGroupId, layer, beforeId));

              case 8:
                return _context11.abrupt('return', this.iMapApi.addLayer(layer, beforeId));

              case 9:
                return _context11.abrupt('return', null);

              case 10:
              case 'end':
                return _context11.stop();
            }
          }
        }, _callee11, this);
      }));

      function addServicesLayer(_x32, _x33, _x34) {
        return _ref12.apply(this, arguments);
      }

      return addServicesLayer;
    }()

    /**
     * 根据对应内置的Web GIS Service服务类型自定义数据集合批量添加图层到地图
     * @param {Array} arrayList 内置Web GIS Service服务类型数据集合数组
     * @param {String} beforeId 待添加到指定图层(组)Id之前
     * @param {String} layerGroupId 图层组的Id名称
     */

  }, {
    key: 'addServicesLayers',
    value: function () {
      var _ref13 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12(arrayList, beforeId, layerGroupId) {
        var layers;
        return _regeneratorRuntime.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                _context12.next = 2;
                return this.getServicesLayers(arrayList);

              case 2:
                layers = _context12.sent;

                if (!(layers && layers.length)) {
                  _context12.next = 9;
                  break;
                }

                if (!layerGroupId) {
                  _context12.next = 8;
                  break;
                }

                return _context12.abrupt('return', this.iMapApi.addLayersToGroup(layerGroupId, layers, beforeId));

              case 8:
                return _context12.abrupt('return', this.iMapApi.addLayers(layers, beforeId));

              case 9:
                return _context12.abrupt('return', null);

              case 10:
              case 'end':
                return _context12.stop();
            }
          }
        }, _callee12, this);
      }));

      function addServicesLayers(_x35, _x36, _x37) {
        return _ref13.apply(this, arguments);
      }

      return addServicesLayers;
    }()
  }]);

  return Services;
}(BasicMapApi);

export default Services;