/**
 * @private
 */
Ext.define('Ext.util.paintmonitor.Abstract', {

    config: {
        element: null,

        callback: Ext.emptyFn,

        scope: null,

        args: []
    },

    eventName: '',

    monitorClass: '',

    constructor: function(config) {
        this.onElementPainted = Ext.Function.bind(this.onElementPainted, this);

        this.initConfig(config);
    },

    bindListeners: function(bind) {
        this.monitorElement[bind ? 'addEventListener' : 'removeEventListener'](this.eventName, this.onElementPainted, true);
    },

    applyElement: function(element) {
        if (element) {
            return Ext.get(element);
        }
    },

    updateElement: function(element) {
        this.monitorElement = Ext.Element.create({
            classList: [Ext.baseCSSPrefix + 'paint-monitor', this.monitorClass]
        }, true);

        element.appendChild(this.monitorElement);
        element.addCls(Ext.baseCSSPrefix + 'paint-monitored');
        this.bindListeners(true);
    },

    onElementPainted: function() {},

    destroy: function() {
        var me = this,
            monitorElement = me.monitorElement,
            parentNode = monitorElement.parentNode,
            element = me.getElement();

        me.bindListeners(false);
        delete me.monitorElement;

        if (element && !element.destroyed) {
            element.removeCls(Ext.baseCSSPrefix + 'paint-monitored');
            delete me._element;
        }

        if (parentNode) {
            parentNode.removeChild(monitorElement);
        }

        me.callParent();
    }
});
