/**
 * @category Core
 * @subcategory Application
 */
class View {

    _sparcId = null;
    _className = null;
    _controller = null;
    
    title = "";
    description = "";

    /**
     * 
     * @param {*} parms 
     */
    constructor(parms) {
        parms = parms || {};
        this._sparcId = crypto.randomUUID();
        this.title = parms.title || '';
        this.description = parms.description || '';
    }

    /**
     * base method called when content is appended to the document.
     */
    DOMContentLoaded() {}

    /**
     * base method called when content is removed from the document.
     */
    DOMContentFocused() {}

    /**
     * base method called when content is removed from the document.
     */
    DOMContentBlured() {}
    
    /**
     * base method called when content is removed from the document.
     */
    DOMContentRemoved() {}
    /**
     * acts as a shortcut for vanilla querySelector Element method.
     * @param {*} selector 
     * @returns {Element|null}
     */
    find(selector) { return this.el ? this.el.querySelector(selector): null; }

    /**
     * acts as a shortcut for vanilla querySelectorAll Element method.
     * @param {*} selector 
     * @returns {Array<Element>}
     */
    findAll(selector) { return this.el ? this.el.querySelectorAll(selector): null; }

    /**
     * wrapper for vanilla addEventListener Element method.
     * @param {*} type 
     * @param {*} callback 
     */
    addEvent(type, callback) { app.addEvent(type, callback, this._sparcId); }

    /**
     * AddEvent to all found selector.
     * @param {*} selector 
     * @param {*} type 
     * @param {*} callback  
     */
    addEventTo(selector, type, callback) { 
        for(let el of this.findAll(selector)) {
            // Cannot use the wrapper because not attached to el, but to window
            // app.addEvent(type, callback, this._sparcId); 
            //TODO: see with Mike if addEvent could include target element .
            el.addEventListener(type, callback);
        }
    }

    /**
     * Add an action to all found selector.
     * @param {*} selector 
     * @param {*} type  
     * @todo what is this used for ? deprecate ?
     */    
    addActions(selector, type) {
        this.addEventTo(selector+'[action]', type, e => {
            let ax = this['action_'+e.target.getAttribute('action')];
            if(typeof(ax)== 'function') ax.bind(this)(e);
            else console.warn('Bad action: '+e.target.getAttribute('action'));
        });
    }

    /**
     * aggregates the content inner key to the targeted selector, avoiding targeting other content.
     * @param {string} selector 
     * @returns {string}
     */
    scope(selector) { return `${selector}@${this._sparcId}`; }

    /**
     * Wrapper for Controller.loadView
     * @param {*} name 
     * @param {*} args 
     * @async
     * @returns {View}
     */
    loadView(name, args) { return this._controller.loadView(name, args); }

  }

  app.registerClass('View', View)