import * as MU from "../modules/MathUtils.js";
import M3 from "../modules/M3.js";

var vsh = `#version 300 es
    uniform mat3 u_matrix;
    uniform vec2 sPoint;
    uniform vec2 vector;
    uniform float thickness;
    void main(){
        vec3 position; 
        int id = gl_VertexID;
        //Posición final del vector dado el punto inicial
        vec2 ePoint = sPoint + vector;
        if(id < 8){
            vec2 normal = normalize(vec2(vector.y, -vector.x));
            // Escalamos la normal de acuerdo al grosor dado
            if(id < 6) //Grosor rectángulo
                normal = thickness * normal;
            else      //Grosor flecha
                normal = 3.0 * thickness * normal;

            if(id == 0 || id == 5)
                position = vec3(sPoint - normal, 1); //LS
            else if(id == 1)
                position = vec3(sPoint + normal, 1); //RS
            else{
                float t = (length(vector) - (thickness * 7.0))/ length(vector);
                //Donde empieza la flecha (ahora termina el rectángulo)
                vec2 sArrow = mix(sPoint, ePoint, t);
                if(id == 2 || id == 3 || id == 7)
                    position = vec3(sArrow + normal, 1); //RE
                else
                    position = vec3(sArrow - normal, 1); //LE
            }
        }else{//Punta de la flecha
            position = vec3(ePoint, 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 = color/255.0;
    }
`; 

/**
 * Renderiza un vector o flecha 2D, dada su definición paramétrica.
 * @author Melissa Méndez Servín.
 */
export default class Vector2D{

    constructor(gl, WebGL, sPoint, vector, unit, thickness, color){ 
        if (WebGL.programs["Vector2D"])
            this.program = WebGL.programs["Vector2D"];
        else
            this.program = WebGL.createProgram(gl, vsh, fsh, "Vector2D");
        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.color = color || [MU.randomInt(255), MU.randomInt(255), MU.randomInt(255), MU.randomInt(255)],
        this.sPoint = (sPoint) ? [sPoint.x, sPoint.y] : [0,0];
        this.uniforms = {   
                            thickness : thickness * 0.02 || 0.06
                        }; 
        this.scaleMatrix = M3.scale(unit, unit);               
    }

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

        this.uniforms.u_matrix = M3.multiply(projectionMatrix, this.scaleMatrix);
        this.uniforms.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,  9);
    }
}