import { compileShader, linkProgram } from "./shader";
let shader;
export class PolygonDraw {
    _generate(gl, points) {
        if (!this._vbo) {
            this._vbo = gl.createBuffer();
        }
        if (!this._vbo)
            throw new Error("Unable to create buffer object");
        gl.bindBuffer(gl.ARRAY_BUFFER, this._vbo);
        gl.bufferData(gl.ARRAY_BUFFER, points, gl.DYNAMIC_DRAW);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        return this._vbo;
    }
    drawPolygon(gl, projectionMatrix, cameraMatrix, targetMatrix, points) {
        let shader = getShader(gl);
        let v = this._generate(gl, points);
        gl.disable(gl.DEPTH_TEST);
        gl.disable(gl.SCISSOR_TEST);
        gl.disable(gl.CULL_FACE);
        gl.disable(gl.STENCIL_TEST);
        gl.disable(gl.BLEND);
        gl.useProgram(shader.prog);
        gl.uniformMatrix4fv(shader.unif_proj, false, projectionMatrix);
        gl.uniformMatrix4fv(shader.unif_camera, false, cameraMatrix);
        gl.uniformMatrix4fv(shader.unif_matrix, false, targetMatrix);
        gl.bindBuffer(gl.ARRAY_BUFFER, v);
        gl.vertexAttribPointer(shader.attr_position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(shader.attr_position);
        gl.drawArrays(gl.LINE_LOOP, 0, points.length / 2);
        gl.disableVertexAttribArray(shader.attr_position);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
    }
}
let vertexShaderSrc = `
#ifndef GL_ES
#define highp
#define mediump
#define lowp
#endif

uniform mat4 projMatrix;
uniform mat4 cameraMatrix;
uniform mat4 modelViewMatrix;
attribute vec2 position;

void main()
{
    gl_Position = projMatrix * cameraMatrix * modelViewMatrix * vec4(position.x, 0.0, position.y, 1.0);
}`;
let fragmentShaderSrc = `
#define highp mediump
#ifdef GL_ES
    // define default precision for float, vec, mat.
    precision highp float;
#else
#define highp
#define mediump
#define lowp
#endif

void main()
{
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}`;
function getShader(gl) {
    if (shader)
        return shader;
    let prog = gl.createProgram();
    if (!prog)
        throw new Error("Unable to create program");
    let vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexShaderSrc);
    let fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSrc);
    gl.attachShader(prog, vertexShader);
    gl.attachShader(prog, fragmentShader);
    linkProgram(gl, prog);
    let unif_proj = gl.getUniformLocation(prog, "projMatrix");
    if (!unif_proj)
        throw new Error("Unable to get uniform location projMatrix");
    let unif_matrix = gl.getUniformLocation(prog, "modelViewMatrix");
    if (!unif_matrix)
        throw new Error("Unable to get uniform location modelViewMatrix");
    let unif_camera = gl.getUniformLocation(prog, "cameraMatrix");
    if (!unif_camera)
        throw new Error("Unable to get uniform location cameraMatrix");
    shader = {
        prog,
        unif_matrix,
        unif_proj,
        unif_camera,
        attr_position: gl.getAttribLocation(prog, "position"),
    };
    return shader;
}
