/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.events;

import net.ranides.assira.annotations.Meta;

/**
 *
 * @author ranides
 */
public abstract class EventBinding<T extends Event> {

    public abstract Class<T> event();

    public abstract EventListener<? super T> listener();

    @SuppressWarnings("unchecked")
    public static void copyTo(EventRouter target, EventRouter source) {
        for(EventBinding entry : source.getEventListeners()) {
            target.addEventListener(entry.event(), entry.listener());
        }
    }

    public static <TT extends Event> EventBinding<TT> make(Class<TT> event, EventListener<? super TT> listener) {
        return new Simple<>(event, listener);
    }

    @Meta.Unsafe
    @SuppressWarnings("unchecked")
    static EventBinding<?> $make(Object event, Object listener) {
        assert event instanceof Class;
        assert listener instanceof EventListener;
        return new Simple((Class)event, (EventListener)listener);
    }

    private static final class Simple<TT extends Event> extends EventBinding<TT> {

        private final Class<TT> event;
        private final EventListener<? super TT> listener;

        public Simple(Class<TT> event, EventListener<? super TT> listener) {
            this.event = event;
            this.listener = listener;
        }

        @Override
        public Class<TT> event() {
            return event;
        }

        @Override
        public EventListener<? super TT> listener() {
            return listener;
        }

    }

//    Map.Entry<Class<? extends Event>, EventListener<? super Event>>

}
