import { Color } from "three";
import { convertTexture2Sampler2D } from "../../../texture/sampler/convertTexture2Sampler2D.js";
import { sampler2d_multiply_vector } from "../../../texture/sampler/sampler2d_multiply_vector.js";
import { iterate_three_material_textures } from "../../../three/material/iterate_three_material_textures.js";
import { StandardMaterial } from "./StandardMaterial.js";
import { StandardTexture } from "./StandardTexture.js";

/**
 *
 * @param {Map<number,StandardTexture>} cache
 * @param {AssetManager} asset_manager
 * @param {THREE.Material} material
 * @returns {Promise<void>}
 */
async function precache_textures(cache, asset_manager, material) {

    const textures = iterate_three_material_textures(material);

    for (const { name, texture } of textures) {
        if (cache.has(texture.id)) {
            // already processed
            continue;
        }


    }


}

export class MaterialConverter {
    /**
     * Maps {@link Texture.id} to relevant sampler
     * @type {Map<number, StandardTexture>}
     */
    #textures = new Map();

    /**
     *
     * @param {THREE.Texture} texture
     * @returns {StandardTexture}
     */
    #ensure_texture(texture) {
        const existing = this.#textures.get(texture.id);

        if (existing !== undefined) {
            return existing
        }

        const sampler2D = convertTexture2Sampler2D(texture, undefined, undefined, false);

        const st = StandardTexture.from(sampler2D);

        this.#textures.set(texture.id, st);

        return st;
    }

    /**
     *
     * @param {THREE.Material} material
     * @returns {StandardMaterial}
     */
    convert(material) {

        const result = new StandardMaterial();

        const textures = iterate_three_material_textures(material);

        //patch textures

        for (const { name, texture } of textures) {

            const sampler = this.#ensure_texture(texture);

            if (name === "diffuse") {
                result.diffuse = sampler;
            } else if (name === "normal") {
                result.normal = sampler;
            } else if (name === "metalness") {
                result.metalness = sampler;
            } else if (name === "roughness") {
                result.roughness = sampler;
            } else if (name === "emissive") {
                result.emissive = sampler;
            } else {
                // unused
            }

        }

        if (material.color !== undefined && !material.color.equals(new Color(1, 1, 1))) {
            const tinted_diffuse = result.diffuse.clone();

            tinted_diffuse.sampler = tinted_diffuse.sampler.clone();

            sampler2d_multiply_vector(tinted_diffuse.sampler, result.diffuse.sampler, material.color.toArray());

            result.diffuse = tinted_diffuse;
        }

        return result;
    }

}