"use strict";

import {resize, Button, MathBox} 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 {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";

/**
 * Suma de tres vectores 3D.
 * @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");
    controls.className = "vertical-up-bttns-box";

    //HTML CONTROLS
    let buttons = [ new Button(controls, upadateStep(1), "Sig"),
                    new Button(controls, upadateStep(-1), "Prev", null, true),
                    new Button(controls, reset, "Reset")];

    let lightPosition = [2, 3, 3, 0];
    let diffuseUniforms = { u_light_position: lightPosition, 
                            u_color: [.8,.8,.8,1] };
    
    let u_label = new MathBox(container, {}, "\\mathbf{u}");
    let uP_label = new MathBox(container, {}, "\\mathbf{u}");
    let v_label = new MathBox(container, {}, "\\mathbf{v}");
    let vP_label = new MathBox(container, {}, "\\mathbf{v}");
    let add_label = new MathBox(container, {}, "\\mathbf{u}+\\mathbf{v}");

    let sPoint = new V3(0,-.5,0);
    let u_vec = new V3(2,1,0);
    let v_vec = new V3(-1,1,0);
    let add_vec = u_vec.add(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,1,0,1], lightPosition, v_label); 

    let uPrimeArrow = new Vector3D(gl, WebGL, u_vec, sPoint.add(v_vec), .1, [1,0,0,1], lightPosition, uP_label); 
    let vPrimeArrow = new Vector3D(gl, WebGL, v_vec, sPoint.add(u_vec), .1, [.15,.6,.14,1], lightPosition, vP_label); 
    let additionArrow = new Vector3D(gl, WebGL, add_vec, sPoint, .1, [0,0,1,1], lightPosition, add_label); 

    let centerTranslation = M4.translate(sPoint.x,sPoint.y,sPoint.z);
    let center = new GeometryPainter(gl, new Diffuse(gl, WebGL, new Sphere(.09, 30, 30), diffuseUniforms), centerTranslation);
    var rect = new RectangularPrism(4,.05,4,true);
    let plane = new GeometryPainter(gl, new SolidColor(gl, WebGL, rect, [.8,.9,1,1]), centerTranslation);    
    
    var fov = 65;
    if(window.innerWidth < window.innerHeight)
        fov = 120;

    let zNear = .1;
    let zFar = 2000;
    let camera = new TrackballCamera(new V3(0,1,3));
    
    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);
    
    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();
        var lightPos = M4.multiplyVector(viewMatrix, lightPosition);
        diffuseUniforms.u_light_position = lightPos;
    
        uArrow.draw(gl, viewMatrix, projectionMatrix, lightPos);
        vArrow.draw(gl, viewMatrix, projectionMatrix, lightPos);
        center.draw(gl, viewMatrix, projectionMatrix, diffuseUniforms);
        //esconde etiquetas por si no se deben mostrar
        uPrimeArrow.hideLabel();
        vPrimeArrow.hideLabel();
        additionArrow.hideLabel();
        if(step >= 3){
            uPrimeArrow.draw(gl,viewMatrix, projectionMatrix, lightPos);
            if(step >= 4){
                additionArrow.draw(gl, viewMatrix, projectionMatrix, lightPos);
                if(step == 5)
                    vPrimeArrow.draw(gl,viewMatrix, projectionMatrix, lightPos);
        }
        }else if(step >= 1){
            vPrimeArrow.draw(gl,viewMatrix, projectionMatrix, lightPos);
            if(step == 2)
                additionArrow.draw(gl, viewMatrix, projectionMatrix, lightPos);
        } 
        plane.draw(gl, viewMatrix, projectionMatrix);
    }
    function upadateStep(button){
        return function(){
            if (step + button < 0 || step + button > 5)
                return;
            step += button;
            buttons[0].updateState(step, 0, 4);
            buttons[1].updateState(step, 1, 5);
            draw(); 
        }
    }
    function reset(){
        step = 0;
        buttons[0].updateState(step, 0, 4);
        buttons[1].updateState(step, 1, 5);
        draw();
    }
}