"use strict";

import {resize, Slider, addLabel, resizeAndCenterX, DarkMode, Select} from "../../modules/HTMLUtils.js";
import WebGL from "../../modules/WebGLUtils.js";
import M4 from "../../modules/M4.js";
import PhongTMaterial from "../../materials/PhongTMaterial.js";
import {Sphere, Cube, RectangularPrism, Plane} from "../../geometry/Figure.js";
import GeometryPainter from "../../geometry/GeometryPainter.js";
import {TrackballCamera, registerCameraEvents} from "../../modules/Trackballcamera.js";
import V3 from "../../modules/V3.js";
import Teapot from "../../geometry/Teapot.js";

/**
 * Transparencia en dos planos.
 * @author Melissa Méndez Servín.
 */
window.addEventListener("load", main);

function main(){
    var canvas = document.getElementById("gl_canvas");
    var gl = WebGL.init(canvas);
    if(!gl) return;
    
    let sphereFigure = new Sphere(1, 30,30);
    let cubeFigure = new Cube(1.35);
    let teapotFigure = new Teapot();
    let planeFigure = new Plane(1.3,1.3);
    
    let height = -1.5;
    let lightPosition = [0, 6, 5, 0];
    let material = [ {ka: [0.24725, 0.1995, 0.0745,1], kd: [0.75164, 0.60648, 0.22648,1], ks: [0.628281,0.555802, 0.366065,1], 
                     shininess: 0.4*128},
                     { ka: [0.1, 0.18725, 0.1745, 1], kd: [0.196, 0.4151, 0.69102,1], ks: [0.297254, 0.30829, 0.306678,1], 
                        shininess: 12.8},
                      { ka: [0.25, 0.20725,	0.20725,1], kd: [0.829, 0.829, 0.829,1], ks: [0.296648,	0.296648, 0.296648,1], 
                        shininess: 0.088*128}];
                            
    let figures = [ new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, teapotFigure, {u_material: material[0]}), M4.multiply(M4.scale(.9,.9,.9),  M4.translate(0,-.5,-.6))),
                    new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, cubeFigure, {u_material: material[1]}), M4.translate(-3.5,-.3,-3)) ,
                    new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, sphereFigure, {u_material: material[2]}), M4.translate(3,-.1,-3.5)),
                ];

    //Piso 
    var rect = new RectangularPrism(25,1,25,true);
    const floorMaterial = { ka: [0.105882, 0.058824, 0.113725, 1], kd: [0.427451, 0.470588, 0.541176, 1], ks: [0,0,0,1], 
                            shininess: 1};
    let floor = new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, rect, {u_material: floorMaterial}), M4.translate(0,height,-7)); 

    var planeMaterials = [ {u_material: { ka: [0.1745, 0.01175, 0.01175, .45], kd: [0.61424, 0.04136, 0.04136, .45], ks: [0.727811, 0.626959, 0.626959,0], 
                            shininess: 0.6*128}},
                           {u_material: {  ka: [0.0215, 0.1745, 0.0215,.45], kd: [0.07568, 0.61424, 0.07568,.45], ks: [0.633, 0.727811, 0.633,0], 
                            shininess: 0.6*128}}];
    
    let redPlane = new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, planeFigure, planeMaterials[0]));
    let greenPlane = new GeometryPainter(gl, new PhongTMaterial(gl, WebGL, planeFigure, planeMaterials[1]));
    let  greenPosition = [0,.5,1];
    let redPosition = [0,.5,1.5];
 
    var fov = 90;
    let zNear = .1;
    let zFar = 100;
    var pos = new V3(0,1,2.9);
    let camera = new TrackballCamera(pos);
    
    let controlPos = document.getElementById("ui-container-up");
    let controlAlpha = document.getElementById("ui-container-center");
    addLabel(controlPos, "Plano Rojo");
    var red_plane_x = new Slider(controlPos, "x", -5, 5, upadateRedPosition(0), redPosition[0], 0.1, ["#4994D0"]);
    var red_plane_y = new Slider(controlPos, "y",  0, 2.5, upadateRedPosition(1), redPosition[1], 0.1, ["#4994D0"]);
    var red_plane_z = new Slider(controlPos, "z", -15, 5, upadateRedPosition(2), redPosition[2], 0.1, ["#4994D0"]);
    
    addLabel(controlPos, "Plano Verde");
    var green_plane_x = new Slider(controlPos, "x", -5, 5, upadateGreenPosition(0), greenPosition[0], 0.1, ["#4994D0"]);
    var green_plane_y = new Slider(controlPos, "y",  0, 2.5, upadateGreenPosition(1), greenPosition[1], 0.1, ["#4994D0"]);
    var green_plane_z = new Slider(controlPos, "z", -5, 2.5, upadateGreenPosition(2), greenPosition[2], 0.1, ["#4994D0"]);

    let right_controls = document.getElementById("right-options");
    let darkMode = new DarkMode(draw, [controlPos]);
    let transparencyMode = { "mezcla":  gl.ONE_MINUS_SRC_ALPHA, "mezcla aditiva":  gl.ONE};
    let selectTransparencyMode = new Select(right_controls, "figures", setBlendingMode, transparencyMode, "mezcla");
    var blendingMode =  gl.ONE_MINUS_SRC_ALPHA;
    
    controlAlpha.setAttribute("obscure-mode", true);
    var alphaRed = new Slider(controlAlpha, "α<sub>R</sub>", 0, 1, upadateAlpha(0), .45, .01, ["#4994D0"]);
    var alphaGreen = new Slider(controlAlpha, "α<sub>G</sub>", 0, 1, upadateAlpha(1), .45, .01, ["#4994D0"]);

    window.addEventListener('resize', draw);
    registerCameraEvents(camera, canvas, draw);
    
    draw();

    function draw(){        
        resize(canvas);
        resizeAndCenterX(controlPos, {top:0});
        resizeAndCenterX(controlAlpha, {bottom:5});
        var {width, height} = gl.canvas;
        
        darkMode.check(gl);

        gl.enable(gl.DEPTH_TEST);
        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);
        
        floor.draw(gl, viewMatrix, projectionMatrix, {u_light_position : lightPos});
        
        for(var i = 0; i < figures.length; i++){
            figures[i].draw(gl, viewMatrix, projectionMatrix, {u_light_position : lightPos});       
        }

        //Transparecia
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, blendingMode);
        //gl.depthMask(false);
        let translate = M4.translate(greenPosition[0], greenPosition[1], greenPosition[2]);
        greenPlane.draw(gl,M4.multiply(viewMatrix, translate), projectionMatrix, {u_light_position : lightPos});
        translate = M4.translate(redPosition[0], redPosition[1], redPosition[2]);
        redPlane.draw(gl, M4.multiply(viewMatrix, translate), projectionMatrix, {u_light_position : lightPos});
        gl.disable(gl.BLEND);
        //gl.depthMask(true);

    }
    function upadateRedPosition(index){
        return function(value){
            redPosition[index] = value;
            draw();
        }
    }
    function upadateGreenPosition(index){
        return function(value){
            greenPosition[index] = value;
            draw();
        }
    }
    function setBlendingMode(value){
        blendingMode = transparencyMode[value];
        draw();
    }
    function upadateAlpha(index){
        return function(a){
            planeMaterials[index].u_material.ka[3]  = a;
            planeMaterials[index].u_material.kd[3]  = a;
            draw();
        }
    }
}