"use strict";
// *****************************************************************************
// Copyright (C) 2018 TypeFox 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);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TheiaDockPanel = exports.BOTTOM_AREA_ID = exports.MAIN_AREA_ID = exports.MAXIMIZED_CLASS = void 0;
const algorithm_1 = require("@phosphor/algorithm");
const widgets_1 = require("@phosphor/widgets");
const signaling_1 = require("@phosphor/signaling");
const disposable_1 = require("../../common/disposable");
const widgets_2 = require("../widgets");
const core_preferences_1 = require("../core-preferences");
const inversify_1 = require("inversify");
const common_1 = require("../../common");
exports.MAXIMIZED_CLASS = 'theia-maximized';
const VISIBLE_MENU_MAXIMIZED_CLASS = 'theia-visible-menu-maximized';
exports.MAIN_AREA_ID = 'theia-main-content-panel';
exports.BOTTOM_AREA_ID = 'theia-bottom-content-panel';
/**
 * This specialization of DockPanel adds various events that are used for implementing the
 * side panels of the application shell.
 */
let TheiaDockPanel = class TheiaDockPanel extends widgets_1.DockPanel {
    constructor(options, preferences) {
        super(options);
        this.preferences = preferences;
        /**
         * Emitted when a widget is added to the panel.
         */
        this.widgetAdded = new signaling_1.Signal(this);
        /**
         * Emitted when a widget is activated by calling `activateWidget`.
         */
        this.widgetActivated = new signaling_1.Signal(this);
        /**
         * Emitted when a widget is removed from the panel.
         */
        this.widgetRemoved = new signaling_1.Signal(this);
        this.onDidToggleMaximizedEmitter = new common_1.Emitter();
        this.onDidToggleMaximized = this.onDidToggleMaximizedEmitter.event;
        this.toDisposeOnMarkAsCurrent = new disposable_1.DisposableCollection();
        this.toDisposeOnToggleMaximized = new disposable_1.DisposableCollection();
        this['_onCurrentChanged'] = (sender, args) => {
            this.markAsCurrent(args.currentTitle || undefined);
            super['_onCurrentChanged'](sender, args);
        };
        this['_onTabActivateRequested'] = (sender, args) => {
            this.markAsCurrent(args.title);
            super['_onTabActivateRequested'](sender, args);
        };
        if (preferences) {
            preferences.onPreferenceChanged(preference => {
                if (!this.isElectron() && preference.preferenceName === 'window.menuBarVisibility' && (preference.newValue === 'visible' || preference.oldValue === 'visible')) {
                    this.handleMenuBarVisibility(preference.newValue);
                }
            });
        }
    }
    isElectron() {
        return common_1.environment.electron.is();
    }
    handleMenuBarVisibility(newValue) {
        const areaContainer = this.node.parentElement;
        const maximizedElement = this.getMaximizedElement();
        if (areaContainer === maximizedElement) {
            if (newValue === 'visible') {
                this.addClass(VISIBLE_MENU_MAXIMIZED_CLASS);
            }
            else {
                this.removeClass(VISIBLE_MENU_MAXIMIZED_CLASS);
            }
        }
    }
    get currentTitle() {
        return this._currentTitle;
    }
    get currentTabBar() {
        return this._currentTitle && this.findTabBar(this._currentTitle);
    }
    findTabBar(title) {
        return (0, algorithm_1.find)(this.tabBars(), bar => algorithm_1.ArrayExt.firstIndexOf(bar.titles, title) > -1);
    }
    markAsCurrent(title) {
        this.toDisposeOnMarkAsCurrent.dispose();
        this._currentTitle = title;
        if (title) {
            const resetCurrent = () => this.markAsCurrent(undefined);
            title.owner.disposed.connect(resetCurrent);
            this.toDisposeOnMarkAsCurrent.push(disposable_1.Disposable.create(() => title.owner.disposed.disconnect(resetCurrent)));
        }
    }
    addWidget(widget, options) {
        if (this.mode === 'single-document' && widget.parent === this) {
            return;
        }
        super.addWidget(widget, options);
        this.widgetAdded.emit(widget);
    }
    activateWidget(widget) {
        super.activateWidget(widget);
        this.widgetActivated.emit(widget);
    }
    onChildRemoved(msg) {
        super.onChildRemoved(msg);
        this.widgetRemoved.emit(msg.child);
    }
    nextTabBarWidget(widget) {
        const current = this.findTabBar(widget.title);
        const next = current && this.nextTabBarInPanel(current);
        return next && next.currentTitle && next.currentTitle.owner || undefined;
    }
    nextTabBarInPanel(tabBar) {
        const tabBars = (0, algorithm_1.toArray)(this.tabBars());
        const index = tabBars.indexOf(tabBar);
        if (index !== -1) {
            return tabBars[index + 1];
        }
        return undefined;
    }
    previousTabBarWidget(widget) {
        const current = this.findTabBar(widget.title);
        const previous = current && this.previousTabBarInPanel(current);
        return previous && previous.currentTitle && previous.currentTitle.owner || undefined;
    }
    previousTabBarInPanel(tabBar) {
        const tabBars = (0, algorithm_1.toArray)(this.tabBars());
        const index = tabBars.indexOf(tabBar);
        if (index !== -1) {
            return tabBars[index - 1];
        }
        return undefined;
    }
    toggleMaximized() {
        var _a;
        const areaContainer = this.node.parentElement;
        if (!areaContainer) {
            return;
        }
        const maximizedElement = this.getMaximizedElement();
        if (areaContainer === maximizedElement) {
            this.toDisposeOnToggleMaximized.dispose();
            return;
        }
        if (this.isAttached) {
            widgets_2.UnsafeWidgetUtilities.detach(this);
        }
        maximizedElement.style.display = 'block';
        this.addClass(exports.MAXIMIZED_CLASS);
        const preference = (_a = this.preferences) === null || _a === void 0 ? void 0 : _a.get('window.menuBarVisibility');
        if (!this.isElectron() && preference === 'visible') {
            this.addClass(VISIBLE_MENU_MAXIMIZED_CLASS);
        }
        widgets_2.UnsafeWidgetUtilities.attach(this, maximizedElement);
        this.fit();
        this.onDidToggleMaximizedEmitter.fire(this);
        this.toDisposeOnToggleMaximized.push(disposable_1.Disposable.create(() => {
            maximizedElement.style.display = 'none';
            this.removeClass(exports.MAXIMIZED_CLASS);
            this.onDidToggleMaximizedEmitter.fire(this);
            if (!this.isElectron()) {
                this.removeClass(VISIBLE_MENU_MAXIMIZED_CLASS);
            }
            if (this.isAttached) {
                widgets_2.UnsafeWidgetUtilities.detach(this);
            }
            widgets_2.UnsafeWidgetUtilities.attach(this, areaContainer);
            this.fit();
        }));
        const layout = this.layout;
        if (layout instanceof widgets_1.DockLayout) {
            const onResize = layout['onResize'];
            layout['onResize'] = () => onResize.bind(layout)(widgets_1.Widget.ResizeMessage.UnknownSize);
            this.toDisposeOnToggleMaximized.push(disposable_1.Disposable.create(() => layout['onResize'] = onResize));
        }
        const removedListener = () => {
            if (!this.widgets().next()) {
                this.toDisposeOnToggleMaximized.dispose();
            }
        };
        this.widgetRemoved.connect(removedListener);
        this.toDisposeOnToggleMaximized.push(disposable_1.Disposable.create(() => this.widgetRemoved.disconnect(removedListener)));
    }
    getMaximizedElement() {
        if (!this.maximizedElement) {
            this.maximizedElement = document.createElement('div');
            this.maximizedElement.style.display = 'none';
            document.body.appendChild(this.maximizedElement);
        }
        return this.maximizedElement;
    }
};
TheiaDockPanel = __decorate([
    __param(1, (0, inversify_1.inject)(core_preferences_1.CorePreferences)),
    __metadata("design:paramtypes", [Object, Object])
], TheiaDockPanel);
exports.TheiaDockPanel = TheiaDockPanel;
//# sourceMappingURL=theia-dock-panel.js.map