"use strict";

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

/**
 * Transformaciones en 2D: Escalamiento, rotación y traslación.
 * @author Melissa Méndez Servín.
 */
var vsh = `#version 300 es
            uniform mat3 u_matrix;

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

            void main(){
                color = a_color;
                
                vec3 position =  u_matrix * vec3(a_position,1);

                gl_Position = vec4(position.xy, 0, 1);
            }
            `;
var fsh = `#version 300 es
            precision highp float;
            
            in vec4 color;
            
            out vec4 glColor;
            
            void main(){
                glColor = color;
            }
            `;

window.addEventListener("load", main);

var translation = [0,0];
var scale = [1,1];
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);
    //Triángulo posicionado en el centro
    var attributes = {  position:   { numComponents: 2,
                                      data: [-35, -35,
                                              70, -35, 
                                             -35, 70]},
                          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 matrixU = gl.getUniformLocation(program, "u_matrix");
    //Grid
    Utils.resize(canvas);
    var grid = new Grid(gl, 35, true);
    
    //HTML CONTROLS
    let controls = document.getElementById("ui-container");
    controls.className = "right-box";

    const offset = 100;
    var {width, height} = gl.canvas;
    let boundary = { l: -width * (3/8), r: width * (5/8), 
        t: height * (5/8), b: -height * (3/8)};
    const widthScale = boundary.r/offset;
    const heightScale = boundary.t/offset;

    let sliders = [        new Utils.Slider(controls, "T<sub>x</sub>", Math.floor(boundary.l) , Math.floor(boundary.r) - offset, updateTranslation(0), translation[0],1),
                           new Utils.Slider(controls, "T<sub>y</sub>", Math.floor(boundary.b), Math.floor(boundary.t) - offset, updateTranslation(1), translation[1],1),
                           new Utils.Slider(controls, "S<sub>x</sub>", - widthScale, widthScale, updateScale(0), scale[0], 0.1),
                           new Utils.Slider(controls, "S<sub>y</sub>", - heightScale, heightScale, updateScale(1), scale[1], 0.1),
                           new Utils.Slider(controls, "φ", 0, 360, updateRotation, phi)];

    Utils.createResetButton(reset);

    let checkbox = new Utils.Checkbox(controls, "Grid", "Cuadrícula", draw);

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

    function draw(){
        Utils.resize(canvas);
        var {width, height} = gl.canvas;
        let boundary = { l: -width * (3/8), r: width * (5/8), 
                     t: height * (5/8), b: -height * (3/8)};
        
        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(boundary.l, boundary.r, boundary.t, boundary.b );
        var translationMatrix = M3.translate(translation[0],translation[1]);
        var rotationMatrix = M3.rotate(phi);
        var scaleMatrix = M3.scale(scale[0],scale[1]);

        let matrix = M3.multiply(translationMatrix, M3.multiply(rotationMatrix, scaleMatrix));
        //Con respecto al origen
        //let matrix = M3.multiply(scaleMatrix, M3.multiply(rotationMatrix, translationMatrix));
        matrix = M3.multiply(projectionMatrix, matrix);
        gl.uniformMatrix3fv(matrixU, false, matrix);

        gl.drawArrays(gl.TRIANGLES,0,3);        
    
        //Grid
        if(checkbox.checked())    
            grid.draw(gl, boundary);  
    }

    function updateScale(index){
        return function(value){
            scale[index] = value;
            draw();
        };
    }
    function updateRotation(value){
        phi = value;
        draw();
    }
    function updateTranslation(index){
        return function(value){
            translation[index] = value;
            draw();
        };
    }
    function reset(){
        scale = [1,1];
        translation = [0,0];
        phi = 0;
        for(var i = 0; i< sliders.length; i++){
            sliders[i].updateSlider(sliders[i].initValue);
        }
        draw();
    }
}