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

/**
 * Ejemplo de Transformación 2D. Rotación de cuadrado sobre su baricentro.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

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

    var srcTexture = '../../../images/capitulo_04/fave_c.png';
    
    const unit = 40;
    //console.log(unit);
    var rparams = { sPoint: new V2(-0.5,-0.5), width: 1, height: 1};
    var model = new Figure2D(gl, WebGL, 'rect', 1, null, rparams, srcTexture);
    var grid = new Grid(gl, unit);

    //HTML CONTROLS
    let labelPosition = {top: 0, left: 0};
    let container = document.getElementById("container");
    let step_label = Utils.createMathBox(container, labelPosition);
    var fave = "Dibujo por Diego Favela";
    let ccLabel = new Utils.TextBox(container, { right: 1, bottom: 0}, fave);
    
    let sequenceOfSteps = function*(){
        while(true){
            yield 'start';
            yield 'to_origin';
            yield 'rotate';
            yield 'back';
        }
    }
    let sequence = sequenceOfSteps();
    let step = sequence.next().value;
    let angle = 0;
    let max_angle = 45;
    let wait_time = 1.5;
    let time = 0;
    
    Utils.resize(canvas);
    // Matrices de transformación
    var centerPoint = {x: -150, y: -50};
    let scale = M3.scale(113.4, 133.6); //Escala del dibujo
    var initialPosition = M3.multiply(M3.translate(centerPoint.x, centerPoint.y), scale);
    var translateToOrigin = M3.multiply(M3.translate(-centerPoint.x, -centerPoint.y), initialPosition);
    var rotateMatrix = M3.multiply(M3.rotate(max_angle), translateToOrigin);
    var translateBack = M3.multiply(M3.translate(centerPoint.x, centerPoint.y), rotateMatrix);
    
    var then = 0;

    requestAnimationFrame(draw);
    // Para la ejecución correcta de la animación al hacer un resize.
    window.addEventListener('resize', function(){
        if (!window.requestAnimationFrame){
            window.requestAnimationFrame(draw);
        }
        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function() {
                time = 0;
        };
    });

    function draw(current){
        Utils.resize(canvas);
        
        var {width, height} = gl.canvas;
        gl.viewport(0, 0, width, height);
        
        current *= 0.001;

        var delta_time = current - then;
        then = current;
        
        let boundary = { l: -width * (7/12), r: width * (5/12),
                         t: height * (4/10), b: -height * (6/10)};
        
        var projectionMatrix =  M3.projection(boundary.l, boundary.r, boundary.t, boundary.b);
        let currentMatrix = getCurrentMatrix(delta_time);
        //Dibuja el modelo con la matrix de transformación actual
        grid.draw(gl, boundary); 
        model.draw(gl, currentMatrix, projectionMatrix);   
        time += delta_time;

        requestAnimationFrame(draw);
    }

    function getCurrentMatrix(delta_time){
        if(step == 'rotate'){
            angle += (10 * delta_time);//Actualizamos el ángulo
        }
        //Esperamos
        if(time >= wait_time && step != 'rotate'){ 
            time = 0;
            step = sequence.next().value;
        }
        return getMatrixByStep(delta_time);
    }

    function getMatrixByStep(){
        switch(step){
            case 'start':
                Utils.setMathBox(step_label, ""); 
                return initialPosition;
            case 'to_origin':
                Utils.setMathBox(step_label, "\\mathbf{T}(C_x,C_y)"); 
                return translateToOrigin;
            case 'rotate':
                Utils.setMathBox(step_label, "\\mathbf{T}(C_x,C_y) \\  \\mathbf{R}(" + Math.floor(angle) + " \\degree)"); 
                if( angle >= max_angle){
                    var rotate = M3.rotate(max_angle);
                    angle = 0;
                    time = 0;
                    step = sequence.next(step).value;
                    return rotateMatrix;
                }
                var rotate = M3.rotate(angle);
                return M3.multiply(rotate, translateToOrigin);
            default:
                let math_text = "\\mathbf{T}(C_x,C_y) \\  \\mathbf{R}(" + max_angle + " \\degree)" + "\\ \\mathbf{T}(-C_x,-C_y)";
                Utils.setMathBox(step_label, math_text); 
                return translateBack;
        }
    }

}