/**
 * Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @author David Sehnal <david.sehnal@gmail.com>
 */
import { ParamDefinition as PD } from '../mol-util/param-definition.js';
import { WebGLContext } from '../mol-gl/webgl/context.js';
import { ColorTheme } from '../mol-theme/color.js';
import { SizeTheme } from '../mol-theme/size.js';
import { ThemeRegistryContext, Theme } from '../mol-theme/theme.js';
import { Subject } from 'rxjs';
import { GraphicsRenderObject } from '../mol-gl/render-object.js';
import { Task } from '../mol-task/index.js';
import { PickingId } from '../mol-geo/geometry/picking.js';
import { MarkerAction, MarkerActions } from '../mol-util/marker-action.js';
import { Loci as ModelLoci } from '../mol-model/loci.js';
import { Overpaint } from '../mol-theme/overpaint.js';
import { Transparency } from '../mol-theme/transparency.js';
import { Mat4 } from '../mol-math/linear-algebra.js';
import { LocationCallback } from './util.js';
import { BaseGeometry } from '../mol-geo/geometry/base.js';
import { CustomProperty } from '../mol-model-props/common/custom-property.js';
import { Clipping } from '../mol-theme/clipping.js';
import { Substance } from '../mol-theme/substance.js';
import { Emissive } from '../mol-theme/emissive.js';
import { Location } from '../mol-model/location.js';
export type RepresentationProps = {
    [k: string]: any;
};
export interface RepresentationContext {
    readonly webgl?: WebGLContext;
    readonly colorThemeRegistry: ColorTheme.Registry;
    readonly sizeThemeRegistry: SizeTheme.Registry;
}
export type RepresentationParamsGetter<D, P extends PD.Params> = (ctx: ThemeRegistryContext, data: D) => P;
export type RepresentationFactory<D, P extends PD.Params, S extends Representation.State> = (ctx: RepresentationContext, getParams: RepresentationParamsGetter<D, P>) => Representation<D, P, S>;
export interface RepresentationProvider<D = any, P extends PD.Params = any, S extends Representation.State = any, Id extends string = string> {
    readonly name: Id;
    readonly label: string;
    readonly description: string;
    readonly factory: RepresentationFactory<D, P, S>;
    readonly getParams: RepresentationParamsGetter<D, P>;
    readonly defaultValues: PD.Values<P>;
    readonly defaultColorTheme: {
        name: string;
        props?: {};
    };
    readonly defaultSizeTheme: {
        name: string;
        props?: {};
    };
    readonly isApplicable: (data: D) => boolean;
    readonly ensureCustomProperties?: {
        attach: (ctx: CustomProperty.Context, data: D) => Promise<void>;
        detach: (data: D) => void;
    };
    readonly getData?: (data: D, props: PD.Values<P>) => D;
    readonly mustRecreate?: (oldProps: PD.Values<P>, newProps: PD.Values<P>) => boolean;
    readonly locationKinds?: ReadonlyArray<Location['kind']>;
}
export declare namespace RepresentationProvider {
    type ParamValues<R extends RepresentationProvider<any, any, any>> = R extends RepresentationProvider<any, infer P, any> ? PD.Values<P> : never;
    function getDefaultParams<R extends RepresentationProvider<D, any, any>, D>(r: R, ctx: ThemeRegistryContext, data: D): PD.Values<any>;
}
export type AnyRepresentationProvider = RepresentationProvider<any, {}, Representation.State>;
export declare const EmptyRepresentationProvider: RepresentationProvider;
export declare class RepresentationRegistry<D, S extends Representation.State> {
    private _list;
    private _map;
    private _name;
    get default(): {
        name: string;
        provider: RepresentationProvider<D, any, any>;
    };
    get types(): [string, string][];
    constructor();
    add<P extends PD.Params>(provider: RepresentationProvider<D, P, S>): void;
    getName(provider: RepresentationProvider<D, any, any>): string;
    remove(provider: RepresentationProvider<D, any, any>): void;
    get<P extends PD.Params>(name: string): RepresentationProvider<D, P, S>;
    get list(): {
        name: string;
        provider: RepresentationProvider<D, any, any>;
    }[];
    getApplicableList(data: D): {
        name: string;
        provider: RepresentationProvider<D, any, any>;
    }[];
    getApplicableTypes(data: D): [string, string][];
    clear(): void;
}
export { Representation };
interface Representation<D, P extends PD.Params = PD.Params, S extends Representation.State = Representation.State> {
    readonly label: string;
    readonly updated: Subject<number>;
    /** Number of addressable groups in all visuals of the representation */
    readonly groupCount: number;
    readonly renderObjects: ReadonlyArray<GraphicsRenderObject>;
    readonly geometryVersion: number;
    readonly props: Readonly<PD.Values<P>>;
    readonly params: Readonly<P>;
    readonly state: Readonly<S>;
    readonly theme: Readonly<Theme>;
    createOrUpdate: (props?: Partial<PD.Values<P>>, data?: D) => Task<void>;
    setState: (state: Partial<S>) => void;
    setTheme: (theme: Theme) => void;
    getLoci: (pickingId: PickingId) => ModelLoci;
    getAllLoci: () => ModelLoci[];
    eachLocation: (cb: LocationCallback) => void;
    mark: (loci: ModelLoci, action: MarkerAction) => boolean;
    destroy: () => void;
}
declare namespace Representation {
    interface Loci<T extends ModelLoci = ModelLoci> {
        loci: T;
        repr?: Representation.Any;
    }
    namespace Loci {
        function areEqual(a: Loci, b: Loci): boolean;
        function isEmpty(a: Loci): boolean;
        const Empty: Loci;
    }
    interface State {
        /** Controls if the representation's renderobjects are rendered or not */
        visible: boolean;
        /** A factor applied to alpha value of the representation's renderobjects */
        alphaFactor: number;
        /** Controls if the representation's renderobjects are pickable or not */
        pickable: boolean;
        /** Controls if the representation's renderobjects is rendered in color pass (i.e., not pick and depth) or not */
        colorOnly: boolean;
        /** Overpaint applied to the representation's renderobjects */
        overpaint: Overpaint;
        /** Per group transparency applied to the representation's renderobjects */
        transparency: Transparency;
        /** Per group emissive applied to the representation's renderobjects */
        emissive: Emissive;
        /** Per group material applied to the representation's renderobjects */
        substance: Substance;
        /** Bit mask of per group clipping applied to the representation's renderobjects */
        clipping: Clipping;
        /** Strength of the representations overpaint, transparency, emmissive, substance*/
        themeStrength: {
            overpaint: number;
            transparency: number;
            emissive: number;
            substance: number;
        };
        /** Controls if the representation's renderobjects are synced automatically with GPU or not */
        syncManually: boolean;
        /** A transformation applied to the representation's renderobjects */
        transform: Mat4;
        /** Bit mask of allowed marker actions */
        markerActions: MarkerActions;
    }
    function createState(): State;
    function updateState(state: State, update: Partial<State>): void;
    interface StateBuilder<S extends State> {
        create(): S;
        update(state: S, update: Partial<S>): void;
    }
    const StateBuilder: StateBuilder<State>;
    type Any<P extends PD.Params = PD.Params, S extends State = State> = Representation<any, P, S>;
    const Empty: Any;
    function createEmpty(): Any;
    type Def<D, P extends PD.Params = PD.Params, S extends State = State> = {
        [k: string]: RepresentationFactory<D, P, S>;
    };
    class GeometryState {
        private curr;
        private next;
        private _version;
        get version(): number;
        add(id: number, version: number): void;
        snapshot(): void;
    }
    function createMulti<D, P extends PD.Params = PD.Params, S extends State = State>(label: string, ctx: RepresentationContext, getParams: RepresentationParamsGetter<D, P>, stateBuilder: StateBuilder<S>, reprDefs: Def<D, P>): Representation<D, P, S>;
    function fromRenderObject(label: string, renderObject: GraphicsRenderObject): Representation<GraphicsRenderObject, BaseGeometry.Params>;
}
