"use strict";

import {MathBox, resize, Slider} from "../../modules/HTMLUtils.js";
import WebGL from "../../modules/WebGLUtils.js";
import M4 from "../../modules/M4.js";
import Diffuse from "../../materials/Diffuse.js";
import { Sphere } from "../../geometry/Figure.js";
import { cos, sin} from "../../modules/MathUtils.js";
import Vector3D from "../../geometry/Vector3D.js";
import GeometryPainter from "../../geometry/GeometryPainter.js";
import {TrackballCamera, registerCameraEvents} from "../../modules/Trackballcamera.js";
import V3 from "../../modules/V3.js";
import GridXZ from "../../geometry/GridXZ.js";

/**
 * Rotación sobre un eje arbitrario 3D.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

let angle = .8;
let theta = angle * Math.PI;
function main(){
    let container = document.getElementById("container");
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
   
    let gridXZ = new GridXZ(gl,84);

    let sphereFigure = new Sphere(.05, 10, 10);
    
    let lightPosition = [0, -.5, 1, 0];
    let centerUniforms = {u_color: [1,0,1,1]};

    let arbitraryAxis = new V3(1,1,-1);
    let a_axis = arbitraryAxis.normalize();
    let vPos = new V3(2.1,.85,-1);
    let vParallel = a_axis.scale(vPos.dotProduct(a_axis));
    let vPerpendicular = vPos.sub(vParallel);
    let aCrossV = vPos.cross(a_axis);
    let vPerpPrime = vPerpendicular.scale(cos(theta)).add(aCrossV.scale(sin(theta)));
    let vRotated = vPerpPrime.add(vParallel);

    let a_label = new MathBox(container, {}, "\\color{#FF00FF}\\mathbf{a}");
    let v_label = new MathBox(container, {}, "\\color{#006400}\\mathbf{v}");
    let a = new Vector3D(gl, WebGL, a_axis, null, .12, [1,0,1,1], lightPosition, a_label);
    let v = new Vector3D(gl, WebGL, vPos, null, .08, [0,.5,0,1], lightPosition, v_label);
    
    let vPar_label = new MathBox(container, {}, "\\color{#9ACD32}\\mathbf{v}_{\\parallel}");
    let vPerp_label = new MathBox(container, {}, "\\color{#FF1932}\\mathbf{v}_{\\perp}");
    let vPerpPrime_label = new MathBox(container, {}, "\\color{#FFD700}\\mathbf{v}_{\\perp}'");
    let w_label = new MathBox(container, {}, "\\color{#00BFFF}\\mathbf{a}\\times\\mathbf{v}");
    let vP_label = new MathBox(container, {}, "\\color{#FF8C00}\\mathbf{v}'");
    let vPar = new Vector3D(gl, WebGL, vParallel, null, .065, [.6,.8,.2,1], lightPosition, vPar_label);
    let vPerp = new Vector3D(gl, WebGL, vPerpendicular, vParallel, .065, [1,.1,.2,1], lightPosition, vPerp_label);
    let w = new Vector3D(gl, WebGL, aCrossV, vParallel, .065, [0,.8,1,1], lightPosition, w_label);
    let vPerpP = new Vector3D(gl, WebGL, vPerpPrime, vParallel, .065, [1,1,0,1], lightPosition, vPerpPrime_label);
    let vR = new Vector3D(gl, WebGL, vRotated, null, .065, [1,.6,0,1], lightPosition, vP_label);
    
    let center = new GeometryPainter(gl, new Diffuse(gl, WebGL, sphereFigure, centerUniforms));

    
    //HTML CONTROLS
    let controls = document.getElementById("ui-container");
    controls.className = "right-box simpleS";
    let colors = ["#FF8C00"]
    let slider = new Slider(controls, "θ", 0 ,2, updateAngle, angle, 0.01, colors, "π"); 
    slider.setStyle("simple-slider", "simple-value");

    var fov = 70;
    let zNear = .1;
    let zFar = 200;
    let pos = [1.9,2.2,1.2,1];

    let camera = new TrackballCamera(
        new V3(pos[0], pos[1],pos[2]),
        new V3(1,1,-1)
    );
    
    resize(canvas);
    
    gl.enable(gl.CULL_FACE);
    gl.enable(gl.DEPTH_TEST);
    gl.clearColor(0, 0, 0, 0);

    registerCameraEvents(camera, canvas, draw);

    draw();

    function draw(){        
        resize(canvas);
        var {width, height} = gl.canvas;
       
        gl.viewport(0, 0, width, height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
             
        let aspect = width/height;
        var projectionMatrix = M4.perspective(fov, aspect, zNear, zFar);

        let viewMatrix = camera.getMatrix();
        gridXZ.draw(gl, viewMatrix, projectionMatrix);
        
        
        var lightPos = M4.multiplyVector(viewMatrix, lightPosition);
        centerUniforms.u_light_position = lightPos;
      
        v.draw(gl, viewMatrix, projectionMatrix, lightPos);    
        vPar.draw(gl, viewMatrix, projectionMatrix, lightPos);
        vPerp.draw(gl, viewMatrix, projectionMatrix, lightPos);
        w.draw(gl, viewMatrix, projectionMatrix, lightPos);    
        //Actualizamos el ángulo
        vPerpPrime = vPerpendicular.scale(cos(theta)).add(aCrossV.scale(sin(theta)));
        vRotated = vPerpPrime.add(vParallel);

        vPerpP.draw(gl, viewMatrix, projectionMatrix, lightPos, vPerpPrime);
        vR.draw(gl, viewMatrix, projectionMatrix, lightPos, vRotated);
        //Eje arbitrario
        a.draw(gl, viewMatrix, projectionMatrix, lightPos);    
        center.draw(gl, viewMatrix, projectionMatrix, centerUniforms);
    }
    function updateAngle(value){
        theta = value * Math.PI;
        draw();
    }
}