"use strict";

import * as Utils from "../../modules/HTMLUtils.js";
import WebGL from "../../modules/WebGLUtils.js";
import M4 from "../../modules/M4.js";
import GeometryPainter from "../../geometry/GeometryPainter.js";
import Cube from "../../geometry/Cube.js";
import VertexColor from "../../materials/VertexColor.js";

/**
 * Transformaciones en 3D: Escalamiento, rotación y traslación.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

var translation = [0,0,0];
var scale = [1,1,1];
var angle = [10,35,0];

function main(){
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
    
    let cubeFigure = new Cube(100, 0);
    let cube = new GeometryPainter(gl, new VertexColor(gl, WebGL, cubeFigure, true));
 
    //HTML CONTROLS
    let controls = document.getElementById("ui-container");
    controls.className = "right-box";

    const offset = 50;
    const size = 100;
    Utils.resize(canvas);
    var {width, height} = gl.canvas;
    
    let boundary = { l: -width/2 + offset, r: width/2 - offset, 
                     t: height/2 - offset, b: -height/2 + offset};
    
    const widthScale = width/size;
    const heightScale = height/size;

    let sliders = [ new Utils.Slider(controls, "T<sub>x</sub>", boundary.l , boundary.r , updateTranslation(0), translation[0]),
                    new Utils.Slider(controls, "T<sub>y</sub>", boundary.b, boundary.t, updateTranslation(1), translation[1]),
                    new Utils.Slider(controls, "T<sub>z</sub>", boundary.b, boundary.t, updateTranslation(2), translation[2]),
                    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, "S<sub>z</sub>", - heightScale, heightScale, updateScale(2), scale[2], 0.1),
                    new Utils.Slider(controls, "φ<sub>x</sub>", 0, 360, updateRotation(0), angle[0]),
                    new Utils.Slider(controls, "φ<sub>y</sub>", 0, 360, updateRotation(1), angle[1]),
                    new Utils.Slider(controls, "φ<sub>z</sub>", 0, 360, updateRotation(2), angle[2])
                    ];
    
    Utils.createResetButton(reset);

    window.addEventListener('resize', draw);
    
    gl.enable(gl.CULL_FACE);
    gl.clearColor(0, 0, 0, 0);
    draw();

    function draw(){
        Utils.resize(canvas);
        var {width, height} = gl.canvas;

        gl.viewport(0, 0, width, height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER);
             
        let boundary = { l: -width/2, r: width/2, 
                         t: height/2, b: -height/2,
                         n: 500, f: -500
                        };
        var projectionMatrix = M4.ortho(boundary.l, boundary.r, boundary.t, boundary.b, boundary.n, boundary.f);
        
        var translationMatrix = M4.translate(translation[0], translation[1], translation[2]);
        let rotationMatrix = M4.multiply(M4.rotateZ(angle[2]), M4.multiply(M4.rotateY(angle[1]), M4.rotateX(angle[0])));          
        var scaleMatrix = M4.scale(scale[0], scale[1], scale[2]);

        var modelMatrix = M4.multiply(translationMatrix, M4.multiply(rotationMatrix, scaleMatrix));

        cube.drawSimple(gl, modelMatrix, projectionMatrix);       
    }

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