"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CalloutEntity = exports.CALLOUT_MAXIMUM_SIZE = exports.CALLOUT_MINIMUM_SIZE = void 0;
exports.makeCalloutEntity = makeCalloutEntity;
const core_1 = require("@vived/core");
const Hideable_1 = require("../../Hideable/Entities/Hideable");
const LabelEntity_1 = require("../../Label/Entities/LabelEntity");
const OverlayColor_1 = require("../../OverlayColor/Entities/OverlayColor");
const Selectable_1 = require("../../Selection/Entities/Selectable");
const Transform3D_1 = require("../../Transform3D/Entities/Transform3D");
exports.CALLOUT_MINIMUM_SIZE = 0.3;
exports.CALLOUT_MAXIMUM_SIZE = 1.3;
class CalloutEntity extends core_1.AppObjectEntity {
    static get(appObj) {
        return appObj.getComponent(this.type);
    }
    static getById(id, appObjects) {
        return appObjects.get(id)?.getComponent(this.type);
    }
}
exports.CalloutEntity = CalloutEntity;
CalloutEntity.type = "CALLOUT";
function makeCalloutEntity(appObject) {
    return new CalloutImp(appObject);
}
class CalloutImp extends CalloutEntity {
    get id() {
        return this.appObject.id;
    }
    get size() {
        return this.rangedSize.val;
    }
    set size(val) {
        this.rangedSize.val = val;
    }
    get rootPosition() {
        return this.rootTransform.localPosition;
    }
    set rootPosition(p) {
        this.rootTransform.localPosition = p;
    }
    get rootRotation() {
        return this.rootTransform.localRotation;
    }
    set rootRotation(r) {
        this.rootTransform.localRotation = r;
    }
    get labelPosition() {
        return this.labelTransform.localPosition;
    }
    set labelPosition(p) {
        this.labelTransform.localPosition = p;
    }
    get labelRotation() {
        return this.labelTransform.localRotation;
    }
    set labelRotation(r) {
        this.labelTransform.localRotation = r;
    }
    get offsetDirection() {
        const worldStartPos = this.rootTransform.worldPosition;
        const worldEndPos = this.labelTransform.worldPosition;
        const delta = core_1.Vector3.Subtract(worldEndPos, worldStartPos);
        let offsetDirection = "LEFT";
        if (Math.abs(delta.y) > Math.abs(delta.x)) {
            if (delta.y < 0)
                offsetDirection = "DOWN";
            else
                offsetDirection = "UP";
        }
        else {
            if (delta.x < 0)
                offsetDirection = "LEFT";
            else
                offsetDirection = "RIGHT";
        }
        return offsetDirection;
    }
    get data() {
        return {
            id: this.appObject.id,
            parentID: this.inRepo ? this.inRepo.appObject.id : "",
            rootPosition: this.rootPosition.dto,
            rootRotation: this.rootRotation.dto,
            labelPosition: this.labelPosition.dto,
            size: this.size,
            label: this.label.custom,
            defaultLabel: this.label.default,
            color: this.overlayColor.overlayColor,
        };
    }
    set data(dto) {
        this.rootPosition = core_1.Vector3.FromDTO(dto.rootPosition);
        this.rootRotation = core_1.Quaternion.FromDTO(dto.rootRotation);
        this.labelPosition = core_1.Vector3.FromDTO(dto.labelPosition);
        this.size = dto.size;
        this.label.custom = dto.label;
        this.label.default = dto.defaultLabel;
        const overlayColor = dto.color;
        this.overlayColor.overlayColor = overlayColor ?? OverlayColor_1.OverlayColorEnums.WHITE;
    }
    constructor(appObject) {
        super(appObject, CalloutEntity.type);
        this.dispose = () => {
            super.dispose();
            this.label.dispose();
            this.hideable.dispose();
            this.selectable.dispose();
            this.overlayColor.dispose();
            this.labelTransform.appObject.dispose();
            this.rootTransform.appObject.dispose();
            if (this.inRepo) {
                this.inRepo.removeForAppObject(this.appObject.id);
            }
        };
        this.label = LabelEntity_1.LabelEntity.addIfMissing(appObject);
        this.label.addChangeObserver(this.notifyOnChange);
        this.hideable = Hideable_1.Hideable.addIfMissing(appObject);
        this.hideable.addChangeObserver(this.notifyOnChange);
        this.overlayColor = OverlayColor_1.OverlayColor.addIfMissing(appObject);
        this.overlayColor.addChangeObserver(this.notifyOnChange);
        this.selectable = (0, Selectable_1.makeSelectable)(appObject);
        this.selectable.addChangeObserver(this.notifyOnChange);
        this.rangedSize = new core_1.RangedNumber({
            min: exports.CALLOUT_MINIMUM_SIZE,
            max: exports.CALLOUT_MAXIMUM_SIZE,
            initialValue: exports.CALLOUT_MINIMUM_SIZE +
                0.5 * (exports.CALLOUT_MAXIMUM_SIZE - exports.CALLOUT_MINIMUM_SIZE),
        }, this.notifyOnChange);
        const myID = appObject.id;
        const rootAO = appObject.appObjectRepo.getOrCreate(myID + "_root");
        this.rootTransform = (0, Transform3D_1.makeTransform3D)(rootAO);
        this.rootTransform.addChangeObserver(this.notifyOnChange);
        const labelAO = appObject.appObjectRepo.getOrCreate(myID + "_label");
        this.labelTransform = (0, Transform3D_1.makeTransform3D)(labelAO);
        this.labelTransform.localRotation = core_1.Quaternion.FromYawPitchRoll(core_1.Angle.FromDegrees(180), core_1.Angle.FromDegrees(0), core_1.Angle.FromDegrees(0));
        this.labelTransform.addChangeObserver(this.notifyOnChange);
    }
}
//# sourceMappingURL=CalloutEntity.js.map