// ResourceEventMulticaster.java
// $Id: ResourceEventMulticaster.java,v 1.3 1997/07/30 14:07:44 ylafon Exp $  
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.tools.resources.impl;

import java.util.EventListener;
import w3c.tools.resources.event.*;

/**
 * Event dispatching suport class.
 */

public class ResourceEventMulticaster 
    implements AttributeChangedListener, 
               StructureChangedListener
{
    protected final EventListener a, b;

    protected ResourceEventMulticaster(EventListener a, EventListener b) {
	this.a = a;
	this.b = b;
    }

    protected EventListener remove(EventListener oldl) {
	// Remember these old lisp days ?
	if ( oldl == a )
	    return b;
	if ( oldl == b)
	    return a;
	EventListener a2 = removeInternal(a, oldl);
	EventListener b2 = removeInternal(b, oldl);
	if (a2 == a && b2 == b)
	    return this;
	return addInternal(a2, b2);
    }

    protected static 
    EventListener removeInternal(EventListener l, EventListener oldl) {
	if ( l == oldl || l == null ) {
	    return null;
	} else if ( l instanceof ResourceEventMulticaster ) {
	    return ((ResourceEventMulticaster) l).remove(oldl);
	} else {
	    return l;
	}
    }

    protected static
    EventListener addInternal(EventListener a, EventListener b) {
	if ( a == null )
	    return b;
	if ( b == null )
	    return a;
	return new ResourceEventMulticaster(a, b);
    }

    /**
     * Add an attribute change listener.
     */

    public static 
    AttributeChangedListener add(AttributeChangedListener a
				 , AttributeChangedListener b) {
	return (AttributeChangedListener) addInternal(a, b);
    }
    
    /**
     * Remove an attrbite change listener.
     */

    public static
    AttributeChangedListener remove(AttributeChangedListener l
				   , AttributeChangedListener oldl) {
	return (AttributeChangedListener) removeInternal(l, oldl);
    }

    /**
     * Propagate AttributeChanged events.
     */

    public void attributeChanged(AttributeChangedEvent evt) {
	((AttributeChangedListener) a).attributeChanged(evt);
	((AttributeChangedListener) b).attributeChanged(evt);
    }

    /**
     * Add a structure changed listener.
     */

    public static 
    StructureChangedListener add(StructureChangedListener a
				 , StructureChangedListener b) {
	return (StructureChangedListener) addInternal(a, b);
    }

    /**
     * Remove a structure changed listener.
     */

    public static 
    StructureChangedListener remove(StructureChangedListener l
				    , StructureChangedListener oldl) {
	return (StructureChangedListener) removeInternal(l, oldl);
    }

    public void resourceUnloaded(StructureChangedEvent evt) {
	((StructureChangedListener) a).resourceUnloaded(evt);
	((StructureChangedListener) b).resourceUnloaded(evt);
    }

    public void resourceInited(StructureChangedEvent evt) {
	((StructureChangedListener) a).resourceInited(evt);
	((StructureChangedListener) b).resourceInited(evt);
    }

    public void resourceCreated(StructureChangedEvent evt) {
	((StructureChangedListener) a).resourceCreated(evt);
	((StructureChangedListener) b).resourceCreated(evt);
    }

    public void resourceDeleted(StructureChangedEvent evt) {
	((StructureChangedListener) a).resourceDeleted(evt);
	((StructureChangedListener) b).resourceDeleted(evt);
    }
	
	
}
