import {ViewerControlsController} from "./utils/ControlsController";
import {TypedViewer} from "./_Base";
const CSS_CLASS = "CoreThreejsViewer";
export class ThreejsViewer extends TypedViewer {
  constructor(_container, _scene, _camera_node, _properties) {
    super(_container, _scene, _camera_node);
    this._scene = _scene;
    this._camera_node = _camera_node;
    this._properties = _properties;
    this._do_render = true;
    this._animate_method = this.animate.bind(this);
    this._do_render = this._properties != null ? this._properties.autoRender : true;
    this._canvas = document.createElement("canvas");
    this._canvas.id = `canvas_id_${Math.random()}`.replace(".", "_");
    this._canvas.style.display = "block";
    this._canvas.style.outline = "none";
    this._container.appendChild(this._canvas);
    this._container.classList.add(CSS_CLASS);
    this._build();
    this._set_events();
  }
  get controlsController() {
    return this._controls_controller = this._controls_controller || new ViewerControlsController(this);
  }
  _build() {
    this._init_display();
    this.activate();
  }
  dispose() {
    this._cancel_animate();
    this.controlsController.dispose();
    super.dispose();
  }
  get cameraControlsController() {
    return this._camera_node.controls_controller;
  }
  _set_events() {
    this.eventsController.init();
    this.webglController.init();
    window.onresize = () => {
      this.onResize();
    };
  }
  onResize() {
    const canvas = this.canvas();
    if (!canvas) {
      return;
    }
    this.camerasController.computeSizeAndAspect();
    this._camera_node.renderController.set_renderer_size(canvas, this.camerasController.size);
    this.camerasController.updateCameraAspect();
  }
  _init_display() {
    if (!this._canvas) {
      console.warn("no canvas found for viewer");
      return;
    }
    this.camerasController.computeSizeAndAspect();
    const size = this.camerasController.size;
    this._camera_node.renderController.createRenderer(this._canvas, size);
    this.camerasController.prepareCurrentCamera();
    this.animate();
  }
  setAutoRender(state = true) {
    this._do_render = state;
    if (this._do_render) {
      this.animate();
    }
  }
  animate() {
    if (this._do_render) {
      this._request_animation_frame_id = requestAnimationFrame(this._animate_method);
      this._scene.timeController.increment_time_if_playing();
      this.render();
      this._controls_controller?.update();
    }
  }
  _cancel_animate() {
    this._do_render = false;
    if (this._request_animation_frame_id) {
      cancelAnimationFrame(this._request_animation_frame_id);
    }
    if (this._canvas) {
      this._camera_node.renderController.delete_renderer(this._canvas);
    }
  }
  render() {
    if (this.camerasController.cameraNode && this._canvas) {
      const size = this.camerasController.size;
      const aspect = this.camerasController.aspect;
      this._camera_node.renderController.render(this._canvas, size, aspect);
    } else {
      console.warn("no camera to render with");
    }
  }
  renderer() {
    if (this._canvas) {
      return this._camera_node.renderController.renderer(this._canvas);
    }
  }
}
