var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var textures_exports = {};
__export(textures_exports, {
  buildTexturePixels: () => buildTexturePixels,
  createPatternPlaceholderTexture: () => createPatternPlaceholderTexture,
  createTextureMaterial: () => createTextureMaterial,
  ensureTextureInstance: () => ensureTextureInstance,
  toThreeColorRGB: () => toThreeColorRGB
});
module.exports = __toCommonJS(textures_exports);
function toThreeColor(THREE, rgb) {
  const color = new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);
  if (typeof color.convertSRGBToLinear === "function") {
    color.convertSRGBToLinear();
  } else if (typeof color.convertGammaToLinear === "function") {
    color.convertGammaToLinear(2.2);
  }
  return color;
}
function buildTexturePixels(context, textureDef, pattern, materialsById) {
  const [width, height] = pattern.size;
  const colorBuffer = new Uint8Array(width * height * 4);
  const emissiveBuffer = new Uint8Array(width * height * 4);
  let hasEmissive = false;
  for (let y = 0; y < height; y += 1) {
    for (let x = 0; x < width; x += 1) {
      const sourceIndex = y * width + x;
      const paletteIndex = pattern.data[sourceIndex];
      const materialId = textureDef.materials[paletteIndex];
      const material = materialId ? materialsById.get(materialId) : void 0;
      const color = material?.baseColor ?? [59, 130, 246];
      const opacityValue = material?.opacity !== void 0 ? Number(material.opacity) : 1;
      const clampedOpacity = Number.isFinite(opacityValue) ? Math.max(0, Math.min(1, opacityValue)) : 1;
      const targetY = height - 1 - y;
      const targetIndex = (targetY * width + x) * 4;
      colorBuffer[targetIndex] = color[0];
      colorBuffer[targetIndex + 1] = color[1];
      colorBuffer[targetIndex + 2] = color[2];
      colorBuffer[targetIndex + 3] = Math.round(clampedOpacity * 255);
      const emissive = material?.emissiveColor ?? null;
      if (emissive) {
        emissiveBuffer[targetIndex] = emissive[0];
        emissiveBuffer[targetIndex + 1] = emissive[1];
        emissiveBuffer[targetIndex + 2] = emissive[2];
        emissiveBuffer[targetIndex + 3] = 255;
        if (!hasEmissive) {
          hasEmissive = emissive.some((component) => component !== 0);
        }
      } else {
        emissiveBuffer[targetIndex] = 0;
        emissiveBuffer[targetIndex + 1] = 0;
        emissiveBuffer[targetIndex + 2] = 0;
        emissiveBuffer[targetIndex + 3] = 0;
      }
    }
  }
  return {
    color: colorBuffer,
    emissive: hasEmissive ? emissiveBuffer : null
  };
}
function ensureTextureInstance(context, textureDef) {
  const cached = context.textureCache.get(textureDef.id);
  if (cached) {
    return cached;
  }
  if (!context.entity) {
    return null;
  }
  const pattern = context.entity.patterns.find((entry) => entry.id === textureDef.pattern);
  if (!pattern) {
    console.warn("[boxel-three] pattern not found for texture", textureDef.id);
    return null;
  }
  const { color, emissive } = buildTexturePixels(context, textureDef, pattern, context.materialsById);
  const colorTexture = new context.THREE.DataTexture(color, pattern.size[0], pattern.size[1]);
  colorTexture.needsUpdate = true;
  colorTexture.magFilter = context.THREE.NearestFilter;
  colorTexture.minFilter = context.THREE.NearestFilter;
  colorTexture.wrapS = context.THREE.ClampToEdgeWrapping;
  colorTexture.wrapT = context.THREE.ClampToEdgeWrapping;
  colorTexture.flipY = false;
  if ("colorSpace" in colorTexture) {
    colorTexture.colorSpace = context.THREE.SRGBColorSpace ?? colorTexture.colorSpace;
  } else if ("encoding" in colorTexture) {
    colorTexture.encoding = context.THREE.sRGBEncoding ?? colorTexture.encoding;
  }
  let emissiveTexture;
  if (emissive) {
    emissiveTexture = new context.THREE.DataTexture(emissive, pattern.size[0], pattern.size[1]);
    emissiveTexture.needsUpdate = true;
    emissiveTexture.magFilter = context.THREE.NearestFilter;
    emissiveTexture.minFilter = context.THREE.NearestFilter;
    emissiveTexture.wrapS = context.THREE.ClampToEdgeWrapping;
    emissiveTexture.wrapT = context.THREE.ClampToEdgeWrapping;
    emissiveTexture.flipY = false;
    if ("colorSpace" in emissiveTexture) {
      emissiveTexture.colorSpace = context.THREE.SRGBColorSpace ?? emissiveTexture.colorSpace;
    } else if ("encoding" in emissiveTexture) {
      emissiveTexture.encoding = context.THREE.sRGBEncoding ?? emissiveTexture.encoding;
    }
  }
  const bundle = {
    color: colorTexture,
    emissive: emissiveTexture
  };
  context.textureCache.set(textureDef.id, bundle);
  return bundle;
}
function createPatternPlaceholderTexture(context, pattern) {
  const [width, height] = pattern.size;
  const buffer = new Uint8Array(width * height * 4);
  const maxValue = pattern.data.reduce((acc, value) => Math.max(acc, value), 0);
  const normalizer = maxValue > 0 ? maxValue : 1;
  for (let y = 0; y < height; y += 1) {
    for (let x = 0; x < width; x += 1) {
      const sourceIndex = y * width + x;
      const value = pattern.data[sourceIndex];
      const shade = Math.round(value / normalizer * 255);
      const targetY = height - 1 - y;
      const targetIndex = (targetY * width + x) * 4;
      buffer[targetIndex] = shade;
      buffer[targetIndex + 1] = shade;
      buffer[targetIndex + 2] = shade;
      buffer[targetIndex + 3] = 255;
    }
  }
  const texture = new context.THREE.DataTexture(buffer, width, height);
  texture.needsUpdate = true;
  texture.magFilter = context.THREE.NearestFilter;
  texture.minFilter = context.THREE.NearestFilter;
  texture.wrapS = context.THREE.ClampToEdgeWrapping;
  texture.wrapT = context.THREE.ClampToEdgeWrapping;
  texture.flipY = false;
  if ("colorSpace" in texture) {
    texture.colorSpace = context.THREE.SRGBColorSpace ?? texture.colorSpace;
  } else if ("encoding" in texture) {
    texture.encoding = context.THREE.sRGBEncoding ?? texture.encoding;
  }
  return texture;
}
function createTextureMaterial(context, textureId) {
  if (!textureId || !context.entity) {
    return new context.THREE.MeshStandardMaterial({
      color: 3900150,
      opacity: 0.45,
      transparent: true,
      metalness: 0,
      roughness: 1
    });
  }
  const textureDef = context.entity.textures.find((entry) => entry.id === textureId);
  if (!textureDef) {
    console.warn("[boxel-three] texture not found", textureId);
    return new context.THREE.MeshStandardMaterial({
      color: 3900150,
      opacity: 0.45,
      transparent: true,
      metalness: 0,
      roughness: 1
    });
  }
  const bundle = ensureTextureInstance(context, textureDef);
  if (!bundle) {
    return new context.THREE.MeshStandardMaterial({
      color: 3900150,
      opacity: 0.45,
      transparent: true,
      metalness: 0,
      roughness: 1
    });
  }
  const material = new context.THREE.MeshStandardMaterial({
    map: bundle.color,
    transparent: true,
    metalness: 0,
    roughness: 1
  });
  if (bundle.emissive) {
    material.emissiveMap = bundle.emissive;
    material.emissive = new context.THREE.Color(1, 1, 1);
    material.emissiveIntensity = 1;
  } else {
    material.emissive.setRGB(0, 0, 0);
    material.emissiveIntensity = 1;
  }
  material.needsUpdate = true;
  return material;
}
function toThreeColorRGB(context, rgb) {
  return toThreeColor(context.THREE, rgb);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildTexturePixels,
  createPatternPlaceholderTexture,
  createTextureMaterial,
  ensureTextureInstance,
  toThreeColorRGB
});
