import { Raycaster, Vector3 } from "three"

class Clickable {
    constructor(defaultDistance) {
        const objects = [];
        const raycaster = new Raycaster();
        let v = new Vector3;

        this.add = function (object, fn, distance) {
            objects.push(object);
            object._clickable = { fn, distance: distance || defaultDistance };
        };

        this.remove = function (object) {
            objects.splice(objects.indexOf(object), 1);
            delete object._clickable;
        };

        this.removeAll = function(){
            objects.forEach(o=>delete o._clickable)
            objects.splice(0, objects.length);
        }

        this.update = function (mouse, camera, event) {
            raycaster.setFromCamera(mouse, camera);
            let forExecute = [];
            objects.filter(o=>{
                do {
                    if (o.__locked) return false;
                    o = o.parent;
                } while (o);
                return true;
            }).forEach(o => {
                o.getWorldPosition(v);
                if (camera.position.distanceTo(v) <= o._clickable.distance && o.visible) {
                    const intersects = raycaster.intersectObject(o);
                    // intersects.forEach(i=>{
                    //     forExecute.push({o, i})
                    // })
                    if (intersects[0]) forExecute.push({ o, i: intersects[0] });
                }
            });
            if (forExecute[0]) {
                let sorted = forExecute.sort((a, b) => a.i.distance - b.i.distance);
                sorted[0].o._clickable.fn(sorted[0].i);
                if (this.onclick) {
                    this.onclick(sorted[0].o, sorted[0].i, event);
                }
            }
        };
    }
}

export {Clickable}