Source: package/mesh/gltf.js

// import { GLTFLoader } from '../../../node_modules/three/build/three.module.js';
import { Reporter } from '../../reporter/reporter.js';
import { LoadableComponent } from '../component/loadable_component.js';
import { checkPropTypes, copyProps, UUIDRegex } from '../../lib.js';
import { LoadingBase } from '../loader/loading_base.js';
import { SceneManager } from '../../scene/scene_manager.js';

//bases transfrom
import { Group, Vector3, Matrix4, Mesh } from '../../../node_modules/three/build/three.module.js';
import { getBasisTransform } from './bases_transform.js';


//Loaders

// import { GLTFLoader } from '../loader/gltf_loader.js';
// import { DRACOLoader } from '../loader/draco_loader.js';

import { GLTFLoader } from '../../../node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from '../../../node_modules/three/examples/jsm/loaders/DRACOLoader.js';
//import { DracoDecoderModule } from '../../../node_modules/three/examples/js/libs/draco/draco_decoder.js';


// dit is heel annoying
// ik wil dit includen in de build, niet achteraf "bijladen"


const dracoLoader = new DRACOLoader();

const pathToDir = window.location.href.replace(/[^/]*$/, '');

dracoLoader.setDecoderPath(pathToDir + 'draco/');
const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);

/**
 * Refers to loadable file that can hold one or more multiple geometries
 */

class GLTF extends LoadableComponent {

    /**
     * @param {Reporter} reporter
     * @param {Object} settings
     * @param {UUID} [settings.id]
     * @param {string} [settings.name]
     * @param {QualitySourceMap} settings.source
     * @param {Array<string>} settings.meshNames
     * @param {string} settings.basis
     */

    constructor(reporter, settings) {

        super(reporter, settings);

        checkPropTypes(
            settings,
            {
                meshNames: val => Array.isArray(val) && val.every(name => typeof (name) === 'string'),
                basis: 'string' 
            },
            {}
        );

        this.transformMatrix = new Matrix4();
        getBasisTransform( settings.basis || '+X+Y+Z' , SceneManager.basis, this.transformMatrix );

    }

    static _exportName = {
        singular: 'gltf',
        plural: 'gltfs'
    };


    /**
     * @param {LoadingBase} base
     * @param {LoadingQuality} quality 
     */

    async _load(base, quality ) {

        const component = this;

        const fileURL = new URL(base.url.href + this._settings.source[quality].path);

        this.report({ msg: `Loading file from ${fileURL}` })

        return new Promise((resolve, reject) => {

            gltfLoader.load(

                fileURL.href,

                // onLoad callback
                function (file) {

                    const gltf = {};

                    for (let meshName of component._settings.meshNames) {

                        //binnenkomende mesh omzetten naar nieuwe schone mesh
                        const obj = file.scene.getObjectByName(meshName, true);

                        const cleanMesh = new Mesh()
                        cleanMesh.name = meshName
                        cleanMesh.geometry = obj.geometry
                        //cleanMesh.matrixAutoUpdate = false;

                        // Create an object to represent the framee
                        const group = new Group();
                        component.transformMatrix.decompose( group.position, group.quaternion, group.scale );
                        
                        const meshObject = { 
                            meshName: meshName,
                            mesh: cleanMesh,
                            transformMatrix: component.transformMatrix,
                            transformQuaternion: group.quaternion,
                            basis: component.settings.basis
                        };
                        
                        //cleanMesh.matrixAutoUpdate = true;

                        if (!obj) {
                            throw new Error(`Missing specified geometry "${meshName}" in geometry file at ${fileURL}`);
                        }

                        gltf[meshName] = meshObject  //cleanMesh //.geometry 
                        
                    }

                    resolve({ file, gltf });
                    
                    // component._setContent('main', quality, { file, geometries })
                    //     .then( _ => resolve(component));
                },

                // onProgress callback currently not supported
                undefined,

                // onError callback
                function (error) {
                    reject(error);
                }
            );
        });
    }

    
    
}

export { GLTF };