import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.min.js";

const container = document.getElementById("panorama");
const loading = document.getElementById("loading");

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  72,
  window.innerWidth / window.innerHeight,
  0.1,
  100
);

camera.rotation.order = "YXZ";

const renderer = new THREE.WebGLRenderer({
  antialias: true,
  powerPreference: "high-performance"
});

renderer.setPixelRatio(
  Math.min(window.devicePixelRatio || 1, 2)
);

renderer.setSize(
  container.clientWidth,
  container.clientHeight
);

container.appendChild(renderer.domElement);

/*
CubeTextureLoader expects this exact order:

1. Positive X = right
2. Negative X = left
3. Positive Y = up
4. Negative Y = down
5. Positive Z = front
6. Negative Z = back
*/

const cubeLoader = new THREE.CubeTextureLoader();

const panoramaTexture = cubeLoader.load(
  [
    "images/pano_r.jpg",
    "images/pano_l.jpg",
    "images/pano_u.jpg",
    "images/pano_d.jpg",
    "images/pano_f.jpg",
    "images/pano_b.jpg"
  ],

  () => {
    loading.classList.add("is-hidden");
  },

  undefined,

  (error) => {
    console.error("Could not load panorama:", error);
    loading.textContent = "Could not load the panorama.";
  }
);

panoramaTexture.colorSpace = THREE.SRGBColorSpace;

scene.background = panoramaTexture;

/*
PAN SETTINGS
*/

const PAN_RANGE = THREE.MathUtils.degToRad(42);

// Time from one side to the other
const PAN_SECONDS = 20;

// Change this to rotate the starting direction
const START_YAW = Math.PI;

// Slight vertical camera angle
const PITCH = THREE.MathUtils.degToRad(-2);

camera.rotation.x = PITCH;

const reducedMotion = window.matchMedia(
  "(prefers-reduced-motion: reduce)"
).matches;

const startedAt = performance.now();

function animate(now) {
  requestAnimationFrame(animate);

  if (!reducedMotion) {
    const elapsedSeconds =
      (now - startedAt) / 1000;

    const phase =
      elapsedSeconds * Math.PI / PAN_SECONDS;

    camera.rotation.y =
      START_YAW +
      Math.cos(phase) * PAN_RANGE;
  }

  renderer.render(scene, camera);
}

function resize() {
  const width = container.clientWidth;
  const height = container.clientHeight;

  camera.aspect = width / height;
  camera.updateProjectionMatrix();

  renderer.setSize(width, height, false);

  renderer.setPixelRatio(
    Math.min(window.devicePixelRatio || 1, 2)
  );
}

window.addEventListener("resize", resize);

resize();
requestAnimationFrame(animate);