"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrackableObjectImpl = exports.TrackableObjectState = void 0;
const robotics_types_1 = require("./robotics-types");
const EMPTY_POSE = {
    x: NaN,
    y: NaN,
    z: NaN,
    u: NaN,
    v: NaN,
    w: NaN
};
const isSamePose = (pose1, pose2, threshold) => {
    if ((!pose1 || pose1 === EMPTY_POSE) && (!pose2 || pose2 === EMPTY_POSE)) {
        return true;
    }
    if (!pose1 || pose1 === EMPTY_POSE || !pose2 || pose2 === EMPTY_POSE) {
        return false;
    }
    /* TODO 미세한 변화는 움직이지 않은 것으로 한다. */
    var { x: x1, y: y1, z: z1, u: u1, v: v1, w: w1 } = pose1;
    var { x: x2, y: y2, z: z2, u: u2, v: v2, w: w2 } = pose2;
    var { x: tx, y: ty, z: tz, u: tu, v: tv, w: tw } = threshold;
    return (Math.abs(x1 - x2) < Number(tx) &&
        Math.abs(y1 - y2) < Number(ty) &&
        Math.abs(z1 - z2) < Number(tz) &&
        Math.abs(u1 - u2) < Number(tu) &&
        Math.abs(v1 - v2) < Number(tv) &&
        Math.abs(w1 - w2) < Number(tw));
};
const isValidPose = pose => {
    if (!pose) {
        return false;
    }
    var { x, y, z, u, v, w } = pose;
    return [x, y, z, u, v, w].findIndex(x => isNaN(x) || x === null || x === '') === -1;
};
var TrackableObjectState;
(function (TrackableObjectState) {
    TrackableObjectState[TrackableObjectState["UNDETERMIN"] = -1] = "UNDETERMIN";
    TrackableObjectState[TrackableObjectState["MOVING"] = 0] = "MOVING";
    TrackableObjectState[TrackableObjectState["STABLE"] = 1] = "STABLE";
})(TrackableObjectState = exports.TrackableObjectState || (exports.TrackableObjectState = {}));
class TrackableObjectImpl {
    //   state: TrackableObjectState = TrackableObjectState.UNDETERMIN
    constructor(id) {
        this.unknownRetention = 0;
        this.id = id;
    }
    update(roi, pose, threshold) {
        if (pose && !isValidPose(pose)) {
            this.unknownRetention++;
            return null;
            //   pose = EMPTY_POSE
        }
        if (!roi) {
            roi = '';
        }
        var from = {
            roi: this.roi,
            pose: this.pose,
            retention: this.retention
        };
        var to = {
            roi: roi,
            pose: pose,
            retention: 0
        };
        var moving = true;
        var movein = false;
        var moveout = false;
        if (this.roi !== roi) {
            /* roi가 바뀌었다면 movein/out 중이다 */
            movein = !!roi;
            moveout = !!this.roi;
        }
        else {
            moving = !isSamePose(this.pose, pose, threshold);
        }
        var events = [];
        moveout &&
            events.push({
                type: robotics_types_1.TRACKING_EVENT_TYPES.OUT,
                object: this,
                from,
                to
            });
        this.roi = roi || '';
        this.pose = pose || EMPTY_POSE;
        this.retention = moving ? 0 : this.retention + this.unknownRetention + 1;
        this.unknownRetention = 0;
        this.updatedAt = Date.now();
        if (moving) {
            this.movedAt = this.updatedAt;
        }
        movein &&
            events.push({
                type: robotics_types_1.TRACKING_EVENT_TYPES.IN,
                object: this,
                from,
                to
            });
        this.retention == 1 &&
            events.push({
                type: robotics_types_1.TRACKING_EVENT_TYPES.STAY,
                object: this,
                from,
                to: Object.assign(Object.assign({}, to), { retention: 1 })
            });
        return events;
    }
    get state() {
        return this.unknownRetention > 0
            ? TrackableObjectState.UNDETERMIN
            : this.retention > 1
                ? TrackableObjectState.STABLE
                : TrackableObjectState.MOVING;
    }
}
exports.TrackableObjectImpl = TrackableObjectImpl;
//# sourceMappingURL=trackable-object.js.map