import {
    _testFinish,
    IObject3D,
    LinearToneMapping,
    LoadingScreenPlugin,
    Mesh,
    PerspectiveCamera2,
    PlaneGeometry,
    PopmotionPlugin,
    ProgressivePlugin,
    Texture,
    ThreeViewer,
    ToneMapping,
    TonemapPlugin,
    UnlitMaterial,
    VirtualCamerasPlugin,
} from 'threepipe'

async function init() {

    const viewer = new ThreeViewer({
        canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
        debug: true,
        plugins: [new ProgressivePlugin(16), LoadingScreenPlugin],
    })
    const virtualCameras = viewer.addPluginSync(VirtualCamerasPlugin)
    const popmotion = viewer.addPluginSync(PopmotionPlugin)

    await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
    await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
        autoCenter: true,
        autoScale: true,
    })

    const aspect = 2
    const plane = new Mesh(
        new PlaneGeometry(5 * aspect, 5)
            .translate(0, 0, -3),
        new UnlitMaterial({
            color: '#ffffff',
        })
    )
    plane.castShadow = false
    plane.receiveShadow = true
    viewer.scene.addObject(plane)

    const camera = new PerspectiveCamera2('', viewer.canvas, false, 45, aspect)
    camera.position.set(0, 0, 5)
    camera.target.set(0, 0.25, 0)
    camera.userData.autoLookAtTarget = true
    camera.near = 1
    camera.far = 10
    camera.setDirty()
    const vCam = virtualCameras.addCamera(camera)
    plane.material.map = vCam.target.texture as Texture

    popmotion.animate({
        from: 0,
        to: 1,
        repeat: Infinity,
        duration: 6000,
        onUpdate: (v)=>{
            // Set camera position xz in a circle around the target
            const angle = v * Math.PI * 2 + Math.PI / 2
            const radius = 5
            camera.position.set(Math.cos(angle) * radius, 0, Math.sin(angle) * radius)
            camera.setDirty()
            viewer.setDirty() // since camera is not in the scene
        },
    })

    // We need to disable tonemapping when rendering the virtual camera, otherwise the tonemapping will be applied multiple times.
    let lastTonemapping: ToneMapping = LinearToneMapping
    const tonemap = viewer.getPlugin(TonemapPlugin)!
    virtualCameras.addEventListener('preRenderCamera', ()=>{
        lastTonemapping = tonemap.toneMapping
        // Comment this and see what happens to the color in the plane
        tonemap.toneMapping = LinearToneMapping
    })
    virtualCameras.addEventListener('postRenderCamera', ()=>{
        tonemap.toneMapping = lastTonemapping
    })

}

init().finally(_testFinish)
