import WebGL from "../modules/WebGLUtils.js";
import M4 from "../modules/M4.js";

var vsh = `#version 300 es
            uniform mat4 PV_matrix;
            uniform int numLines;
            uniform int size;
            uniform vec4 axisColor;
            uniform vec4 gridColor;
            uniform vec2 center;
            uniform float y_coord;

            out vec4 lineColor;
            
            void main(){
                int extr = (gl_VertexID % 2) * 2 - 1;
                float step = float(int((gl_VertexID % numLines)/2)) - float(numLines/4);
                vec4 pos = vec4(extr * size, y_coord, step, 1);
                if(gl_VertexID > numLines)
                    pos = pos.zyxw;
                
                gl_Position = PV_matrix * pos;

                //Eje XY 
                if(pos.x == center.x || pos.z == center.y)
                    lineColor =  normalize(axisColor);
                else
                    lineColor = normalize(gridColor);
            }`;
var fsh = `#version 300 es
            precision highp float;
            
            in vec4 lineColor;
            out vec4 glColor;

            void main(){
                glColor = lineColor;
            }
            `;
            
/**
 * GridXZ.
 * Clase que dibuja una rejilla definida por en los 
 * ejes X y Z de un espacio 3D.
 * @author Melissa Méndez Servín.
 */
export default class GridXZ{
    /**
     * Dibuja un plano cartesiado estático (o rejilla) XZ ajustado de acuerdo al 
     * tamaño del canvas y el clipspace. 
     * @param {WebGLRenderingContext} gl el WebGLRenderingContext sobre el cual se 
     *                                   construirá el plano.
     * @param {Number} unit la unidad con la que se creará el plano.
     * @param {Object} basis constructor con los vectores base definidos como x y y. 
     */
    constructor(gl, numVertices=68, y_coord= 0, colors=null, center=null){
        if(!gl) return;

        this.program = WebGL.createProgram(gl,vsh,fsh);
        this.vao = gl.createVertexArray();
        this.numVertices = numVertices;
        this.size = Math.floor(this.numVertices/8);
        gl.bindVertexArray(this.vao);   
        gl.bindVertexArray(null); 
        const center_axis = center || [0,0];
        //Uniforms que no cambian.
        this.uniforms = { y_coord : y_coord, 
                             size : this.size,
                         numLines : this.numVertices/2,
                      numVertices : this.numVertices, 
                        gridColor : [123, 143, 159, 255],
                        axisColor : [0, 0, 0, 255],
                        center : center_axis
                        };
        if(colors){
            if(colors.length > 1)
                this.uniforms.axisColor = colors[1];
            if(colors[0] != null)
                this.uniforms.gridColor = colors[0];
        }

        this.setUniforms = WebGL.setUniforms(gl, this.program);
    }
    /**
     * Renderiza la cuadrícula.
     * limits = { width: viewportWidth, height: viewportHeight,
     *            l: left, r: right, t: top, b: bottom};
     * @param {WebGLRenderingContext} gl el WebGLRenderingContext sobre el cual se 
     *                                   construirá el plano.
     * @param {Object} limits (opcional) medidas para la proyección (clipspace) y/o 
     *                         del viewport.
     */
    draw(gl, viewMatrix, projectionMatrix, basis, axis){
        gl.useProgram(this.program);
        gl.bindVertexArray(this.vao);
 
        let PV_matrix = M4.multiply(projectionMatrix, viewMatrix);
        ///var vecZero = M4.multiplyVector(PV_matrix,[0,0,0,1]);
        
        this.uniforms.PV_matrix = PV_matrix;
        this.setUniforms(this.uniforms);
        
        gl.drawArrays(gl.LINES, 0, this.numVertices);
    }
}