import { __awaiter, __extends, __generator } from "tslib";
import { throttle } from 'lodash';
import { EventEmitter } from 'events';
import { Cartesian3, Cartesian2, Color, 
//@ts-ignore
Batched3DModel3DTileContent, HeightReference, LabelStyle, VerticalOrigin } from '@taotieh/cesium_extend';
import { TIMESPAN_INSTANT } from '../../../core/Constant';
var Measure = /** @class */ (function (_super) {
    __extends(Measure, _super);
    function Measure(viewer, instance) {
        var _this = _super.call(this) || this;
        _this._entities = [];
        _this._target = new Cartesian3();
        /** **********************************************************
         *  基类实现 _onMove 的一些基础功能. 比如在跟踪拾取位置上描点.
         *  当子类没有去重写这部分功能的时候, 默认使用基类所实现的行为.
         *  子类有特殊需求的时候重写 _onMove 属性即可.
         *  子类不需要自行注册事件订阅/取消订阅. _onMove 是属性.
         *************************************************************/
        _this._onMove = throttle(function (evt) { return __awaiter(_this, void 0, void 0, function () {
            var cPo;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        cPo = _a.sent();
                        cPo.target.clone(this._target);
                        return [2 /*return*/];
                }
            });
        }); }, TIMESPAN_INSTANT);
        _this._onPointerDown = function (evt) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
            return [2 /*return*/];
        }); }); };
        _this._onPointerUp = function (evt) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
            return [2 /*return*/];
        }); }); };
        _this._viewer = viewer;
        _this._instance = instance;
        return _this;
    }
    Measure.prototype._installEvents = function () {
        return __awaiter(this, void 0, void 0, function () {
            var cPo;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        cPo = _a.sent();
                        cPo.on('move', this._onMove);
                        cPo.on('down', this._onPointerDown);
                        cPo.on('up', this._onPointerUp);
                        return [2 /*return*/];
                }
            });
        });
    };
    Measure.prototype._uninstallEvents = function () {
        return __awaiter(this, void 0, void 0, function () {
            var cPo;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        cPo = _a.sent();
                        cPo.off('move', this._onMove);
                        cPo.on('down', this._onPointerDown);
                        cPo.on('up', this._onPointerUp);
                        return [2 /*return*/];
                }
            });
        });
    };
    Measure.prototype._selectPoint = function (target) {
        var _this = this;
        // Promise 方式等待用户拾取一个 空间点 对象
        var viewer = this._viewer;
        var scene = viewer.scene;
        return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
            var cPo, selector;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        cPo = _a.sent();
                        selector = function (evt_down) {
                            return __awaiter(this, void 0, void 0, function () {
                                var _a, x, y, cart2_down;
                                var _this = this;
                                return __generator(this, function (_b) {
                                    _a = evt_down, x = _a.layerX, y = _a.layerY;
                                    cart2_down = new Cartesian2(x, y);
                                    cPo.once('up', function (evt_up) { return __awaiter(_this, void 0, void 0, function () {
                                        var _a, x, y, cart2_up;
                                        return __generator(this, function (_b) {
                                            _a = evt_up, x = _a.layerX, y = _a.layerY;
                                            cart2_up = new Cartesian2(x, y);
                                            if (Cartesian2.equals(cart2_down, cart2_up)) {
                                                scene.pickPosition(cart2_up, target);
                                                if (!target.equals(Cartesian3.ZERO)) {
                                                    cPo.off('down', selector);
                                                    resolve(target);
                                                }
                                            }
                                            return [2 /*return*/];
                                        });
                                    }); });
                                    return [2 /*return*/];
                                });
                            });
                        };
                        cPo.on('down', selector);
                        return [2 /*return*/];
                }
            });
        }); });
    };
    Measure.prototype._selectC3DTileFeature = function (target) {
        if (target === void 0) { target = new Cartesian3(); }
        // Promise 方式等待用户选中一个 要素 对象
        var viewer = this._viewer;
        var scene = viewer.scene;
        return new Promise(function (resolve, reject) {
            viewer.container.addEventListener('click', function (evt) {
                var _a = evt, x = _a.layerX, y = _a.layerY;
                var cart2 = new Cartesian2(x, y);
                scene.pickPosition(cart2, target);
                var festure = scene.pick(cart2);
                if (festure &&
                    festure.content instanceof Batched3DModel3DTileContent) {
                    resolve(festure.content);
                }
                else {
                    reject(null);
                }
            }, { once: true });
        });
    };
    Measure.prototype._rmEnt = function (ent) {
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        ent && viewer.entities.contains(ent) && viewer.entities.remove(ent);
    };
    Measure.prototype._drawPoint = function (cart3, color, size, depthTest) {
        if (depthTest === void 0) { depthTest = false; }
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        var ent = viewer.entities.add({
            position: cart3,
            point: {
                color: color,
                pixelSize: size,
                heightReference: HeightReference.NONE,
                disableDepthTestDistance: 10
            }
        });
        entities.push(ent);
        return ent;
    };
    Measure.prototype._drawLine = function (cart3s, color, width, depthTest) {
        if (depthTest === void 0) { depthTest = false; }
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        var ent = viewer.entities.add({
            polyline: {
                show: true,
                positions: cart3s,
                material: color,
                width: width,
                disableDepthTestDistance: 10
            }
        });
        entities.push(ent);
        return ent;
    };
    Measure.prototype._drawLabel = function (achor, text, offset, bg, size, fg, isScale, depthTest) {
        if (offset === void 0) { offset = new Cartesian2(0, -9); }
        if (size === void 0) { size = 12; }
        if (fg === void 0) { fg = Color.YELLOW; }
        if (isScale === void 0) { isScale = false; }
        if (depthTest === void 0) { depthTest = false; }
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        var ent = viewer.entities.add({
            position: achor,
            label: {
                text: text,
                font: size + "pt monospace",
                style: LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: VerticalOrigin.BOTTOM,
                pixelOffset: offset,
                showBackground: bg && true,
                backgroundColor: bg,
                backgroundPadding: new Cartesian2(7, 5),
                fillColor: fg,
                disableDepthTestDistance: 10
            }
        });
        entities.push(ent);
        return ent;
    };
    Measure.prototype._drawArc = function (pO, pA, pB) {
        /** *****************************
         *  构建一个三维圆的参数方程
         *  圆心 (Ox,Oy,Oz)
         *  半径 r
         *  所在平面法向量 n
         *  平面上的基 u,v.  u 是 OA 方向
         *
         *  x = Ox + r(ux*cost + vx*sint)
         *  y = Oy + r(uy*cost + vy*sint)
         *  z = Oz + r(uz*cost + vz*sint)
         ********************************/
        var ps = [];
        var u = Cartesian3.normalize(Cartesian3.subtract(pA, pO, new Cartesian3()), new Cartesian3());
        var v = Cartesian3.subtract(pB, pO, new Cartesian3());
        if (Cartesian3.equals(v, Cartesian3.ZERO))
            return ps;
        Cartesian3.normalize(v, v);
        var n = Cartesian3.normalize(Cartesian3.cross(v, u, new Cartesian3()), new Cartesian3());
        var r = 1;
        // const angle = Math.acos(Cartesian3.dot(u, v));
        /* 转为正交单位轴 */
        /* 固定90度 */
        var angle = 90 * 180 / Math.PI;
        // 利用参数方程, 十等分弧段
        var seg = 10;
        /* 利用基底公式：a = λ1e1 + λ2e2，e1,e1为基向量u,v，λ1,λ2为x，y */
        for (var i = 0; i <= seg; i++) {
            var ang = (i * angle) / seg;
            var _a = [
                r * (u.x * Math.cos(ang) + v.x * Math.sin(ang)),
                r * (u.y * Math.cos(ang) + v.y * Math.sin(ang)),
                r * (u.z * Math.cos(ang) + v.z * Math.sin(ang))
            ], x = _a[0], y = _a[1], z = _a[2];
            ps.push(new Cartesian3(pO.x + x, pO.y + y, pO.z + z));
        }
        console.log('_drawArc', { angle: angle, pO: pO, pA: pA, pB: pB, ps: ps });
        // ps.length && this._drawLine(ps, Color.BLUE, 2);
        return ps;
    };
    Measure.prototype._clearEntity = function (ent) {
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        ent ? viewer.entities.remove(ent) : viewer.entities.removeAll();
        ent ? entities.splice(entities.indexOf(ent), 1) : (entities.length = 0);
    };
    Measure.prototype.start = function () {
        this._installEvents();
    };
    Measure.prototype.next = function () { };
    Measure.prototype.stop = function () {
        this._uninstallEvents();
    };
    return Measure;
}(EventEmitter));
export default Measure;
