"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 stringify_1 = require("../../../../../spec/stringify");
const _ids_1 = require("../../../../_ids");
class Open extends Semifunctional_1.Semifunctional {
    constructor(system) {
        super({
            fi: ['url', 'target', 'features'],
            fo: ['window'],
            i: ['done'],
            o: [],
        }, {
            output: {
                window: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_OPEN);
        this._release = () => {
            // console.log('WakeLock', '_release')
            if (this._window) {
                this._window.close();
            }
        };
        this._on_release = () => {
            // console.log('WakeLock', '_on_release')
            this._window = null;
        };
    }
    f({ url, target, features }, done) {
        const { api: { window: { open }, }, } = this.__system;
        const windowFeatures = Object.entries(features)
            .map(([key, value]) => {
            return `${key}=${value}`;
        })
            .join(',');
        const _window = open(url, target, windowFeatures);
        this._window = _window;
        const channel = new (class Channel extends _1.$ {
            constructor() {
                super(...arguments);
                this.__ = ['CH'];
            }
            send(data) {
                return __awaiter(this, void 0, void 0, function* () {
                    const _data = (0, stringify_1.stringify)(data);
                    // TODO should channel get "target" argument?
                    _window.postMessage(_data, '*');
                    return;
                });
            }
        })(this.__system);
        try {
            window.addEventListener('message', (event) => {
                // @ts-ignore
                channel.emit('message', event.data);
            });
        }
        catch (err) {
            done(undefined, err.message);
            return;
        }
        done({
            window: channel,
        });
    }
    d() {
        this._release();
    }
    onIterDataInputData(name, data) {
        // if (name === 'done') {
        this._release();
        // }
    }
}
exports.default = Open;
//# sourceMappingURL=index.js.map