'use strict';

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

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

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

var _assign2 = _interopRequireDefault(_assign);

var _round = require('lodash/round');

var _round2 = _interopRequireDefault(_round);

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

var _constants2 = _interopRequireDefault(_constants);

var _common_selectors = require('../libs/common_selectors');

var _is_event_at_coordinates = require('../libs/is_event_at_coordinates');

var _is_event_at_coordinates2 = _interopRequireDefault(_is_event_at_coordinates);

var _point = require('./point');

var _line = require('./line');

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

var DEFAULT_CURSOR_OPTIONS = {
  cursor: 'default',
  icon: 'highlight',
  content: '单击确定起点，ESC键取消',
  clicked: '单击绘制节点，双击结束'
};

// 计算当前绘制Polygon面要素的面积与周长
/**
 * @文件说明: Draw.Modes.Polygon 绘制“多边形面”模式
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-05-29 18:18:42
 */

var calculatePolygonArea = exports.calculatePolygonArea = function calculatePolygonArea(context, coordinates) {
  if (!coordinates || coordinates.length < 1) {
    return {};
  }
  var iMapApi = context.ctx.api.iMapApi;
  var turf = iMapApi.exports.turf;

  var wgs84Coordinates = iMapApi.toWGS84(coordinates);
  // 循环计算周长
  var distance = 0;
  wgs84Coordinates && wgs84Coordinates.map(function (coordinate) {
    if (coordinate.length > 2) {
      coordinate.length === 3 && coordinate.splice(coordinate.length - 1, 1);
      var _measure = (0, _line.calculateLineDistance)(context, coordinate);
      if (_measure && _measure.measure && _measure.measure.line) {
        distance += _measure.measure.line.unit === 'm' ? _measure.measure.line.distance / 1000 : _measure.measure.line.distance;
      }
    }
  });
  var measure = {};
  if (distance > 0) {
    var length = distance < 1 ? distance * 1000 : distance;
    measure.perimeter = {
      distance: length,
      round: (0, _round2['default'])(length, 2),
      unit: distance < 1 ? 'm' : 'km',
      unitCN: distance < 1 ? '米' : '千米'
    };
  }
  // 判定是否面的坐标点是否超过3个
  if (wgs84Coordinates && wgs84Coordinates[0] && wgs84Coordinates[0].length > 3) {
    // 计算面积
    var polygon = turf.polygon(wgs84Coordinates);
    var area = turf.area(polygon);
    measure.polygon = {
      area: area >= 1000 ? area / 1000 : area,
      round: area,
      unit: area >= 1000 ? 'km²' : '㎡',
      unitCN: area >= 1000 ? '平方千米' : '平方米'
    };
    measure.polygon.round = (0, _round2['default'])(measure.polygon.area, 2);
  }

  return {
    measure: measure
  };
};

var PolygonMode = {};

// Mode模式的注册 - 激活入口
PolygonMode.onSetup = function () {
  var _this = this;

  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

  // 合并绘制Polygon模式的光标
  var cursorOptions = (0, _assign2['default'])({}, DEFAULT_CURSOR_OPTIONS, options && options.cursor || {});
  options && (options.cursor = cursorOptions);
  // 执行默认初始化
  (0, _point.defaultDrawSetupMethodsSetup)(this, options.cursor);

  var renderRequest = void 0;
  return {
    options: options,
    // 当前节点的索引值
    currentVertexIndex: 0,
    // 当前单击时间戳
    clickTime: null,
    // MouseMove事件的节流刷新
    handleThrottleMouseMove: function handleThrottleMouseMove(state, e) {
      if (!renderRequest) {
        renderRequest = requestAnimationFrame(function () {
          renderRequest = null;
          _this.throttleMouseMove.call(_this, state, e);
        });
      }
    }
  };
};

// 触发已绘制的所有Feature矢量要素对象进行显示渲染
PolygonMode.toDisplayFeatures = function (state, geojson, display) {
  var isActiveVertexPoint = state && state.vertex && state.vertex.id === geojson.id;
  var isActiveTempLine = state && state.templine && state.templine.id === geojson.id;
  var isActiveMoveLine = state && state.moveline && state.moveline.id === geojson.id;
  var isActivePolygon = state && state.polygon && state.polygon.id === geojson.id;

  // 判断是否为当前绘制<活动状态>的节点要素、Move移动线要素、TempLine线要素、Polygon面要素
  if (isActiveVertexPoint || isActiveTempLine || isActiveMoveLine || isActivePolygon) {
    if (geojson.properties['draw:active'] === _constants2['default'].activeStates.INACTIVE) {
      isActiveVertexPoint && state.vertex.updateInternalProperty('active', _constants2['default'].activeStates.ACTIVE);
      isActiveTempLine && state.templine.updateInternalProperty('active', _constants2['default'].activeStates.ACTIVE);
      isActiveMoveLine && state.moveline.updateInternalProperty('active', _constants2['default'].activeStates.ACTIVE);
      isActivePolygon && state.polygon.updateInternalProperty('active', _constants2['default'].activeStates.ACTIVE);
      geojson.properties['draw:active'] = _constants2['default'].activeStates.ACTIVE;
    }
    // 判断是否绘制完成
    if (isActivePolygon && state.polygon && state.polygon.completed === true) {
      // 修改当前绘制的Feature为非活动状态
      if (geojson.properties['draw:active'] === _constants2['default'].activeStates.ACTIVE) {
        geojson.properties['draw:active'] = _constants2['default'].activeStates.INACTIVE;
        state.polygon.updateInternalProperty('active', _constants2['default'].activeStates.INACTIVE);
      }
      display(geojson);
      this.onCompleted(geojson);
      return;
    }
  }
  display(geojson);
};

// Mode模式 - 取消释放
PolygonMode.onStop = function (state) {
  // 移除当前绘制<活动状态>的临时线与节点要素
  this.deleteMoveLineAndVertex(state);
  // 移除当前绘制<活动状态>未完成的Polygon面要素
  if (state.polygon && !state.polygon.completed) {
    this.deleteFeature([state.polygon.id], { silent: true });
    delete state.polygon;
    // 驱动事件回调
    this.ctx.api.fire(_constants2['default'].events.DRAW_CANCEL, {
      mode: this.getMode()
    });
  }
  // 执行默认取消释放
  (0, _point.defaultDrawSetupMethodsStop)(this);
  // 重置当前绘制Polygon要素的节点索引
  state.currentVertexIndex = 0;
  // 重置当前单击的时间戳
  state.clickTime = null;
};

// 触发删除选中的Feature矢量要素
PolygonMode.onTrash = function (state) {
  this.onCancel(state);
};

// 触发Tap/Click时的响应事件
PolygonMode.onTap = PolygonMode.onClick = function (state, e) {
  // 判断是否未构建<活动状态>的Polygon要素，则进行创建
  if (!state || !state.polygon) {
    var polygon = this.newFeature({
      geometry: {
        type: _constants2['default'].geojsonTypes.POLYGON,
        coordinates: []
      }
    });
    state.polygon = polygon;
    state.polygon.completed = false;
    this.addFeature(polygon);
    // 创建临时Vertex节点要素对象
    var vertex = this.newFeature({
      geometry: {
        type: _constants2['default'].geojsonTypes.MULTI_POINT,
        coordinates: []
      }
    });
    vertex.updateInternalProperty('meta', _constants2['default'].meta.VERTEX);
    vertex.updateInternalProperty('pid', state.polygon.id);
    state.vertex = vertex;
    this.addFeature(vertex);
    // 创建临时Outline边线要素对象
    var templine = this.newFeature({
      geometry: {
        type: _constants2['default'].geojsonTypes.LINE_STRING,
        coordinates: []
      }
    });
    templine.updateInternalProperty('meta', _constants2['default'].meta.TEMPLINE);
    templine.updateInternalProperty('pid', state.polygon.id);
    state.templine = templine;
    this.addFeature(templine);
    // 创建临时Move时Line要素对象
    var moveline = this.newFeature({
      geometry: {
        type: _constants2['default'].geojsonTypes.LINE_STRING,
        coordinates: []
      }
    });
    moveline.updateInternalProperty('meta', _constants2['default'].meta.MOVELINE);
    moveline.updateInternalProperty('pid', state.polygon.id);
    state.moveline = moveline;
    this.addFeature(moveline);
    // 重置当前节点的索引值
    state.currentVertexIndex = 0;
    // 重置单击的时间戳
    state.clickTime = new Date().valueOf();
  }
  // 设置绘图为活动状态
  this.ctx.setActive(true);

  // 判断是否进行双击判定
  if (this.isDoubleClick(state, e)) {
    this.doubleClick(state);
    return;
  }

  // 判断是否单击在绘制的节点要素上，则忽略
  if ((0, _common_selectors.isVertex)(e)) {
    return;
  }
  // 绘制单击Click事件
  this.clickAnywhere(state, e);
};

// 触发MouseMove时的响应事件
PolygonMode.onMouseMove = function (state, e) {
  state.handleThrottleMouseMove && state.handleThrottleMouseMove(state, e);
};

// 触发键盘KeyUp时的响应事件
PolygonMode.onKeyUp = function (state, e) {
  // 判断是否输入Esc键则取消
  if ((0, _common_selectors.isEscapeKey)(e)) {
    this.onCancel(state);
  } else if ((0, _common_selectors.isEnterKey)(e)) {
    // 判定是否输入Enter键则完成
    this.doubleClick(state);
  }
};

// Mode模式 - 绘制完成
PolygonMode.onCompleted = function (geojson) {
  // 计算绘制Move的临时线要素的量算
  var measure = calculatePolygonArea(this, geojson.geometry.coordinates);
  // 驱动事件回调
  this.ctx.api.fire(_constants2['default'].events.DRAW_COMPLETE, (0, _extends3['default'])({
    mode: this.getMode(),
    feature: geojson
  }, measure));
  // 切换到“选取”模式
  this.changeMode(_constants2['default'].modes.SELECT, {
    featureIds: [geojson.id]
  });
};

// Mode模式 - 绘制取消
PolygonMode.onCancel = function (state) {
  // 移除当前绘制<活动状态>的临时线与节点要素
  this.deleteMoveLineAndVertex(state);
  // 移除当前绘制<活动状态>的Polygon面要素
  if (state.polygon) {
    this.deleteFeature([state.polygon.id], { silent: true });
    delete state.polygon;
  }
  // 驱动事件回调
  this.ctx.api.fire(_constants2['default'].events.DRAW_CANCEL, {
    mode: this.getMode()
  });
  // 切换到“选取”模式
  this.changeMode(_constants2['default'].modes.SELECT);
};

// <自定义函数>触发单击地图的任意地方
PolygonMode.clickAnywhere = function (state, e) {
  var coordinates = [e.lngLat.lng, e.lngLat.lat];
  // 更新添加Vertex节点要素坐标点
  var vertexs = state.vertex.getCoordinates();
  vertexs.push(coordinates);
  state.vertex.setCoordinates(vertexs);
  // 增加Polygon面要素坐标点
  state.polygon.updateCoordinate('0.' + state.currentVertexIndex, coordinates[0], coordinates[1]);
  // 更新Polygon面的临时边线坐标
  state.templine.updateCoordinate(state.currentVertexIndex, coordinates[0], coordinates[1]);
  // 更新Polygon面的MoveLine线要素的起始坐标
  state.moveline.setCoordinates(vertexs.length > 2 ? [coordinates, vertexs[0]] : [coordinates]);
  // 更新当前节点的索引
  state.currentVertexIndex++;
  // 重新记录单击时间戳
  state.clickTime = new Date().valueOf();
  // 绘制要素的测量数据
  var measure = {};
  var polygonFeature = state.polygon.toGeoJSON();
  // 判定是否绘制的为起始点，则更新鼠标提示
  if (state.polygon.coordinates && state.polygon.coordinates[0] && state.polygon.coordinates[0].length === 1) {
    state.options.cursor.clicked && this.updateCursor({ content: state.options.cursor.clicked });
  } else if (state.polygon && state.polygon.coordinates[0].length > 1) {
    measure = calculatePolygonArea(this, polygonFeature.geometry.coordinates);
  }

  // 触发执行绘制单击时的回调事件
  this.ctx.api.fire(_constants2['default'].events.DRAW_CLICK, (0, _extends3['default'])({
    e: e,
    mode: this.getMode(),
    feature: state.polygon.toGeoJSON()
  }, measure));
};

// <自定义函数>判定doubleClick时的响应事件
PolygonMode.doubleClick = function (state) {
  // 判断当前绘制<活动状态>的Polygon要素坐标是否绘制大于2个点
  if (state.vertex && state.vertex.features && state.vertex.features.length > 2) {
    // 强制刷新Line线段要素
    this.ctx.store.featureChanged(state.polygon.id);
    // 移除当前绘制<活动状态>的临时线与节点要素
    this.deleteMoveLineAndVertex(state);
    // 更新状态
    state.polygon.completed = true;
  } else {
    // 绘制无效则进行清除
    this.onCancel(state);
  }
};

// <自定义函数>判定是否为DoubleClick双击事件
PolygonMode.isDoubleClick = function (state, e) {
  var timestamp = new Date().valueOf();
  if (timestamp - state.clickTime < 300 && state.polygon && state.polygon.coordinates.length) {
    var coordinates = state.polygon.coordinates[0];
    if (coordinates && (0, _is_event_at_coordinates2['default'])(e, coordinates[coordinates.length - 1])) {
      return true;
    }
  }
  return false;
};

// <自定义函数>触发MouseMove事件的节流响应
PolygonMode.throttleMouseMove = function (state, e) {
  if (!state.moveline) {
    return;
  }
  var coordinates = [e.lngLat.lng, e.lngLat.lat];
  // 更新临时MoveLine线要素的截止坐标
  state.moveline.updateCoordinate(1, coordinates[0], coordinates[1]);
  // 判定是否绘制的节点至少有2个，则可形成Polygon
  if (state.currentVertexIndex > 1) {
    var startPolygonCoordinates = state.polygon.coordinates[0][0];
    // 增加闭合线段的坐标
    state.moveline.updateCoordinate(2, startPolygonCoordinates[0], startPolygonCoordinates[1]);
    // 增加临时Polygon面要素坐标点
    state.polygon.updateCoordinate('0.' + state.currentVertexIndex, coordinates[0], coordinates[1]);
  }

  // 创建Move的临时线要素数据
  var polygonFeature = state.polygon.toGeoJSON();
  state.currentVertexIndex <= 1 && polygonFeature.geometry.coordinates[0].splice(1, 0, coordinates);

  // 计算绘制Move的临时线要素的量算
  var measure = calculatePolygonArea(this, polygonFeature.geometry.coordinates);
  // 触发执行绘制Move时的回调事件
  this.ctx.api.fire(_constants2['default'].events.DRAW_MOUSEMOVE, (0, _extends3['default'])({
    e: e,
    mode: this.getMode(),
    feature: polygonFeature
  }, measure));
};

// <自定义函数>移除临时移动MoveLine要素和节点要素
PolygonMode.deleteMoveLineAndVertex = function (state) {
  var deleteFeatureIds = [];
  state.moveline && deleteFeatureIds.push(state.moveline.id);
  state.templine && deleteFeatureIds.push(state.templine.id);
  state.vertex && deleteFeatureIds.push(state.vertex.id);
  deleteFeatureIds && deleteFeatureIds.length && this.deleteFeature(deleteFeatureIds);
  state.moveline && delete state.moveline;
  state.templine && delete state.templine;
  state.vertex && delete state.vertex;
};

exports['default'] = PolygonMode;