"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 DisplacementMapping from "../../materials/DisplacementMapping.js";
import {Sphere} from "../../geometry/Figure.js";
import {TrackballCamera, registerCameraEvents} from "../../modules/Trackballcamera.js";
import V3 from "../../modules/V3.js";
import GeometryPainter from "../../geometry/GeometryPainter.js";
import Light from "../../geometry/Light.js";

/**
 * Displacement mappgin.
 * @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 srcTextures = ["../../../images/capitulo_07/textures/Gravel022_1K_Color.png",
                      "../../../images/capitulo_07/textures/Gravel022_1K_Displacement.png",
                      "../../../images/capitulo_07/textures/Bricks071_1K_Color.jpg",
                      "../../../images/capitulo_07/textures/Bricks071_1K_Displacement.jpg",
                      "../../../images/capitulo_07/textures/2k_moon.jpeg",
                      "../../../images/capitulo_07/textures/2k_moon.jpeg",
                    ];
    
    let textureIds = { grava: 0, ladrillos: 2, luna: 4};
    let lightPosition = [0, 1, 1.6, 0];
    let uniforms = { u_material : {}, 
                     u_light: { position: lightPosition, la: [0.1,0.1,0.1], ld: [1, 1, 1],
                                ls: [1.0, 1.0, 1.0]}};
        
    let sphereFigure =  new Sphere(.5, 200,200);
    var material = new DisplacementMapping(gl, WebGL, sphereFigure, srcTextures, setTextures, uniforms);
    let sphere = new GeometryPainter(gl, material, M4.translate(0,-.05,-.3));
    
    var pos = new V3(0,0,.8);
    let camera = new TrackballCamera(pos);
    camera.setZoomConfig(2, .5);
    let bulb = new Light(gl, WebGL, lightPosition);

    let textures;
    var textureId = 4;
    var viewMatrix;
    
    let light_controls = document.getElementById("ui-container-up");
    addLabel(light_controls, "Posición de la luz");
    var light_pos_x = new Slider(light_controls, "x", -10, 10, upadeteLPos(0), lightPosition[0], 0.01, ["#4994D0"]);
    var light_pos_y = new Slider(light_controls, "y", -10, 10, upadeteLPos(1), lightPosition[1], 0.01, ["#4994D0"]);
    var light_pos_z = new Slider(light_controls, "z", -10, 10, upadeteLPos(2), lightPosition[2], 0.01, ["#4994D0"]);

    let right_controls = document.getElementById("right-options");
    let darkMode = new DarkMode(draw, [light_controls]);
    let selectTexture = new Select(right_controls, "textures", setTexture, textureIds, "luna");
    let maxHeightSlider = new Slider(right_controls, "Altura", 0, 0.5, updateHeight, 0.05, 0.001, ["#4994D0"]);
    let divsionSlider = new Slider(right_controls, "Subdiviciones", 10, 260, updateSphere, 142, 1, ["#4994D0"]) ;
    divsionSlider.label.className = "long-label";
    divsionSlider.slider_value.className = "hidde-value";
    
    gl.enable(gl.DEPTH_TEST);
    
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.clearColor(0, 0, 0, 0);

    window.addEventListener('resize', draw);
    registerCameraEvents(camera, canvas, draw);
    
    function draw(){        
        resize(canvas);
        resizeAndCenterX(light_controls, {});
        darkMode.check(gl);
        
        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(90, aspect, .1, 100);
        viewMatrix = camera.getMatrix();
        var lightPos = M4.multiplyVector(viewMatrix, lightPosition);
        
        uniforms.u_light.position = lightPos;
        if(textureId == 4){
            uniforms.texture_factor = 1;
        }else{
            uniforms.texture_factor = 1.5;
        }
        if(textures){
            uniforms.u_material = { diffuse_map : { id: textureId, texture: textures[textureId]},
                                    shininess: 0.088*128};
            uniforms.displacement_map = { id: textureId + 1, texture: textures[textureId+1]};
        }

        sphere.draw(gl, viewMatrix, projectionMatrix, uniforms);
        bulb.draw(gl, M4.multiply(viewMatrix, M4.scale(.5, .5, .5)), projectionMatrix, lightPosition);
    }
    function setTextures(loadedTextures){
        textures = loadedTextures;
        draw();
    }
    function upadeteLPos(index){
        return function(value){
            lightPosition[index] = value;
            draw();
        }
    }
    function setTexture(value){
        textureId = textureIds[value];
        draw();
    }
    function updateHeight(maxHeight){
        uniforms.max_height = maxHeight;
        draw();
    }
    function updateSphere(value){
        sphereFigure =  new Sphere(.5, value, value);
        material = new DisplacementMapping(gl, WebGL, sphereFigure, srcTextures, setTextures, uniforms);
        sphere = new GeometryPainter(gl, material, M4.translate(0,-.1,-.3));
        draw();
    }
} 