<template>
    <div class="asset-preview">
        <div v-show="forRendering">
            <div class="position-relative">
                <div ref="target"></div>
                <div class="renderer-gizmo"></div>
            </div>
            <v-slide-group show-arrows>
                <v-slide-group-item v-for="(a, i) in animations" :key="i" v-slot="{ isSelected }">
                    <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2"
                        :prepend-icon="'mdi-' + (a.playing ? 'stop' : 'play')" rounded @click="toggleAnimation(a)">
                        {{ a.name }}
                    </v-btn>
                </v-slide-group-item>
            </v-slide-group>
        </div>
        <img v-if="obj && !forRendering && obj.type == 'object2d'" :src="`/asset/default/${obj.asset?.name}`" />
        <video v-if="obj && !forRendering && obj.type == 'video'" controls :autoplay="autoplay ? 'autoplay' : ''" 
            :src="`/asset/default/${obj.asset?.name}`"></video>
        <audio v-if="obj && !forRendering && obj.type == 'audio'" controls :autoplay="autoplay ? 'autoplay' : ''" 
            :src="`/asset/default/${obj.asset?.name}`" class="d-block w-100"></audio>
    </div>
</template>

<script>
import { GameEngine } from '@/lib/GameEngine.js';
let engine = null;

export default{
    props:{
        object: Object,
        objectId: Number,
        autoplay: Boolean
    },
    data(){
        return {
            animations: [],
            obj: null
        }
    },
    async mounted(){
        if (this.object) {
            this.obj = this.object;
        }else{
            this.obj = (await this.$api.gameObject.load(this.objectId)).data; 
        }
    },
    beforeUnmount() {
        engine?.dispose();
        engine = null;
    },
    watch:{
        object(n){
            this.obj = n;
        },
        async obj(){
            if (!this.obj) return;
            engine = new GameEngine();
            await engine.init(this.$refs.target, {
                gizmo: true, 
                xr: true,
                mode: 'ObjectPreview'
            });
            await this.loadAsset();
        }
    },
    computed:{
        forRendering() {
            return this.$p.objectTypes.find(t=> t.value == this.obj?.type)?.render || this.obj?.asset?.name?.endsWith('ktx2')
        }
    },
    methods:{
        async loadAsset() {
            if (this.forRendering) {
                engine.resetScene();
                engine.ambientLight.intensity = 25;
                if (this.obj.type == 'panorama2d') {
                    await engine.loadPanorama(this.obj.asset.name);
                } else if(this.obj.asset.name.endsWith('ktx2')){
                    let tx = await engine.loadTexture(this.obj.asset.name);
                    let k = Math.min(window.innerHeight / tx.image.height, 1);
                    engine.resize(tx.image.width * k, tx.image.height * k);
                    engine.scene.background = tx;
                }else{
                    let gltf = await engine.load(this.obj.asset.name);
                    this.loadedAsset = gltf;
                    this.animations = gltf.animations.map(a => ({
                        name: a.name, id: a.uuid
                    }));
                    engine.meshUtils.autoScale(gltf.scene);
                    let bb = engine.meshUtils.getBoundingBox(gltf.scene);
                    let ln = engine.meshUtils.getBoundingBoxMaxLength(bb);
                    let cp = engine.meshUtils.getBoundingBoxCenterPoint(bb);
                    engine.camera.position.set(cp.x, cp.y*1.77, ln*1.5);
                    engine.orbitControls.target.set(cp.x,cp.y*1.77,cp.z)
                    engine.orbitControls.update();
                    engine.activeObjects.add(gltf.scene);
                }
            }
        },

        async toggleAnimation(animation){
            animation.playing = !animation.playing;
            engine.playAnimation(
                engine.scene, 
                this.loadedAsset.animations.find(a=>a.uuid == animation.id),
                animation.playing
            );
        },

        async captureScreenshot(){
            return await engine.captureScreenshot();
        }
    }
}
</script>