import { Animator } from "./Animator";
import { Layer, LayerAB, Scene } from "./Scene";
import { createProgram, createShader } from "./utils";




export class Triangle extends LayerAB {


  private vertexShaderCode = /*glsl*/ `
    attribute vec2 a_position;
    uniform mat4 u_matrix; 
    void main() {
      gl_Position = u_matrix * vec4(a_position, 0, 1);
    }
  `

  private fragmentShaderCode = /*glsl*/ `
    precision mediump float;
    uniform float u_alpha; 

    void main() {
      gl_FragColor = vec4(1, 0, 0, u_alpha);
    }
  
  `

  program: WebGLProgram;

  positionLoc: number
  uMatrixLoc: WebGLUniformLocation
  uAlphaLoc: WebGLUniformLocation


  positionBuffer: WebGLBuffer

  constructor(private scene: Scene) {
    super()

    const gl = scene.gl
    this.program = createProgram(gl,
      createShader(gl, gl.VERTEX_SHADER, this.vertexShaderCode)!,
      createShader(gl, gl.FRAGMENT_SHADER, this.fragmentShaderCode)!)!


    this.positionLoc = gl.getAttribLocation(this.program, 'a_position');
    this.uMatrixLoc = gl.getUniformLocation(this.program, "u_matrix")!!;
    this.uAlphaLoc = gl.getUniformLocation(this.program, 'u_alpha')!!;

    this.positionBuffer = gl.createBuffer()!;
    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
      0, 0,
      0, 100,
      100, 0,
      100, 0,
      0, 100,
      100, 100
    ]), gl.STATIC_DRAW);
  }



  private colorAnimator: Animator | null = null

  private alpha: number = 1


  override tap(cx: number, cy: number, sx: number, sy: number): void {
    this.colorAnimator?.cancel()

    this.colorAnimator = new Animator(1000, (ani) => {
      this.alpha = 1 - ani.progress
    }, () => {
      this.alpha = 1
    })
    this.scene.addAnimator(this.colorAnimator)
  }


  draw() {
    const gl = this.scene.gl
    gl.useProgram(this.program)
    gl.enableVertexAttribArray(this.positionLoc)
    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer)
    gl.vertexAttribPointer(this.positionLoc, 2, gl.FLOAT, false, 0, 0)

    gl.uniformMatrix4fv(this.uMatrixLoc, false, this.scene.drawMatrix)
    gl.uniform1f(this.uAlphaLoc, this.alpha)

    gl.drawArrays(gl.TRIANGLES, 0, 6);
  }

}