window.addEventListener("load", function(evt) {
  const canvas = document.getElementById("the_canvas");
  const gl = canvas.getContext("webgl2");
  if (!gl) throw "WebGL no soportado";

  window.addEventListener("resize", resize);
  function resize() {
    let container = document.getElementById("contenedor");
    let scaleToFitX = window.innerWidth/container.offsetWidth;
    let scaleToFitY = window.innerHeight/container.offsetHeight;

    container.style.transformOrigin = "0 0";
    container.style.position = "absolute";
    container.style.margin = container.style.padding = 0;

    container.style.left = (scaleToFitX < scaleToFitY) ? "0" : "50%";
    container.style.top  = (scaleToFitX < scaleToFitY) ? "50%" : "0";
    container.style.transform = `translate3d(0px, 0px, 0px) scale(${Math.min(scaleToFitX, scaleToFitY)}) translate(-${container.style.left}, -${container.style.top})`;
  }
  resize();


  ////////////////////////////////////////////////////
  let geo_initial_transform = [
    identity(),
    identity(),
    identity(),
    identity()
  ];

  let geometry = [
    new Teapot(
      gl, 
      new PhongMaterial(gl, [0.1,0.1,0.1], [0,0,0], [0,0,0], 1, [1,1,1,1]), // material
      geo_initial_transform[0] // transformación
    ),
    new Teapot(
      gl, 
      new PhongMaterial(gl, [0,0,0], [243/255, 156/255, 18/255], [0,0,0], 1, [1,1,1,1]), // material
      geo_initial_transform[1] // transformación
    ),
    new Teapot(
      gl, 
      new PhongMaterial(gl, [0,0,0], [0,0,0], [1, 1, 1], 20, [1, 1, 1, 1]), // material
      geo_initial_transform[2] // transformación
    ),
    new Teapot(
      gl, 
      new PhongMaterial(gl, [0.1,0.1,0.1], [243/255, 156/255, 18/255], [1, 1, 1], 20, [1, 1, 1, 1]), // material
      geo_initial_transform[3] // transformación
    ),
  ];
  geometry[0].isSmooth = geometry[1].isSmooth = geometry[2].isSmooth = geometry[3].isSmooth = true;

  let camera = new Camera(
    { x:0, y:6, z:8 }, // posición
    { x:0, y:0, z:0 }, // centro de interés
    { x:0, y:1, z:0 }, // vector hacia arriba
  );
  let viewMatrix;

  let area_width = 250;
  let area_height = 250;
  let projectionMatrix = perspective(45*Math.PI/180, area_width/area_height, 0.1, 2000);

  let light = new LuzPuntual(
    { x: 3, y: 3, z: 5 }, // posición
    [ 0.1, 0.1, 0.1 ],    // component ambiental
    [ 1, 1, 1 ],          // componente difuso
    [ 1, 1, 1 ]           // componente especular
  );

  gl.clearColor(0, 0, 0, 0);

  let geo_rotation_transform = identity();

  /**
   */
  function draw() {
    gl.enable(gl.DEPTH_TEST);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    viewMatrix = camera.getMatrix();
    light.update(viewMatrix);

    for (let i=0; i<geometry.length; i++) {
      geometry[i].transform = multiply( geo_initial_transform[i], geo_rotation_transform );
    }

    gl.viewport(12, 250, area_width, area_height);
    geometry[0].draw(gl, projectionMatrix, viewMatrix, light, [camera.pos.x, camera.pos.y, camera.pos.z]);

    gl.viewport(12+250+12, 250, area_width, area_height);
    geometry[1].draw(gl, projectionMatrix, viewMatrix, light, [camera.pos.x, camera.pos.y, camera.pos.z]);

    gl.viewport(12+250+12+250+15, 250, area_width, area_height);
    geometry[2].draw(gl, projectionMatrix, viewMatrix, light, [camera.pos.x, camera.pos.y, camera.pos.z]);

    gl.viewport(12+250+12, 0, area_width, area_height);
    geometry[3].draw(gl, projectionMatrix, viewMatrix, light, [camera.pos.x, camera.pos.y, camera.pos.z]);
  }

  draw();


  let theta_x = theta_y = old_theta_x = old_theta_y = 0;
  let initial_mouse_position = null;
  let new_mouse_position;
  canvas.addEventListener("mousedown", (evt) => {
    initial_mouse_position = getMousePositionInElement(evt, canvas);
    window.addEventListener("mousemove", mousemove);
  });
  window.addEventListener("mouseup", (evt) => {
    if (initial_mouse_position != null) {
      old_theta_x = theta_x;
      old_theta_y = theta_y;
      window.removeEventListener("mousemove", mousemove);
    }
    initial_mouse_position = null;
  });
  let mousemove = (evt) => {
    new_mouse_position = getMousePositionInElement(evt, canvas);
    theta_x = old_theta_x + (new_mouse_position.x - initial_mouse_position.x)*Math.PI/180;
    theta_y = old_theta_y + (new_mouse_position.y - initial_mouse_position.y)*Math.PI/180;

    geo_rotation_transform = multiply(
      rotateX(theta_y),
      rotateY(theta_x)
    );

    draw();
  }
});
