import _regeneratorRuntime from 'babel-runtime/regenerator';
import _asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _extends from 'babel-runtime/helpers/extends';
/**
 * @文件说明: Services.GeoTile 吉奥瓦片服务
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-03-25 12:13:14
 */

import assign from 'lodash/assign';
import { isBooleanFlase } from '../../../_util/methods-util';
import { defaultServicesSourceOptions, defaultServicesLayerOptions, getServicesLayerSource, getServicesBaseLayer } from './index';

/**
 * 解析GeoTile类型的服务地址获取图层服务数据信息
 */
var fetchGeoTileCapabilities = function fetchGeoTileCapabilities(own, url, options) {
  var GeoGlobe = own.exports.GeoGlobe;

  var isProxyUrl = isBooleanFlase(options.proxy) ? false : true;

  return new Promise(function (resolve, reject) {
    var capabilitiesUrl = url;
    // 处理吉奥瓦片服务的地址
    var urlParams = url.indexOf('?') !== -1 ? url.split('?')[1] : '';
    if (url.indexOf('/DataServer') !== -1) {
      capabilitiesUrl = url.replace(/\/DataServer/g, '/services/tile/GetCapabilities');
    } else if (url.indexOf('/services/tile') !== -1) {
      capabilitiesUrl = url + '/GetCapabilities';
    }
    isProxyUrl && (capabilitiesUrl = '' + own.proxyURL + capabilitiesUrl);
    urlParams && (capabilitiesUrl = capabilitiesUrl + '?' + urlParams);

    // 请求图层数据信息
    var errorMsg = '\u5409\u5965\u74E6\u7247GeoTile\u670D\u52A1\u5730\u5740[ ' + url + ' ]\u6570\u636E\u89E3\u6790\u5931\u8D25.';
    GeoGlobe.Request.GET({
      url: capabilitiesUrl,
      success: function success(data) {
        var opts = {};
        try {
          var capabilities = new GeoGlobe.Format.XML().read(data.responseText);
          if (capabilities) {
            var tileData = capabilities.querySelector('Data').querySelector('TileData');
            // 图层标识
            opts.layerName = capabilities.querySelector('Name').textContent;
            // 版本号
            opts.version = capabilities.querySelector('Version').textContent;
            // 瓦片大小
            var tileSize = tileData.querySelector('TilePixelsX').textContent;
            opts.tileSize = tileSize || 256;
            // CRS
            opts.crs = tileData.querySelector('CRS').textContent;
            // 矩形范围
            var bounding = tileData.querySelector('BoundBox');
            opts.tileBBox = [bounding.getAttribute('minx'), bounding.getAttribute('miny'), bounding.getAttribute('maxx'), bounding.getAttribute('maxy')].join(',');
            // 层级
            opts.minZoom = parseInt(tileData.querySelector('TopLevel').textContent, 10);
            opts.maxZoom = parseInt(tileData.querySelector('BottomLevel').textContent, 10);
            // 金字塔顶级范围
            var topTile = tileData.querySelector('Pyramid').querySelector('TopTile');
            opts.topTileExtent = [Number(topTile.getAttribute('FromX')), Number(topTile.getAttribute('ToY')), Number(topTile.getAttribute('ToX')), Number(topTile.getAttribute('FromY'))];
          }
        } catch (e) {
          console.error(errorMsg);
          reject();
        }
        resolve(opts);
      },
      failure: function failure() {
        console.error(errorMsg);
        reject();
      }
    });
  });
};

/**
 * 解析GeoTile类型的服务地址获取图层样式信息
 */
var fetchGeoTileLayerStyles = function fetchGeoTileLayerStyles(own, id, url, layerOptions, options) {
  var isProxyUrl = isBooleanFlase(options.proxy) ? false : true;
  // 构建数据源
  var source = getServicesLayerSource(options);
  source.tileSize = options.tileSize || layerOptions.tileSize || source.defaultTileSize;
  // 拼接数据源瓦片地址
  var urlParams = url.indexOf('?') !== -1 ? url.split('?')[1] : '';
  var tileUrl = url;
  if (tileUrl.indexOf('/services/tile') !== -1) {
    tileUrl = tileUrl.replace(/\/services\/tile/g, '/DataServer');
  }
  tileUrl += '?T=tile&X={x}&Y={y}&L={z}';
  urlParams && (tileUrl += '&' + urlParams);
  isProxyUrl && (tileUrl = '' + own.proxyURL + tileUrl);
  source.tiles = [tileUrl];
  // 构建图层
  var layer = getServicesBaseLayer(options);
  layer.id = id;
  layer.source = source;
  layer.minzoom = !layer.minzoom || layer.minzoom < layerOptions.minZoom ? layerOptions.minZoom : layer.minzoom;
  layer.maxzoom = !layer.maxzoom || layer.maxzoom > layerOptions.maxZoom + 1 ? layerOptions.maxZoom + 1 : layer.maxzoom;
  layer.metadata = assign({}, layer.metadata, _extends({
    serviceType: 'GeoTile',
    serviceName: options.name || ''
  }, layerOptions));
  if (layer.metadata.tileBBox) {
    var bbox = layer.metadata.tileBBox.split(',');
    layer.metadata.tileBBox = [[Number(bbox[0]), Number(bbox[1])], [Number(bbox[2]), Number(bbox[3])]];
  }
  return layer;
};

var GeoTile = function () {
  function GeoTile(iMapApi) {
    _classCallCheck(this, GeoTile);

    this.iMapApi = iMapApi;
    this.exports = iMapApi && iMapApi.exports ? iMapApi.exports : {};
    this.proxyURL = iMapApi.proxyURL || '';
    this.options = _extends({}, defaultServicesSourceOptions, defaultServicesLayerOptions);
  }

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


  _createClass(GeoTile, [{
    key: 'getLayer',
    value: function () {
      var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(id) {
        var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
        var url = arguments[2];
        var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
        var opts, layerOptions;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                opts = assign(this.options, options);
                // 获取服务信息

                _context.next = 3;
                return fetchGeoTileCapabilities(this, url, opts);

              case 3:
                layerOptions = _context.sent;
                return _context.abrupt('return', fetchGeoTileLayerStyles(this, id, url, layerOptions, _extends({}, opts, { name: name })));

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

      function getLayer(_x3) {
        return _ref.apply(this, arguments);
      }

      return getLayer;
    }()
  }]);

  return GeoTile;
}();

export default GeoTile;