/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Rendering
 */
import { TransientIdSequence } from "@itwin/core-bentley";
import { _implementationProhibited } from "../Symbols";
import { ColorDef, Gradient, ImageSource, RenderMaterial, RenderTexture, RgbColor, TextureMapping } from "@itwin/core-common";
export class WorkerTexture extends RenderTexture {
    index;
    source;
    constructor(index, params) {
        let type = RenderTexture.Type.Normal;
        if (!(params instanceof Gradient.Symb) && undefined !== params.type) {
            type = params.type;
        }
        super(type);
        this.index = index;
        if (params instanceof Gradient.Symb) {
            this.source = { gradient: params };
        }
        else {
            const transparency = params.transparency;
            if (params.source instanceof URL) {
                this.source = { transparency, url: params.source.toString() };
            }
            else if (params.source instanceof ImageSource) {
                this.source = { transparency, imageSource: params.source.data, format: params.source.format };
            }
            else {
                this.source = { transparency, imageBuffer: params.source.data, format: params.source.format, width: params.source.width };
            }
        }
    }
    dispose() { }
    get bytesUsed() { return 0; } // doesn't matter, nobody's calling this.
    toProps(xfer) {
        const source = this.source.gradient ? { ...this.source, gradient: this.source.gradient.toJSON() } : this.source;
        const buffer = source.imageBuffer ?? source.imageSource;
        if (buffer instanceof Uint8Array) {
            xfer.add(buffer.buffer);
        }
        return {
            type: this.type,
            source,
        };
    }
}
function materialColorToImdl(color) {
    if (!(color instanceof ColorDef)) {
        color = RgbColor.fromJSON(color).toColorDef();
    }
    return color?.toJSON();
}
export class WorkerMaterial extends RenderMaterial {
    params;
    constructor(params) {
        let textureMapping;
        if (params.textureMapping) {
            textureMapping = new TextureMapping(params.textureMapping.texture, new TextureMapping.Params({
                textureMat2x3: params.textureMapping.transform,
                mapMode: params.textureMapping.mode,
                textureWeight: params.textureMapping.weight,
                worldMapping: params.textureMapping.worldMapping,
                useConstantLod: params.textureMapping.useConstantLod,
                constantLodProps: params.textureMapping.constantLodProps,
            }));
            textureMapping.normalMapParams = params.textureMapping.normalMapParams;
        }
        super({ textureMapping });
        this.params = params;
    }
    toImdl() {
        let diffuse;
        if (this.params.diffuse) {
            diffuse = {
                weight: this.params.diffuse.weight,
                color: materialColorToImdl(this.params.diffuse.color),
            };
        }
        let specular;
        if (this.params.specular) {
            specular = {
                weight: this.params.specular.weight,
                exponent: this.params.specular.exponent,
                color: materialColorToImdl(this.params.specular.color),
            };
        }
        return {
            isAtlas: false,
            material: {
                alpha: this.params.alpha,
                diffuse,
                specular,
            },
        };
    }
}
export class WorkerGraphicDescriptionContextImpl {
    [_implementationProhibited] = undefined;
    constraints;
    transientIds;
    textures = [];
    materials = [];
    constructor(props) {
        const propsImpl = props;
        if (typeof propsImpl.transientIds !== "object" || typeof propsImpl.constraints !== "object") {
            throw new Error("Invalid WorkerGraphicDescriptionContextProps");
        }
        this.constraints = propsImpl.constraints;
        this.transientIds = TransientIdSequence.fromJSON(propsImpl.transientIds);
    }
    createMaterial(params) {
        const material = new WorkerMaterial(params);
        this.materials.push(material);
        return material;
    }
    createTexture(params) {
        const texture = new WorkerTexture(this.textures.length, params);
        this.textures.push(texture);
        return texture;
    }
    createGradientTexture(gradient) {
        const existing = this.textures.find((tx) => tx.source.gradient && tx.source.gradient.equals(gradient));
        if (existing) {
            return existing;
        }
        const texture = new WorkerTexture(this.textures.length, gradient);
        this.textures.push(texture);
        return texture;
    }
    toProps(transferables) {
        // We don't yet have any transferable objects. In the future we expect to support transferring texture image data for textures created on the worker thread.
        return {
            [_implementationProhibited]: undefined,
            transientIds: this.transientIds.toJSON(),
            textures: this.textures.map((tx) => tx.toProps(transferables)),
        };
    }
}
//# sourceMappingURL=GraphicDescriptionContextImpl.js.map