"use strict";

import {resize, MathBox, InputElement, scaleToFitContainer} from "../../../modules/HTMLUtils.js";
import WebGL from "../../../modules/WebGLUtils.js";
import M4 from "../../../modules/M4.js";
import Diffuse from "../../../materials/Diffuse.js";
import SolidColor from "../../../materials/SolidColor.js";
import Vector3D from "../../../geometry/Vector3D.js";
import Line3D from "../../../geometry/Line3D.js";
import {Sphere, RectangularPrism} from "../../../geometry/Figure.js";
import GeometryPainter from "../../../geometry/GeometryPainter.js";
import {TrackballCamera, registerCameraEvents} from "../../../modules/Trackballcamera.js";
import V3 from "../../../modules/V3.js";

/**
 * Producto cruz.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

let step = 0;
function main(){
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
    let controls = document.getElementById("ui-container");
    
    let u_control = new MathBox(controls, {top: 18, left: 32, type: 'px'}, "\\mathbf{u} = ");
    let v_control = new MathBox(controls, {top: 59, left: 32, type: 'px'}, "\\mathbf{v} = ");
    let um = [];
    let vm = [];
    let u_id = document.getElementById("u");
    let v_id = document.getElementById("v");
    for(var i = 0; i < 3; i++){
        var init_num = (i == 2) ? 1 : 0; 
        um.push(new InputElement(u_id, "element input", init_num, draw));
        init_num = (i == 0) ? 1 : 0; 
        vm.push(new InputElement(v_id, "element input", init_num, draw));
        if(i < 2){
            createDiv(u_id, ",");
            createDiv(v_id, ",");
        }
    }

    let lightPosition = [2, 3, 3, 0];
    let diffuseUniforms = { u_light_position: lightPosition}; 
    let sColor = { u_color: [.8,.8,.8,1] };
    let sPoint = new V3(0,-0.3,0);
    let u_label = new MathBox(container, {}, "\\mathbf{u}");
    let v_label = new MathBox(container, {}, "\\mathbf{v}");
    let cross_label = new MathBox(container, {}, "\\mathbf{u} \\times \\mathbf{v}");
  
    //Flechas
    let u_vec = new V3(0,0,1);
    let v_vec = new V3(1,0,0);
    let cross_vec = u_vec.cross(v_vec);
    
    let uArrow = new Vector3D(gl, WebGL, u_vec, sPoint, .1, [1,.2,.3,1], lightPosition, u_label);
    let vArrow = new Vector3D(gl, WebGL, v_vec, sPoint, .1, [0,.7,0,1], lightPosition, v_label); 
    let crossArrow = new Vector3D(gl, WebGL, cross_vec, sPoint, .1, [0,.2,.9,1], lightPosition, cross_label); 
    crossArrow.setOffsetLabelPosition(8,0);
   
    let s = new GeometryPainter(gl, new Diffuse(gl, WebGL, new Sphere(.07, 30, 30), sColor));
    
    //Plano
    var rect = new RectangularPrism(20,.02,20,true);
    let plane = new GeometryPainter(gl, new SolidColor(gl, WebGL, rect, [.8,.9,1,1]), M4.translate(0,sPoint.y,0));    
    
    //Lineas
    let u_scale = u_vec.scale(.2);
    let v_scale = v_vec.scale(.2);
    let cross_scale = cross_vec.scale(.2);

    let intersectionUCross = u_scale.add(cross_scale);
    let intersectionVCross = v_scale.add(cross_scale);
    let lineUToAdd = new Line3D(gl, WebGL, u_scale, intersectionUCross, sPoint, .025, [0,0,0,1]);
    let lineCrossToAU = new Line3D(gl, WebGL, cross_scale, intersectionUCross, sPoint, .025, [0,0,0,1]);

    let lineVToAdd = new Line3D(gl, WebGL, v_scale, intersectionVCross, sPoint, .025, [0,0,0,1]);
    let lineCrossToAV = new Line3D(gl, WebGL, cross_scale, intersectionVCross, sPoint, .025, [0,0,0,1]);

    var fov = 80;
    if(window.innerWidth < window.innerHeight)
        fov = 120;

    let zNear = .1;
    let zFar = 2000;
    let pos = M4.multiplyVector(M4.rotateY(20), [1.2,.7,2.8,1]);
    let camera = new TrackballCamera(new V3(pos[0],pos[1],pos[2]));
    camera.setZoomConfig(20,2);
    resize(canvas);

    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.CULL_FACE);
    gl.clearColor(0, 0, 0, 0);

    
    window.addEventListener('resize', draw);
    registerCameraEvents(camera, canvas, draw);
    const position = {x:0, y:0};
    draw();
    

    function draw(){        
        resize(canvas);
        scaleToFitContainer(controls, position);
        
        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();
        var lightPos = M4.multiplyVector(viewMatrix, lightPosition);
        diffuseUniforms.u_light_position = lightPos;
    
        u_vec = new V3(um[0].getNum(), um[1].getNum(), um[2].getNum());
        v_vec = new V3(vm[0].getNum(), vm[1].getNum(), vm[2].getNum());
        cross_vec = u_vec.cross(v_vec);

        uArrow.draw(gl, viewMatrix, projectionMatrix, lightPos, u_vec);
        vArrow.draw(gl, viewMatrix, projectionMatrix, lightPos, v_vec);
        crossArrow.draw(gl, viewMatrix, projectionMatrix, lightPos, cross_vec);

        let sVM = M4.multiply(viewMatrix, M4.translate(sPoint.x, sPoint.y, sPoint.z));
        s.draw(gl, sVM, projectionMatrix, diffuseUniforms);     
       

        u_scale = u_vec.scale(.2);
        v_scale = v_vec.scale(.2);
        cross_scale = cross_vec.scale(.2);

        intersectionUCross = u_scale.add(cross_scale);
        intersectionVCross = v_scale.add(cross_scale);

        lineCrossToAU.draw(gl, viewMatrix, projectionMatrix, cross_scale, intersectionUCross);
        lineUToAdd.draw(gl, viewMatrix, projectionMatrix, u_scale, intersectionUCross);
        lineCrossToAV.draw(gl, viewMatrix, projectionMatrix, cross_scale, intersectionVCross);
        lineVToAdd.draw(gl, viewMatrix, projectionMatrix, v_scale, intersectionVCross);
       
        plane.draw(gl, viewMatrix, projectionMatrix);
    }
    function createDiv(parent, text){
        let div = parent.appendChild(document.createElement("div"));
        div.className = "coma";
        div.innerHTML = text + "";
    }
}