import M3 from "../modules/M3.js";

var vsh = `#version 300 es
    uniform mat3 u_matrix;
    uniform vec2 sPoint;
    uniform vec2 vector;
    uniform float thickness;
    uniform float t;
    void main(){
        vec3 position; 
        int id = gl_VertexID;
        vec2 v = normalize(vector);
        vec2 normal = thickness * vec2(v.y, -v.x);
        if(id == 0 || id == 5)
            position = vec3(sPoint - normal, 1);
        else if(id == 1)
            position = vec3(sPoint + ((t * v) - normal), 1);
        else if(id == 2 || id == 3)
            position = vec3(sPoint + ((t * v) + normal), 1);
        else
            position = vec3(sPoint + normal, 1);

        position =  u_matrix * position;
        gl_Position = vec4(position.xy, 0, 1);
    }
`;
var fsh = `#version 300 es
    precision highp float;

    uniform vec4 color;

    out vec4 glColor;

    void main(){
        glColor = normalize(color);
    }
`; 
/**
 * Clase que define la geometría de una línea 2D dada su definición 
 * paramétrica.
 * @author Melissa Méndez Servín.
 */
export default class Line2D{
    constructor(gl, WebGL, sPoint, vector, t, unit, thickness, color){ 
        if (WebGL.programs["Line2D"])
            this.program = WebGL.programs["Line2D"];
        else
            this.program = WebGL.createProgram(gl, vsh, fsh, "Line2D");
        this.vao = gl.createVertexArray();
        gl.bindVertexArray(this.vao);   
        gl.bindVertexArray(null); 

        this.setUniforms = WebGL.setUniforms(gl, this.program);
        
        this.vector = [vector.x, vector.y];
        this.sPoint = (sPoint) ? [sPoint.x, sPoint.y] : [0,0];
        this.t = t;
        this.color = color || [ 95, 95, 95, 255];
        this.uniforms = {   
                            color: this.color,
                            thickness : (thickness) ? thickness * 0.02 : 0.06
                        }; 
        this.scaleMatrix = M3.scale(unit, unit);               
    }

    draw(gl, projectionMatrix, t, sPoint=null, vector=null, color){
        gl.useProgram(this.program);
        gl.bindVertexArray(this.vao);

        this.uniforms.u_matrix = M3.multiply(projectionMatrix, this.scaleMatrix);
        this.uniforms.t = (t) ? t : this.t;
        this.uniforms.color = (color) ? color : this.color;
        this.uniforms.sPoint = (sPoint) ? [sPoint.x, sPoint.y] : this.sPoint;
        this.uniforms.vector = (vector) ? [vector.x, vector.y] : this.vector;
        
        this.setUniforms(this.uniforms);
        gl.drawArrays(gl.TRIANGLES, 0,  6);
    }

}