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

import java.util.Objects;

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

    Class<T> event();

    EventListener<? super T> listener();
    
    static <TT extends Event> EventBinding<TT> bind(Class<TT> event, EventListener<? super TT> listener) {
        return new Immutable<>(event, listener);
    }
    
    final class Immutable<TT extends Event> implements EventBinding<TT> {

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

        public Immutable(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;
        }

        @Override
        public int hashCode() {
            return event.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if(!(obj instanceof EventBinding<?>)) {
                return false;
            }
            final EventBinding<?> other = (EventBinding<?>) obj;
            return 
                Objects.equals(event(), other.event()) &&
                Objects.equals(listener(), other.listener());
        }

        @Override
        public String toString() {
            return "{ event=" + event.getSimpleName() + " listener=" + listener + " }";
        }

    }

}
