import {
  EventHandler
} from "./chunk-SGIVSRN5.js";

// src/js-tools/google/google-three.ts
import proj4 from "proj4";
import {
  Matrix4,
  PerspectiveCamera,
  Scene,
  Vector2,
  WebGLRenderer
} from "three";
var wgs84ToEpsg3857 = proj4("WGS84", "EPSG:3857");
function latLngAltToWorldXYZ({
  lng,
  lat,
  altitude
}) {
  const xy = wgs84ToEpsg3857.forward([lng, lat]);
  return [xy[0], xy[1], altitude || 0];
}
function metersToMercatorCoordinateUnit(lat) {
  return Math.cos(lat * Math.PI / 180);
}
function getWebGLOverlayViewClass(WebGLOverlayView) {
  return class extends WebGLOverlayView {
    constructor(anchor) {
      super();
      this._renderer = null;
      this._mousePosition = new Vector2();
      this._listeningDiv = null;
      this.anchor = new google.maps.LatLng(anchor);
      this.worldAnchor = latLngAltToWorldXYZ({
        lat: this.anchor.lat(),
        lng: this.anchor.lng(),
        altitude: 0
      });
      this._scene = new Scene();
      this._camera = new PerspectiveCamera();
      this._eventHandler = new EventHandler();
      this.onMouseMove = this.onMouseMove.bind(this);
    }
    add(...args) {
      return this._scene.add(...args);
    }
    remove(...args) {
      return this._scene.remove(...args);
    }
    onAdd() {
      const map = this.getMap();
      if (map) {
        this._listeningDiv = map.getDiv();
        this._listeningDiv.addEventListener(
          "mousemove",
          this.onMouseMove
        );
      }
    }
    onRemove() {
      if (this._listeningDiv) {
        this._listeningDiv.removeEventListener(
          "mousemove",
          this.onMouseMove
        );
      }
      this.dispose();
    }
    onContextRestored({ gl }) {
      this.dispose();
      this._renderer = new WebGLRenderer({
        canvas: gl.canvas,
        context: gl,
        ...gl.getContextAttributes(),
        antialias: true
      });
      this._renderer.autoClear = false;
    }
    onContextLost() {
      this.dispose();
    }
    onDraw({ gl, transformer }) {
      if (!this._renderer) {
        this.onContextRestored({ gl });
      }
      if (this._renderer) {
        const params = transformer.getCameraParams();
        const latLngAltitudeLiteral = {
          lat: params.center.lat(),
          lng: params.center.lng(),
          altitude: 0
        };
        const anchorXYZ = latLngAltToWorldXYZ(latLngAltitudeLiteral);
        const scale = metersToMercatorCoordinateUnit(
          latLngAltitudeLiteral.lat
        );
        this._camera.rotation.set(-Math.PI / 2, 0, 0);
        this._camera.updateMatrixWorld(true);
        this._camera.projectionMatrix = new Matrix4().fromArray(
          transformer.fromLatLngAltitude(latLngAltitudeLiteral)
        ).multiply(new Matrix4().makeScale(scale, scale, scale)).multiply(
          new Matrix4().makeTranslation(
            this.worldAnchor[0] - anchorXYZ[0],
            this.worldAnchor[1] - anchorXYZ[1],
            anchorXYZ[2]
          )
        );
        this._eventHandler.dispatchEvent("beforerender", {
          renderer: this._renderer,
          scene: this._scene,
          camera: this._camera
        });
        this._renderer.render(this._scene, this._camera);
        this._eventHandler.dispatchEvent("afterrender", {
          renderer: this._renderer,
          scene: this._scene,
          camera: this._camera
        });
        this._renderer.resetState();
      }
    }
    addRenderEventListener(type, cb) {
      return this._eventHandler.addListener(type, cb);
    }
    removeRenderEventListener(type, cb) {
      this._eventHandler.removeListener(type, cb);
    }
    onMouseMove(e) {
      const { left, bottom, width, height } = e.currentTarget.getBoundingClientRect();
      this._mousePosition.set(
        (e.clientX - left) / width,
        (bottom - e.clientY) / height
      );
      this.requestRedraw();
    }
    dispose() {
      if (this._renderer) {
        this._renderer.dispose();
        this._renderer = null;
      }
    }
  };
}

export {
  getWebGLOverlayViewClass
};
