import {
  CustomLayer
} from "./chunk-EEOMRBEG.js";
import "./chunk-JSBRDJBE.js";

// src/js-tools/mapbox/mapbox-helpers.ts
import proj4 from "proj4";
var wgs84ProjDef = proj4.defs("WGS84");
var MAX_MERCATOR_LAT = 85.05112877980659;
var DEG_TO_RAD = Math.PI / 180;
var RAD_TO_DEG = 180 / Math.PI;
function mercatorXfromLng(lng) {
  return (180 + lng) / 360;
}
function mercatorYfromLat(lat) {
  const clamped = lat > MAX_MERCATOR_LAT ? MAX_MERCATOR_LAT : lat < -MAX_MERCATOR_LAT ? -MAX_MERCATOR_LAT : lat;
  return (180 - RAD_TO_DEG * Math.log(Math.tan(Math.PI / 4 + clamped * DEG_TO_RAD / 2))) / 360;
}
var _crsId = 0;
function projectPositionsToMapboxMercators(positions, worldAnchor, offset = [0, 0, 0], crs, out) {
  const output = out ?? new Float32Array(positions.length);
  const meterScale = worldAnchor.meterInMercatorCoordinateUnits();
  const anchorX = worldAnchor.x;
  const anchorY = worldAnchor.y;
  const anchorZ = worldAnchor.z ?? 0;
  const [ox, oy, oz] = offset;
  if (crs && crs.title !== wgs84ProjDef.title) {
    const uuid = `__crs_${_crsId++}`;
    proj4.defs(uuid, crs);
    const transformer = proj4(uuid, "WGS84");
    const toMeters = crs.to_meter || 1;
    for (let i = 0; i < positions.length; i += 3) {
      const transformed = transformer.forward([
        positions[i] + ox,
        -(positions[i + 2] + oz)
      ]);
      const lng = transformed[0];
      const lat = transformed[1];
      const elev = (positions[i + 1] + oy) * toMeters;
      output[i] = mercatorXfromLng(lng) - anchorX;
      output[i + 1] = elev * meterScale - anchorZ;
      output[i + 2] = anchorY - mercatorYfromLat(lat);
    }
  } else {
    for (let i = 0; i < positions.length; i += 3) {
      const lng = positions[i] + ox;
      const elev = positions[i + 1] + oy;
      const lat = -(positions[i + 2] + oz);
      output[i] = mercatorXfromLng(lng) - anchorX;
      output[i + 1] = elev * meterScale - anchorZ;
      output[i + 2] = anchorY - mercatorYfromLat(lat);
    }
  }
  return output;
}

// src/js-tools/mapbox/mapbox-utils.ts
import { transfer } from "comlink";
import { BufferAttribute } from "three";

// src/js-tools/mapbox/mapbox-worker-api.ts
import { releaseProxy, wrap } from "comlink";
function createMapboxWorker() {
  const worker = new Worker(
    new URL("./workers/mapbox-worker.min.js", import.meta.url),
    { type: "module" }
  );
  const api = wrap(worker);
  return {
    api,
    terminate() {
      api[releaseProxy]();
      worker.terminate();
    }
  };
}

// src/js-tools/mapbox/mapbox-utils.ts
async function projectGeometriesToMapboxCoords(input, anchor, { useWorker = true, ...options } = {}) {
  const geometries = Array.isArray(input) ? input : [input];
  const positionAttrs = geometries.map((g) => g.getAttribute("position"));
  for (const attr of positionAttrs) {
    if (!(attr.array instanceof Float32Array)) {
      throw new Error("Position attribute array must be Float32Array.");
    }
  }
  const newBuffers = useWorker ? await projectViaWorker(positionAttrs, anchor, options) : positionAttrs.map(
    (a) => projectPositionsToMapboxMercators(
      a.array,
      anchor,
      options.offset,
      options.crs
    ).buffer
  );
  geometries.forEach((geometry, i) => {
    geometry.setAttribute(
      "position",
      new BufferAttribute(new Float32Array(newBuffers[i]), 3, false)
    );
    geometry.computeBoundingBox();
    geometry.computeBoundingSphere();
  });
}
async function projectViaWorker(positionAttrs, anchor, options) {
  const handle = createMapboxWorker();
  try {
    const inputBuffers = positionAttrs.map(
      (a) => a.array.buffer
    );
    const worldAnchorMeterScale = anchor.meterInMercatorCoordinateUnits();
    const { positions } = await handle.api.projectGeometries(
      transfer(
        {
          positions: inputBuffers,
          worldAnchor: anchor,
          worldAnchorMeterScale,
          ...options
        },
        inputBuffers
      )
    );
    return positions;
  } finally {
    handle.terminate();
  }
}
async function projectGeometryToMapboxCoords(geometry, anchor, options = {}) {
  await projectGeometriesToMapboxCoords(geometry, anchor, options);
}
export {
  CustomLayer,
  createMapboxWorker,
  projectGeometriesToMapboxCoords,
  projectGeometryToMapboxCoords,
  projectPositionsToMapboxMercators
};
