/**
 * 
 * @category Core
 * @subcategory Libraries
 */
class Events {

    // collection of registered app events
    static _registered = [];
    
    constructor() {
        this.channel = document.body;
    }
    /**
     * Candidate for deprecation: registering callbacks sounds like shit load of issues
     * 
     * @param {string} type 
     * @param {*} callback 
     * @param {string} scope 
     */
    addEvent(type, callback, scope) {
        let available = Events._registered.find(o => o.type == type && o.scope == scope);

        if(!available) {
            switch(type) {
                case 'resize':
                    window.addEventListener(type, callback);
                    break;
                default:
                    this.channel.addEventListener(type, callback);
            }

            Events._registered.push({scope: scope, type: type, callback: callback})
        }
    }

    removeEvent(type, callback, scope) {
        let index = Events._registered.findIndex(o => o.type == type && o.scope == scope);

        if(index != -1) {
            switch(type) {
                case 'resize':
                    window.removeEventListener(type, callback);
                    break;
                default:
                    this.channel.removeEventListener(type, callback);
            }

            Events._registered.splice(index,1);
        }
    }


    /**
     * 
     * @param {string} type 
     * @param {*} data 
     */
    trigger(type, data) {

        let event = new CustomEvent(type, {detail: data});
        
        switch(type) {
            case 'resize':
                window.dispatchEvent(event);
                break;
            default:
                this.channel.dispatchEvent(event);
        }
        
    }

    /**
     * 
     * @param {string} scope 
     */
    clear(scope) {
        let i = 0;
        while(i < Events._registered.length) {
            let event = Events._registered[i];

            if(event.scope == scope) {
                switch(event.type) {
                    case 'resize':
                        window.removeEventListener(event.type, event.callback);
                        break;
                    default:
                        document.body.removeEventListener(event.type, event.callback);
                }
                Events._registered.splice(i, 1);
            } else {
                i++;
            }
        }
    }
}

app.registerClass('Events', Events);