import { Polygon } from '../../../maths/shapes/Polygon.mjs';
import { uid } from '../../../utils/data/uid.mjs';
import { State } from '../../renderers/shared/state/State.mjs';
import { Texture } from '../../renderers/shared/texture/Texture.mjs';
import { emptyViewObserver } from '../../renderers/shared/View.mjs';

const tempPolygon = new Polygon();
class MeshView {
  constructor(options) {
    this.uid = uid("meshView");
    this.renderPipeId = "mesh";
    this.canBundle = true;
    this.owner = emptyViewObserver;
    this.state = State.for2d();
    this.shader = options.shader;
    this.texture = options.texture ?? this.shader?.texture ?? Texture.WHITE;
    this._geometry = options.geometry;
    this._geometry.on("update", this.onUpdate, this);
  }
  set shader(value) {
    if (this._shader === value)
      return;
    this._shader = value;
    this.onUpdate();
  }
  get shader() {
    return this._shader;
  }
  set geometry(value) {
    if (this._geometry === value)
      return;
    this._geometry?.off("update", this.onUpdate, this);
    value.on("update", this.onUpdate, this);
    this._geometry = value;
    this.onUpdate();
  }
  get geometry() {
    return this._geometry;
  }
  set texture(value) {
    if (this._texture === value)
      return;
    if (this.shader) {
      this.shader.texture = value;
    }
    this._texture = value;
    this.onUpdate();
  }
  get texture() {
    return this._texture;
  }
  get batched() {
    if (this._shader)
      return false;
    if (this._geometry.batchMode === "auto") {
      return this._geometry.positions.length / 2 <= 100;
    }
    return this._geometry.batchMode === "batch";
  }
  addBounds(bounds) {
    bounds.addVertexData(this.geometry.positions, 0, this.geometry.positions.length);
  }
  containsPoint(point) {
    const { x, y } = point;
    const vertices = this.geometry.getBuffer("aPosition").data;
    const points = tempPolygon.points;
    const indices = this.geometry.getIndex().data;
    const len = indices.length;
    const step = this.geometry.topology === "triangle-strip" ? 3 : 1;
    for (let i = 0; i + 2 < len; i += step) {
      const ind0 = indices[i] * 2;
      const ind1 = indices[i + 1] * 2;
      const ind2 = indices[i + 2] * 2;
      points[0] = vertices[ind0];
      points[1] = vertices[ind0 + 1];
      points[2] = vertices[ind1];
      points[3] = vertices[ind1 + 1];
      points[4] = vertices[ind2];
      points[5] = vertices[ind2 + 1];
      if (tempPolygon.contains(x, y)) {
        return true;
      }
    }
    return false;
  }
  /** Called when the geometry is updated. */
  onUpdate() {
    this.owner.onViewUpdate();
  }
  /**
   * Destroys this sprite renderable and optionally its texture.
   * @param options - Options parameter. A boolean will act as if all options
   *  have been set to that value
   * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well
   * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well
   */
  destroy(options = false) {
    const destroyTexture = typeof options === "boolean" ? options : options?.texture;
    if (destroyTexture) {
      const destroyTextureSource = typeof options === "boolean" ? options : options?.textureSource;
      this._texture.destroy(destroyTextureSource);
    }
    this._texture = null;
    this._geometry = null;
    this._shader = null;
  }
}

export { MeshView };
//# sourceMappingURL=MeshView.mjs.map
