import * as MU from "../../../modules/MathUtils.js";
import {resize, MathBox, Button} from "../../../modules/HTMLUtils.js";
import WebGL from "../../../modules/WebGLUtils.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";

/**
 * Resta de dos vectores.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

var step = 0;
function main(){
    //document.body.style.backgroundColor = "#f3f5f5";
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
    
    resize(canvas);

    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", "", true),
                    new Button(controls, reset, "Reset")];

    const {width, height} = gl.canvas;
    var unit = 29;  
    //Vectors
    const color1 = [19, 41, 61, 255]; 
    const color2 = [255, 0, 0, 255];
    const color3 = [250, 128, 114, 255];
    const color4 = [46, 139, 87, 255];
    const opaqueColor = [97, 100, 112, 200]; 
    const sizeVec = 2.8;
    let sPoint  = new V2(0,0);
    //Vector U
    let uVector  = new V2(Math.floor(.35*width/unit), Math.floor(.2*height/unit));
    let uVector2D = new Vector2D(gl, WebGL, sPoint, uVector, unit, sizeVec, color1);
    //Vector V
    let vVector  = new V2(Math.floor(.1*width/unit), Math.floor(.35*height/unit));
    let vVector2D = new Vector2D(gl, WebGL, sPoint, vVector, unit, sizeVec, color2);
    //Vector -V
    let vNegVector = vVector.scale(-1)
    let vNegVector2D = new Vector2D(gl, WebGL, sPoint, vNegVector, unit, sizeVec, color2);
    //Vector -VPrime
    let vNegPVector2D = new Vector2D(gl, WebGL, uVector, vNegVector, unit, sizeVec, color2);
    //Vector U-V
    let uSubVVector = uVector.sub(vVector);
    let uSubVVector2D = new Vector2D(gl, WebGL, sPoint, uSubVVector, unit, sizeVec, color4);
    //Vector U-V
    let uSubVPVector2D = new Vector2D(gl, WebGL, vVector, uSubVVector, unit, sizeVec, color4);
    
    //Etiquetas vectores
    let uLabel = new MathBox(container, {}, "\\mathbf{u}", "math-label");
    let vLabel = new MathBox(container, {}, "\\mathbf{v}", "math-label");
    let vNegLabel = new MathBox(container, {}, "\\mathbf{-v}", "math-label");
    let vNegPLabel = new MathBox(container, {}, "\\mathbf{-v}", "math-label");
    let uSubVLabel = new MathBox(container, {}, "\\mathbf{u-v}", "math-label");
    let uSubVPLabel = new MathBox(container, {}, "\\mathbf{u-v}", "math-label");
 
    const radiusRegion = 0.45;
    //Circunferencia para señalar el área/región para mover la flecha
    var cparams = { center: sPoint, r: radiusRegion, thickness: 0.15, numPoints: 10};
    let uCRegion = new Figure2D(gl, WebGL, 'circumference', unit, opaqueColor, cparams);
    let vCRegion = new Figure2D(gl, WebGL, 'circumference', unit, opaqueColor, cparams);

    //Límites de la proyección
    let projectionLimits = { l : -.35, r: .65, t: .5, b: -.5};
    //Constructor auxiliar para  el manejador de eventos con el ratón
    let uMV = new MouseVector(gl, radiusRegion, unit, uVector, projectionLimits);
    let vMV = new MouseVector(gl, radiusRegion, unit, vVector, projectionLimits);
    let mouseVectors = [ uMV, vMV];

    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(){
        resize(canvas);
        const {width, height} = gl.canvas;
        gl.viewport(0, 0, width, height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER);
                
        let projectionMatrix = M3.projection(projectionLimits.l * width, 
                                             projectionLimits.r * width, 
                                             projectionLimits.t * height, 
                                             projectionLimits.b * height); 
        //Vectores
        var u = uMV.vector;
        var v = vMV.vector;
        var vNeg = v.scale(-1);
        var uSubV = u.sub(v);

        //Verificamos la posición del mouse para mostrar o no la región
        if(uMV.showRegion)
            uCRegion.draw(gl, M3.translate(u.x, u.y), projectionMatrix);
        if(vMV.showRegion)
            vCRegion.draw(gl, M3.translate(v.x, v.y), projectionMatrix);
 
        let labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, u);
        uLabel.setPosition(labelPos);
        
        labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, v);
        vLabel.setPosition(labelPos);

        vNegLabel.hideLabel();
        vNegPLabel.hideLabel();
        uSubVLabel.hideLabel();
        uSubVPLabel.hideLabel();

        if(step > 0){ //-V 1 ->
            labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, vNeg);
            vNegLabel.setPosition(labelPos);
            vNegVector2D.draw(gl, projectionMatrix, null, vNeg);
        }
        if(step > 1){ //-V PRIME 2->
            labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, vNeg, u);
            vNegPLabel.setPosition(labelPos);
            vNegPVector2D.draw(gl, projectionMatrix, null, vNeg, u);
        }
        if(step > 2){ //U-V 3->
            labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, u.sub(v));
            uSubVLabel.setPosition(labelPos);
            uSubVVector2D.draw(gl, projectionMatrix, null, uSubV); 
        }
        if(step == 4){ //U-V PRIME
            labelPos = MU.getVectorLabelMidPosition(projectionMatrix, width, height, unit, u.sub(v), v);
            uSubVPLabel.setPosition(labelPos);
            uSubVPVector2D.draw(gl, projectionMatrix, null, uSubV, v); 
        }

        var vColor = (step == 0) ? color2 : color3; 
        uVector2D.draw(gl, projectionMatrix, null, u);
        vVector2D.draw(gl, projectionMatrix, vColor, v);
        
    }

    function upadateStep(button){
        return function(){
            if (step + button < 0 || step + button > 4)
                return;
            step += button;
            buttons[0].updateState(step, 0, 3);
            buttons[1].updateState(step, 1, 4);
            draw(); 
        }
    }
    function reset(){
        step = 0;
        buttons[0].updateState(step, 0, 3);
        buttons[1].updateState(step, 1, 4);
        uMV.vector = uVector;
        vMV.vector = vVector;
        draw();
    }
}