"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require("../../../../../Class/$");
const Semifunctional_1 = require("../../../../../Class/Semifunctional");
const array_1 = require("../../../../../util/array");
const _ids_1 = require("../../../../_ids");
const globalComponent_1 = require("../../../../globalComponent");
class IntersectionObserver_ extends Semifunctional_1.Semifunctional {
    constructor(system) {
        super({
            fi: ['root', 'opt'],
            fo: ['observer'],
            i: ['done'],
            o: [],
        }, {
            input: {
                root: {
                    ref: true,
                },
            },
            output: {
                observer: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_INTERSECTION_OBSERVER);
    }
    f({ root }, done) {
        return __awaiter(this, void 0, void 0, function* () {
            const { api: { document: { IntersectionObserver }, }, } = this.__system;
            const globalId = root.getGlobalId();
            const _component = yield (0, globalComponent_1.firstGlobalComponentPromise)(this.__system, globalId);
            const callback = (entries) => {
                for (let i = 0; i < entries.length; i++) {
                    const entry = entries[i];
                    const callback = callbacks[i];
                    if (!callback) {
                        return;
                    }
                    const _entry = {
                        isIntersecting: entry.isIntersecting,
                        time: entry.time,
                    };
                    callback(_entry);
                }
            };
            let base = _component.getRootBase();
            let r = _component;
            while (base.length === 0) {
                base = r.$slotParent.getRootBase();
                r = r.$slotParent;
            }
            const rootFirstRootLeaf = base[0][1];
            const _observer = new IntersectionObserver(callback, {
                root: rootFirstRootLeaf.$element,
                threshold: 0.1,
            });
            const callbacks = [];
            const observer = new (class IntersectionObserver_ extends _1.$ {
                constructor() {
                    super(...arguments);
                    this.__ = ['OB'];
                }
                observe(element, callback) {
                    callbacks.push(callback);
                    _observer.observe(element);
                    return () => {
                        (0, array_1.remove)(callbacks, callback);
                        _observer.unobserve(element);
                    };
                }
            })(this.__system);
            done({ observer });
        });
    }
    d() {
        // TODO
    }
}
exports.default = IntersectionObserver_;
//# sourceMappingURL=index.js.map