<script lang="ts">
  import { beforeUpdate, afterUpdate, onMount, onDestroy } from 'svelte';
  import * as Three from 'three';

  export let width: number;
  export let height: number;

  //#region variables
  let container: HTMLElement;
  let canvas: HTMLCanvasElement;
  let maxInnerWidth: number = 0;
  let maxInnerHeight: number = 0;

  let portrait: boolean = true;
  let focalLength: number = 540 / Math.atan((70 * Math.PI) / 180);
  let fov = 75;
  //let baseHorizontalFOV: number = 2.0*Math.atan(baseAspectRation*Math.tan(baseVerticalFOV*0.5));

  let scene: Three.Scene = new Three.Scene();
  let camera: Three.PerspectiveCamera = new Three.PerspectiveCamera(
    75,
    1,
    0.1,
    1000,
  );

  let renderer: Three.WebGLRenderer = new Three.WebGLRenderer();
  let box: Three.BoxGeometry = new Three.BoxGeometry(1, 1, 1);
  let mat: Three.MeshBasicMaterial = new Three.MeshBasicMaterial({
    color: 0x00ff00,
  });
  let cube = new Three.Mesh(box, mat);
  //#endregion

  //#region functions
  function updateVerticalFOV() {
    fov = (180 / Math.PI) * Math.tan(innerHeight / (focalLength * 2));
  }

  function resetMaxDimensions() {
    maxInnerWidth = 0;
    maxInnerHeight = 0;
  }

  function updateMaxInnerDimensions() {
    if (maxInnerWidth < width) {
      maxInnerWidth = width;
    }
    if (maxInnerHeight < height) {
      maxInnerHeight = height;
    }
  }

  function checkOrientation(oldPortrait: boolean) {
    if (innerWidth > height) {
      portrait = false;
    } else {
      portrait = true;
    }

    if (oldPortrait != portrait) {
      resetMaxDimensions();
    }
  }

  function animate() {
    requestAnimationFrame(animate);

    cube.rotation.x += 0.05;
    cube.rotation.y += 0.05;

    renderer.render(scene, camera);
  }
  //#endregion

  onMount(() => {
    canvas = container.appendChild(renderer.domElement);

    scene.add(cube);

    camera.position.z = 5;

    animate();
  });

  beforeUpdate(() => {
    checkOrientation(portrait);
    updateMaxInnerDimensions();
    updateVerticalFOV();

    camera.aspect = width / height;
    camera.fov = fov;
    camera.setViewOffset(width, height, 0, 0, width, height);
    renderer.setSize(width, height);

    renderer.setClearColor(0x000000, 0.1);
  });

  afterUpdate(() => {});

  onDestroy(() => {
    container.removeChild(canvas);
  });
</script>

<div class="Container" bind:this={container} />

<style>
  .Container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
</style>
