"use strict";

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

/**
 * Sistema de tres ecuaciones con tres incógnitas.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

const colorPlane = [ [0,0.2,0.2,0.3], [0,0,0.2,0.3], [0,0.1,0.2,0.3], [1,.9,0,.5]];
let index = 0;
let min_index = 0;
let max_index = 4;
function main(){
        
    document.body.style.backgroundColor = "white"; 
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
    resize(canvas);

    //Matrices para modelar los planos
    let modelMatrixOne = [  M4.multiply(M4.rotateY(7),M4.rotateX(2)), 
                            M4.multiply(M4.scale(1,1,1.2), 
                            M4.multiply(M4.translate(0.1,0.05,-0.2), M4.rotateX(10))),
                            M4.multiply(M4.translate(0,0.4,-0.2), M4.rotateY(15)),
                            M4.multiply(M4.multiply(M4.translate(0,0.1,0), M4.scale(0.8,1,1)), 
                            M4.multiply(M4.rotateY(40), M4.rotateZ(70))),
                            M4.multiply(M4.scale(1,1,.8), M4.translate(0,-.3, -0.2))];
    let modelMatrixTwo = [  M4.multiply(modelMatrixOne[0], M4.rotateZ(45)), 
                            M4.multiply(M4.multiply(M4.scale(.7,.8, 1),
                            M4.rotateZ(90)), M4.rotateX(-5)),
                            modelMatrixOne[2], 
                            modelMatrixOne[3],
                            M4.multiply(M4.scale(1,1,.8), 
                            M4.multiply(M4.translate(0.4,0.1,-0.2), M4.rotateZ(-50)))];
    let modelMatrixThree = [M4.multiply(modelMatrixOne[0], M4.rotateZ(270)),
                            M4.rotateX(90),
                            M4.multiply(M4.translate(0,-0.3,-0.2),M4.rotateY(15)),
                            modelMatrixOne[3], 
                            M4.multiply(M4.scale(1,1,.8), 
                            M4.multiply(M4.translate(-0.4,0.1,-0.2), M4.rotateZ(50)))];

    let sphereFigure = new Sphere(0.05, 10, 10, true);
    let P0 = M4.multiplyVector(modelMatrixOne[0], [0,0,1,1]);
    let P1 = M4.multiplyVector(modelMatrixOne[0], [0,0,-1,1]);
    let solutions = [   new Line3D(gl, WebGL, new V3(P0[0],P0[1],P0[2]), new V3(P1[0],P1[1],P1[2]), new V3(0,0,0), .025, [1,.9,0,.9]),
                        new GeometryPainter(gl, new SolidColor(gl, WebGL, sphereFigure,[1,.9,0,.9]))];
    let planeFigure = new RectangularPrism(2, .01, 2, true);
    let modelMatrix = [ modelMatrixOne, modelMatrixTwo, modelMatrixThree];
    let plane = new GeometryPainter(gl, new SolidColor(gl, WebGL, planeFigure));
    var colorUniform = {};
    //HTML CONTROLS
    let controls = document.getElementById("ui-container");
    controls.className = "bottom-bttns-box";
    
    //HTML CONTROLS
    let buttons = [ new Button(controls, upadateStep(-1), "Prev", null, true),
                    new Button(controls, upadateStep(1), "Sig"),
                    new Button(controls, reset, "Reset")];

    let textInfo = document.getElementById("text-info");
    let infoByIndex = [ "Los tres planos se intersecan en una misma línea (infinitas soluciones)",
                        "Los tres planos se intersecan exactamente en un punto (solución única)", 
                        "Al menos dos planos son paralelos y distintos (ninguna solución)", 
                        "Los tres planos coinciden (infinitas soluciones)", 
                        "Los planos pueden interesecarse por pares pero no comparten un " + 
                        "punto de intersección común (ninguna solución)"
                    ];
    let zNear = .1;
    let zFar = 2000;
    let pos = new V3(0,0,2.1);
    let camera = new TrackballCamera(pos);
    
    
    window.addEventListener('resize', draw);
    registerCameraEvents(camera, canvas, draw);

    
    gl.clearColor(0,0,0,0);
    gl.enable(gl.DEPTH_TEST);
    //Transparecia
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_DST_ALPHA);
    
    draw();

    function draw(){
        resize(canvas);
        var {width, height} = gl.canvas;
        gl.viewport(0, 0, width, height);
        
        textInfo.innerHTML = infoByIndex[index];
        
        let aspect = width/height;
        var projectionMatrix = M4.perspective(90, aspect, zNear, zFar);
        var viewMatrix = camera.getMatrix();
        var modelViewMatrix;
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.depthMask(false);
        for(var i = 0; i < 3; i++){
            modelViewMatrix = M4.multiply(viewMatrix , modelMatrix[i][index]);
            colorUniform.u_color = colorPlane[i];
            plane.draw(gl,modelViewMatrix, projectionMatrix, colorUniform);
        }       
        if(index < 2)
            solutions[index].draw(gl, viewMatrix, projectionMatrix);
        else if(index == 3){
            colorUniform.u_color = colorPlane[3];
            plane.draw(gl, modelViewMatrix, projectionMatrix, colorUniform);
        }
    }
    function upadateStep(button){
        return function(){
            if (index + button < min_index || index + button > max_index)
                return;
            index += button;
            buttons[0].updateState(index, 1, max_index);
            buttons[1].updateState(index, 0, max_index-1);
            draw(); 
        }
    }
    function reset(){
        index = 0;
        buttons[0].updateState(index, 1, max_index);
        buttons[1].updateState(index, 0, max_index-1);
        camera.resetInitialPosition();
        draw();
    }
}