"use strict";

function cssAnimationSync(animationName) {
    var defaultOptions = {
        graceful: true
    };
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var opts = defaultOptions;
    var elements = new Set();
    var eventTime;
    var lastInterationTS = cssSyncNow();
    var interationDuration = 0;

    function animationStart(event) {
        if (event.animationName === animationName) {
            var el = event.target;

            if (opts.graceful && !elements.has(el) && interationDuration !== 0) {
                gracefulStart(el, interationDuration, lastInterationTS);
            }

            elements.add(el);
        }
    }

    function animationIteration(event) {
        if (event.animationName === animationName) {
            elements.add(event.target);
            requestAnimationFrame(function (frameTime) {
                if (frameTime !== eventTime) {
                    interationDuration = cssSyncNow() - lastInterationTS;
                    lastInterationTS = cssSyncNow();
                    cssSyncRestart(elements);
                }

                eventTime = frameTime;
            });
        }
    }

    window.addEventListener('animationstart', animationStart, true);
    window.addEventListener('animationiteration', animationIteration, true);
    return {
        free: function free() {
            window.removeEventListener('animationstart', animationStart);
            window.removeEventListener('animationiteration', animationIteration);
            this.start();
            elements.clear();
        },
        start: function start() {
            elements.forEach(function (el) {
                if (cssSyncValidate(elements, el)) {
                    el.style.removeProperty('animation');
                }
            });
        },
        stop: function stop() {
            elements.forEach(function (el) {
                if (cssSyncValidate(elements, el)) {
                    el.style.setProperty('animation', 'none');
                }
            });
        },
        pause: function pause() {
            elements.forEach(function (el) {
                if (cssSyncValidate(elements, el)) {
                    el.style.setProperty('animation-play-state', 'paused');
                }
            });
        }
    };
}

function cssSyncRestart(elements) {
    elements.forEach(function (el) {
        if (window.getComputedStyle(el).animationPlayState !== 'paused') {
            if (cssSyncValidate(elements, el)) {
                el.style.setProperty('animation', 'none');
            }
        }
    });
    requestAnimationFrame(function () {
        elements.forEach(function (el) {
            if (window.getComputedStyle(el).animationPlayState !== 'paused') {
                if (cssSyncValidate(elements, el)) {
                    el.style.removeProperty('animation');
                }
            }
        });
    });
}

function gracefulStart(el, interationDuration, lastInterationTS) {
    var remaining = interationDuration - (cssSyncNow() - lastInterationTS);
    console.log(interationDuration, remaining);
    el.style.setProperty('animation-duration', remaining);
}

function cssSyncNow() {
    return new Date().getTime();
}

function cssSyncValidate(elements, el) {
    var isValid = document.body.contains(el);

    if (!isValid) {
        elements.delete(el);
    }

    return isValid;
}