var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { serializable } from "../../engine/engine_serialization_decorator.js";
import { getParam } from "../../engine/engine_utils.js";
import { Behaviour, GameObject } from "../Component.js";
const debug = getParam("debugxrflags");
const disable = getParam("disablexrflags");
if (disable) {
    console.warn("XRFlags are disabled");
}
export var XRStateFlag;
(function (XRStateFlag) {
    XRStateFlag[XRStateFlag["Never"] = 0] = "Never";
    XRStateFlag[XRStateFlag["Browser"] = 1] = "Browser";
    XRStateFlag[XRStateFlag["AR"] = 2] = "AR";
    XRStateFlag[XRStateFlag["VR"] = 4] = "VR";
    XRStateFlag[XRStateFlag["FirstPerson"] = 8] = "FirstPerson";
    XRStateFlag[XRStateFlag["ThirdPerson"] = 16] = "ThirdPerson";
    XRStateFlag[XRStateFlag["All"] = 4294967295] = "All";
})(XRStateFlag || (XRStateFlag = {}));
export class XRState {
    static Global = new XRState();
    Mask = XRStateFlag.Browser | XRStateFlag.ThirdPerson;
    Has(state) {
        const res = (this.Mask & state);
        return res !== 0;
    }
    Set(state) {
        if (debug)
            console.warn("Set XR flag state to", state);
        this.Mask = state;
        XRFlag.Apply();
    }
    Enable(state) {
        this.Mask |= state;
        XRFlag.Apply();
    }
    Disable(state) {
        this.Mask &= ~state;
        XRFlag.Apply();
    }
    Toggle(state) {
        this.Mask ^= state;
        XRFlag.Apply();
    }
    EnableAll() {
        this.Mask = 0xffffffff | 0;
        XRFlag.Apply();
    }
    DisableAll() {
        this.Mask = 0;
        XRFlag.Apply();
    }
}
/**
 * XRFlag shows or hides GameObjects based on the current XR state or session.
 * Use for XR-responsive content that should only appear in specific modes.
 *
 * **XR states:**
 * - `Browser` - Normal web browsing (no XR)
 * - `AR` - Augmented reality session
 * - `VR` - Virtual reality session
 * - `FirstPerson` - First-person view mode
 * - `ThirdPerson` - Third-person/spectator view mode
 * - Combine with bitwise OR: `AR | VR`
 *
 * **Debug options:**
 * - `?debugxrflags` - Log flag changes
 * - `?disablexrflags` - Disable all XR flags
 *
 * @example Show only in VR
 * ```ts
 * const flag = myObject.addComponent(XRFlag);
 * flag.visibleIn = XRStateFlag.VR;
 * ```
 *
 * @example Show in AR and VR, hide in browser
 * ```ts
 * flag.visibleIn = XRStateFlag.AR | XRStateFlag.VR;
 * ```
 *
 * @category XR
 * @category Utilities
 * @group Components
 * @see {@link XRStateFlag} for state options
 * @see {@link XRState} for global state management
 * @see {@link DeviceFlag} for device-based visibility
 * @see {@link WebXR} for XR session management
 */
export class XRFlag extends Behaviour {
    static registry = [];
    static Apply() {
        for (const r of this.registry)
            r.UpdateVisible(XRState.Global);
    }
    static firstApply;
    static buffer = new XRState();
    visibleIn;
    awake() {
        XRFlag.registry.push(this);
    }
    onEnable() {
        if (!XRFlag.firstApply) {
            XRFlag.firstApply = true;
            XRFlag.Apply();
        }
        else {
            this.UpdateVisible(XRState.Global);
        }
    }
    onDestroy() {
        const i = XRFlag.registry.indexOf(this);
        if (i >= 0)
            XRFlag.registry.splice(i, 1);
    }
    get isOn() { return this.gameObject.visible; }
    UpdateVisible(state = null) {
        if (disable) {
            return;
        }
        // XR flags set visibility of whole hierarchy which is like setting the whole object inactive
        // so we need to ignore the enabled state of the XRFlag component
        // if(!this.enabled) return;
        let res = undefined;
        const flag = state;
        if (flag && typeof flag === "number") {
            console.assert(typeof flag === "number", "XRFlag.UpdateVisible: state must be a number", flag);
            if (debug)
                console.log(flag);
            XRFlag.buffer.Mask = flag;
            state = XRFlag.buffer;
        }
        if (state instanceof XRState) {
            if (debug)
                console.warn(this.name, "use passed in mask", state.Mask, this.visibleIn);
            res = state.Has(this.visibleIn);
        }
        else {
            if (debug)
                console.log(this.name, "use global mask");
            XRState.Global.Has(this.visibleIn);
        }
        if (res === undefined)
            return;
        if (res) {
            if (debug)
                console.log(this.name, "is visible", this.gameObject.uuid);
            // this.gameObject.visible = true;
            GameObject.setActive(this.gameObject, true);
        }
        else {
            if (debug)
                console.log(this.name, "is not visible", this.gameObject.uuid);
            const isVisible = this.gameObject.visible;
            if (!isVisible)
                return;
            this.gameObject.visible = false;
            // console.trace("DISABLE", this.name);
            // GameObject.setActive(this.gameObject, false);
        }
    }
}
__decorate([
    serializable()
], XRFlag.prototype, "visibleIn", void 0);
//# sourceMappingURL=XRFlag.js.map