import { Ob, viewport, utils } from "negl";
import { Vector2, MeshStandardMaterial, ExtrudeGeometry, Shape } from "three";

export default class extends Ob {
  setupVertex() {
    return;
  }
  setupFragment() {
    return;
  }
  setupGeometry() {
    // @see
    // https://stackoverflow.com/questions/27193732/three-js-creating-a-right-triangular-prism
    try {
      // const PrismGeometry = function (vertices, height) {
      //   var _Shape = new Shape();

      //   (function f(ctx) {
      //     ctx.moveTo(vertices[0].x, vertices[0].y);
      //     for (var i = 1; i < vertices.length; i++) {
      //       ctx.lineTo(vertices[i].x, vertices[i].y);
      //     }
      //     ctx.lineTo(vertices[0].x, vertices[0].y);
      //   })(_Shape);

      //   var settings = {};
      //   settings.amount = height;
      //   settings.bevelEnabled = false;
      //   ExtrudeGeometry.prototype.constructor.call(this, _Shape, settings);
      // };

      // PrismGeometry.prototype = Object.create(ExtrudeGeometry.prototype);

      // three.js : Creating a right triangular prism
      // https://stackoverflow.com/questions/27193732/three-js-creating-a-right-triangular-prism
      class PrismGeometry extends ExtrudeGeometry {
        constructor(vertices, depth) {
          const extrudeSettings = {};
          extrudeSettings.depth = +depth;
          // extrudeSettings.bevelEnabled = false;

          const _Shape = new Shape();

          (function f(ctx) {
            ctx.moveTo(vertices[0].x, vertices[0].y);
            for (let i = 1; i < vertices.length; i++) {
              ctx.lineTo(vertices[i].x, vertices[i].y);
            }
            ctx.lineTo(vertices[0].x, vertices[0].y);
          })(_Shape);

          // ExtrudeGeometry - https://threejs.org/docs/?q=ExtrudeGeometry#api/en/geometries/ExtrudeGeometry
          super(_Shape, extrudeSettings);

          // ExtrudeGeometry.prototype.constructor.call(this, _Shape, settings);
        }
      }

      const x = this.rect.width / 2;
      const y = this.rect.height;
      const A = new Vector2(-x, 0);
      const B = new Vector2(x, 0);
      const C = new Vector2(0, y);

      const depth = this.dataAttrs.depth ?? this.rect.width;
      const geometry = new PrismGeometry([A, B, C], depth);
      geometry.translate(0,0,-depth/2)
      return geometry;
    } catch (e) {
      debugger;
    }
  }
  async resize(duration = 1) {
    this.resizing = true;

    const {
      $: { el },
      mesh,
      originalRect,
    } = this;

    const nextRect = el.getBoundingClientRect();
    const { x, y } = this.getWorldPosition(nextRect, viewport);

    if (mesh === undefined) return;

    const p1 = new Promise((onComplete) => {
      utils.tween(mesh.position, {
        x,
        y,
        duration,
        onComplete,
      });
    });

    // 大きさの変更
    const p2 = new Promise((onComplete) => {
      utils.tween(this.scale, {
        width: nextRect.width / originalRect.width,
        height: nextRect.height / originalRect.height,
        depth: nextRect.width / originalRect.width,
        duration,
        onUpdate: () => {
          mesh.scale.set(this.scale.width, this.scale.height, this.scale.depth);
        },
        onComplete,
      });
    });

    await Promise.all([p1, p2]);

    this.rect = nextRect;

    this.resizing = false;
  }
  setupMaterial() {
    return new MeshStandardMaterial();
  }
  debug(folder) {
    folder.addColor(this.material, "color");
    folder.addColor(this.material, "emissive");
  }
  afterInit() {
    this.mesh.position.z = this.dataAttrs.z ?? 0;
  }
}
