/* CVS: $Id: EventManager.java,v 1.6 2001/03/14 15:31:30 gvijf Exp $ */

package evolution.events;

import java.util.*;

import evolution.KnowledgeCatalog;

/** 
 * The event manager.
 * @stereotype singleton
 */
public class EventManager {

    /**
     * Create a new eventmanager.
     */
    protected EventManager() {
    }

    /**
     * Get an instance of this singleton.
     */
    public static EventManager getInst() {
        if (instance == null)
            instance = new EventManager();
        return instance;
    }

    /**
     * Subscribe an observer for an event.
     */
    public void subscribe(Observer observer, Class evt) {
        // if the observer is already registered for this event
        // then ignore
        Set regs = (Set) events.get(evt);
        if((regs != null) && regs.contains(observer)) return;
        // if there is no list then create one and add to events
        if(regs == null) {
            regs = new HashSet();
            events.put(evt, regs);
        }
		// add the observer to the list
        regs.add(observer);
    }

    /**
     * Unsubscribe an observer for an event.
     */
    public void unsubscribe(Observer observer, Class evt) {
	    Set regs = (Set) events.get(evt);
        if((regs == null) || !regs.remove(observer))
            throw new RuntimeException("Tried to unsubscribe for event which the observer was not subscribed to");
        // if there are no observers left remove the event list
        if(regs.isEmpty())
            events.remove(regs);
    }

    /**
     * Signal a new event.
     * All the observers subscribed to this event will be notified.
     */
    public void signalEvent(Event event) {
        // see if we have observers for this event
        Set regs = (Set) events.get(event.getClass());
        if(regs == null) {
            return;
        }
        // notify each one of them
        Iterator it = regs.iterator();
        while(it.hasNext()) {
            Observer ob = (Observer) it.next();
            ob.update(event);
        }
	}

    /**
     * An map with events  (Class) as keys and a Set as value with
     * the subscribed observers as elements.
     */
    private Map events = new HashMap();

    /**
     * Instance of the singleton.
     */
    private static EventManager instance = null;

}
