import { __awaiter, __generator } from "tslib";
// declare const Cesium: typeof import("cesium");
import * as Cesium from '@taotieh/cesium_extend';
import MeasureDistancePointToSurface from './Mods/MeasureDistancePointToSurface';
import MeasureDistancePointChain from './Mods/MeasureDistancePointChain';
import MeasureDistanceHeight from './Mods/MeasureDistanceHeight';
import MeasureAnglePointChain from './Mods/MeasureAnglePointChain';
var MeasureControl = /** @class */ (function () {
    function MeasureControl(viewer, instance) {
        this._entities = [];
        this._measureType = '';
        this._positions = [];
        this._distance = '';
        this._installed = false;
        this._viewer = viewer;
        this._instance = instance;
        this._modMeasureDistancePointToSurface = new MeasureDistancePointToSurface(viewer, instance);
        this._modMeasureDistancePointChain = new MeasureDistancePointChain(viewer, instance);
        this._modMeasureDistanceHeight = new MeasureDistanceHeight(viewer, instance);
        this._modMeasureAnglePointChain = new MeasureAnglePointChain(viewer, instance);
    }
    MeasureControl.prototype.getSpaceDistance = function (positions) {
        var distance = 0;
        for (var i = 0; i < positions.length - 1; i++) {
            distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
        }
        return distance.toFixed(2);
    };
    MeasureControl.prototype.doRemoveAllEntities = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _viewer, cSc;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _viewer = this._viewer;
                        _viewer.entities.removeAll();
                        return [4 /*yield*/, this._instance.getInstanceSceneControl()];
                    case 1:
                        cSc = _a.sent();
                        return [4 /*yield*/, cSc.forceRender(100)];
                    case 2:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    MeasureControl.prototype.doSetMeasureModel = function (measureType) {
        return __awaiter(this, void 0, void 0, function () {
            var cPo;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this._measureType = measureType;
                        this._installed || this.doInstallMeasureEvents();
                        return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        cPo = _a.sent();
                        if (measureType === 'clear') {
                            cPo['_modFree'].isActive = true;
                            this.doRemoveAllEntities();
                        }
                        else {
                            cPo['_modFree'].isActive = false;
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    MeasureControl.prototype.doInstallMeasureEvents = function () {
        return __awaiter(this, void 0, void 0, function () {
            var pc;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._instance.getInstancePointerControl()];
                    case 1:
                        pc = _a.sent();
                        pc.on('move', function (evt) {
                            switch (_this['_measureType']) {
                                case 'distance':
                                    _this.onMeasureDistanceMove(evt);
                                    break;
                                case 'area':
                                    break;
                                default:
                                    break;
                            }
                        });
                        pc.on('click', function (evt) {
                            switch (_this['_measureType']) {
                                case 'distance':
                                    _this.onMeasureDistanceClick(evt);
                                    break;
                                case 'area':
                                    break;
                                default:
                                    break;
                            }
                        });
                        pc.on('rightClick', function (evt) {
                            switch (_this['_measureType']) {
                                case 'distance':
                                    _this.onMeasureDistanceRightClick(evt);
                                    break;
                                case 'area':
                                    break;
                                default:
                                    break;
                            }
                        });
                        this._installed = true;
                        return [2 /*return*/];
                }
            });
        });
    };
    MeasureControl.prototype.onMeasureDistanceClick = function (evt) {
        var _a = this, _positions = _a._positions, _viewer = _a._viewer, _entities = _a._entities;
        var _distance = this._distance;
        var _b = evt, x = _b.layerX, y = _b.layerY;
        var cart2 = new Cesium.Cartesian2(x, y);
        var cartesian = _viewer.scene.pickPosition(cart2);
        if (!cartesian)
            return;
        if (_positions.length === 0) {
            _positions.push(cartesian.clone());
        }
        _positions.push(cartesian);
        var textDistance = _distance ? _distance + '米' : '';
        var labelOption = {
            name: '空间直线距离',
            position: cartesian.clone(),
            point: {
                pixelSize: 10,
                color: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
                outlineWidth: 2,
                heightReference: Cesium.HeightReference.NONE
            },
            label: {
                text: textDistance,
                font: '14px sans-serif',
                fillColor: Cesium.Color.YELLOW,
                showBackground: true,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(20, -20),
                heightReference: Cesium.HeightReference.NONE
            }
        };
        // @ts-ignore
        var floatingPoint = _viewer.entities.add(labelOption);
        _entities.push(floatingPoint);
    };
    MeasureControl.prototype.onMeasureDistanceMove = function (evt) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, _positions, _viewer, _entities, _b, x, y, cart2, cartesian, getSpaceDistance, PolyLinePrimitive, cSc;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        _a = this, _positions = _a._positions, _viewer = _a._viewer, _entities = _a._entities;
                        _b = evt, x = _b.layerX, y = _b.layerY;
                        cart2 = new Cesium.Cartesian2(x, y);
                        cartesian = _viewer.scene.pickPosition(cart2);
                        if (!cartesian)
                            return [2 /*return*/];
                        getSpaceDistance = function (positions) {
                            var distance = 0;
                            for (var i = 0; i < positions.length - 1; i++) {
                                distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
                            }
                            return distance.toFixed(2);
                        };
                        PolyLinePrimitive = (function () {
                            function _(positions) {
                                var options = {
                                    name: '',
                                    polyline: {
                                        show: true,
                                        positions: [],
                                        material: Cesium.Color.CHARTREUSE,
                                        width: 2
                                    }
                                };
                                var _update = function () {
                                    return positions;
                                };
                                // @ts-ignore
                                options.polyline.positions = new Cesium.CallbackProperty(_update, false);
                                // @ts-ignore
                                var line = _viewer.entities.add(options);
                                _entities.push(line);
                            }
                            return _;
                        })();
                        if (this['_positions'].length >= 2) {
                            if (!Cesium.defined(this['_poly'])) {
                                this['_poly'] = new PolyLinePrimitive(_positions);
                            }
                            else {
                                _positions.pop();
                                _positions.push(cartesian);
                            }
                            this['_distance'] = getSpaceDistance(_positions);
                        }
                        return [4 /*yield*/, this._instance.getInstanceSceneControl()];
                    case 1:
                        cSc = _c.sent();
                        return [4 /*yield*/, cSc.forceRender(100)];
                    case 2:
                        _c.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    MeasureControl.prototype.onMeasureDistanceRightClick = function (evt) {
        this._measureType = 'stopMeasure';
        console.log('doRemoveAllEntities');
        this._positions = [];
        this._distance = 0;
        this._poly = null;
    };
    MeasureControl.prototype.calcArea = function (points) {
        var res = 0;
        //拆分三角曲面
        for (var i = 0; i < points.length - 2; i++) {
            var j = (i + 1) % points.length;
            var k = (i + 2) % points.length;
            var totalAngle = this.calcAngle(points[i], points[j], points[k]);
            var dis_temp1 = Cesium.Cartesian3.distance(points[i], points[j]);
            var dis_temp2 = Cesium.Cartesian3.distance(points[j], points[k]);
            res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
        }
        return (res / 1000000.0).toFixed(4);
    };
    /*角度*/
    MeasureControl.prototype.calcAngle = function (p1, p2, p3) {
        var bearing21 = this.calcBearing(p2, p1);
        var bearing23 = this.calcBearing(p2, p3);
        var angle = bearing21 - bearing23;
        if (angle < 0) {
            angle += 360;
        }
        return angle < 0 ? angle + 360 : angle;
    };
    MeasureControl.prototype.calcBearing = function (from, to) {
        var fromCart = Cesium.Cartographic.fromCartesian(from);
        var toCart = Cesium.Cartographic.fromCartesian(to);
        var radiansPerDegree = Math.PI / 180.0; // 角度转化为弧度(rad)
        var degreesPerRadian = 180.0 / Math.PI; // 弧度转化为角度
        var lat1 = Cesium.Math.toDegrees(fromCart['latitude']) * radiansPerDegree;
        var lon1 = Cesium.Math.toDegrees(fromCart['longitude']) * radiansPerDegree;
        var lat2 = Cesium.Math.toDegrees(toCart['latitude']) * radiansPerDegree;
        var lon2 = Cesium.Math.toDegrees(toCart['longitude']) * radiansPerDegree;
        var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) -
            Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
        if (angle < 0) {
            angle += Math.PI * 2.0;
        }
        angle = angle * degreesPerRadian;
        return angle;
    };
    MeasureControl.prototype.switchMeasureTool = function (tool) {
        if (tool === void 0) { tool = ''; }
        var _a = this, dp2s = _a._modMeasureDistancePointToSurface, dps = _a._modMeasureDistancePointChain, dhs = _a._modMeasureDistanceHeight, aps = _a._modMeasureAnglePointChain;
        dp2s.stop();
        dps.stop();
        dhs.stop();
        aps.stop();
        switch (tool) {
            case 'distance_point_to_surface':
                dp2s.start();
                break;
            case 'distance_point_chain':
                dps.start();
                break;
            case 'distance_height':
                dhs.start();
                break;
            case 'angle_point_chain':
                aps.start();
                break;
            case 'clear':
                this.doRemoveAllEntities();
                break;
        }
    };
    MeasureControl.prototype.next = function () {
        var activeMode = this._activeMod;
        if (activeMode) {
            activeMode.next();
        }
    };
    return MeasureControl;
}());
export default MeasureControl;
