import { DEFAULT_CANVAS_SIZE, WEBGL_CONTEXT_ATTRIBUTES } from '../constant';
import { BackendContext } from './backend-context';

export class GlobalCanvas {
  private _canvas: HTMLCanvasElement | OffscreenCanvas | null = null;
  private _glContext: BackendContext | null = null;
  private width = DEFAULT_CANVAS_SIZE;
  private height = DEFAULT_CANVAS_SIZE;
  private retainCount = 0;

  public retain() {
    if (this.retainCount === 0) {
      try {
        this._canvas = new OffscreenCanvas(0, 0);
      } catch (error) {
        this._canvas = document.createElement('canvas');
      }
      this._canvas.width = this.width;
      this._canvas.height = this.height;

      const gl = this._canvas.getContext('webgl', WEBGL_CONTEXT_ATTRIBUTES) as WebGLRenderingContext;
      if (!gl) throw new Error('Canvas context is not WebGL!');
      this._glContext = BackendContext.from(gl);
    }
    this.retainCount += 1;
  }

  public release() {
    this.retainCount -= 1;
    if (this.retainCount === 0) {
      if (!this._glContext) return;
      this._glContext.destroy();
      this._glContext = null;
      this._canvas = null;
    }
  }

  public get canvas() {
    return this._canvas;
  }

  public get glContext() {
    return this._glContext;
  }

  public setCanvasSize(width = DEFAULT_CANVAS_SIZE, height = DEFAULT_CANVAS_SIZE) {
    this.width = width;
    this.height = height;
    if (this._glContext && this._canvas) {
      this._canvas.width = width;
      this._canvas.height = height;
    }
  }
}
