"use strict";
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Toolbar
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToolbarItemsManager = void 0;
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_react_1 = require("@itwin/core-react");
const core_bentley_1 = require("@itwin/core-bentley");
const ToolbarItem_1 = require("./ToolbarItem");
function isInstance(args) {
    return !Array.isArray(args);
}
/**
 * Controls status bar items.
 * @internal
 * @deprecated in 4.4.0. This is no longer used internally, left because of an erroneous public dependency that is also deprecated.
 */
class ToolbarItemsManager {
    constructor(items) {
        // This class should be removed once `useDefaultToolbarItems` and `useUiItemsProviderToolbarItems` (public version) get removed.
        // If you are attempting to fix/clean this class, it is probably an error as it is no longer used and should not be reintroduced, use Hooks instead.
        this._items = [];
        /** Event raised when Toolbar items are changed.
         * @internal
         */
        this.onItemsChanged = new core_bentley_1.BeEvent();
        if (items)
            this.loadItemsInternal(items, true, false);
    }
    loadItemsInternal(items, processConditions, sendItemChanged) {
        if (processConditions && items) {
            // eslint-disable-next-line deprecation/deprecation
            const eventIds = ToolbarItemsManager.getSyncIdsOfInterest(items);
            if (0 !== eventIds.length) {
                const { itemsUpdated, updatedItems } = this.internalRefreshAffectedItems(items, new Set(eventIds));
                // istanbul ignore else
                if (itemsUpdated)
                    items = updatedItems;
            }
        }
        this._items = items;
        if (sendItemChanged)
            this.onItemsChanged.raiseEvent({ items });
    }
    /** load items but do not fire onItemsChanged
     * @internal
     */
    loadItems(items) {
        this.loadItemsInternal(items, true, false);
    }
    /** Get an array of the Toolbar items  */
    get items() {
        return this._items;
    }
    set items(items) {
        // istanbul ignore else
        if (items !== this._items)
            this.loadItemsInternal(items, true, true);
    }
    add(itemOrItems) {
        let itemsToAdd;
        if (isInstance(itemOrItems))
            itemsToAdd = [itemOrItems];
        else {
            itemsToAdd = itemOrItems.filter((itemToAdd, index) => itemOrItems.findIndex((item) => item.id === itemToAdd.id) === index);
        }
        itemsToAdd = itemsToAdd.filter((itemToAdd) => this._items.find((item) => item.id === itemToAdd.id) === undefined);
        if (itemsToAdd.length === 0)
            return;
        const items = [...this._items, ...itemsToAdd];
        this.items = items;
    }
    /** Remove Toolbar items based on id */
    remove(itemIdOrItemIds) {
        const items = this._items.filter((item) => {
            return isInstance(itemIdOrItemIds)
                ? item.id !== itemIdOrItemIds
                : !itemIdOrItemIds.find((itemId) => itemId === item.id);
        });
        this.items = items;
    }
    /** @internal */
    removeAll() {
        this._items = [];
    }
    static gatherSyncIds(eventIds, items) {
        for (const item of items) {
            for (const [, entry] of Object.entries(item)) {
                if (entry instanceof appui_abstract_1.ConditionalBooleanValue) {
                    entry.syncEventIds.forEach((eventId) => eventIds.add(eventId.toLowerCase()));
                }
                else if (entry instanceof appui_abstract_1.ConditionalStringValue) {
                    entry.syncEventIds.forEach((eventId) => eventIds.add(eventId.toLowerCase()));
                } /* istanbul ignore else */
                else if (core_react_1.ConditionalIconItem.isConditionalIconItem(entry)) {
                    entry.syncEventIds.forEach((eventId) => eventIds.add(eventId.toLowerCase()));
                }
            }
            // istanbul ignore else
            if ((0, ToolbarItem_1.isToolbarGroupItem)(item)) {
                this.gatherSyncIds(eventIds, item.items);
            }
        }
    }
    static getSyncIdsOfInterest(items) {
        const eventIds = new Set();
        this.gatherSyncIds(eventIds, items);
        return [...eventIds.values()];
    }
    static refreshChildItems(parentItem, eventIds) {
        const updatedItems = [];
        let itemsUpdated = false;
        for (const item of parentItem.items) {
            let updatedItem;
            if ((0, ToolbarItem_1.isToolbarGroupItem)(item)) {
                updatedItem = { ...item };
                const { childrenUpdated, childItems } = this.refreshChildItems(updatedItem, eventIds);
                // istanbul ignore else
                if (childrenUpdated) {
                    updatedItem.items = childItems;
                    itemsUpdated = true;
                }
            }
            else {
                updatedItem = { ...item };
            }
            for (const [, entry] of Object.entries(updatedItem)) {
                if (entry instanceof appui_abstract_1.ConditionalBooleanValue) {
                    // istanbul ignore else
                    if (appui_abstract_1.ConditionalBooleanValue.refreshValue(entry, eventIds))
                        itemsUpdated = true;
                } /* istanbul ignore else */
                else if (entry instanceof appui_abstract_1.ConditionalStringValue) {
                    // istanbul ignore else
                    if (appui_abstract_1.ConditionalStringValue.refreshValue(entry, eventIds))
                        itemsUpdated = true;
                } /* istanbul ignore else */
                else if (core_react_1.ConditionalIconItem.isConditionalIconItem(entry)) {
                    // istanbul ignore else
                    if (core_react_1.ConditionalIconItem.refreshValue(entry, eventIds))
                        itemsUpdated = true;
                }
            }
            updatedItems.push(updatedItem);
        }
        return { childrenUpdated: itemsUpdated, childItems: updatedItems };
    }
    internalRefreshAffectedItems(items, eventIds) {
        // istanbul ignore next
        if (0 === eventIds.size)
            return { itemsUpdated: false, updatedItems: [] };
        let updateRequired = false;
        const newItems = [];
        for (const item of items) {
            let updatedItem = { ...item };
            if ((0, ToolbarItem_1.isToolbarGroupItem)(updatedItem)) {
                const { childrenUpdated, childItems } = 
                // eslint-disable-next-line deprecation/deprecation
                ToolbarItemsManager.refreshChildItems(updatedItem, eventIds);
                // istanbul ignore else
                if (childrenUpdated) {
                    updatedItem = {
                        ...updatedItem,
                        items: childItems,
                    };
                    updateRequired = true;
                }
            }
            for (const [, entry] of Object.entries(updatedItem)) {
                if (entry instanceof appui_abstract_1.ConditionalBooleanValue) {
                    // istanbul ignore else
                    if (appui_abstract_1.ConditionalBooleanValue.refreshValue(entry, eventIds))
                        updateRequired = true;
                }
                else if (entry instanceof appui_abstract_1.ConditionalStringValue) {
                    // istanbul ignore else
                    if (appui_abstract_1.ConditionalStringValue.refreshValue(entry, eventIds))
                        updateRequired = true;
                } /* istanbul ignore else */
                else if (core_react_1.ConditionalIconItem.isConditionalIconItem(entry)) {
                    // istanbul ignore else
                    if (core_react_1.ConditionalIconItem.refreshValue(entry, eventIds))
                        updateRequired = true;
                }
            }
            newItems.push(updatedItem);
        }
        return { itemsUpdated: updateRequired, updatedItems: newItems };
    }
    refreshAffectedItems(eventIds) {
        // istanbul ignore next
        if (0 === eventIds.size)
            return;
        const { itemsUpdated, updatedItems } = this.internalRefreshAffectedItems(this.items, eventIds);
        // istanbul ignore else
        if (itemsUpdated)
            this.loadItemsInternal(updatedItems, false, true);
    }
    static isActiveToolIdRefreshRequiredForChildren(children, toolId) {
        for (const item of children) {
            if ((0, ToolbarItem_1.isToolbarGroupItem)(item)) {
                if (this.isActiveToolIdRefreshRequiredForChildren(item.items, toolId))
                    return true;
            }
            else {
                const isActive = !!item.isActive;
                if ((isActive && item.id !== toolId) ||
                    (!isActive && item.id === toolId))
                    return true;
            }
        }
        return false;
    }
    isActiveToolIdRefreshRequired(toolId) {
        for (const item of this.items) {
            if ((0, ToolbarItem_1.isToolbarGroupItem)(item)) {
                if (
                // eslint-disable-next-line deprecation/deprecation
                ToolbarItemsManager.isActiveToolIdRefreshRequiredForChildren(item.items, toolId))
                    return true;
            }
            else {
                const isActive = !!item.isActive;
                if ((isActive && item.id !== toolId) ||
                    (!isActive && item.id === toolId))
                    return true;
            }
        }
        return false;
    }
    static refreshActiveToolIdInChildItems(parentItem, toolId) {
        const newChildren = [];
        for (const item of parentItem.items) {
            let updatedItem = { ...item };
            if ((0, ToolbarItem_1.isToolbarGroupItem)(updatedItem)) {
                updatedItem = {
                    ...updatedItem,
                    // eslint-disable-next-line deprecation/deprecation
                    items: ToolbarItemsManager.refreshActiveToolIdInChildItems(updatedItem, toolId),
                };
            }
            updatedItem.isActive = updatedItem.id === toolId;
            newChildren.push(updatedItem);
        }
        return newChildren;
    }
    setActiveToolId(toolId) {
        // first see if any updates are really necessary
        if (!this.isActiveToolIdRefreshRequired(toolId))
            return;
        const newItems = [];
        for (const item of this.items) {
            let updatedItem = { ...item };
            if ((0, ToolbarItem_1.isToolbarGroupItem)(updatedItem)) {
                updatedItem = {
                    ...updatedItem,
                    // eslint-disable-next-line deprecation/deprecation
                    items: ToolbarItemsManager.refreshActiveToolIdInChildItems(updatedItem, toolId),
                };
            }
            updatedItem.isActive = updatedItem.id === toolId;
            newItems.push(updatedItem);
        }
        this.items = newItems;
    }
}
exports.ToolbarItemsManager = ToolbarItemsManager;
//# sourceMappingURL=ToolbarItemsManager.js.map