self.onmessage = function(event) {
	const { type, tokenBounds, tileBounds, tileTextureData, chunkSize } = event.data;

	if (type === 'createMask') {
		const maskGraphics = createOcclusionMask(tokenBounds, tileBounds, tileTextureData, chunkSize);
		self.postMessage({ type: 'maskCreated', maskGraphics });
	}
};

function createOcclusionMask(tokenBounds, tileBounds, tileTextureData, chunkSize = 2) {
	const maskGraphics = [];

	const tempCanvas = new OffscreenCanvas(tileTextureData.width, tileTextureData.height);
	const tempCtx = tempCanvas.getContext('2d');

	const { width, height } = tileTextureData;
	const tempImageData = new ImageData(new Uint8ClampedArray(tileTextureData.pixels), width, height);
	tempCtx.putImageData(tempImageData, 0, 0);

	for (let cy = 0; cy < height; cy += chunkSize) {
		for (let cx = 0; cx < width; cx += chunkSize) {
			let hasOpaquePixel = false;

			chunkCheck: for (let by = 0; by < chunkSize; by++) {
				const y = cy + by;
				if (y >= height) break;

				for (let bx = 0; bx < chunkSize; bx++) {
					const x = cx + bx;
					if (x >= width) break;

					const pixelIndex = y * width + x;
					const alphaValue = tempImageData.data[pixelIndex * 4 + 3];

					if (alphaValue > 0) {
						hasOpaquePixel = true;
						break chunkCheck;
					}
				}
			}

			if (hasOpaquePixel) {
				maskGraphics.push({ x: cx, y: cy, width: Math.min(chunkSize, width - cx), height: Math.min(chunkSize, height - cy) });
			}
		}
	}

	return maskGraphics;
}
