"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const material = require("../material.js");
const threeDomElement = require("../three-dom-element.js");
class Node {
  constructor(name) {
    this.name = "";
    this.children = new Array();
    this.name = name;
  }
}
class PrimitiveNode extends Node {
  constructor(mesh, mvMaterials, modelVariants, correlatedSceneGraph) {
    super(mesh.name);
    this.materials = /* @__PURE__ */ new Map();
    this.variantToMaterialMap = /* @__PURE__ */ new Map();
    this.initialMaterialIdx = 0;
    this.activeMaterialIdx = 0;
    this.mesh = mesh;
    const { gltf, threeGLTF, threeObjectMap } = correlatedSceneGraph;
    this.modelVariants = modelVariants;
    this.mesh.userData.variantData = modelVariants;
    const materialMappings = threeObjectMap.get(mesh.material);
    if (materialMappings.materials != null) {
      this.initialMaterialIdx = this.activeMaterialIdx = materialMappings.materials;
    } else {
      console.error(`Primitive (${mesh.name}) missing initial material reference.`);
    }
    const associations = mesh.userData.associations || {};
    if (associations.meshes == null) {
      console.error("Mesh is missing primitive index association");
      return;
    }
    const meshElementArray = gltf["meshes"] || [];
    const gltfPrimitives = meshElementArray[associations.meshes].primitives || [];
    const gltfPrimitive = gltfPrimitives[associations.primitives];
    if (gltfPrimitive == null) {
      console.error("Mesh primitive definition is missing.");
      return;
    }
    if (gltfPrimitive.material != null) {
      this.materials.set(gltfPrimitive.material, mvMaterials[gltfPrimitive.material]);
    } else {
      const defaultIdx = mvMaterials.findIndex((mat) => {
        return mat.name === "Default";
      });
      if (defaultIdx >= 0) {
        this.materials.set(defaultIdx, mvMaterials[defaultIdx]);
      } else {
        console.warn("gltfPrimitive has no material!");
      }
    }
    if (gltfPrimitive.extensions && gltfPrimitive.extensions["KHR_materials_variants"]) {
      const variantsExtension = gltfPrimitive.extensions["KHR_materials_variants"];
      const extensions = threeGLTF.parser.json.extensions;
      const variantNames = extensions["KHR_materials_variants"].variants;
      for (const mapping of variantsExtension.mappings) {
        const mvMaterial = mvMaterials[mapping.material];
        this.materials.set(mapping.material, mvMaterial);
        for (const variant of mapping.variants) {
          const { name } = variantNames[variant];
          this.variantToMaterialMap.set(variant, mvMaterial);
          mvMaterial[material.$variantIndices]().add(variant);
          if (!modelVariants.has(name)) {
            modelVariants.set(name, { name, index: variant });
          }
        }
      }
    }
  }
  async setActiveMaterial(material$1) {
    const mvMaterial = this.materials.get(material$1);
    if (mvMaterial != null) {
      this.mesh.material = await mvMaterial[material.$getLoadedMaterial]();
      this.activeMaterialIdx = material$1;
    }
    return this.mesh.material;
  }
  getActiveMaterial() {
    return this.materials.get(this.activeMaterialIdx);
  }
  getMaterial(index) {
    return this.materials.get(index);
  }
  async enableVariant(name) {
    if (name == null) {
      return this.setActiveMaterial(this.initialMaterialIdx);
    }
    if (this.variantToMaterialMap != null && this.modelVariants.has(name)) {
      const modelVariants = this.modelVariants.get(name);
      return this.enableVariantHelper(modelVariants.index);
    }
    return null;
  }
  async enableVariantHelper(index) {
    if (this.variantToMaterialMap != null && index != null) {
      const material2 = this.variantToMaterialMap.get(index);
      if (material2 != null) {
        return this.setActiveMaterial(material2.index);
      }
    }
    return null;
  }
  async instantiateVariants() {
    if (this.variantToMaterialMap == null) {
      return;
    }
    for (const index of this.variantToMaterialMap.keys()) {
      const variantMaterial = this.mesh.userData.variantMaterials.get(index);
      if (variantMaterial.material != null) {
        continue;
      }
      const threeMaterial = await this.enableVariantHelper(index);
      if (threeMaterial != null) {
        variantMaterial.material = threeMaterial;
      }
    }
  }
  get variantInfo() {
    return this.variantToMaterialMap;
  }
  addVariant(materialVariant, variantName) {
    if (!this.ensureVariantIsUnused(variantName)) {
      return false;
    }
    if (!this.modelVariants.has(variantName)) {
      this.modelVariants.set(variantName, { name: variantName, index: this.modelVariants.size });
    }
    const modelVariantData = this.modelVariants.get(variantName);
    const variantIndex = modelVariantData.index;
    materialVariant[material.$variantIndices]().add(variantIndex);
    this.variantToMaterialMap.set(variantIndex, materialVariant);
    this.materials.set(materialVariant.index, materialVariant);
    this.updateVariantUserData(variantIndex, materialVariant);
    return true;
  }
  deleteVariant(variantIndex) {
    if (this.variantInfo.has(variantIndex)) {
      this.variantInfo.delete(variantIndex);
      const userDataMap = this.mesh.userData.variantMaterials;
      if (userDataMap != null) {
        userDataMap.delete(variantIndex);
      }
    }
  }
  updateVariantUserData(variantIndex, materialVariant) {
    materialVariant[material.$variantIndices]().add(variantIndex);
    this.mesh.userData.variantData = this.modelVariants;
    this.mesh.userData.variantMaterials = this.mesh.userData.variantMaterials || /* @__PURE__ */ new Map();
    const map = this.mesh.userData.variantMaterials;
    map.set(variantIndex, {
      material: materialVariant[threeDomElement.$correlatedObjects].values().next().value,
      gltfMaterialIndex: materialVariant.index
    });
  }
  ensureVariantIsUnused(variantName) {
    const modelVariants = this.modelVariants.get(variantName);
    if (modelVariants != null && this.variantInfo.has(modelVariants.index)) {
      console.warn(`Primitive cannot add variant '${variantName}' for this material, it already exists.`);
      return false;
    }
    return true;
  }
}
exports.Node = Node;
exports.PrimitiveNode = PrimitiveNode;
//# sourceMappingURL=primitive-node.js.map
