"use strict";

import {resize, Slider, addLabel, resizeAndCenterX, DarkMode, Select, Checkbox} from "../../modules/HTMLUtils.js";
import WebGL from "../../modules/WebGLUtils.js";
import M4 from "../../modules/M4.js";
import Skybox from "../../materials/Skybox.js";
import CubeMapping from "../../materials/CubeMapping.js";
import {TrackballCamera, registerCameraEvents} from "../../modules/Trackballcamera.js";
import V3 from "../../modules/V3.js";
import GeometryPainter from "../../geometry/GeometryPainter.js";
import {Cube, Sphere} from "../../geometry/Figure.js";
import Teapot from "../../geometry/Teapot.js";
import Suzanne from "../../geometry/Suzanne.js";
import Light from "../../geometry/Light.js";
import SolidColor from "../../materials/SolidColor.js";

/**
 * Reflection Mapping.
 * @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 cube_map_info = [{ url: "../../../images/capitulo_07/textures/SaintPetersSquare1/posx.jpg", type: gl.TEXTURE_CUBE_MAP_POSITIVE_X},
                         { url: "../../../images/capitulo_07/textures/SaintPetersSquare1/negx.jpg", type: gl.TEXTURE_CUBE_MAP_NEGATIVE_X},
                         { url: "../../../images/capitulo_07/textures/SaintPetersSquare1/posy.jpg", type: gl.TEXTURE_CUBE_MAP_POSITIVE_Y },
                         { url: "../../../images/capitulo_07/textures/SaintPetersSquare1/negy.jpg", type: gl.TEXTURE_CUBE_MAP_NEGATIVE_Y },
                         { url: "../../../images/capitulo_07/textures/SaintPetersSquare1/posz.jpg", type: gl.TEXTURE_CUBE_MAP_POSITIVE_Z },
                         { url: "../../../images/capitulo_07/textures/SaintPetersSquare1/negz.jpg", type: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z }];
    
    let lightPosition = [0,0,0, 1];
    let uniforms = {};

    let skybox =  new Skybox(gl, WebGL, new Cube(10), cube_map_info, setTextures); 
    
    let sky = new GeometryPainter(gl, skybox);
    var pos = M4.multiplyVector(M4.multiply(M4.rotateY(-30), M4.rotateX(-15)), [0,0,2,1]); 
    
    let camera = new TrackballCamera(new V3(pos[0], pos[1], pos[2]));
    //camera.setZoomConfig(2,.1);
    
    let figuresGeom = [ new Cube(), new Sphere(.7, 30, 30), new Teapot(), new Suzanne()];
    let figures = [ new GeometryPainter(gl, new CubeMapping(gl, WebGL, figuresGeom[0])),
                    new GeometryPainter(gl, new CubeMapping(gl, WebGL, figuresGeom[1])),
                    new GeometryPainter(gl, new CubeMapping(gl, WebGL, figuresGeom[2]), M4.scale(.6,.6,.6)),
                    new GeometryPainter(gl, new CubeMapping(gl, WebGL, figuresGeom[3]), M4.scale(.3,.3,.3))]; 
    
    let bulb = new GeometryPainter(gl, new SolidColor(gl, WebGL,  new Sphere(.1, 10,10)));
    
    let cubeMap;
    var translation;
    var modelMatrix;
    var modelViewMatrix;
     
    let figuresIds = { cubo: 0, esfera: 1, tetera: 2, suzanne: 3};
    /* Selects */
    let right_controls = document.getElementById("right-options");
    let figureId = 0;
    let selectFigure = new Select(right_controls, "figuras", setFigureId, figuresIds, "cubo");
    
    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", -1, 6, upadeteLPos(2), lightPosition[2], 0.01, ["#4994D0"]);
    gl.enable(gl.DEPTH_TEST);
    
    //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

    window.addEventListener('resize', draw);
    registerCameraEvents(camera, canvas, draw);
    
    function draw(){        
        resize(canvas);
        resizeAndCenterX(light_controls, {});
        
        var {width, height} = gl.canvas;
        
        gl.clearColor(0, 0, 0, 0);
        gl.viewport(0, 0, width, height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        
        if(cubeMap)
            uniforms.u_cube_map = {id: 0, texture: cubeMap};
        
        let aspect = width/height;
        var projectionMatrix = M4.perspective(90, aspect, .1, 100);
        var viewMatrix = camera.getMatrix();

        sky.draw(gl, viewMatrix, projectionMatrix, uniforms);

        uniforms.u_IV_matrix = M4.inverse(viewMatrix);
        figures[figureId].draw(gl, viewMatrix, projectionMatrix, uniforms);
        
        bulb.draw(gl, viewMatrix, projectionMatrix,  lightPosition);
    }
    function setTextures(loadedTextures){
        cubeMap = loadedTextures;
        draw();
    }
    function upadeteLPos(index){
        return function(value){
            lightPosition[index] = value;
            draw();
        }
    }
    function setFigureId(value){
        figureId = figuresIds[value];
        draw();
    }
} 