
import { registerCss } from '../../../../../../css.js';
import { __decorate, __param } from '../../../../../../external/tslib/tslib.es6.js';
import * as paneCompositePart from './media/paneCompositePart.css';
import { Event } from '../../../base/common/event.js';
import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
import { IViewDescriptorService } from '../../common/views.service.js';
import { DisposableStore, MutableDisposable } from '../../../base/common/lifecycle.js';
import { Parts } from '../../services/layout/browser/layoutService.js';
import { IWorkbenchLayoutService } from '../../services/layout/browser/layoutService.service.js';
import { CompositePart } from './compositePart.js';
import { PaneCompositeBar } from './paneCompositeBar.js';
import { trackFocus, $, EventHelper, addDisposableListener, EventType, getWindow, prepend, Dimension } from '../../../base/browser/dom.js';
import { Registry } from '../../../platform/registry/common/platform.js';
import { INotificationService } from '../../../platform/notification/common/notification.service.js';
import { IStorageService } from '../../../platform/storage/common/storage.service.js';
import { IContextMenuService } from '../../../platform/contextview/browser/contextView.service.js';
import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.service.js';
import { IThemeService } from '../../../platform/theme/common/themeService.service.js';
import { IContextKeyService } from '../../../platform/contextkey/common/contextkey.service.js';
import { IExtensionService } from '../../services/extensions/common/extensions.service.js';
import { localize } from '../../../nls.js';
import { CompositeDragAndDropObserver, toggleDropEffect } from '../dnd.js';
import { EDITOR_DRAG_AND_DROP_BACKGROUND } from '../../common/theme.js';
import { IMenuService } from '../../../platform/actions/common/actions.service.js';
import { ActionsOrientation } from '../../../base/browser/ui/actionbar/actionbar.js';
import { Gesture, EventType as EventType$1 } from '../../../base/browser/touch.js';
import { StandardMouseEvent } from '../../../base/browser/mouseEvent.js';
import { SubmenuAction } from '../../../base/common/actions.js';
import { ViewsSubMenu } from './views/viewPaneContainer.js';
import { getActionBarActions } from '../../../platform/actions/browser/menuEntryActionViewItem.js';
import { IHoverService } from '../../../platform/hover/browser/hover.service.js';
import { MenuWorkbenchToolBar, HiddenItemStrategy } from '../../../platform/actions/browser/toolbar.js';
import { DeferredPromise } from '../../../base/common/async.js';

var AbstractPaneCompositePart_1;
registerCss(paneCompositePart);
var CompositeBarPosition;
(function(CompositeBarPosition) {
    CompositeBarPosition[CompositeBarPosition["TOP"] = 0] = "TOP";
    CompositeBarPosition[CompositeBarPosition["TITLE"] = 1] = "TITLE";
    CompositeBarPosition[CompositeBarPosition["BOTTOM"] = 2] = "BOTTOM";
})(CompositeBarPosition || (CompositeBarPosition = {}));
let AbstractPaneCompositePart = class AbstractPaneCompositePart extends CompositePart {
    static {
        AbstractPaneCompositePart_1 = this;
    }
    static {
        this.MIN_COMPOSITE_BAR_WIDTH = 50;
    }
    get snap() {
        return this.layoutService.isVisible(this.partId) || !!this.paneCompositeBar.value?.getVisiblePaneCompositeIds().length;
    }
    get onDidPaneCompositeOpen() {
        return ( Event.map(this.onDidCompositeOpen.event, compositeEvent => compositeEvent.composite));
    }
    constructor(
        partId,
        partOptions,
        activePaneCompositeSettingsKey,
        activePaneContextKey,
        paneFocusContextKey,
        nameForTelemetry,
        compositeCSSClass,
        titleForegroundColor,
        titleBorderColor,
        location,
        registryId,
        globalActionsMenuId,
        globalLeftActionsMenuId,
        notificationService,
        storageService,
        contextMenuService,
        layoutService,
        keybindingService,
        hoverService,
        instantiationService,
        themeService,
        viewDescriptorService,
        contextKeyService,
        extensionService,
        menuService
    ) {
        super(
            notificationService,
            storageService,
            contextMenuService,
            layoutService,
            keybindingService,
            hoverService,
            instantiationService,
            themeService,
            ( Registry.as(registryId)),
            activePaneCompositeSettingsKey,
            viewDescriptorService.getDefaultViewContainer(location)?.id || "",
            nameForTelemetry,
            compositeCSSClass,
            titleForegroundColor,
            titleBorderColor,
            partId,
            partOptions
        );
        this.partId = partId;
        this.activePaneContextKey = activePaneContextKey;
        this.paneFocusContextKey = paneFocusContextKey;
        this.location = location;
        this.registryId = registryId;
        this.globalActionsMenuId = globalActionsMenuId;
        this.globalLeftActionsMenuId = globalLeftActionsMenuId;
        this.viewDescriptorService = viewDescriptorService;
        this.contextKeyService = contextKeyService;
        this.extensionService = extensionService;
        this.menuService = menuService;
        this.onDidPaneCompositeClose = this.onDidCompositeClose.event;
        this.headerFooterCompositeBarDispoables = this._register(( new DisposableStore()));
        this.paneCompositeBar = this._register(( new MutableDisposable()));
        this.compositeBarPosition = undefined;
        this.blockOpening = undefined;
        this.registerListeners();
    }
    registerListeners() {
        this._register(this.onDidPaneCompositeOpen(composite => this.onDidOpen(composite)));
        this._register(this.onDidPaneCompositeClose(this.onDidClose, this));
        this._register(this.registry.onDidDeregister(viewletDescriptor => {
            const activeContainers = this.viewDescriptorService.getViewContainersByLocation(this.location).filter(
                container => this.viewDescriptorService.getViewContainerModel(container).activeViewDescriptors.length > 0
            );
            if (activeContainers.length) {
                if (this.getActiveComposite()?.getId() === viewletDescriptor.id) {
                    const defaultViewletId = this.viewDescriptorService.getDefaultViewContainer(this.location)?.id;
                    const containerToOpen = activeContainers.filter(c => c.id === defaultViewletId)[0] || activeContainers[0];
                    this.doOpenPaneComposite(containerToOpen.id);
                }
            } else {
                this.layoutService.setPartHidden(true, this.partId);
            }
            this.removeComposite(viewletDescriptor.id);
        }));
        this._register(this.extensionService.onDidRegisterExtensions(() => {
            this.layoutCompositeBar();
        }));
    }
    onDidOpen(composite) {
        this.activePaneContextKey.set(composite.getId());
    }
    onDidClose(composite) {
        const id = composite.getId();
        if (this.activePaneContextKey.get() === id) {
            this.activePaneContextKey.reset();
        }
    }
    showComposite(composite) {
        this.layoutEmptyMessage(false);
        super.showComposite(composite);
        this.layoutCompositeBar();
    }
    hideActiveComposite() {
        const composite = super.hideActiveComposite();
        this.layoutCompositeBar();
        this.layoutEmptyMessage(true);
        return composite;
    }
    create(parent) {
        this.element = parent;
        this.element.classList.add("pane-composite-part");
        super.create(parent);
        if (this.contentArea) {
            this.createEmptyPaneMessage(this.contentArea);
        }
        this.updateCompositeBar();
        const focusTracker = this._register(trackFocus(parent));
        this._register(focusTracker.onDidFocus(() => this.paneFocusContextKey.set(true)));
        this._register(focusTracker.onDidBlur(() => this.paneFocusContextKey.set(false)));
    }
    createEmptyPaneMessage(parent) {
        this.emptyPaneMessageElement = $(".empty-pane-message-area");
        const messageElement = $(".empty-pane-message");
        messageElement.textContent = ( localize(3673, "Drag a view here to display."));
        this.emptyPaneMessageElement.appendChild(messageElement);
        parent.appendChild(this.emptyPaneMessageElement);
        const setDropBackgroundFeedback = visible => {
            const updateActivityBarBackground = !this.getActiveComposite() || !visible;
            const backgroundColor = visible ? this.theme.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND)?.toString() || "" : "";
            if (this.titleContainer && updateActivityBarBackground) {
                this.titleContainer.style.backgroundColor = backgroundColor;
            }
            if (this.headerFooterCompositeBarContainer && updateActivityBarBackground) {
                this.headerFooterCompositeBarContainer.style.backgroundColor = backgroundColor;
            }
            this.emptyPaneMessageElement.style.backgroundColor = backgroundColor;
        };
        if (this.viewDescriptorService.canMoveViews()) {
            this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(this.element, {
                onDragOver: e => {
                    EventHelper.stop(e.eventData, true);
                    if (this.paneCompositeBar.value) {
                        const validDropTarget = this.paneCompositeBar.value.dndHandler.onDragEnter(e.dragAndDropData, undefined, e.eventData);
                        toggleDropEffect(e.eventData.dataTransfer, "move", validDropTarget);
                    }
                },
                onDragEnter: e => {
                    EventHelper.stop(e.eventData, true);
                    if (this.paneCompositeBar.value) {
                        const validDropTarget = this.paneCompositeBar.value.dndHandler.onDragEnter(e.dragAndDropData, undefined, e.eventData);
                        setDropBackgroundFeedback(validDropTarget);
                    }
                },
                onDragLeave: e => {
                    EventHelper.stop(e.eventData, true);
                    setDropBackgroundFeedback(false);
                },
                onDragEnd: e => {
                    EventHelper.stop(e.eventData, true);
                    setDropBackgroundFeedback(false);
                },
                onDrop: e => {
                    EventHelper.stop(e.eventData, true);
                    setDropBackgroundFeedback(false);
                    if (this.paneCompositeBar.value) {
                        this.paneCompositeBar.value.dndHandler.drop(e.dragAndDropData, undefined, e.eventData);
                    } else {
                        const dragData = e.dragAndDropData.getData();
                        if (dragData.type === "composite") {
                            const currentContainer = this.viewDescriptorService.getViewContainerById(dragData.id);
                            this.viewDescriptorService.moveViewContainerToLocation(currentContainer, this.location, undefined, "dnd");
                            this.openPaneComposite(currentContainer.id, true);
                        } else if (dragData.type === "view") {
                            const viewToMove = this.viewDescriptorService.getViewDescriptorById(dragData.id);
                            if (viewToMove.canMoveView) {
                                this.viewDescriptorService.moveViewToLocation(viewToMove, this.location, "dnd");
                                const newContainer = this.viewDescriptorService.getViewContainerByViewId(viewToMove.id);
                                this.openPaneComposite(newContainer.id, true).then(composite => {
                                    composite?.openView(viewToMove.id, true);
                                });
                            }
                        }
                    }
                }
            }));
        }
    }
    createTitleArea(parent) {
        const titleArea = super.createTitleArea(parent);
        if (!titleArea) {
            return undefined;
        }
        this._register(addDisposableListener(titleArea, EventType.CONTEXT_MENU, e => {
            this.onTitleAreaContextMenu(( new StandardMouseEvent(getWindow(titleArea), e)));
        }));
        this._register(Gesture.addTarget(titleArea));
        this._register(addDisposableListener(titleArea, EventType$1.Contextmenu, e => {
            this.onTitleAreaContextMenu(( new StandardMouseEvent(getWindow(titleArea), e)));
        }));
        if (this.globalLeftActionsMenuId) {
            const globalLeftTitleActionsContainer = titleArea.appendChild($(".global-actions-left"));
            this.globalLeftToolBar = this._register(this.instantiationService.createInstance(
                MenuWorkbenchToolBar,
                globalLeftTitleActionsContainer,
                this.globalLeftActionsMenuId,
                {
                    actionViewItemProvider: (action, options) => this.actionViewItemProvider(action, options),
                    orientation: ActionsOrientation.HORIZONTAL,
                    getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
                    anchorAlignmentProvider: () => this.getTitleAreaDropDownAnchorAlignment(),
                    hoverDelegate: this.toolbarHoverDelegate,
                    hiddenItemStrategy: HiddenItemStrategy.NoHide,
                    highlightToggledItems: false,
                    telemetrySource: this.nameForTelemetry
                }
            ));
        }
        const globalTitleActionsContainer = titleArea.appendChild($(".global-actions"));
        this.globalToolBar = this._register(this.instantiationService.createInstance(
            MenuWorkbenchToolBar,
            globalTitleActionsContainer,
            this.globalActionsMenuId,
            {
                actionViewItemProvider: (action, options) => this.actionViewItemProvider(action, options),
                orientation: ActionsOrientation.HORIZONTAL,
                getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
                anchorAlignmentProvider: () => this.getTitleAreaDropDownAnchorAlignment(),
                toggleMenuTitle: ( localize(3674, "More Actions...")),
                hoverDelegate: this.toolbarHoverDelegate,
                hiddenItemStrategy: HiddenItemStrategy.NoHide,
                highlightToggledItems: true,
                telemetrySource: this.nameForTelemetry
            }
        ));
        return titleArea;
    }
    createTitleLabel(parent) {
        this.titleContainer = parent;
        const titleLabel = super.createTitleLabel(parent);
        this.titleLabelElement.draggable = this.viewDescriptorService.canMoveViews();
        const draggedItemProvider = () => {
            const activeViewlet = this.getActivePaneComposite();
            return {
                type: "composite",
                id: activeViewlet.getId()
            };
        };
        this._register(
            CompositeDragAndDropObserver.INSTANCE.registerDraggable(this.titleLabelElement, draggedItemProvider, {})
        );
        return titleLabel;
    }
    updateCompositeBar(updateCompositeBarOption = false) {
        const wasCompositeBarVisible = this.compositeBarPosition !== undefined;
        const isCompositeBarVisible = this.shouldShowCompositeBar();
        const previousPosition = this.compositeBarPosition;
        const newPosition = isCompositeBarVisible ? this.getCompositeBarPosition() : undefined;
        if (!updateCompositeBarOption && previousPosition === newPosition) {
            return;
        }
        if (wasCompositeBarVisible) {
            const previousCompositeBarContainer = previousPosition === CompositeBarPosition.TITLE ? this.titleContainer : this.headerFooterCompositeBarContainer;
            if (!this.paneCompositeBarContainer || !this.paneCompositeBar.value || !previousCompositeBarContainer) {
                throw ( new Error(
                    "Composite bar containers should exist when removing the previous composite bar"
                ));
            }
            this.paneCompositeBarContainer.remove();
            this.paneCompositeBarContainer = undefined;
            this.paneCompositeBar.value = undefined;
            previousCompositeBarContainer.classList.remove("has-composite-bar");
            if (previousPosition === CompositeBarPosition.TOP) {
                this.removeFooterHeaderArea(true);
            } else if (previousPosition === CompositeBarPosition.BOTTOM) {
                this.removeFooterHeaderArea(false);
            }
        }
        let newCompositeBarContainer;
        switch (newPosition) {
        case CompositeBarPosition.TOP:
            newCompositeBarContainer = this.createHeaderArea();
            break;
        case CompositeBarPosition.TITLE:
            newCompositeBarContainer = this.titleContainer;
            break;
        case CompositeBarPosition.BOTTOM:
            newCompositeBarContainer = this.createFooterArea();
            break;
        }
        if (isCompositeBarVisible) {
            if (this.paneCompositeBarContainer || this.paneCompositeBar.value || !newCompositeBarContainer) {
                throw ( new Error("Invalid composite bar state when creating the new composite bar"));
            }
            newCompositeBarContainer.classList.add("has-composite-bar");
            this.paneCompositeBarContainer = prepend(newCompositeBarContainer, $(".composite-bar-container"));
            this.paneCompositeBar.value = this.createCompositeBar();
            this.paneCompositeBar.value.create(this.paneCompositeBarContainer);
            if (newPosition === CompositeBarPosition.TOP) {
                this.setHeaderArea(newCompositeBarContainer);
            } else if (newPosition === CompositeBarPosition.BOTTOM) {
                this.setFooterArea(newCompositeBarContainer);
            }
        }
        this.compositeBarPosition = newPosition;
        if (updateCompositeBarOption) {
            this.layoutCompositeBar();
        }
    }
    createHeaderArea() {
        const headerArea = super.createHeaderArea();
        return this.createHeaderFooterCompositeBarArea(headerArea);
    }
    createFooterArea() {
        const footerArea = super.createFooterArea();
        return this.createHeaderFooterCompositeBarArea(footerArea);
    }
    createHeaderFooterCompositeBarArea(area) {
        if (this.headerFooterCompositeBarContainer) {
            throw ( new Error("Header or Footer composite bar already exists"));
        }
        this.headerFooterCompositeBarContainer = area;
        this.headerFooterCompositeBarDispoables.add(addDisposableListener(area, EventType.CONTEXT_MENU, e => {
            this.onCompositeBarAreaContextMenu(( new StandardMouseEvent(getWindow(area), e)));
        }));
        this.headerFooterCompositeBarDispoables.add(Gesture.addTarget(area));
        this.headerFooterCompositeBarDispoables.add(addDisposableListener(area, EventType$1.Contextmenu, e => {
            this.onCompositeBarAreaContextMenu(( new StandardMouseEvent(getWindow(area), e)));
        }));
        return area;
    }
    removeFooterHeaderArea(header) {
        this.headerFooterCompositeBarContainer = undefined;
        this.headerFooterCompositeBarDispoables.clear();
        if (header) {
            this.removeHeaderArea();
        } else {
            this.removeFooterArea();
        }
    }
    createCompositeBar() {
        return this.instantiationService.createInstance(
            PaneCompositeBar,
            this.location,
            this.getCompositeBarOptions(),
            this.partId,
            this
        );
    }
    onTitleAreaUpdate(compositeId) {
        super.onTitleAreaUpdate(compositeId);
        this.layoutCompositeBar();
    }
    async openPaneComposite(id, focus) {
        if (typeof id === "string" && this.getPaneComposite(id)) {
            return this.doOpenPaneComposite(id, focus);
        }
        await this.extensionService.whenInstalledExtensionsRegistered();
        if (typeof id === "string" && this.getPaneComposite(id)) {
            return this.doOpenPaneComposite(id, focus);
        }
        return undefined;
    }
    async doOpenPaneComposite(id, focus) {
        if (this.blockOpening) {
            return this.blockOpening.p;
        }
        let blockOpening;
        if (!this.layoutService.isVisible(this.partId)) {
            try {
                blockOpening = this.blockOpening = ( new DeferredPromise());
                this.layoutService.setPartHidden(false, this.partId);
            } finally {
                this.blockOpening = undefined;
            }
        }
        try {
            const result = this.openComposite(id, focus);
            blockOpening?.complete(result);
            return result;
        } catch (error) {
            blockOpening?.error(error);
            throw error;
        }
    }
    getPaneComposite(id) {
        return this.registry.getPaneComposite(id);
    }
    getPaneComposites() {
        return this.registry.getPaneComposites().sort((v1, v2) => {
            if (typeof v1.order !== "number") {
                return 1;
            }
            if (typeof v2.order !== "number") {
                return -1;
            }
            return v1.order - v2.order;
        });
    }
    getPinnedPaneCompositeIds() {
        return this.paneCompositeBar.value?.getPinnedPaneCompositeIds() ?? [];
    }
    getVisiblePaneCompositeIds() {
        return this.paneCompositeBar.value?.getVisiblePaneCompositeIds() ?? [];
    }
    getPaneCompositeIds() {
        return this.paneCompositeBar.value?.getPaneCompositeIds() ?? [];
    }
    getActivePaneComposite() {
        return this.getActiveComposite();
    }
    getLastActivePaneCompositeId() {
        return this.getLastActiveCompositeId();
    }
    hideActivePaneComposite() {
        if (this.layoutService.isVisible(this.partId)) {
            this.layoutService.setPartHidden(true, this.partId);
        }
        this.hideActiveComposite();
    }
    focusCompositeBar() {
        this.paneCompositeBar.value?.focus();
    }
    layout(width, height, top, left) {
        if (!this.layoutService.isVisible(this.partId)) {
            return;
        }
        this.contentDimension = ( new Dimension(width, height));
        super.layout(this.contentDimension.width, this.contentDimension.height, top, left);
        this.layoutCompositeBar();
        this.layoutEmptyMessage();
    }
    layoutCompositeBar() {
        if (this.contentDimension && this.dimension && this.paneCompositeBar.value) {
            const padding = this.compositeBarPosition === CompositeBarPosition.TITLE ? 16 : 8;
            const borderWidth = this.partId === Parts.PANEL_PART ? 0 : 1;
            let availableWidth = this.contentDimension.width - padding - borderWidth;
            availableWidth = Math.max(
                AbstractPaneCompositePart_1.MIN_COMPOSITE_BAR_WIDTH,
                availableWidth - this.getToolbarWidth()
            );
            this.paneCompositeBar.value.layout(availableWidth, this.dimension.height);
        }
    }
    layoutEmptyMessage(visible = !this.getActiveComposite()) {
        this.element.classList.toggle("empty", visible);
        if (visible) {
            this.titleLabel?.updateTitle("", "");
        }
    }
    getToolbarWidth() {
        if (!this.toolBar || this.compositeBarPosition !== CompositeBarPosition.TITLE) {
            return 0;
        }
        const activePane = this.getActivePaneComposite();
        if (!activePane) {
            return 0;
        }
        const toolBarWidth = this.toolBar.getItemsWidth() + this.toolBar.getItemsLength() * 4;
        const globalToolBarWidth = this.globalToolBar ? this.globalToolBar.getItemsWidth() + this.globalToolBar.getItemsLength() * 4 : 0;
        const globalLeftToolBarWidth = this.globalLeftToolBar ? this.globalLeftToolBar.getItemsWidth() + this.globalLeftToolBar.getItemsLength() * 4 : 0;
        return toolBarWidth + globalToolBarWidth + globalLeftToolBarWidth + 8;
    }
    onTitleAreaContextMenu(event) {
        if (this.shouldShowCompositeBar() && this.getCompositeBarPosition() === CompositeBarPosition.TITLE) {
            return this.onCompositeBarContextMenu(event);
        } else {
            const activePaneComposite = this.getActivePaneComposite();
            const activePaneCompositeActions = activePaneComposite ? activePaneComposite.getContextMenuActions() : [];
            if (activePaneCompositeActions.length) {
                this.contextMenuService.showContextMenu({
                    getAnchor: () => event,
                    getActions: () => activePaneCompositeActions,
                    getActionViewItem: (action, options) => this.actionViewItemProvider(action, options),
                    actionRunner: activePaneComposite.getActionRunner(),
                    skipTelemetry: true
                });
            }
        }
    }
    onCompositeBarAreaContextMenu(event) {
        return this.onCompositeBarContextMenu(event);
    }
    onCompositeBarContextMenu(event) {
        if (this.paneCompositeBar.value) {
            const actions = [...this.paneCompositeBar.value.getContextMenuActions()];
            if (actions.length) {
                this.contextMenuService.showContextMenu({
                    getAnchor: () => event,
                    getActions: () => actions,
                    skipTelemetry: true
                });
            }
        }
    }
    getViewsSubmenuAction() {
        const viewPaneContainer = this.getActivePaneComposite()?.getViewPaneContainer();
        if (viewPaneContainer) {
            const disposables = ( new DisposableStore());
            const scopedContextKeyService = disposables.add(this.contextKeyService.createScoped(this.element));
            scopedContextKeyService.createKey("viewContainer", viewPaneContainer.viewContainer.id);
            const menu = this.menuService.getMenuActions(ViewsSubMenu, scopedContextKeyService, {
                shouldForwardArgs: true,
                renderShortTitle: true
            });
            const viewsActions = getActionBarActions(menu, () => true).primary;
            disposables.dispose();
            return viewsActions.length > 1 && ( viewsActions.some(a => a.enabled)) ? ( new SubmenuAction("views", ( localize(3675, "Views")), viewsActions)) : undefined;
        }
        return undefined;
    }
};
AbstractPaneCompositePart = AbstractPaneCompositePart_1 = ( __decorate([( __param(13, INotificationService)), ( __param(14, IStorageService)), ( __param(15, IContextMenuService)), ( __param(16, IWorkbenchLayoutService)), ( __param(17, IKeybindingService)), ( __param(18, IHoverService)), ( __param(19, IInstantiationService)), ( __param(20, IThemeService)), ( __param(21, IViewDescriptorService)), ( __param(22, IContextKeyService)), ( __param(23, IExtensionService)), ( __param(24, IMenuService))], AbstractPaneCompositePart));

export { AbstractPaneCompositePart, CompositeBarPosition };
