import * as Core from "@intelligentgraphics/ig.gfx.core";
import { AsyncHook } from "@intelligentgraphics/ig.utilities";
import { GfxType, Article, Session } from "@intelligentgraphics/igd.productdata";
import { SceneSnapshot } from "./Snapshot";
import { PlaceArticleCallback } from "./ArticleInserter";
export declare type PlannerManagerUpdateScheduler = (cb: () => Promise<void>) => Promise<void>;
export declare type PlannerManagerGeneratePreUpdateSnapshot = (articles: string[]) => SceneSnapshot;
export interface IPlannerManagerOptions {
    parallelUpdates?: boolean;
    gfxType?: GfxType;
    loadMode?: Core.ELoadGeometryPreviews;
    executeArticlePlacement?: PlaceArticleCallback;
    /**
     * Can be used to restrict scene updates to only occur at certain points
     *
     * @type {PlannerManagerUpdateScheduler}
     */
    scheduleSceneUpdate?: PlannerManagerUpdateScheduler;
    generatePreUpdateSnapshot?: PlannerManagerGeneratePreUpdateSnapshot;
    disableHashOptimizations?: boolean;
    /**
     *
     * @deprecated
     */
    onSceneUpdateStart?(): void;
    /**
     *
     * @deprecated
     */
    onSceneUpdateEnd?(): void;
    /**
     *
     * @deprecated
     */
    onArticleUpdateStart?(comId: string): void;
    /**
     *
     * @deprecated
     */
    onArticleUpdateEnd?(comId: string, initial: boolean): void;
}
export interface ArticleUpdateCallbackParams {
    initial: boolean;
}
export declare type ArticleUpdateType = "geometric" | "materialOnly";
export interface ArticleUpdateCallbackParams {
    initial: boolean;
    status: "preview" | "final";
    updateType: ArticleUpdateType;
}
export declare type LoadingStatus = "idle" | "loadingFull" | "loading";
export declare type SceneStatus = "preview" | "normal";
export interface PlannerManagerHooks {
    /**
     * before a gfx representation is loaded
     */
    prepareForUpdate: AsyncHook<[Article, GfxType]>;
    /**
     * after a gfx representation is loaded and we want to manipulate the gfx representation in the scene
     */
    manipulateAfterUpdate: AsyncHook<[Article, ArticleUpdateCallbackParams]>;
    /**
     * after loading and manipulation of loaded articles
     */
    articleUpdateDone: AsyncHook<[Article, ArticleUpdateCallbackParams]>;
    /**
     * Executes right before an article will be removed from the scene
     *
     */
    prepareForRemove: AsyncHook<[Article]>;
    /**
     * called after an article has been removed from the scene
     */
    articleRemoved: AsyncHook<[Article]>;
    /**
     * Executes at the start of a scene update batch, before anything changed
     *
     */
    sceneUpdateStart: AsyncHook<[string[]]>;
    /**
     * Whenever the scene has been updated and no articles are currently loading
     */
    sceneUpdateDone: AsyncHook<[string[]]>;
}
/**
 * Manages the lifecycle of a commercial article inside the gfx context
 *
 * @export
 * @class PlannerManager
 */
export declare class PlannerManager {
    private readonly session;
    hooks: PlannerManagerHooks;
    private options;
    private apiUtil;
    private articleLoadLimiter;
    private loadScheduler;
    private articleInserter;
    private subscription?;
    private setUpdateQueue;
    private articleUpdateQueue;
    private loadInfo;
    private updatePromise;
    constructor(session: Session, options?: IPlannerManagerOptions);
    private readonly api;
    createSceneSnapshot(articles: string[]): SceneSnapshot;
    hasPendingUpdates(): boolean;
    /**
     * Determines the loading status of the whole scene. Returns loadingFull if all loading articles are transitioning from preview to actual geometries
     *
     * @returns {LoadingStatus}
     */
    getLoadingStatus(): LoadingStatus;
    /**
     * Determines the status of the whole scene. Returns "preview" if at least one article is in a preview state
     *
     * @returns {SceneStatus}
     */
    getSceneStatus(): SceneStatus;
    /**
     * Subscribes the PlannerManager to the supplied session and insert/updates or removes articles from the gfx scene on session notifications
     *
     * @returns
     */
    subscribe(): void;
    /**
     * Removes the subscription to the session
     *
     */
    unsubscribe(): void;
    /**
     * Deletes the gfx representation of an article instance or of a comId
     *
     * Should not be used manually when the PlannerManager has been subscribed to the session.
     *
     * @param {(Article | string)} item
     * @returns
     */
    deleteArticle(item: Article | string): Promise<void>;
    /**
     * Loads or updates all available session articles inside the scene
     *
     * Should not be used manually when the PlannerManager has been subscribed to the session.
     *
     * @returns
     */
    loadAllArticles(): Promise<void>;
    /**
     * Loads or updates a spefic session article inside the scene.
     *
     * Should not be used manually when the PlannerManager has been subscribed to the session.
     *
     * @param {string} comId
     * @returns {Promise<void>}
     */
    loadArticle(comId: string): Promise<void>;
    /**
     * Loads or updates spefic session articles inside the scene.
     *
     * Should not be used manually when the PlannerManager has been subscribed to the session.
     *
     * @param {string[]} comIds
     * @returns {Promise<void>}
     */
    loadArticles(comIds: string[]): Promise<void>;
    private processItems;
    private startProcessingQueueIfNecessary;
    private addQueueItem;
    /**
     * Executes all pending article updates and keeps updating as long as the queue is not empty after an update
     *
     * @private
     */
    private executeAllPendingAndCascadingUpdates;
    /**
     * Updates all articles and sets inside of the current queues
     *
     * @private
     * @returns {Promise<void>}
     */
    private updateSceneFromCurrentQueue;
    private updateSet;
    private queueArticleInsert;
    /**
     * Load graphics for the passed commercial article directly.
     *
     * @private
     * @param {string} comId
     */
    private insertSingleArticle;
    private filterArticles;
    private synchronizeArticleSessionPlacement;
    private getSceneArticlePlacement;
    private executeParentActions;
    private executeNeighborActions;
}
