import { Angle, AppObjectEntity, Quaternion, RangedNumber, Vector3, } from "@vived/core";
import { Hideable } from "../../Hideable/Entities/Hideable";
import { LabelEntity } from "../../Label/Entities/LabelEntity";
import { OverlayColor, OverlayColorEnums, } from "../../OverlayColor/Entities/OverlayColor";
import { makeSelectable, } from "../../Selection/Entities/Selectable";
import { makeTransform3D, } from "../../Transform3D/Entities/Transform3D";
export const CALLOUT_MINIMUM_SIZE = 0.3;
export const CALLOUT_MAXIMUM_SIZE = 1.3;
export class CalloutEntity extends AppObjectEntity {
    static get(appObj) {
        return appObj.getComponent(this.type);
    }
    static getById(id, appObjects) {
        return appObjects.get(id)?.getComponent(this.type);
    }
}
CalloutEntity.type = "CALLOUT";
export 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 = 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 = Vector3.FromDTO(dto.rootPosition);
        this.rootRotation = Quaternion.FromDTO(dto.rootRotation);
        this.labelPosition = 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 ?? 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.addIfMissing(appObject);
        this.label.addChangeObserver(this.notifyOnChange);
        this.hideable = Hideable.addIfMissing(appObject);
        this.hideable.addChangeObserver(this.notifyOnChange);
        this.overlayColor = OverlayColor.addIfMissing(appObject);
        this.overlayColor.addChangeObserver(this.notifyOnChange);
        this.selectable = makeSelectable(appObject);
        this.selectable.addChangeObserver(this.notifyOnChange);
        this.rangedSize = new RangedNumber({
            min: CALLOUT_MINIMUM_SIZE,
            max: CALLOUT_MAXIMUM_SIZE,
            initialValue: CALLOUT_MINIMUM_SIZE +
                0.5 * (CALLOUT_MAXIMUM_SIZE - CALLOUT_MINIMUM_SIZE),
        }, this.notifyOnChange);
        const myID = appObject.id;
        const rootAO = appObject.appObjectRepo.getOrCreate(myID + "_root");
        this.rootTransform = makeTransform3D(rootAO);
        this.rootTransform.addChangeObserver(this.notifyOnChange);
        const labelAO = appObject.appObjectRepo.getOrCreate(myID + "_label");
        this.labelTransform = makeTransform3D(labelAO);
        this.labelTransform.localRotation = Quaternion.FromYawPitchRoll(Angle.FromDegrees(180), Angle.FromDegrees(0), Angle.FromDegrees(0));
        this.labelTransform.addChangeObserver(this.notifyOnChange);
    }
}
//# sourceMappingURL=CalloutEntity.js.map