'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _basicMapApiClass = require('../../util/basicMapApiClass');

var _methodsUtil = require('../../../_util/methods-util');

var _assign = require('lodash/assign');

var _assign2 = _interopRequireDefault(_assign);

var _hat = require('hat');

var _hat2 = _interopRequireDefault(_hat);

var _constants = require('./constants');

var _constants2 = _interopRequireDefault(_constants);

var _features_at = require('./libs/features_at');

var _features_at2 = _interopRequireDefault(_features_at);

var _string_set = require('./libs/string_set');

var _string_set2 = _interopRequireDefault(_string_set);

var _modes = require('./modes');

var _modes2 = _interopRequireDefault(_modes);

var _events = require('./events');

var _events2 = _interopRequireDefault(_events);

var _store = require('./store');

var _store2 = _interopRequireDefault(_store);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

/**
 * @文件说明: Interfaces.Draw 地图矢量图形绘制对象
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-05-21 16:12:06
 */

var defaultDrawOptions = {
  // 扩展绘图模式
  modes: null,
  // 绘图的图形主题样式
  theme: {},
  // 默认初始的Feature要素数据集合
  data: [],
  // 单击时的查询缓冲范围
  clickBuffer: 2,
  // Touch时查询缓冲范围
  touchBuffer: 25
};

var _drawOptions = Symbol('options');
var _uid = Symbol('uid');
var _ctx = Symbol('Context');
var _isInitModeChange = Symbol('isInitModeChange');

var Draw = function (_BasicMapApiEvented) {
  (0, _inherits3['default'])(Draw, _BasicMapApiEvented);
  (0, _createClass3['default'])(Draw, [{
    key: 'uid',

    /**
     * 当前绘图的唯一Id
     * @readonly
     */
    get: function get() {
      return this[_uid];
    }

    /**
     * 当前绘图的参数项
     * @readonly
     */

  }, {
    key: 'options',
    get: function get() {
      return this[_drawOptions];
    }

    // 构造函数

  }]);

  function Draw(iMapApi) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    (0, _classCallCheck3['default'])(this, Draw);

    // 合并与设置参数选项
    var _this = (0, _possibleConstructorReturn3['default'])(this, (Draw.__proto__ || Object.getPrototypeOf(Draw)).call(this, iMapApi));

    options.modes = !options.modes ? _modes2['default'] : (0, _assign2['default'])({}, _modes2['default'], options.modes);
    var opts = (0, _assign2['default'])({}, defaultDrawOptions, options);
    _this[_uid] = (0, _hat2['default'])();
    // 添加默认绘图模式
    opts.defaultMode = _constants2['default'].modes.STATIC;
    // 赋值参数选项
    _this[_drawOptions] = opts;
    // 是否首次Mode模式更新
    _this[_isInitModeChange] = true;

    // 禁用/启用状态
    _this._enabled = false;
    // 对象活动状态
    _this._active = false;
    // 定义内部作用域对象
    var ctx = {
      api: _this,
      uid: _this[_uid],
      options: opts,
      iMapApi: _this.iMapApi,
      map: _this.iMapApi && _this.iMapApi.map || null,
      container: _this.iMapApi && _this.iMapApi.getMapViewContainer() || null,
      cursor: _this.iMapApi && _this.iMapApi.Handlers.cursor,
      setActive: function setActive(active) {
        _this._active = !!active;
      }
    };
    // 注册绘图模式的事件框架
    ctx.events = (0, _events2['default'])(ctx);
    // 注册绘图的数据管理对象
    ctx.store = new _store2['default'](ctx);
    // 当有前置矢量数据时，则添加绘图的图层
    if (!(0, _methodsUtil.isEmpty)(opts.data) && !ctx.store.isLoadedLayers()) {
      ctx.store.addLayers();
    }

    _this[_ctx] = ctx;
    return _this;
  }

  /**
   * 激活绘图模式
   */


  (0, _createClass3['default'])(Draw, [{
    key: 'enable',
    value: function enable(mode) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

      var store = this[_ctx].store;
      var events = this[_ctx].events;
      // 判断是否未添加绘图的图层，则渲染图层
      !store.isLoadedLayers() && store.addLayers();
      // 启动绘图事件监听
      var silent = false;
      if (!events.isLoadedEventListeners()) {
        events.addEventListeners();
        // 判断是否首次启动模式激活
        if (this[_isInitModeChange]) {
          events.start();
          this[_isInitModeChange] = false;
          silent = true;
        }
      }
      // 切换绘图模式
      this.changeMode(mode, options, { silent: silent });
      // 更新状态
      this._enabled = mode === _constants2['default'].modes.STATIC ? false : true;
    }

    /**
     * 取消激活绘图模式
     */

  }, {
    key: 'disable',
    value: function disable() {
      var events = this[_ctx].events;
      // 切换成静态模式
      this.changeMode(_constants2['default'].modes.STATIC, {}, { silent: true });
      // 移除绘图事件监听
      if (events.isLoadedEventListeners()) {
        events.removeEventListeners();
      }
      // 更新状态
      this._active = false;
      this._enabled = false;
    }

    /**
     * 获取当前禁用/启用状态
     */

  }, {
    key: 'isEnabled',
    value: function isEnabled() {
      return !!this._enabled;
    }

    /**
     * 获取当前活动状态
     */

  }, {
    key: 'isActive',
    value: function isActive() {
      return !!this._active;
    }

    /**
     * 销毁绘图的实例（包括图层数据）
     */

  }, {
    key: 'destroy',
    value: function destroy() {
      var store = this[_ctx].store;

      // 还原默认静态模式
      this.disable();
      // 移除数据图层
      if (store.isLoadedLayers()) {
        store.removeLayers();
      }
      // 重置内置参数
      this[_isInitModeChange] = true;
      this[_ctx] = null;
    }

    /**
     * 获取当前激活的绘图模式
     */

  }, {
    key: 'getMode',
    value: function getMode() {
      return this[_ctx].events.getMode();
    }

    /**
     * 更新当前绘图模式
     * @param {String} mode 待更新的绘图模式名
     * @param {Object} options 待更新的绘图模式参数选项
     * @param {Object} eventOptions 切换模式时的参数；<silent> 是否不驱动ModeChange事件回调
     */

  }, {
    key: 'changeMode',
    value: function changeMode(mode) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var eventOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

      var events = this[_ctx].events;
      events && events.changeMode(mode, options, eventOptions);
      if (mode === _constants2['default'].modes.STATIC) {
        this._enabled = false;
      }
    }

    /**
     * 设置当前模式的地图光标样式及Tip提示
     * @param {Object} options 光标参数选项
     */

  }, {
    key: 'setModeCursor',
    value: function setModeCursor() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

      var events = this[_ctx].events;
      var mode = events.getCurrentModeInstance();
      mode && mode.updateCursor(options);
    }

    /**
     * 执行当前绘图模式的删除
     */

  }, {
    key: 'trash',
    value: function trash() {
      var events = this[_ctx].events;
      events && events.trash && events.trash();
    }

    /**
     * 执行当前编辑模式的同类型Feature要素合并成复合要素
     */

  }, {
    key: 'combineFeatures',
    value: function combineFeatures() {
      var events = this[_ctx].events;
      events && events.combineFeatures && events.combineFeatures();
    }

    /**
     * 执行当前编辑模式复合要素类型拆分为单类型Feature要素
     */

  }, {
    key: 'uncombineFeatures',
    value: function uncombineFeatures() {
      var events = this[_ctx].events;
      events && events.uncombineFeatures && events.uncombineFeatures();
    }

    /**
     * 根据屏幕坐标点或BBOX范围查询绘图的Feature要素的Id集合
     * @param {Point} point 待查询的屏幕坐标
     */

  }, {
    key: 'getFeatureIdsAt',
    value: function getFeatureIdsAt(point) {
      var ctx = this[_ctx];
      var features = _features_at2['default'].click({ point: point }, null, ctx);
      if (features && features.length) {
        features = features.filter(function (feature) {
          return feature.properties['draw:meta'] === _constants2['default'].meta.FEATURE;
        });
      } else {
        features = [];
      }
      return features.map(function (feature) {
        return feature.id || feature.properties['draw:id'];
      });
    }

    /**
     * 根据要素Id获取Feature要素对象
     * @param {String} id 要素Feature的Id
     */

  }, {
    key: 'getFeature',
    value: function getFeature(id) {
      var feature = this[_ctx].store.get(id);
      if (feature && feature.properties['draw:meta'] === _constants2['default'].meta.FEATURE) {
        var geojson = feature.toGeoJSON();
        var keys = Object.keys(geojson.properties);
        var properties = {};
        keys.map(function (key) {
          if (key.indexOf('draw:') !== 0) {
            properties[key] = geojson.properties[key];
          }
        });
        geojson.properties = properties;
        return geojson;
      }
      return null;
    }

    /**
     * 获取所有的Feature要素
     */

  }, {
    key: 'getAllFeatures',
    value: function getAllFeatures() {
      var _this2 = this;

      var features = this[_ctx].store.getAll();
      return features.map(function (feature) {
        return _this2.getFeature(feature.id);
      }).filter(function (feature) {
        return feature !== null && feature !== undefined;
      });
    }

    /**
     * 获取当前选中的Feature要素Id集合
     */

  }, {
    key: 'getSelectedIds',
    value: function getSelectedIds() {
      return this[_ctx].store.getSelectedIds();
    }

    /**
     * 获取当前选中的Feature要素
     */

  }, {
    key: 'getSelected',
    value: function getSelected() {
      var _this3 = this;

      var selectedIds = this.getSelectedIds();
      if (selectedIds && selectedIds.length) {
        return selectedIds.map(function (id) {
          return _this3.getFeature(id);
        });
      }
      return [];
    }

    /**
     * 获取当前选中的Vertex节点
     */

  }, {
    key: 'getSelectedVertexs',
    value: function getSelectedVertexs() {
      var selectedCoordinates = this[_ctx].store.getSelectedCoordinates();
      if (selectedCoordinates && selectedCoordinates.length) {
        return selectedCoordinates.map(function (item) {
          var id = (0, _hat2['default'])();
          return {
            type: _constants2['default'].geojsonTypes.FEATURE,
            id: id,
            geometry: {
              type: _constants2['default'].geojsonTypes.POINT,
              coordinates: item.coordinates
            },
            properties: {
              'draw:id': id,
              'draw:path': item.path,
              'draw:pid': item.pid
            }
          };
        });
      }
      return [];
    }

    /**
     * 设置指定Id的Feature要素的Properties属性
     * @param {String} id Feature要素的Id
     * @param {String} key 属性名
     * @param {String|Number|Boolean} value 属性值
     */

  }, {
    key: 'setFeatureProperty',
    value: function setFeatureProperty(id, key, value) {
      this[_ctx].store.setFeatureProperty(id, key, value);
    }

    /**
     * 添加绘图的要素数据
     * @param {FeatureCollection} FeatureCollection 待添加的Feature要素集合
     */

  }, {
    key: 'add',
    value: function add(featureCollection) {
      var store = this[_ctx].store;
      var events = this[_ctx].events;
      var collection = this.iMapApi.getFeatureCollection(featureCollection);
      var featureIds = [];
      if (collection && collection.features.length) {
        collection.features.map(function (geojson) {
          geojson.id = geojson.id || (0, _hat2['default'])();
          var _feature = store.get(geojson.id);
          if (_feature === undefined || _feature === null) {
            var feature = store.getFeatureToGeoJSON(geojson);
            store.add(feature);
            featureIds.push(feature.id);
          }
        });
        // 判断是否还未激活绘图模式，则激活默认静态模式
        if (!events.getMode()) {
          this.enable(_constants2['default'].modes.STATIC);
        } else {
          store.render();
        }
        return featureIds;
      }
    }

    /**
     * 删除指定Id的Feature要素
     * @param {Array} featureIds Feature要素的Id集合
     */

  }, {
    key: 'delete',
    value: function _delete(featureIds) {
      var store = this[_ctx].store;
      var events = this[_ctx].events;
      store['delete'](featureIds);
      if (!events.getMode()) {
        this.enable(_constants2['default'].modes.STATIC);
      } else {
        store.setModeChangeRendering();
        store.render();
      }
    }

    /**
     * 清空所有绘制的Feature要素
     */

  }, {
    key: 'deleteAll',
    value: function deleteAll() {
      var ids = this[_ctx].store.getAllIds();
      ids && ids.length && this['delete'](ids);
    }

    /**
     * 设置绘图的要素数据集合
     * @param {FeatureCollection} featureCollection 待覆盖的Feature要素集合
     */

  }, {
    key: 'set',
    value: function set(featureCollection) {
      var store = this[_ctx].store;
      var collection = this.iMapApi.getFeatureCollection(featureCollection);
      if (collection && collection.features.length) {
        var renderBatch = store.createRenderBatch();
        var toDelete = store.getAllIds().slice();
        var newIds = this.add(featureCollection);
        var newIdsLookup = new _string_set2['default'](newIds);
        toDelete = toDelete.filter(function (id) {
          return !newIdsLookup.has(id);
        });
        if (toDelete.length) {
          this['delete'](toDelete);
        }
        renderBatch();
        return newIds;
      }
    }
  }]);
  return Draw;
}(_basicMapApiClass.BasicMapApiEvented);

exports['default'] = Draw;