'use strict';

var helpers = require('./helpers-HuaiWXrB.js');
var listener = require('./listener-DspXpqzY.js');

class BalAnimationListener extends listener.ListenerAbstract {
    constructor() {
        super(...arguments);
        this.debouncedNotify = helpers.debounce(target => this.notify({ target }), 42);
        this.callbackWillAnimate = (ev) => {
            helpers.isChildOfEventTarget(ev, this.el, target => this.debouncedNotify(target));
        };
        this.callbackDidAnimate = (ev) => {
            helpers.isChildOfEventTarget(ev, this.el, target => this.debouncedNotify(target));
        };
    }
    connect(el) {
        super.connect(el);
        const win = window;
        if (win) {
            helpers.addEventListener(win, 'balWillAnimate', this.callbackWillAnimate, { passive: true });
            helpers.addEventListener(win, 'balDidAnimate', this.callbackDidAnimate, { passive: true });
        }
    }
    disconnect() {
        super.disconnect();
        const win = window;
        if (win) {
            helpers.removeEventListener(win, 'balWillAnimate', this.callbackWillAnimate);
            helpers.removeEventListener(win, 'balDidAnimate', this.callbackDidAnimate);
        }
    }
}

class BalAnimationSubject extends listener.SingleSubject {
    constructor() {
        super((observer, data) => {
            observer.animationListener(data);
        });
        this.listener = new BalAnimationListener();
    }
    attach(observer) {
        super.attach(observer);
        this.listener.connect(observer.el);
        this.listener.add(info => super.notify(info));
    }
    detach() {
        super.detach();
        this.listener.disconnect();
    }
}
new BalAnimationSubject();

function ListenToAnimation() {
    return function (target, _propertyKey, _descriptor) {
        const { connectedCallback, componentDidLoad, disconnectedCallback } = target;
        target.connectedCallback = function () {
            if (!this._balAnimationSubject) {
                this._balAnimationSubject = new BalAnimationSubject();
            }
            return connectedCallback && connectedCallback.call(this);
        };
        target.componentDidLoad = function () {
            this._balAnimationSubject.attach(this);
            return componentDidLoad && componentDidLoad.call(this);
        };
        target.disconnectedCallback = function () {
            if (this._balAnimationSubject) {
                this._balAnimationSubject.detach();
                this._balAnimationSubject = undefined;
            }
            return disconnectedCallback && disconnectedCallback.call(this);
        };
    };
}

exports.ListenToAnimation = ListenToAnimation;
