/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Tiles
 */
import { BaseMapLayerSettings } from "@itwin/core-common";
import { DisclosedTileTreeSet, MapTileTreeReference } from "../internal";
import { IModelApp } from "../../IModelApp";
/** @internal */
export class MapTiledGraphicsProvider {
    forEachTileTreeRef(viewport, func) {
        if (viewport.viewFlags.backgroundMap) {
            func(this.backgroundMap);
            func(this.overlayMap);
        }
    }
    constructor(viewportId, displayStyle) {
        this._detachFromDisplayStyle = [];
        const mapSettings = displayStyle.backgroundMapSettings;
        const mapImagery = displayStyle.settings.mapImagery;
        this.backgroundMap = new MapTileTreeReference(mapSettings, mapImagery.backgroundBase, mapImagery.backgroundLayers, displayStyle.iModel, viewportId, false, false, () => displayStyle.overrideTerrainDisplay());
        this.overlayMap = new MapTileTreeReference(mapSettings, undefined, mapImagery.overlayLayers, displayStyle.iModel, viewportId, true, false);
        this.backgroundDrapeMap = new MapTileTreeReference(mapSettings, mapImagery.backgroundBase, mapImagery.backgroundLayers, displayStyle.iModel, viewportId, false, true);
        const removals = this._detachFromDisplayStyle;
        removals.push(displayStyle.settings.onBackgroundMapChanged.addListener((settings) => {
            this.backgroundMap.settings = settings;
            this.overlayMap.settings = settings;
            this.backgroundDrapeMap.settings = settings;
        }));
        removals.push(displayStyle.settings.onMapImageryChanged.addListener((imagery) => {
            this.backgroundMap.setBaseLayerSettings(imagery.backgroundBase);
            this.backgroundMap.setLayerSettings(imagery.backgroundLayers);
            this.backgroundDrapeMap.setBaseLayerSettings(mapImagery.backgroundBase);
            this.backgroundDrapeMap.setLayerSettings(mapImagery.backgroundLayers);
            this.overlayMap.setLayerSettings(imagery.overlayLayers);
        }));
        // We need to clear imagery tiles assigned to map tiles every time a new ImageryTileTree is loaded,
        // otherwise the imagery tiles won't refresh correctly.
        const clearMapLayers = (loadedTileTree, mapTileTreeToClear) => {
            const trees = new DisclosedTileTreeSet();
            mapTileTreeToClear.discloseTileTrees(trees);
            if (trees.has(loadedTileTree)) {
                mapTileTreeToClear.clearLayers();
            }
        };
        removals.push(IModelApp.tileAdmin.onTileTreeLoad.addListener((tileTree) => {
            if (tileTree.tileTree !== undefined) {
                clearMapLayers(tileTree.tileTree, this.backgroundMap);
                clearMapLayers(tileTree.tileTree, this.overlayMap);
            }
        }));
    }
    // This is used in inital view setup and when views are synchronized.  If view is being synchronized
    // we need to clear the layers which purges tile graphics if the settings or layers are changed.
    setView(newView) {
        const layersMatch = ((layers1, layers2) => {
            if (layers1.length !== layers2.length)
                return false;
            for (let i = 0; i < layers1.length; i++)
                if (!layers1[i].displayMatches(layers2[i]))
                    return false;
            return true;
        });
        const mapImagery = newView.displayStyle.settings.mapImagery;
        if (!newView.displayStyle.backgroundMapSettings.equals(this.backgroundMap.settings)
            || !layersMatch(mapImagery.backgroundLayers, this.backgroundMap.layerSettings)
            || (mapImagery.backgroundBase instanceof BaseMapLayerSettings && !layersMatch([mapImagery.backgroundBase], this.backgroundDrapeMap.layerSettings))) {
            this.backgroundMap.clearLayers();
            this.backgroundDrapeMap.clearLayers();
        }
        if (!layersMatch(mapImagery.overlayLayers, this.overlayMap.layerSettings))
            this.overlayMap.clearLayers();
    }
    detachFromDisplayStyle() {
        this._detachFromDisplayStyle.forEach((f) => f());
        this._detachFromDisplayStyle.length = 0;
    }
    /** @internal */
    getMapLayerImageryProvider(mapLayerIndex) {
        const imageryTreeRef = mapLayerIndex.isOverlay ? this.overlayMap.getLayerImageryTreeRef(mapLayerIndex.index) : this.backgroundMap.getLayerImageryTreeRef(mapLayerIndex.index);
        return imageryTreeRef?.imageryProvider;
    }
    resetMapLayer(mapLayerIndex) {
        const imageryTreeRef = mapLayerIndex.isOverlay ? this.overlayMap.getLayerImageryTreeRef(mapLayerIndex.index) : this.backgroundMap.getLayerImageryTreeRef(mapLayerIndex.index);
        imageryTreeRef?.resetTreeOwner();
    }
    /** Return a list of map-layers indexes matching a given MapTile tree Id and a layer imagery tree id.
     * @internal
     */
    getMapLayerIndexesFromIds(mapTreeId, layerTreeId) {
        const layers = new Array();
        if (mapTreeId === this.backgroundMap.treeOwner.tileTree?.id) {
            for (let i = 0; i < this.backgroundMap.layerSettings.length; i++) {
                if (this.backgroundMap.getLayerImageryTreeRef(i)?.treeOwner.tileTree?.id === layerTreeId) {
                    layers.push({ index: i, isOverlay: false });
                }
            }
        }
        else if (mapTreeId === this.overlayMap.treeOwner.tileTree?.id) {
            for (let i = 0; i < this.overlayMap.layerSettings.length; i++) {
                if (this.overlayMap.getLayerImageryTreeRef(i)?.treeOwner.tileTree?.id === layerTreeId) {
                    layers.push({ index: i, isOverlay: true });
                }
            }
        }
        return layers;
    }
    /** @internal */
    mapLayerFromIds(mapTreeId, layerTreeId) {
        const bgMapLayers = this.backgroundMap.layerFromTreeModelIds(mapTreeId, layerTreeId);
        const ovlMapLayers = this.overlayMap.layerFromTreeModelIds(mapTreeId, layerTreeId);
        return [...bgMapLayers, ...ovlMapLayers];
    }
}
//# sourceMappingURL=MapTiledGraphicsProvider.js.map