export default class TransitionDetect {
    constructor(target = null, timeout = false) {
        this.target = target;
        this.animating = false;
        this.timeout = timeout;
    }

    dismiss() {
        this.animating = false;
        this.target && this.target.removeEventListener('transitionend', this.transitionEnd);
        clearTimeout(this._timeout);
        return this;
    }

    setTarget(target) {
        this.target = target;
        return this;
    }

    transitionEnd = () => {
        this.animating = false;
        clearTimeout(this._timeout);
        this._end && this._end();
        if (this._continuous) {
            this.start(false);
        } else {
            this.target.removeEventListener('transitionend', this.transitionEnd);
        }
    };

    update = () => {
        this._update && this._update();
        if (this.animating) {
            window.requestAnimationFrame(this.update);
        }
    };

    onUpdate(callback) {
        this._update = callback;
        return this;
    }

    onEnd(callback) {
        this._end = callback;
        return this;
    }

    isContinuous(is) {
        if (is === undefined) return this._continuous;
        this._continuous = is;
        return this;
    }

    start(addTransitionEndListener = true) {
        // if already started just return
        if (this.animating) {
            return this;
        }
        if (!this.target) {
            throw 'Cannot set a transition event listener without a target!';
        }
        if (addTransitionEndListener) {
            this.target.addEventListener('transitionend', this.transitionEnd, false);
        }
        this.animating = true;
        // skip the update if there is no registered callback
        this._update && window.requestAnimationFrame(this.update);
        if (this.timeout) {
            this._timeout = setTimeout(this.transitionEnd, this.timeout);
        }
        return this;
    }
}
