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 V2 from "../../modules/V2.js";
import Vector2D from "../../geometry/Vector2D.js";

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

var vsh = `#version 300 es
            uniform mat2 u_rotation;
            //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 rPosition =  u_rotation * a_position;
                vec3 resizedPos = u_projection * vec3(rPosition,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 phi = 0;
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 rotationU = gl.getUniformLocation(program, "u_rotation");

    //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 sliderPhi= new Utils.Slider(controls, "φ", 0, 360, updateRotation, phi);
    let checkbox = new Utils.Checkbox(controls, "Grid", "Cuadrícula", draw, true);
    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);

        var rotationMatrix = getRotation();
        gl.uniformMatrix2fv(rotationU, false, rotationMatrix);

        gl.drawArrays(gl.TRIANGLES,0,3);
        
        //Grid
        if(checkbox.checked())
            grid.draw(gl);
        if(checkboxBasis.checked()){
            var xVector = xBasis.multiply2DM(rotationMatrix);
            var yVector = yBasis.multiply2DM(rotationMatrix);
            gridBasis.draw(gl, null, {x: xVector, y: yVector});
            x.draw(gl, projectionMatrix, null, xVector);
            y.draw(gl, projectionMatrix, null, yVector);
        }
    }
    /**
     * [ cos (\phi) -sin (\phi)
     *   sin (\phi)  cos (\phi)] 
     */
    function getRotation(){
        var phiToRadians = phi * (Math.PI / 180);
        var cos = Math.cos(phiToRadians);
        var sin = Math.sin(phiToRadians);
        return [cos, sin,
                -sin,cos];
    }

    function updateRotation(value){
        phi = value;
        draw();
    }
    
    function reset(){
        phi = 0;
        sliderPhi.updateSlider(phi);
        draw();
    }
}