import * as Utils from "../../modules/HTMLUtils.js";
import WebGL from "../../modules/WebGLUtils.js";
import M3 from "../../modules/M3.js";
import Grid from "../../geometry/Grid.js";
import Vector2D from "../../geometry/Vector2D.js";
import V2 from "../../modules/V2.js";

/**
 * Transformación 2D: Escalamiento.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

var vsh = `#version 300 es
            uniform mat2 u_scale;
            //Para ajustar los puntos dentro del clipspace
            uniform mat3 u_projection;

            in vec4 a_color; 
            in vec2 a_position;
            
            out vec4 color;

            void main(){
                color = a_color;

                vec2 sPosition = u_scale * a_position;
                vec3 resizedPos = u_projection * vec3(sPosition,1);
              
                gl_Position = vec4(resizedPos.xy, 0, 1);
            }
            `;
var fsh = `#version 300 es
            precision highp float;
            
            in vec4 color;
            
            out vec4 glColor;
            
            void main(){
                glColor = color;
            }
            `;

var scale = [1,1];
function main(){
    document.body.style.backgroundColor = "white"; 
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;

    var program = WebGL.createProgram(gl,vsh,fsh);

    var attributes = {  position:   { numComponents: 2,
                                        data: [   0,   0,
                                                100,   0, 
                                                  0, 100]},
                          color:    { numComponents: 4, 
                                      type: gl.UNSIGNED_BYTE, 
                                      normalize: true, 
                                      dataType: Uint8Array,
                                      data: [ 22, 177, 176, 255,
                                                 22, 164, 133, 255,
                                                129, 90, 134, 255 ]}
                    };
    
    var vao = WebGL.setVAOAndAttributes(gl, program, attributes);    
    
    var projectionU = gl.getUniformLocation(program, "u_projection");
    var scaleU = gl.getUniformLocation(program, "u_scale");
    
    //Grid
    Utils.resize(canvas);
    const unit = 50;
    const gridColor = [50, 73, 90, 255];
    var grid = new Grid(gl, unit);
    var gridBasis = new Grid(gl, unit, false, null, [gridColor]);
    
    //Vectores base
    const xColor = [19, 41, 61, 255]; 
    const yColor = [44, 34, 91, 255]; 
    let xBasis  = new V2(1, 0);
    let yBasis  = new V2(0, 1);
    let x = new Vector2D(gl, WebGL, null, xBasis, unit, 2, xColor);
    let y = new Vector2D(gl, WebGL, null, yBasis, unit, 2, yColor);

    //HTML CONTROLS
    let controls = document.getElementById("ui-container");
    controls.className = "right-box";
    
    let t_measure = 200; 
    let widthScale =gl.canvas.width/t_measure;
    let heightScale = gl.canvas.height/t_measure;
    let sliderX = new Utils.Slider(controls, "S<sub>x</sub>", - widthScale, widthScale, updateScale(0), scale[0], 0.1);
    let sliderY = new Utils.Slider(controls, "S<sub>y</sub>", - heightScale, heightScale, updateScale(1), scale[1], 0.1);
    
    let checkbox = new Utils.Checkbox(controls, "Grid", "Cuadrícula", draw);
    let checkboxBasis = new Utils.Checkbox(controls, "Grid", "Cuadrícula Transformada", draw);
    
    Utils.createResetButton(reset);

    draw();
    window.addEventListener('resize', draw);

    function draw(){
        Utils.resize(canvas);

        const {width, height} = gl.canvas;
        gl.viewport(0, 0, width, height);
        gl.clearColor(0, 0, 0, 0);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER);
        
        gl.useProgram(program);
        gl.bindVertexArray(vao);

        var projectionMatrix = M3.projection(-width/2, width/2, height/2, -height/2);
        gl.uniformMatrix3fv(projectionU, false, projectionMatrix);
        
        gl.uniformMatrix2fv(scaleU, false, getScale());
        
        gl.drawArrays(gl.TRIANGLES,0,3);
        
        //Grid
        if(checkbox.checked())
            grid.draw(gl);
        if(checkboxBasis.checked()){
            var xVector = xBasis.scale(scale[0]);
            var yVector = yBasis.scale(scale[1]);
            gridBasis.draw(gl, null, {x: xVector, y: yVector});
            x.draw(gl, projectionMatrix, null, xVector);
            y.draw(gl, projectionMatrix, null, yVector);
        }
        
    }

    function getScale(){
        return [ scale[0], 0, 
                 0, scale[1]];
    }
    function updateScale(index){
        return function(value){
            scale[index] = value;
            draw();
        };
    }
    function reset(){
        scale = [1,1];
        sliderX.updateSlider(scale[0]);
        sliderY.updateSlider(scale[0]);
        draw();
    }
}