import {getDisconnectedVertices} from "../geometry/Figure.js";

/**
 * Programa de sombreado de un mapeo de textura simple.
 * Permite aplicar una wrapping function y configurar los filtros.
 * @author Melissa Méndez Servín.
 */
export default class Texture {

    constructor(gl, WebGL, figure, srcTexture, draw_callback, mipmap=true, filters={}){
        var vsh = `#version 300 es
            uniform mat4 u_PVM_matrix;
            uniform mat3 u_texture_matrix;

            in vec4 a_position;
            in vec2 a_texcoord;

            out vec2 v_texcoord;

            void main(){
                
                gl_Position =  u_PVM_matrix * a_position;
                vec3 texcoord = u_texture_matrix * vec3(a_texcoord,1.);
                v_texcoord = texcoord.xy;
            }
            `;
        var fsh = `#version 300 es
            precision highp float;
            
            uniform sampler2D u_texture;
            uniform int clamp_to_border_S;
            uniform int clamp_to_border_T;

            in vec2 v_texcoord;

            out vec4 glColor;
            
            void main(){
                if(clamp_to_border_S == int(1.0) && (v_texcoord.x > 1.0 || v_texcoord.x < 0.0))
                        glColor = vec4(0.9,0.9,0.98,1.0);
                else if(clamp_to_border_T == int(1.0) && (v_texcoord.y > 1.0 || v_texcoord.y < 0.0))
                        glColor = vec4(0.9,0.9,0.98,1.0);
                else
                    glColor = texture(u_texture, v_texcoord);
            }
            `; 
        if (WebGL.programs["Texture"])
            this.program = WebGL.programs["Texture"];
        else
            this.program = WebGL.createProgram(gl, vsh, fsh, "Texture");
            
        let vertices = (figure.byIndices) ?  figure.getVertices() : getDisconnectedVertices(figure.getVertices(), figure.getFaces());
        
        let attributes = {  position: { numComponents: 3, 
                                                    data: vertices},
                            texcoord: { numComponents: 2, 
                                                data: figure.getTexCoordinates(),
                                            normalize: true}
                            };
        if(figure.byIndices){
            let vaoAndIndices = WebGL.setVAOAndAttributes(gl, this.program, attributes, figure.getFaces());
            this.vao = vaoAndIndices.vao;
            this.indexBuffer = vaoAndIndices.indexBuffer;
            this.numIndices = figure.numIndices;
        }else{
            this.vao = WebGL.setVAOAndAttributes(gl, this.program, attributes);  
            this.numElements = attributes.position.data.length/3;
        }
        this.setUniforms = WebGL.setUniforms(gl, this.program);
    
        if(mipmap)
            this.texture = WebGL.loadImageTexture(gl, srcTexture, draw_callback, filters);
        else 
            this.texture = WebGL.loadImageTextureNoMipmap(gl, srcTexture, draw_callback);

        this.uniforms = { u_texture : {id:0, texture : this.texture}, 
                          clamp_to_border_S: 0, clamp_to_border_T: 0,
                          u_texture_matrix: [1,0,0,0,1,0,0,0,1]};
    }
}