import { Sprite, SpriteMaterial, Texture, Vector2, Vector3 } from 'three';
import { Base } from '../base';
import _Map from '../map/map';

interface IOptions {
  name: string;
  icon: any;
  scale?: number;
  renderOrder: number;
  position: Vector3;
}

export default class PoiMarker extends Base {
  private _scale!: number;
  sprite!: Sprite;
  constructor(private options: IOptions) {
    super();
  }

  // 重写父类 _inject
  _inject(map: _Map, _scale?: number) {
    super._inject(map);
    this._scale = _scale!;
    return this;
  }

  async _create() {
    const canvas = await this.generateCanvas(this.options);
    this.sprite = this.makeCanvasSprite(canvas, this.options);
    return this.sprite;
  }

  setPosition(position: Vector3) {
    this.sprite && this.sprite.position.copy(position);
    this.map.reDraw();
  }

  private generateCanvas({
    icon,
    scale = 1
  }: IOptions): Promise<HTMLCanvasElement> {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d')!;
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => {
        const w = img.width * scale;
        const h = img.height * scale;
        // 根据文字内容获取宽度
        canvas.width = w * this._scale;
        canvas.height = h * this._scale;
        // canvas.width = w;
        // canvas.height = h;
        context.drawImage(img, 0, 0, canvas.width, canvas.height);
        resolve(canvas);
      };
      img.src = icon;
    });
  }

  private makeCanvasSprite(
    canvas: HTMLCanvasElement,
    { name, renderOrder, position }: IOptions
  ) {
    const texture = new Texture(canvas);
    texture.needsUpdate = true;
    const spriteMaterial = new SpriteMaterial({
      map: texture,
      transparent: true,
      depthTest: false,
      // depthTest: this.depthTest,
      depthWrite: false
    });
    const sprite = new Sprite(spriteMaterial);
    // sprite.name = OBJECT_NAME.POILabel
    sprite.name = name;
    // sprite.userData.name = name

    sprite.renderOrder = renderOrder;

    sprite.center = new Vector2(0.5, 0);
    sprite.position.copy(position);
    // sprite.position.z += 10
    // this.group.add(sprite)
    // reDraw()
    return sprite;
  }
}
