"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const Validate_1 = __importDefault(require("../Validate/Validate"));
const events_2 = require("./events");
const IOpenLinkOptions_1 = require("./IOpenLinkOptions");
/**
 * There are several use cases when you need to open a web browser on a touch-enabled device (also known as a tablet). For these cases, you can use a custom web browser we built. Default URL can be opened and even the whitelisting/blacklisting of certain domains is supported.
 *
 * :::info
 *
 * **This API is currently available on:**
 * - Android devices with Android 5+ (Philips, Benq, Sharp, generic Android device)
 *
 * **With some limitations, you can also use this API on**
 * - Samsung Tizen (SSSP 4 and above); where the website is just in fullscreen without an address bar or theme options (headless mode)
 * - LG webOS (webOS 3.0 and above); where the website is just in fullscreen without an address bar or theme options (headless mode)
 * - Linux (Fedora, Ubuntu), Raspberry Pi, NEC Compute Module; where the website is just in fullscreen without an address bar or theme options (headless mode)
 * - BrightSign; where the website is just in fullscreen without an address bar or theme options (headless mode)
 * :::
 *
 * <details>
 *     <summary>Device Browser Capabilities</summary>
 * 		| Capability | Description |
 * 		|:------------|:-------------|
 * 		| `BROWSER` | If device can open browser with custom URL |
 *
 * 		If you want to check if the device supports this capability, use [`sos.display.supports()`](https://developers.signageos.io/sdk/sos/display#supports).
 * </details>
 */
class Browser {
    exchange;
    events = new events_1.EventEmitter();
    /** @internal */
    constructor(exchange) {
        this.exchange = exchange;
    }
    /**
     * The `open()` method opens the specified url in a browser window.
     *
     * @param uri The URL to open in the browser.
     * @param options Optional parameters to configure the browser window.
     * @param options.aclDomains List of domains to be interpreted according to `aclMode`. Example: `signageos.io`, `www.example.com`
     * @param options.aclMode `blacklist` – Allow access to all domains except those in aclDomains and their subdomains, `whitelist` – Allow access only to domains in aclDomains and their subdomains.
     * @param options.readOnlyAddressBar If `true`, the address bar is read-only, if `false` the user can navigate away by entering a URL in the address bar.
     * @param options.idleTimeout The browser will automatically close after a specified period of inactivity (in milliseconds).
     * @param options.coordinates Size and position of the browser window. Defaults to fullscreen.
     * @param options.theme Specify custom UI theme. (Android only)
     * @param options.headlessMode Headless mode hides the entire address bar. (Android only)
     * @param options.canUserClose Whether the user can manually close the browser. (default if headless false, else true)
     * @param options.clearData Clear cache after the browser closes. (default if headless false, else true)
     * @param options.method Can only be native (which opens a new, fully sandboxed fullscreen window) or iframe (which opens a configurable-sized window). (only Linux)
     * @returns {Promise<void>} A promise that resolves when the browser is opened.
     * @throws {Error} If the `uri` is not a valid URL or string.
     * @throws {Error} If the `options` are not valid.
     * @throws {Error} If unexpected error occurred when opening link.
     * @since 4.0.0
     *
     * @example // {@link https://github.com/signageos/applet-examples/tree/master/examples/content-js-api/browser | Example of Applet for using browser on Android }
     *
     * @example
     * await sos.browser.open('https://www.signageos.io', {
     * 	aclDomains: ['google.com', 'yahoo.com'],
     * 	aclMode: 'blacklist', // or 'whitelist'
     * 	readOnlyAddressBar: true,
     * 	coordinates: { // Supported only on Linux and Android
     * 		x: 0,
     * 		y: 0,
     * 		height: 500,
     * 		width: 500,
     * 	},
     * 	// theme: { ... }
     * 	headlessMode: false,
     * });
     */
    async open(uri, options = {}) {
        (0, Validate_1.default)({ uri }).required().uri();
        (0, Validate_1.default)({ options }).required().object(IOpenLinkOptions_1.VIOpenLinkOptions);
        const headlessMode = options.headlessMode ?? true;
        await this.exchange.postMessage({
            uri,
            ...options,
            headlessMode,
            type: 'open',
        });
    }
    /**
     * The `close()` method closes the browser window opened by the `open()` method.
     *
     * @returns {Promise<void>} A promise that resolves when the browser is closed.
     * @since 4.0.0
     *
     * @example
     * await sos.browser.open('https://www.signageos.io', {
     * 	readOnlyAddressBar: true,
     * });
     * // some time later
     * await sos.browser.close();
     */
    async close() {
        await this.exchange.postMessage({
            type: 'close',
        });
    }
    /**
     * The `onClose()` method sets up a listener, which is called whenever a browser window is closed. This can happen by an API call, by a
     * user request or after a timeout. This doesn't fire between `open` calls or on subsequent `close` calls.
     *
     * @param listener The listener to be called when the browser is closed.
     * @returns {void} A callback which removes the listener.
     */
    onClose(listener) {
        (0, Validate_1.default)({ listener }).required().function();
        this.events.addListener(events_2.EventType.CLOSE, listener);
        return () => {
            this.events.removeListener(events_2.EventType.CLOSE, listener);
        };
    }
    /** @internal */
    handleMessageData(data) {
        switch (data.type) {
            case this.exchange.messageNameToType('closed'): {
                const event = {
                    type: events_2.EventType.CLOSE,
                    reason: data.reason,
                };
                this.events.emit(events_2.EventType.CLOSE, event);
                break;
            }
            default:
        }
    }
    /**
     * @deprecated use `sos.browser.open()` instead
     */
    async openLink(uri, options = {}) {
        console.warn('sos.browser.openLink() is deprecated and will be removed in the future versions. Use sos.browser.open() instead.');
        (0, Validate_1.default)({ uri }).required().uri();
        (0, Validate_1.default)({ options }).required().object();
        await this.exchange.postMessage({
            uri,
            ...options,
            headlessMode: false,
            type: 'open_link',
        });
    }
}
exports.default = Browser;
//# sourceMappingURL=Browser.js.map