
AFRAME.registerComponent('fade-mesh', {
    schema: {
        meshNameStartsWith: {type: 'array'},
        targetOpacity: {type: 'number', default: 0},
        speed: {type: 'number', default: 2}
    },
	init: function () {
        // console.log("*** FADE_MESH ***");
        var component = this;
        component.startingOpacity = 1;
        component.direction = 0;
        component.meshNameStartsWith = this.data.meshNameStartsWith;
        component.ready = false;
        component.model = component.el.getObject3D('mesh');

        const initializeFade = () => {
            // console.log("*** FADE_MESH *** INITIALIZE STARTED");
            component.model = component.el.getObject3D('mesh');
            component.model.traverse(node => {
                if (node.isMesh) {
                    component.meshNameStartsWith.forEach(function (element) {
                        if (node.name.startsWith(element)) {
                            component.startingOpacity = node.material.opacity;
                        }
                    });
                }
            });
        };

        if(component.model === undefined){
            // console.log("*** FADE_MESH *** MODEL NOT READY - Wait for model-loaded");
            this.el.addEventListener("model-loaded", (e)=>{initializeFade()});
        }
        else{
            // console.log("*** FADE_MESH *** MODEL READY - Initialize fade");
            initializeFade();
        }

            if(component.startingOpacity > component.data.targetOpacity){
                component.direction = -1;
            } else if(component.startingOpacity < component.data.targetOpacity){
                component.direction = 1;
            }

            component.ready = true;
            // console.log('*** FADE_MESH ***  INITIALIZED: StartingOpacity: ' + component.startingOpacity + ' targetOpacity: ' + component.data.targetOpacity + ' direction: ' + component.direction + ' meshNameStartsWith: ' + component.meshNameStartsWith);


        this.el.addEventListener("model-loaded", (e)=>{});
    },
    tick: function(time, timeDelta) {

        if(this.ready != true){
            console.log('not ready');
            return;
        }

        var component = this;
        var model = this.model;
        var targetOpacity = this.data.targetOpacity;
        var direction = this.direction;
        var meshNameStartsWith = this.meshNameStartsWith;
        
        //check the latest opacity
        var newOpacity = -1;
        
        model.traverse(node => {
            if (node.isMesh) {
                meshNameStartsWith.forEach(function (element) {
                    if (node.name.startsWith(element)) {
                        newOpacity = node.material.opacity;
                    }
                });
            }
        });

        // console.log('*** TICK ***  Model: ' + model + ' targetOpacity: ' + targetOpacity + ' newOpacity ' + newOpacity + ' direction: ' + direction + ' meshNameStartsWith: ' + component.meshNameStartsWith);


        //if newOpacity was never changed
        if(newOpacity === -1){
            //QUIT because no objects found
        }

        var distance = 0.0;

        if(direction > 0){
            if(newOpacity >= targetOpacity){
                component.el.removeAttribute('fade-mesh');
                // console.log('*** FADE_MESH *** Completed');
            }else{
                distance = targetOpacity - newOpacity;
            }
        }else if(direction < 0){
            if(newOpacity <= targetOpacity){
                component.el.removeAttribute('fade-mesh');
                // console.log('*** FADE_MESH *** Completed');
            }else{
                distance = newOpacity - targetOpacity;
            }
        }else{
            component.el.removeAttribute('fade-mesh');
            // console.log('*** FADE_MESH *** Completed');
        }

        model.traverse(node => {
            if (node.isMesh) {
                this.meshNameStartsWith.forEach(function (element) {
                    if (node.name.startsWith(element)) {
                        targetOpacity = newOpacity + ((component.data.speed * (timeDelta / 1000)) * direction);
                        node.material.opacity = targetOpacity;
                    }
                });
            }
        });
    }
});