import * as MU from "../../../modules/MathUtils.js";
import * as Utils from "../../../modules/HTMLUtils.js";
import WebGL from "../../../modules/WebGLUtils.js";
import Grid from "../../../geometry/Grid.js";
import M3 from "../../../modules/M3.js";
import V2 from "../../../modules/V2.js";
import Vector2D from "../../../geometry/Vector2D.js";
import Figure2D from "../../../geometry/Figure2D.js";
import { MouseVector, registerMouseEvents2DVec } from "../../../modules/MouseEvents.js";

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

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

    let container = document.getElementById("container");
    Utils.resize(canvas);
   
    const unit = 55;   
    let grid = new Grid(gl, unit);
    //Colores
    const basisColor = [19, 41, 61, 255]; 
    const opaqueColor = [97, 100, 112, 200]; 
    const color2 = [122, 111, 140, 255];
    const lineColor = [255, 100, 0, 255];
    
    const {width, height} = gl.canvas;
    
    let sPoint  = new V2(0,0);
    //Vectores
    let size = 1.5 * Math.floor(width/unit/6);
    let xBasis = new V2(1, 0);
    let xVector  = new V2(size, 0);
    let yVector  = new V2(0, size);
    let u = new Vector2D(gl, WebGL, sPoint, xVector, unit, 2, basisColor);
    let v = new Vector2D(gl, WebGL, sPoint, yVector, unit, 2, basisColor);
    
    //Punto céntrico 
    var cparams = { center: sPoint, r: 0.1, numPoints: 10};
    let cPoint = new Figure2D(gl, WebGL, 'circle', unit, basisColor, cparams);
    
    const radiusRegion = 0.3;
    //Circunferencia para señalar el área para mover la flecha
    var cparams = { center: sPoint, r: radiusRegion, thickness: 0.1, numPoints: 10};
    let uCRegion = new Figure2D(gl, WebGL, 'circumference', unit, opaqueColor, cparams);
    let vCRegion = new Figure2D(gl, WebGL, 'circumference', unit, opaqueColor, cparams);
    
    //Atributos del arco
    var arcparams = { center: sPoint, sAngle : 0, eAngle: .5 * Math.PI, r: 0.7, thickness: 0.06 , numPoints: 50};

    //Etiqueta vector
    let uLabel = Utils.createMathBox(container, {});
    let vLabel = Utils.createMathBox(container, {});
    
    //Constructor auxiliar para  el manejador de eventos con el ratón
    let uMV = new MouseVector(gl, radiusRegion, unit, xVector);
    let vMV = new MouseVector(gl, radiusRegion, unit, yVector);
    let mouseVectors = [ uMV, vMV];
    
    //Info Labels
    const top = 60;
    const left = 7;
    let uLengthLabel = Utils.createMathBox(container, {top: top, left: left});
    let vLengthLabel = Utils.createMathBox(container, {top: top + 8, left: left});
    let cosLabel = Utils.createMathBox(container, {top: top + 16, left: left});
    let dpLabel = Utils.createMathBox(container, {top: top + 24, left: left});

    gl.clearColor(0, 0, 0, 0);
    //Transparecia
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    
    draw();
    window.addEventListener('resize', draw);
    registerMouseEvents2DVec(canvas, mouseVectors, draw);
    
    function draw(){
        Utils.resize(canvas);
        const {width, height} = gl.canvas;
        gl.viewport(0, 0, width, height);
        
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER);
        
        grid.draw(gl);

        var projectionMatrix = M3.projection(-width/2, width/2, height/2, -height/2);
    
        //Label u
        var diff = {t: -30, l: 0};
        let labelPos = getVectorLabelPosition(uMV.vector, projectionMatrix, width, height, unit, diff);
        Utils.setElementPosition(uLabel, labelPos);
        Utils.setMathBox(uLabel, "\\mathbf{u}");

        //Label v   
        diff = {t: -50, l: -20};     
        labelPos = getVectorLabelPosition(vMV.vector, projectionMatrix, width, height, unit, diff);
        Utils.setElementPosition(vLabel, labelPos);
        Utils.setMathBox(vLabel, "\\mathbf{v}");

        //Valores
        var uLength = uMV.vector.length();  
        var vLength = vMV.vector.length();
        var dotProduct = uMV.vector.dotProduct(vMV.vector);
        var cos = dotProduct/(uLength * vLength);
        Utils.setMathBox(uLengthLabel, "\\lVert \\mathbf{u} \\rVert = " + MU.round(uLength));
        Utils.setMathBox(vLengthLabel, "\\lVert \\mathbf{v} \\rVert = " + MU.round(vLength));
        Utils.setMathBox(cosLabel, "\\cos \\theta = " +  MU.round(cos));
        Utils.setMathBox(dpLabel, "\\mathbf{u} \\cdot \\mathbf{v} = " + MU.round(dotProduct));

        //Cálculos para el arco del ángulo
        var uAngle = Math.acos(uMV.vector.normalize().dotProduct(xBasis));
        uAngle = (uMV.vector.dotProduct(yVector) < 0) ? 2*Math.PI - uAngle : uAngle;
        var vAngle = Math.acos(vMV.vector.normalize().dotProduct(xBasis));
        vAngle = (vMV.vector.dotProduct(yVector) < 0) ?  2*Math.PI - vAngle : vAngle;
        if(Math.abs(uAngle - vAngle) > Math.PI){ //Si es mayor de 180ª
            if(uAngle > vAngle) //Empezamos con el ángulo mayor
                uAngle -= 2*Math.PI; 
            else
                vAngle -= 2*Math.PI; 
        }
        
        arcparams.sAngle = (uAngle < vAngle) ? uAngle : vAngle;
        arcparams.eAngle = (uAngle < vAngle) ? vAngle : uAngle;
        let arcAngle  = new Figure2D(gl, WebGL, 'arc', unit, [255, 165, 0, 255], arcparams);
        
        //Dibujamos
        arcAngle.draw(gl, M3.identity(), projectionMatrix);
        u.draw(gl, projectionMatrix, null, uMV.vector);
        v.draw(gl, projectionMatrix, null, vMV.vector);
        v.draw(gl, projectionMatrix, null, vMV.vector);       
        cPoint.draw(gl, M3.identity(), projectionMatrix); 
        if(uMV.showRegion)
            uCRegion.draw(gl, M3.translate(uMV.vector.x, uMV.vector.y), projectionMatrix);
        if(vMV.showRegion)
            vCRegion.draw(gl, M3.translate(vMV.vector.x, vMV.vector.y), projectionMatrix);
           
    }
    function getVectorLabelPosition(point, projectionMatrix, width, height, unit, diff){
        let midPoint = point;
        let coord = MU.getPixelPosition(midPoint, projectionMatrix, width, height, unit);
        if (diff)
            return {top : coord.y + diff.t, left: coord.x + diff.l, type: 'px'};
        return { top: coord.y, left: coord.x, type: 'px'};
    }
}