import { __awaiter, __extends, __generator } from "tslib";
import Clip from './Clip';
import { ClippingPlane, ClippingPlaneCollection, Plane, Matrix4, Color, Cartesian3, HeightReference, CallbackProperty, Cartesian2, Cartographic } from '@taotieh/cesium_extend';
var State;
(function (State) {
    State[State["UNSET"] = 0] = "UNSET";
    State[State["READY"] = 1] = "READY";
    State[State["POINT_ORIGIN_SELECTED"] = 2] = "POINT_ORIGIN_SELECTED";
    State[State["POINT_DIRECTION_SELECTED"] = 3] = "POINT_DIRECTION_SELECTED";
    State[State["DONE"] = 4] = "DONE";
    State[State["DISTROY"] = 5] = "DISTROY";
})(State || (State = {}));
var ClipWithParmas = /** @class */ (function (_super) {
    __extends(ClipWithParmas, _super);
    function ClipWithParmas() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._state = State.UNSET;
        _this._tileset_inverse_transform = new Matrix4();
        _this._world_point_on_plane = new Cartesian3();
        _this._origin_point_on_plane = new Cartesian3();
        _this._world_clipping_direction_target = new Cartesian3();
        _this._origin_clipping_direction_target = new Cartesian3();
        _this._origin_direction = new Cartesian3();
        _this._origin_normal = new Cartesian3();
        _this._origin_move = new Cartesian3();
        _this._normal_move = new Cartesian3(1, 0, 0);
        _this._isVertical = false;
        _this._active = false;
        _this._entities = [];
        _this._onMove = function (evt) { return __awaiter(_this, void 0, void 0, function () {
            var _a, viewer, _world_point_on_plane, _origin_point_on_plane, vertical, scene, _b, _normal_move, _tileset_inverse_transform, _c, x, y, cart2_up, targetWorld, targetLocal, _origin_normal_move, startCartographic, endCartographic;
            return __generator(this, function (_d) {
                _a = this, viewer = _a._viewer, _world_point_on_plane = _a._world_point_on_plane, _origin_point_on_plane = _a._origin_point_on_plane, vertical = _a._isVertical;
                scene = viewer.scene;
                if (this._state !== State.POINT_ORIGIN_SELECTED)
                    return [2 /*return*/];
                _b = this, _normal_move = _b._normal_move, _tileset_inverse_transform = _b._tileset_inverse_transform;
                _c = evt, x = _c.layerX, y = _c.layerY;
                cart2_up = new Cartesian2(x, y);
                targetWorld = new Cartesian3();
                targetLocal = new Cartesian3();
                _origin_normal_move = new Cartesian3();
                scene.pickPosition(cart2_up, targetWorld);
                if (targetWorld.equals(Cartesian3.ZERO))
                    return [2 /*return*/];
                if (vertical) {
                    startCartographic = Cartographic.fromCartesian(_world_point_on_plane);
                    endCartographic = Cartographic.fromCartesian(targetWorld);
                    endCartographic.height = startCartographic.height;
                    targetWorld = Cartographic.toCartesian(endCartographic);
                }
                this._origin_move = targetWorld;
                Matrix4.multiplyByPoint(_tileset_inverse_transform, targetWorld, targetLocal);
                Cartesian3.subtract(targetLocal, _origin_point_on_plane, _origin_normal_move);
                Cartesian3.normalize(_origin_normal_move, _normal_move);
                return [2 /*return*/];
            });
        }); };
        return _this;
    }
    // 选择切割面所经过的点
    ClipWithParmas.prototype._to_select_clipping_origin = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _a, tileset, _world_point_on_plane, _origin_point_on_plane, _tileset_inverse_transform, world_point;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        console.log('等待选择起点');
                        _a = this, tileset = _a._tileset, _world_point_on_plane = _a._world_point_on_plane, _origin_point_on_plane = _a._origin_point_on_plane, _tileset_inverse_transform = _a._tileset_inverse_transform;
                        return [4 /*yield*/, this._selectPoint(_world_point_on_plane)];
                    case 1:
                        world_point = _b.sent();
                        this._origin_move = world_point;
                        // 计算并保存 用户所选世界坐标点 在原 tileset 的内部坐标
                        Matrix4.multiplyByPoint(_tileset_inverse_transform, world_point, _origin_point_on_plane);
                        this._state = State.POINT_ORIGIN_SELECTED;
                        this._drawPoint(_world_point_on_plane, Color.RED, 8);
                        this._drawLine();
                        this._drawPlane();
                        this.next();
                        return [2 /*return*/];
                }
            });
        });
    };
    ClipWithParmas.prototype._to_select_clipping_direction = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _a, _world_point_on_plane, _world_clipping_direction_target, _origin_clipping_direction_target, _tileset_inverse_transform, vertical, world_point, startCartographic, endCartographic;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        console.log('等待选择方向');
                        _a = this, _world_point_on_plane = _a._world_point_on_plane, _world_clipping_direction_target = _a._world_clipping_direction_target, _origin_clipping_direction_target = _a._origin_clipping_direction_target, _tileset_inverse_transform = _a._tileset_inverse_transform, vertical = _a._isVertical;
                        return [4 /*yield*/, this._selectPoint(_world_clipping_direction_target)];
                    case 1:
                        world_point = _b.sent();
                        console.log(world_point, 'world_point1');
                        if (vertical) {
                            startCartographic = Cartographic.fromCartesian(_world_point_on_plane);
                            endCartographic = Cartographic.fromCartesian(world_point);
                            endCartographic.height = startCartographic.height;
                            world_point = Cartographic.toCartesian(endCartographic);
                        }
                        // 计算并保存 用户所选方向锚点在 tileset 的原坐标
                        Matrix4.multiplyByPoint(_tileset_inverse_transform, world_point, _origin_clipping_direction_target);
                        this._state = State.POINT_DIRECTION_SELECTED;
                        this.next();
                        return [2 /*return*/];
                }
            });
        });
    };
    ClipWithParmas.prototype._to_refursh_clipping_plane = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _a, _origin_clipping_direction_target, _origin_point_on_plane, _origin_direction, _origin_normal, _tileset, temp_plane, clipping_plane;
            return __generator(this, function (_b) {
                console.log('实施切割');
                _a = this, _origin_clipping_direction_target = _a._origin_clipping_direction_target, _origin_point_on_plane = _a._origin_point_on_plane, _origin_direction = _a._origin_direction, _origin_normal = _a._origin_normal, _tileset = _a._tileset;
                Cartesian3.subtract(_origin_clipping_direction_target, _origin_point_on_plane, _origin_direction);
                Cartesian3.normalize(_origin_direction, _origin_normal);
                temp_plane = Plane.fromPointNormal(_origin_point_on_plane, _origin_normal);
                clipping_plane = new ClippingPlane.fromPlane(temp_plane);
                _tileset.clippingPlanes = new ClippingPlaneCollection({
                    planes: [clipping_plane],
                    edgeColor: Color.WHITESMOKE,
                    edgeWidth: 4
                });
                this._state = State.DONE;
                this.next();
                return [2 /*return*/];
            });
        });
    };
    ClipWithParmas.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;
    };
    ClipWithParmas.prototype._drawLine = function () {
        var _a = this, viewer = _a._viewer, entities = _a._entities;
        var ent = viewer.entities.add({
            polyline: {
                show: true,
                positions: new CallbackProperty(this._createLineUpdateFunction(), false),
                material: Color.GREEN,
                width: 10,
                disableDepthTestDistance: 10
            }
        });
        entities.push(ent);
        return ent;
    };
    ClipWithParmas.prototype._drawPlane = function () {
        var _a = this, viewer = _a._viewer, entities = _a._entities, _world_point_on_plane = _a._world_point_on_plane;
        var plane = new Plane(new Cartesian3(1, 0, 0), 0);
        var ent = viewer.entities.add({
            position: _world_point_on_plane,
            plane: {
                dimensions: new Cartesian2(100, 100),
                material: Color.GREEN.withAlpha(0.05),
                plane: new CallbackProperty(this._createPlaneUpdateFunction(plane), false),
                outline: true,
                outlineColor: Color.WHITE
            }
        });
        entities.push(ent);
        return ent;
    };
    ClipWithParmas.prototype._createLineUpdateFunction = function () {
        var _this = this;
        return function () {
            return [_this._world_point_on_plane, _this._origin_move];
        };
    };
    ClipWithParmas.prototype._createPlaneUpdateFunction = function (plane) {
        var _this = this;
        return function () {
            plane.normal = _this._normal_move;
            return plane;
        };
    };
    ClipWithParmas.prototype._createEdgeWidthUpdateFunction = function () {
        return function (time) {
            return (1 + Math.sign(time)) * 4;
        };
    };
    ClipWithParmas.prototype._createEdgeColorUpdateFunction = function () {
        var color = Color.BLUE.clone();
        return function (time) {
            color.alpha = (1 + Math.sign(time)) / 2;
            return color;
        };
    };
    ClipWithParmas.prototype._to_reset = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                this._state = State.READY;
                this.clearEntity();
                this.next();
                return [2 /*return*/];
            });
        });
    };
    ClipWithParmas.prototype.clearEntity = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _a, viewer, entities;
            return __generator(this, function (_b) {
                _a = this, viewer = _a._viewer, entities = _a._entities;
                entities.forEach(function (entity) {
                    viewer.entities.remove(entity);
                });
                return [2 /*return*/];
            });
        });
    };
    ClipWithParmas.prototype.start = function (option) {
        var _this = this;
        _super.prototype.start.call(this, option);
        /** ***************************************************
         *  1. 初始化环境
         ******************************************************/
        // 初始化你变换矩阵
        this._tileset = option.tileset;
        this._isVertical = option._isVertical;
        this._active = true;
        var tileset_transform = this._tileset.root.transform || Matrix4.IDENTITY;
        Matrix4.inverseTransformation(tileset_transform, this._tileset_inverse_transform);
        this._tileset = option.tileset;
        this._world_point_on_plane = new Cartesian3();
        this._origin_point_on_plane = new Cartesian3();
        this._origin_move = new Cartesian3();
        var cPo = this._instance.getInstancePointerControl();
        cPo.once('rightClick', function () { return _this.stop(); });
        this.next();
    };
    ClipWithParmas.prototype.stop = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                this._active = false;
                this._state = State.DISTROY;
                this.clearEntity();
                this._tileset.clippingPlanes && this._tileset.clippingPlanes.removeAll();
                _super.prototype.stop.call(this);
                return [2 /*return*/];
            });
        });
    };
    ClipWithParmas.prototype.next = function (option) {
        return __awaiter(this, void 0, void 0, function () {
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!this._active)
                            return [2 /*return*/];
                        _super.prototype.next.call(this, option);
                        _a = this._state;
                        switch (_a) {
                            case State.READY: return [3 /*break*/, 1];
                            case State.POINT_ORIGIN_SELECTED: return [3 /*break*/, 3];
                            case State.POINT_DIRECTION_SELECTED: return [3 /*break*/, 5];
                            case State.DONE: return [3 /*break*/, 7];
                        }
                        return [3 /*break*/, 9];
                    case 1: return [4 /*yield*/, this._to_select_clipping_origin()];
                    case 2:
                        _b.sent();
                        return [3 /*break*/, 11];
                    case 3: return [4 /*yield*/, this._to_select_clipping_direction()];
                    case 4:
                        _b.sent();
                        return [3 /*break*/, 11];
                    case 5: return [4 /*yield*/, this._to_refursh_clipping_plane()];
                    case 6:
                        _b.sent();
                        return [3 /*break*/, 11];
                    case 7: return [4 /*yield*/, this._to_reset()];
                    case 8:
                        _b.sent();
                        return [3 /*break*/, 11];
                    case 9: return [4 /*yield*/, this._to_reset()];
                    case 10:
                        _b.sent();
                        _b.label = 11;
                    case 11: return [2 /*return*/];
                }
            });
        });
    };
    return ClipWithParmas;
}(Clip));
export default ClipWithParmas;
