import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props';
import _defineProperty from 'babel-runtime/helpers/defineProperty';
/**
 * @文件说明: Map Component - 地图组件
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-03-10 19:01:55
 */

import 'whatwg-fetch';
import Vue from 'vue';
import Base from '../base';
import hat from 'hat';
import isPlainObject from 'lodash/isPlainObject';
import { PreLoading, Message } from './components';
import Controls from './controls';
import Interactions from './interactions';
import { initDefaultProps } from '../_util/antdv';
import { getPrefixCls, isString, isNumeric, isFunction, isArray, isNotEmptyArray, isBoolean, isBooleanTrue, isBooleanFlase, isInteger, isEmpty, has, isHttpUrl, isCoordinate, hasClass, addClass, removeClass, getUrlToLink, fetchJsFile } from '../_util/methods-util';
import { topTileExtentToGauss, topTileExtentToWMTS, topTileExtentToResolution } from '../_pmap/util/topTileExtent';
import transform from '../_pmap/util/transform';
import DOM from '../_pmap/util/dom';
import Query from '../_pmap/query';
import PJtoolsMap from '../_pmap';
import mapProps from './mapProps';

var Map = {
  name: 'PjMap',
  components: {
    PreLoading: PreLoading,
    Controls: Controls,
    Interactions: Interactions
  },
  inheritAttrs: false,
  props: initDefaultProps(mapProps(), {
    width: '100%',
    height: '100%',
    baseUrl: '/static/GeoMap/',
    plugins: {},
    imageIcons: []
  }),
  data: function data() {
    var message = this.setMapMessageInstance();

    return {
      // 地图的Pre-Loading预加载状态
      preloading: true,
      // 地图的Pre-Loading预加载的描述
      description: '',
      // 地图的Message消息实例对象
      message: message,
      // 地图Map的实例化对象
      iMapApi: null,
      // 地图控件数据集合
      mapControls: null,
      // 地图UI组件对象集合
      mapInteractions: [],
      // 地图移除销毁状态
      mapRemoved: false
    };
  },
  provide: function provide() {
    var _vm = this;
    // 定义Class类名前缀
    var customizePrefixCls = _vm.prefixCls;

    var prefixCls = getPrefixCls('map', customizePrefixCls);
    // 定义传递属性的代理对象
    this.proxyVm = new Vue({
      data: function data() {
        return {
          prefixCls: prefixCls,
          message: _vm.message,
          iMapApi: _vm.iMapApi,
          $slots: _vm.$slots,
          $scopedSlots: _vm.$scopedSlots
        };
      }
    });
    return {
      mapProvider: this.proxyVm._data
    };
  },

  computed: {
    classes: function classes() {
      var _ref;

      var bordered = this.bordered,
          prefixCls = this.proxyVm.prefixCls;

      return _ref = {}, _defineProperty(_ref, '' + prefixCls, true), _defineProperty(_ref, prefixCls + '-bordered', bordered), _ref;
    },
    styles: function styles() {
      var width = this.width,
          height = this.height;

      var containerWidth = isNumeric(width) ? width + 'px' : String(width);
      var containerHeight = isNumeric(height) ? height + 'px' : String(height);
      return {
        width: containerWidth,
        height: containerHeight
      };
    }
  },
  mounted: function mounted() {
    this.proxyVm._data.$scopedSlots = this.$scopedSlots;
    this.preloadMapPluginsDll();
  },
  beforeDestroy: function beforeDestroy() {
    this.destroyPJtoolsMap();
  },

  methods: {
    // 实例化当前地图组件的Message消息
    setMapMessageInstance: function setMapMessageInstance() {
      var _this = this;

      return new Message(hat(), {
        getContainer: function getContainer() {
          return _this.$refs.PJtoolsMapSection || document.body;
        }
      });
    },


    // 渲染地图的预加载初始化时的Pre-Loading组件
    renderPreLoading: function renderPreLoading() {
      var h = this.$createElement;
      var preloading = this.preloading,
          description = this.description;


      if (!preloading) {
        return null;
      }

      return h(
        PreLoading,
        {
          attrs: { description: description },
          on: {
            'destroy': this.handlePreLoadingDestroy
          }
        },
        [this.$slots && this.$slots.preloading ? h(
          'template',
          { slot: 'preloading' },
          [this.$slots.preloading]
        ) : null]
      );
    },


    // 触发Pre-Loading组件注销时回调事件
    handlePreLoadingDestroy: function handlePreLoadingDestroy() {
      this.$emit('loaded', this.iMapApi);
    },


    // 预加载地图依赖插件基础库
    preloadMapPluginsDll: function preloadMapPluginsDll() {
      var _this2 = this;

      var baseUrl = this.baseUrl,
          plugins = this.plugins;
      // 判断是否有追加的地图配置清单插件，则预加载注入

      var appendLoad = {};
      plugins && plugins.js && isNotEmptyArray(plugins.js) && (appendLoad.js = plugins.js);
      plugins && plugins.css && isNotEmptyArray(plugins.css) && (appendLoad.css = plugins.css);

      this.description = '地图依赖资源加载中';
      this.$preload.load({
        baseUrl: baseUrl,
        appendLoad: appendLoad
      }).then(function (exports) {
        setTimeout(function () {
          _this2.initPJtoolsMap(exports);
        }, 0);
      })['catch'](function () {
        _this2.message.error('地图前置依赖资源库加载失败，资源库地址可能错误或不存在.');
      });
    },


    // 渲染地图的容器区域
    renderMapContainer: function renderMapContainer() {
      var h = this.$createElement;
      var prefixCls = this.proxyVm.prefixCls,
          mapControls = this.mapControls,
          mapInteractions = this.mapInteractions,
          mapRemoved = this.mapRemoved;

      var mapCls = prefixCls + '-container';

      return !mapRemoved ? h(
        'div',
        { 'class': mapCls },
        [h(
          'div',
          { 'class': mapCls + '-views-group', attrs: { tabindex: '0', hidefocus: 'true' }
          },
          [h('div', { ref: 'PJMapViewWrapper', 'class': mapCls + '-view-wrapper' })]
        ), h(
          'div',
          { 'class': prefixCls + '-extended-components' },
          [mapControls && mapControls.length ? h(Controls, { ref: 'mapControls', attrs: { dataList: mapControls }
          }) : null, h(Interactions, { ref: 'mapInteractions', attrs: { data: mapInteractions }
          }), h('section', {
            attrs: { 'data-type': 'component' }
          })]
        )]
      ) : null;
    },


    // 加载解析当前地图的配置文件
    loadMapConfig: function loadMapConfig() {
      var _this3 = this;

      var baseUrl = this.baseUrl,
          config = this.config;


      return new Promise(function (resolve, reject) {
        if (config) {
          // 判断config是否为字符串格式类型，则采用异步读取配置文件形式
          if (typeof config === 'string') {
            var url = '' + config;
            // 判断是否不是有效的Http链接地址，则拼接前缀基础路径
            if (!isHttpUrl(config)) {
              url = getUrlToLink(url, baseUrl);
            }
            // 异步请求Config配置文件
            fetchJsFile(url).then(function (data) {
              if (data) {
                resolve(data);
              } else {
                _this3.message.error('地图初始化[config]参数配置文件地址路径或内容解析错误.');
                reject();
              }
            })['catch'](function (error) {
              reject(error);
            });
          } else if (isPlainObject(config)) {
            resolve(config);
          }
        } else {
          reject('未设定地图初始化[config]参数配置项，无法保证地图的有效渲染.');
        }
      });
    },


    // 实例化PJtools.Map地图对象
    initPJtoolsMap: function initPJtoolsMap(exports) {
      var _this4 = this;

      if (!this.$refs.PJMapViewWrapper) {
        this.message.error('地图初始化容器对象不存在，请检查设定是否正确.');
        return;
      }

      this.mapRemoved = false;
      this.description = '地图初始化配置';
      this.loadMapConfig().then(function (config) {
        // 设定Map地图样式的默认字体库
        config.glyphs = getUrlToLink('glyphs/', _this4.baseUrl) + '{fontstack}/{range}.pbf';
        // 实例化地图
        new PJtoolsMap(_this4.$refs.PJMapViewWrapper, exports, config, {
          onRender: function onRender(iMapApi) {
            _this4.iMapApi = iMapApi;
            _this4.iMapApi.component = _this4;
            _this4.proxyVm._data.iMapApi = _this4.iMapApi;
            // 更新Pre-Loading的提示语
            _this4.description = '地图正在加载图层源数据';
            // 更新地图控件数据
            _this4.mapControls = _this4.iMapApi && _this4.iMapApi.options && _this4.iMapApi.options.mapControls && _this4.iMapApi.options.mapControls.length ? _this4.iMapApi.options.mapControls : [];
            // 触发设定存在的[render]回调事件
            _this4.$emit('render', _this4.iMapApi);
          },
          onLoad: function onLoad() {
            var completed = function completed() {
              // 移除Pre-Loading预加载转场
              _this4.description = '';
              _this4.preloading = false;
            };
            // 判断是否有前置地图图标资源需加载，则渲染加载图标后再执行地图完成事件
            if (isNotEmptyArray(_this4.imageIcons)) {
              _this4.iMapApi.loadImages(_this4.imageIcons).then(function () {
                completed();
              })['catch'](function () {
                completed();
              });
            } else {
              completed();
            }
          }
        });
      });
    },


    // 销毁PJtools.Map地图对象
    destroyPJtoolsMap: function destroyPJtoolsMap() {
      // 销毁实例化地图
      this.iMapApi && this.iMapApi.remove();
      // 销毁地图控件
      this.mapControls = null;
      // 销毁地图交互组件
      this.mapInteractions = [];
      // 更新地图销毁状态
      this.mapRemoved = true;
      // 销毁地图实例化对象
      this.iMapApi = null;
    }
  },
  render: function render() {
    var h = arguments[0];
    var classes = this.classes,
        styles = this.styles;

    var mapProps = {
      'class': classes,
      style: styles
    };

    return h(
      'section',
      _mergeJSXProps([{ ref: 'PJtoolsMapSection' }, mapProps]),
      [this.renderMapContainer(), this.renderPreLoading()]
    );
  }
};

Map.install = function (Vue) {
  Vue.use(Base);
  Vue.component(Map.name, Map);
};

// 对外挂接静态方法
Map.$methods = {
  topTileExtentToGauss: topTileExtentToGauss,
  topTileExtentToWMTS: topTileExtentToWMTS,
  topTileExtentToResolution: topTileExtentToResolution,
  isString: isString,
  isNumeric: isNumeric,
  isPlainObject: isPlainObject,
  isFunction: isFunction,
  isArray: isArray,
  isNotEmptyArray: isNotEmptyArray,
  isBoolean: isBoolean,
  isBooleanTrue: isBooleanTrue,
  isBooleanFlase: isBooleanFlase,
  isInteger: isInteger,
  isEmpty: isEmpty,
  has: has,
  isHttpUrl: isHttpUrl,
  isCoordinate: isCoordinate,
  hasClass: hasClass,
  addClass: addClass,
  removeClass: removeClass,
  getUrlToLink: getUrlToLink
};
// 对外挂接互联网坐标转换静态方法
Map.$transform = transform;
// 对外挂接常见DOM操作静态方法
Map.$dom = DOM;
// 对外挂接Web GIS Service服务查询静态方法
Map.$query = new Query();

export default Map;