<template>
    <div id="cubetti" ref="cubetti" />
</template>

<style lang="pcss" scoped>
@media screen(sm) {
    #cubetti {
        position: absolute;
        width: 200px !important;
        height: 200px !important;
        top: -55px !important;
        left: 0px !important;
    }
}

#cubetti {
    position: absolute;
    width: 120px;
    height: 120px;
    overflow: visible;
    top: -24px;
    left: -22px;
}
</style>

<script lang="ts" setup>
    import { AmbientLight } from 'three/src/lights/AmbientLight';
    import { DirectionalLight } from 'three/src/lights/DirectionalLight';
    import { BoxGeometry } from 'three/src/geometries/BoxGeometry';
    import { Mesh } from 'three/src/objects/Mesh';
    import { MeshStandardMaterial } from 'three/src/materials/MeshStandardMaterial';
    import { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera';
    import { Scene } from 'three/src/scenes/Scene';
    import { Vector3 } from 'three/src/math/Vector3';
    import { WebGLRenderer } from 'three/src/renderers/WebGLRenderer';
    import anime from 'animejs';
    import { randInt } from 'three/src/math/MathUtils';

    const scene = new Scene()
    const camera = new PerspectiveCamera(80, 1, 0.1, 1000)
    const renderer = new WebGLRenderer({ antialias: true, alpha: true })
    renderer.setPixelRatio(window.devicePixelRatio);
    const directionalLight = new DirectionalLight(0x808080)
    const ambientLight = new AmbientLight(0x808080*1.75)
    const geometry = new BoxGeometry(1, 1, 1)
    const blueMaterial = new MeshStandardMaterial({ color: 'dodgerblue' })
    const greenMaterial = new MeshStandardMaterial({ color: 'greenyellow' })
    const orangeMaterial = new MeshStandardMaterial({ color: 'orange' })
    const blueCube = new Mesh(geometry, blueMaterial)
    blueCube.position.set(-1, 0, 1)
    const greenCube = new Mesh(geometry, greenMaterial)
    greenCube.position.set(1, 0, 1)
    const orangeCube = new Mesh(geometry, orangeMaterial)
    orangeCube.position.set(0, 0, -1)
    const cubeGroup = new Scene()
    cubeGroup.add(blueCube, greenCube, orangeCube)

    const cubettiAnims = [
        { // group spin
            targets: [cubeGroup.rotation],
            keyframes: [
                { y: 2 * Math.PI, duration: 1000 },
            ],
            easing: 'easeOutCubic',
            duration: 1000,
            complete: playRandomAnimation,
        },
        { // floating cubes
            targets: [orangeCube.position, blueCube.position, greenCube.position],
            keyframes: [
                { y: -0.5, duration: 500/3 },
                { y:  0.5, duration: 707/3 },
                { y:  0.0, duration: 500/3 },
            ],
            easing: 'easeInOutSine',
            delay: anime.stagger(500/3),
            complete: playRandomAnimation,
        },
        { // rotating cubes
            targets: [orangeCube.rotation, blueCube.rotation, greenCube.rotation],
            x: randInt(0, 1) * 2 * Math.PI, y: randInt(0, 1) * 2 * Math.PI, z: randInt(0, 1) * 2 * Math.PI, duration: 1000,
            easing: 'easeOutSine',
            delay: anime.stagger(500/3),
            complete: playRandomAnimation
        }
    ]
    
    const cubetti = ref()

    function playRandomAnimation() {
        setTimeout(() => {
            anime(cubettiAnims[randInt(0, cubettiAnims.length-1)])
        }, randInt(1000, 8000))
    }

    const animate = () => {
        requestAnimationFrame(animate)
        renderer.render(scene, camera)
    }

    const resizeCanvas = () => {
        if (window.innerWidth < 640) {
            renderer.setSize(120, 120);
        } else {
            renderer.setSize(200, 200);
        }
    }

    onMounted(() => {
        scene.add(camera)
        scene.add(ambientLight, directionalLight)
        scene.add(cubeGroup)
        // renderer.setSize(200, 200)
        resizeCanvas();
        camera.position.copy((new Vector3(-2, 1.5, 2)).multiplyScalar(1.2))
        camera.lookAt(0, 0, 0)
        scene.background = null
        cubetti.value.appendChild(renderer.domElement)

        window.addEventListener('resize', resizeCanvas);

        playRandomAnimation()

        animate()
    })

    onUnmounted(() => {
        window.removeEventListener('resize', resizeCanvas);
    })
</script>