import global from '@dojo/framework/shim/global';
import { create, destroy, diffProperty } from '@dojo/framework/core/vdom';
import { shallow } from '@dojo/framework/core/diff';
import { createICacheMiddleware } from '@dojo/framework/core/middleware/icache';
const factory = create({
    destroy,
    diffProperty,
    icache: createICacheMiddleware()
}).properties();
export const GlobalEvent = factory(function ({ children, properties, middleware: { destroy, diffProperty, icache } }) {
    const registerListeners = (type, previousListeners, newListeners) => {
        const currentListeners = icache.getOrSet('listeners', {
            window: {},
            document: {}
        });
        const registeredListeners = {};
        previousListeners &&
            Object.keys(previousListeners).forEach((eventName) => {
                const newListener = newListeners ? newListeners[eventName] : undefined;
                if (newListener === undefined) {
                    global[type].removeEventListener(eventName, currentListeners[type][eventName]);
                }
                else if (previousListeners[eventName] !== newListener) {
                    global[type].removeEventListener(eventName, currentListeners[type][eventName]);
                    global[type].addEventListener(eventName, newListener);
                    registeredListeners[eventName] = newListener;
                }
                else {
                    registeredListeners[eventName] = newListener;
                }
            });
        newListeners &&
            Object.keys(newListeners).forEach((eventName) => {
                if (previousListeners === undefined || previousListeners[eventName] === undefined) {
                    global[type].addEventListener(eventName, newListeners[eventName]);
                    registeredListeners[eventName] = newListeners[eventName];
                }
            });
        currentListeners[type] = registeredListeners;
        icache.set('listeners', currentListeners);
    };
    diffProperty('window', properties, (previous, next) => {
        const { changed } = shallow(previous.window, next.window);
        changed && registerListeners('window', previous.window, next.window);
    });
    diffProperty('document', properties, (previous, next) => {
        const { changed } = shallow(previous.document, next.document);
        changed && registerListeners('document', previous.document, next.document);
    });
    const removeAllRegisteredListeners = (type) => {
        const currentListeners = icache.getOrSet('listeners', {
            window: {},
            document: {}
        });
        Object.keys(currentListeners[type]).forEach((eventName) => {
            global[type].removeEventListener(eventName, currentListeners[type][eventName]);
        });
    };
    destroy(() => {
        removeAllRegisteredListeners('window');
        removeAllRegisteredListeners('document');
    });
    if (children().length > 0) {
        return children();
    }
    return null;
});
export default GlobalEvent;

/*# sourceMappingURL=index.mjs.map*/