"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const DeviceHelper_1 = require("../helpers/DeviceHelper");
const VideoHelper_1 = require("../helpers/VideoHelper");
const Validate_1 = __importDefault(require("../../Validate/Validate"));
const IScreen_1 = require("./IScreen");
/**
 * The `sos.management.screen` API groups together methods for controlling the screen of the device. It allows for manipulating the screen
 * resolution or orientation, set brightness, retrieve the current brightness of the display, and manipulate the power mode.
 *
 * :::warning
 * This method only turns on/off the display/backlight. It will **not** set any power-saving mode. We also strongly recommend rebooting any
 * device once a day.
 * :::
 *
 * :::info
 * There is a specific behavior based on the device type you operate:
 * **On SoC displays** (e.g., Samsung Tizen, LG webOS, Android-based SoC displays from Sony, Vestel Philips,...)
 * - `powerOn()` and `powerOff()` are turning the display backlight and the panel off
 * **On external media players** (e.g., BrightSign, Windows PC, Android players, Raspberry Pi)
 * - `powerOn()` and `powerOff()` are turning off the video output (typically HDMI-out); this functionality does not manage the connected display backlight and needs to be controlled via RS232 or another way.
 * :::
 *
 * <details>
 *     <summary>Screen Management Capabilities</summary>
 * 		| Capability | Description |
 * 		|:------------|:-------------|
 * 		| `SET_BRIGHTNESS` | If device can brightness. |
 * 		| `GET_BRIGHTNESS` | If device can return current brightness. |
 * 		| `SCREEN_RESIZE` | If the device can change screen resolution and orientation. |
 * 		| `ORIENTATION_LANDSCAPE` | If device supports landscape orientation. |
 * 		| `ORIENTATION_PORTRAIT` | If device supports portrait orientation. |
 * 		| `ORIENTATION_LANDSCAPE_FLIPPED` | If device supports flipped landscape orientation. |
 * 		| `ORIENTATION_PORTRAIT_FLIPPED` | If device supports flipped portrait orientation. |
 * 		| `ORIENTATION_AUTO` | If device supports auto orientation. |
 *
 * 		If you want to check if the device supports those capabilities, use [`sos.management.supports()`](https://developers.signageos.io/sdk/sos_management/#supports).
 * </details>
 */
class Screen {
    messagePrefix;
    postMessage;
    /** @internal */
    constructor(messagePrefix, postMessage) {
        this.messagePrefix = messagePrefix;
        this.postMessage = postMessage;
    }
    /**
     * The `resize()` method changes the resolution and orientation of the display.
     *
     * :::info
     * For Tizen, you have to provide `baseUrl` which points to the Core App for Tizen, which will be downloaded to the device [Read more on how to upload your Core Apps here.](https://docs.signageos.io/hc/en-us/articles/4405245195666).
     * :::
     *
     * @param baseUrl SSSP & Tizen devices require installing an orientation-specific Core App if you want to switch orientation to portrait or landscape.
     * @param orientation Screen orientation
     * @param resolution Where it applies (mainly SSSP 2/3)
     * @param currentVersion Core App version
     * @param videoOrientation If the video has a different orientation than the HTML5 content
     * @returns {Promise<void>} A promise that resolves when the screen is successfully resized.
     * @throws {Error} If `baseUrl` is not a valid URL
     * @throws {Error} If `orientation` is not a valid orientation
     * @throws {Error} If `resolution` is not a valid resolution
     * @throws {Error} If `currentVersion` is not a valid string
     * @throws {Error} If `videoOrientation` is not a valid video orientation
     * @since 3.0.0
     *
     * @example
     * // for Tizen
     * await sos.management.screen.resize(
     *     "https://cdn.your-cms.com/tizen/1.0.4",
     *     "PORTRAIT",
     *     "FULL_READY",
     *     "1.0.4"
     * );
     *
     * // for all other supported devices
     * await sos.management.screen.resize(
     *     "",
     *     "PORTRAIT",
     *     "HD_READY",
     *     ""
     * );
     *
     * @example // {@link https://github.com/signageos/applet-examples/blob/master/examples/management-js-api/resize/ |How to resize screen on device}
     */
    async resize(baseUrl, orientation, resolution, currentVersion, videoOrientation) {
        (0, Validate_1.default)({ baseUrl }).required().uri();
        (0, Validate_1.default)({ currentVersion }).required().string();
        if (typeof DeviceHelper_1.Orientation[orientation] === 'undefined') {
            throw new Error('Invalid orientation');
        }
        if (typeof DeviceHelper_1.Resolution[resolution] === 'undefined') {
            throw new Error('Invalid resolution');
        }
        if (videoOrientation && typeof VideoHelper_1.Orientation[videoOrientation] === 'undefined') {
            throw new Error('Invalid video orientation');
        }
        await this.postMessage({
            type: this.getMessage('resize_screen'),
            baseUrl,
            orientation,
            resolution,
            currentVersion,
            videoOrientation,
        });
    }
    /**
     * The `getOrientation()` method returns the current orientation of the screen.
     *
     * @returns {Promise<IOrientation>} A promise that resolves to the current screen orientation.
     * @throws {Error} If the orientation cannot be retrieved.
     * @since 4.7.0
     *
     * @example
     * const orientation = (await sos.management.screen.getOrientation()).screenOrientation;
     * console.log(`Current screen orientation is: ${orientation}`);
     */
    async getOrientation() {
        const { screenOrientation } = await this.postMessage({
            type: this.getMessage('get_screen_orientation'),
        });
        return screenOrientation;
    }
    /**
     * The `setBrightness()` method sets the brightness of the screen. It supports two different brightness values for 2 time points in the day.
     *
     * @param timeFrom1 Time in the XX:XX format
     * @param brightness1 Brightness value between 0 and 100
     * @param timeFrom2 Time in the XX:XX format
     * @param brightness2 Brightness value between 0 and 100
     * @return {Promise<void>} A promise that resolves when the brightness is successfully set.
     * @throws {Error} If `timeFrom1` is not a valid time in the XX:XX format
     * @throws {Error} If `brightness1` is not a number between 0 and 100
     * @throws {Error} If `timeFrom2` is not a valid time in the XX:XX format
     * @throws {Error} If `brightness2` is not a number between 0 and 100
     * @since 3.0.0
     *
     * @example // {@link https://github.com/signageos/applet-examples/blob/master/examples/management-js-api/brightness/ | Applet Example with Brightness setup}
     *
     * @example
     * // Set brightness to 10% between 00:00 and 17:00, and to 30% between 17:00 and 23:59
     * await sos.management.screen.setBrightness(
     *     '00:00',
     *     '10',
     *     '17:00',
     *     '30'
     * );
     *
     * // Set brightness to 50% all day
     * await sos.management.screen.setBrightness(
     *    00:00,
     *    50,
     *    23:59,
     *    50
     * );
     */
    async setBrightness(timeFrom1, brightness1, timeFrom2, brightness2) {
        (0, Validate_1.default)({ brightness1 }).required().number().min(0).max(100);
        (0, Validate_1.default)({ brightness2 }).required().number().min(0).max(100);
        (0, Validate_1.default)({ timeFrom1 })
            .canBeNull()
            .required()
            .string()
            .matchRegExp(/\d{2}:\d{2}/)
            .timerTime();
        (0, Validate_1.default)({ timeFrom2 })
            .canBeNull()
            .required()
            .string()
            .matchRegExp(/\d{2}:\d{2}/)
            .timerTime();
        await this.postMessage({
            type: this.getMessage('set_screen_brightness'),
            timeFrom1,
            brightness1,
            timeFrom2,
            brightness2,
        });
    }
    /**
     * The `getBrightness()` method returns information about the currently set brightness values.
     *
     * @returns {Promise<IBrightness>} A promise that resolves to the current brightness settings.
     * @throws {Error} If the brightness cannot be retrieved.
     * @since 3.0.0
     */
    async getBrightness() {
        const { screenBrightness } = await this.postMessage({
            type: this.getMessage('get_screen_brightness'),
        });
        return screenBrightness;
    }
    /** @internal */
    async takeAndUploadScreenshot(...args) {
        if (typeof args[0] === 'string' && typeof args[1] === 'undefined') {
            // 1st implementation (deprecated) - takeAndUploadScreenshot(uploadBaseUrl: string): Promise<string>
            const [uploadBaseUrl] = args;
            (0, Validate_1.default)({ uploadBaseUrl }).required().uri();
            const response = await this.postMessage({
                type: this.getMessage('upload_screenshot'),
                uploadBaseUrl,
            });
            if (typeof response === 'string') {
                return response; // For backward compatibility, return string directly
            }
            else if (typeof response === 'object' && 'screenshotUrl' in response) {
                const { screenshotUrl } = response;
                return screenshotUrl;
            }
        }
        else if (typeof args[0] === 'string' && typeof args[1] === 'boolean') {
            // 2nd implementation (deprecated) - takeAndUploadScreenshot(uploadBaseUrl: string, computeHash?: boolean): Promise<TakeAndUploadScreenshotResult>
            const [uploadBaseUrl, computeHash] = args;
            (0, Validate_1.default)({ uploadBaseUrl }).required().uri();
            (0, Validate_1.default)({ computeHash }).boolean();
            const { screenshotUrl, aHash } = await this.postMessage({
                type: this.getMessage('upload_screenshot'),
                uploadBaseUrl,
                computeHash,
            });
            return {
                screenshotUrl,
                aHash,
            };
        }
        else if (typeof args[0] === 'string' && typeof args[1] === 'object') {
            // 3rd implementation - takeAndUploadScreenshot(uploadBaseUrl: string, options: TakeAndUploadScreenshotOptions): Promise<TakeAndUploadScreenshotResult>
            const [uploadBaseUrl, options] = args;
            (0, Validate_1.default)({ uploadBaseUrl }).required().uri();
            if (options !== undefined) {
                (0, Validate_1.default)({ options }).object(IScreen_1.VTakeAndUploadScreenshotOptions);
            }
            const { screenshotUrl, aHash } = await this.postMessage({
                type: this.getMessage('upload_screenshot'),
                uploadBaseUrl,
                computeHash: options.computeHash,
                headers: options.headers,
            });
            return {
                screenshotUrl,
                aHash,
            };
        }
    }
    /**
     * The `powerOn()` method turns the screen on.
     *
     * @returns {Promise<void>} A promise that resolves when the screen is successfully turned on.
     * @throws {Error} If the screen cannot be turned on.
     * @since 3.0.0
     */
    async powerOn() {
        await this.postMessage({
            type: this.getMessage('power_on_display'),
        });
    }
    /**
     * The `powerOff()` method turns the screen off. It will turn off the display backlight and the panel, and it will also disable the applet.
     *
     * :::warning
     * On Android devices, `powerOff()` also shuts down the webview and the Applet. It's the default Android behavior that cannot be changed. Once
     * the Applet is off, you cannot call `powerOn()` to resume the playback.
     *
     * To manage the display On/Off state, use [REST API Power Actions](https://developers.signageos.io/api/#tag/DevicePower-Actions) instead.
     * :::
     *
     * @returns {Promise<void>} A promise that resolves when the screen is successfully turned off.
     * @throws {Error} If the screen cannot be turned off.
     * @since 3.0.0
     */
    async powerOff() {
        await this.postMessage({
            type: this.getMessage('power_off_display'),
        });
    }
    /**
     * The `isPoweredOn()` method returns whether the screen is on.
     *
     * @returns {Promise<boolean>} A promise that resolves to a boolean indicating whether the screen is powered on.
     * @throws {Error} If the power state cannot be retrieved.
     * @since 3.0.0
     */
    async isPoweredOn() {
        const { isDisplayPowerOn } = await this.postMessage({
            type: this.getMessage('get_is_display_power_on'),
        });
        return isDisplayPowerOn;
    }
    getMessage(name) {
        return this.getMessagePrefix() + '.' + name;
    }
    getMessagePrefix() {
        return this.messagePrefix;
    }
}
exports.default = Screen;
//# sourceMappingURL=Screen.js.map