"use strict";

function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _cesium = require("cesium");
require("./index.less");
var _util = _interopRequireDefault(require("./util"));
var _InfoTool;
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
/**
 * 信息工具。
 *
 * @alias InfoTool
 * @constructor
 * @param {viewer} viewer Cesium视窗。
 */
var _element = /*#__PURE__*/new WeakMap();
var InfoTool = /*#__PURE__*/function () {
  function InfoTool(options) {
    _classCallCheck(this, InfoTool);
    _classPrivateFieldInitSpec(this, _element, void 0);
    _defineProperty(this, "viewer", void 0);
    this.viewer = options.map;
    // 在Cesium容器中添加元素
    _classPrivateFieldSet(_element, this, document.createElement('div'));
  }

  /**
   * 添加。
   * @param {Object} options 选项。
   * @param {Element} options.element 弹窗元素。
   * @param {Cartesian2|Cartesian3} options.position 点击位置。
   * @param {Cesium3DTileFeature} [options.inputFeature] 模型要素。
   * @param {String} options.type 类型（默认值为default，即任意点击模式；如果设置为info，即信息模式，只有点击Feature才会响应）。
   * @param {String} options.content 内容（只有类型为default时才起作用）。
   * @param {Function} callback 回调函数。
   */
  return _createClass(InfoTool, [{
    key: "add",
    value: function add(options) {
      var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
      this.element = options.element;
      // 判断参数为空返回
      if (!options) {
        return;
      }
      // 点
      var position, cartesian2d, cartesian3d, inputFeature;
      if (options instanceof _cesium.Cesium3DTileFeature) {
        inputFeature = options;
        options = {};
      } else {
        if (options instanceof _cesium.Cartesian2 || options instanceof _cesium.Cartesian3) {
          position = options;
          options = {};
        } else {
          position = options.position;
          inputFeature = options.inputFeature;
        }
        // 判断点位为空返回
        if (!position) {
          return;
        }
        if (position instanceof _cesium.Cartesian2) {
          // 二维转三维
          // 如果支持拾取模型则取模型值
          cartesian3d = this.viewer.scene.pickPositionSupported && (0, _cesium.defined)(this.viewer.scene.pick(options.position)) ? this.viewer.scene.pickPosition(position) : this.viewer.camera.pickEllipsoid(position, this.viewer.scene.globe.ellipsoid);
          cartesian2d = position;
        } else {
          cartesian3d = position;
          cartesian2d = _cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, cartesian3d);
        }
        // 判断点位为空返回
        if (!cartesian3d) {
          return;
        }
      }
      var that = this;

      // 1.组织信息
      var info = '';
      if (options.type === 'info') {
        // 拾取要素
        var feature = inputFeature || this.viewer.scene.pick(cartesian2d);
        // 判断拾取要素为空返回
        if (!(0, _cesium.defined)(feature)) {
          this.remove();
          return;
        }
        if (feature instanceof _cesium.Cesium3DTileFeature) {
          var _feature$getPropertyN;
          // 3dtiles
          var propertyNames = (feature === null || feature === void 0 || (_feature$getPropertyN = feature.getPropertyNames) === null || _feature$getPropertyN === void 0 ? void 0 : _feature$getPropertyN.call(feature)) || [];
          var length = propertyNames.length;
          for (var i = 0; i < length; ++i) {
            var propertyName = propertyNames[i];
            info += '"' + (propertyName + '": "' + feature.getProperty(propertyName)) + '",\n';
          }
        } else if (feature) {
          // Entity
          var properties = feature.properties;
          if (properties) {
            var _propertyNames = properties._propertyNames;
            var _length = _propertyNames.length;
            for (var _i = 0; _i < _length; ++_i) {
              var _propertyName = _propertyNames[_i];
              info += '"' + (_propertyName + '": "' + properties[_propertyName]._value) + '",\n';
            }
          }
        }
      } else {
        options.content && (info = options.content);
      }

      // 2.生成特效
      // 添加之前先移除
      this.remove();
      // if (!info) {
      //   return;
      // }
      options.position = cartesian3d;
      options.element = options.element || _classPrivateFieldGet(_element, this);
      _createInfoTool.call(InfoTool, this.viewer, options, function () {
        _util["default"].setInnerText(options.element, info);
        typeof callback === 'function' && callback();
      });
    }
  }, {
    key: "show",
    value: function show() {
      _util["default"].setCss(this.element, 'opacity', '1');
      _util["default"].setCss(this.element, 'z-index', '1');
      _util["default"].setCss(_classPrivateFieldGet(_element, this), 'opacity', '1');
    }

    /**
     * 移除。
     */
  }, {
    key: "remove",
    value: function remove() {
      _util["default"].setCss(this.element, 'opacity', '0');
      _util["default"].setCss(this.element, 'z-index', '-1');
      _util["default"].setCss(_classPrivateFieldGet(_element, this), 'opacity', '0');
    }
  }]);
}();
_InfoTool = InfoTool;
/**
 * 创建一个动态实体弹窗。
 *
 * @param {viewer} viewer Cesium视窗。
 * @param {Number} options 选项。
 * @param {Cartesian3} options.position 弹出位置。
 * @param {HTMLElement} options.element 弹出窗元素容器。
 * @param {Function} callback 回调函数。
 * @ignore
 */
function _createInfoTool(viewer, options) {
  var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
  var cartographic = _cesium.Cartographic.fromCartesian(options.position);
  var lon = _cesium.Math.toDegrees(cartographic.longitude); //.toFixed(5);
  var lat = _cesium.Math.toDegrees(cartographic.latitude); //.toFixed(5);

  // 回调
  callback();

  // 添加div弹窗
  setTimeout(function () {
    _popup.call(_InfoTool, viewer, options.element, lon, lat, cartographic.height,
    // options.geometryType,
    options.offset);
  }, 100);
}
/**
 * 弹出HTML元素弹窗。
 * @param {viewer} viewer Cesium视窗。
 * @param {Element|HTMLElement} element 弹窗元素。
 * @param {Number} lon 经度。
 * @param {Number} lat 纬度。
 * @param {Number} height 高度。
 * @ignore
 */
function _popup(viewer, element, lon, lat, height, offset) {
  setTimeout(function () {
    // 设置元素效果
    _util["default"].setCss(element, 'opacity', '1');
    _util["default"].setCss(element, 'z-index', '0');
  }, 100);
  var divPosition = _cesium.Cartesian3.fromDegrees(lon, lat, height);
  var x = (offset === null || offset === void 0 ? void 0 : offset.x) || 0;
  var y = (offset === null || offset === void 0 ? void 0 : offset.y) || 0;
  _hookToGlobe.call(_InfoTool, viewer, element, divPosition, [-4 + x, -parseInt(_util["default"].getCss(element, 'offsetHeight') + y)], true);
  viewer.scene.requestRender();
}
/**
 * 将HTML弹窗挂接到地球上。
 *
 * @param {viewer} viewer Cesium视窗。
 * @param {Element} element 弹窗元素。
 * @param {Cartesian3} position 地图坐标点。
 * @param {Array} offset 偏移。
 * @param {Boolean} hideOnBehindGlobe 当元素在地球背面会自动隐藏，以减轻判断计算压力。
 * @ignore
 */
function _hookToGlobe(viewer, element, position, offset, hideOnBehindGlobe) {
  var scene = viewer.scene,
    camera = viewer.camera;
  var cartesian2 = new _cesium.Cartesian2();
  var _style = {};
  scene.preRender.addEventListener(function () {
    var canvasPosition = scene.cartesianToCanvasCoordinates(position, cartesian2); // 笛卡尔坐标到画布坐标

    if ((0, _cesium.defined)(canvasPosition)) {
      var left = parseInt(canvasPosition.x + offset[0]);
      var top = parseInt(canvasPosition.y + offset[1]);
      if (_style.left) {
        _style.left = _style.left - left > 1 || _style.left - left < -1 ? left : _style.left;
      } else {
        _style.left = left;
      }
      _style.top = top;
      _util["default"].setCss(element, 'left', _style.left + 'px');
      _util["default"].setCss(element, 'top', _style.top + 'px');

      // 是否在地球背面隐藏
      if (hideOnBehindGlobe) {
        var cameraPosition = camera.position;
        var height = scene.globe.ellipsoid.cartesianToCartographic(cameraPosition).height;
        height += scene.globe.ellipsoid.maximumRadius;
        if (!(_cesium.Cartesian3.distance(cameraPosition, position) > height)) {
          // util.setCss(element, 'display', 'flex');
        } else {
          // util.setCss(element, 'display', 'none');
        }
      }
    }
  });
}
var _default = exports["default"] = InfoTool;
//# sourceMappingURL=index.js.map
