"use strict";
// *****************************************************************************
// Copyright (C) 2023 STMicroelectronics and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************
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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TheiaRendererAPI = exports.TheiaMainApi = void 0;
const electron_1 = require("@theia/electron/shared/electron");
const nativeKeymap = require("@theia/electron/shared/native-keymap");
const inversify_1 = require("inversify");
const electron_token_1 = require("../electron-common/electron-token");
const electron_api_1 = require("../electron-common/electron-api");
const common_1 = require("../common");
const event_utils_1 = require("./event-utils");
let TheiaMainApi = class TheiaMainApi {
    constructor() {
        this.openPopups = new Map();
    }
    onStart(application) {
        // electron security token
        electron_1.ipcMain.on(electron_api_1.CHANNEL_GET_SECURITY_TOKEN, event => {
            event.returnValue = this.electronSecurityToken.value;
        });
        electron_1.ipcMain.handle(electron_api_1.CHANNEL_ATTACH_SECURITY_TOKEN, (event, endpoint) => electron_1.session.defaultSession.cookies.set({
            url: endpoint,
            name: electron_token_1.ElectronSecurityToken,
            value: JSON.stringify(this.electronSecurityToken),
            httpOnly: true,
            sameSite: 'no_restriction'
        }));
        // application menu
        electron_1.ipcMain.on(electron_api_1.CHANNEL_SET_MENU, (event, menuId, menu) => {
            var _a;
            let electronMenu;
            if (menu) {
                electronMenu = electron_1.Menu.buildFromTemplate(this.fromMenuDto(event.sender, menuId, menu));
            }
            else {
                // eslint-disable-next-line no-null/no-null
                electronMenu = null;
            }
            if (common_1.isOSX) {
                electron_1.Menu.setApplicationMenu(electronMenu);
            }
            else {
                (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.setMenu(electronMenu);
            }
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_SET_MENU_BAR_VISIBLE, (event, visible, windowName) => {
            let electronWindow;
            if (windowName) {
                electronWindow = electron_1.BrowserWindow.getAllWindows().find(win => win.webContents.mainFrame.name === windowName);
            }
            else {
                electronWindow = electron_1.BrowserWindow.fromWebContents(event.sender);
            }
            if (electronWindow) {
                electronWindow.setMenuBarVisibility(visible);
            }
            else {
                console.warn(`There is no known secondary window '${windowName}'. Thus, the menu bar could not be made visible.`);
            }
        });
        // popup menu
        electron_1.ipcMain.handle(electron_api_1.CHANNEL_OPEN_POPUP, (event, menuId, menu, x, y) => {
            const zoom = event.sender.getZoomFactor();
            // TODO: Remove the offset once Electron fixes https://github.com/electron/electron/issues/31641
            const offset = process.platform === 'win32' ? 0 : 2;
            // x and y values must be Ints or else there is a conversion error
            x = Math.round(x * zoom) + offset;
            y = Math.round(y * zoom) + offset;
            const popup = electron_1.Menu.buildFromTemplate(this.fromMenuDto(event.sender, menuId, menu));
            this.openPopups.set(menuId, popup);
            popup.popup({
                callback: () => {
                    this.openPopups.delete(menuId);
                    event.sender.send(electron_api_1.CHANNEL_ON_CLOSE_POPUP, menuId);
                }
            });
        });
        electron_1.ipcMain.handle(electron_api_1.CHANNEL_CLOSE_POPUP, (event, handle) => {
            if (this.openPopups.has(handle)) {
                this.openPopups.get(handle).closePopup();
            }
        });
        // focus windows for secondary window support
        electron_1.ipcMain.on(electron_api_1.CHANNEL_FOCUS_WINDOW, (event, windowName) => {
            const electronWindow = electron_1.BrowserWindow.getAllWindows().find(win => win.webContents.mainFrame.name === windowName);
            if (electronWindow) {
                if (electronWindow.isMinimized()) {
                    electronWindow.restore();
                }
                electronWindow.focus();
            }
            else {
                console.warn(`There is no known secondary window '${windowName}'. Thus, the window could not be focussed.`);
            }
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_SHOW_ITEM_IN_FOLDER, (event, fsPath) => {
            electron_1.shell.showItemInFolder(fsPath);
        });
        electron_1.ipcMain.handle(electron_api_1.CHANNEL_GET_TITLE_STYLE_AT_STARTUP, event => application.getTitleBarStyleAtStartup(event.sender));
        electron_1.ipcMain.on(electron_api_1.CHANNEL_SET_TITLE_STYLE, (event, style) => application.setTitleBarStyle(event.sender, style));
        electron_1.ipcMain.on(electron_api_1.CHANNEL_MINIMIZE, event => {
            var _a;
            (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.minimize();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_IS_MAXIMIZED, event => {
            var _a;
            event.returnValue = (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.isMaximized();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_MAXIMIZE, event => {
            var _a;
            (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.maximize();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_UNMAXIMIZE, event => {
            var _a;
            (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.unmaximize();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_CLOSE, event => {
            var _a;
            (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.close();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_RESTART, event => {
            application.restart(event.sender);
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_TOGGLE_DEVTOOLS, event => {
            event.sender.toggleDevTools();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_SET_ZOOM_LEVEL, (event, zoomLevel) => {
            event.sender.setZoomLevel(zoomLevel);
        });
        electron_1.ipcMain.handle(electron_api_1.CHANNEL_GET_ZOOM_LEVEL, event => event.sender.getZoomLevel());
        electron_1.ipcMain.on(electron_api_1.CHANNEL_TOGGLE_FULL_SCREEN, event => {
            const win = electron_1.BrowserWindow.fromWebContents(event.sender);
            if (win) {
                win.setFullScreen(!win.isFullScreen());
            }
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_IS_FULL_SCREENABLE, event => {
            var _a;
            event.returnValue = (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.isFullScreenable();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_IS_FULL_SCREEN, event => {
            var _a;
            event.returnValue = (_a = electron_1.BrowserWindow.fromWebContents(event.sender)) === null || _a === void 0 ? void 0 : _a.isFullScreen();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_READ_CLIPBOARD, event => {
            event.returnValue = electron_1.clipboard.readText();
        });
        electron_1.ipcMain.on(electron_api_1.CHANNEL_WRITE_CLIPBOARD, (event, text) => {
            electron_1.clipboard.writeText(text);
        });
        nativeKeymap.onDidChangeKeyboardLayout(() => {
            const newLayout = {
                info: nativeKeymap.getCurrentKeyboardLayout(),
                mapping: nativeKeymap.getKeyMap()
            };
            for (const webContent of electron_1.webContents.getAllWebContents()) {
                webContent.send('keyboardLayoutChanged', newLayout);
            }
        });
    }
    fromMenuDto(sender, menuId, menuDto) {
        return menuDto.map(dto => {
            const result = {
                id: dto.id,
                label: dto.label,
                type: dto.type,
                checked: dto.checked,
                enabled: dto.enabled,
                visible: dto.visible,
                role: dto.role,
                accelerator: dto.accelerator
            };
            if (dto.submenu) {
                result.submenu = this.fromMenuDto(sender, menuId, dto.submenu);
            }
            if (dto.handlerId) {
                result.click = () => {
                    sender.send(electron_api_1.CHANNEL_INVOKE_MENU, menuId, dto.handlerId);
                };
            }
            return result;
        });
    }
};
__decorate([
    (0, inversify_1.inject)(electron_token_1.ElectronSecurityToken),
    __metadata("design:type", Object)
], TheiaMainApi.prototype, "electronSecurityToken", void 0);
TheiaMainApi = __decorate([
    (0, inversify_1.injectable)()
], TheiaMainApi);
exports.TheiaMainApi = TheiaMainApi;
let nextReplyChannel = 0;
var TheiaRendererAPI;
(function (TheiaRendererAPI) {
    function sendWindowEvent(wc, event) {
        wc.send(electron_api_1.CHANNEL_ON_WINDOW_EVENT, event);
    }
    TheiaRendererAPI.sendWindowEvent = sendWindowEvent;
    function requestClose(wc, stopReason) {
        const channelNr = nextReplyChannel++;
        const confirmChannel = `confirm-${channelNr}`;
        const cancelChannel = `cancel-${channelNr}`;
        const disposables = new common_1.DisposableCollection();
        return new Promise(resolve => {
            wc.send(electron_api_1.CHANNEL_REQUEST_CLOSE, stopReason, confirmChannel, cancelChannel);
            (0, event_utils_1.createDisposableListener)(electron_1.ipcMain, confirmChannel, e => {
                resolve(true);
            }, disposables);
            (0, event_utils_1.createDisposableListener)(electron_1.ipcMain, cancelChannel, e => {
                resolve(false);
            }, disposables);
        }).finally(() => disposables.dispose());
    }
    TheiaRendererAPI.requestClose = requestClose;
    function onRequestReload(wc, handler) {
        return createWindowListener(wc, electron_api_1.CHANNEL_REQUEST_RELOAD, handler);
    }
    TheiaRendererAPI.onRequestReload = onRequestReload;
    function onApplicationStateChanged(wc, handler) {
        return createWindowListener(wc, electron_api_1.CHANNEL_APP_STATE_CHANGED, state => handler(state));
    }
    TheiaRendererAPI.onApplicationStateChanged = onApplicationStateChanged;
    function onIpcData(handler) {
        return (0, event_utils_1.createDisposableListener)(electron_1.ipcMain, electron_api_1.CHANNEL_IPC_CONNECTION, (event, data) => handler(event.sender, data));
    }
    TheiaRendererAPI.onIpcData = onIpcData;
    function sendData(wc, data) {
        wc.send(electron_api_1.CHANNEL_IPC_CONNECTION, data);
    }
    TheiaRendererAPI.sendData = sendData;
    function createWindowListener(wc, channel, handler) {
        return (0, event_utils_1.createDisposableListener)(electron_1.ipcMain, channel, (event, ...args) => {
            if (wc.id === event.sender.id) {
                handler(...args);
            }
        });
    }
})(TheiaRendererAPI = exports.TheiaRendererAPI || (exports.TheiaRendererAPI = {}));
//# sourceMappingURL=electron-api-main.js.map