package relational.email;

import javax.swing.*;
import javax.swing.event.*;

/**
 * This class does for senders of ChangeEvent what AWTEventMulticaster does
 * for all the other events.
 * Maintains an immutable linked list of listeners, multicasting
 * any events to all listeners on the list.
 * Bears a striking resemblance to AWTEventMulticaster.
 *
 * @classConcise true
 * @author Jon Howell
 */
public class ChangeEventMulticaster
	implements ChangeListener {

	protected final ChangeListener a, b;

	protected ChangeEventMulticaster(ChangeListener a, ChangeListener b) {
		this.a = a;
		this.b = b;
	}

	protected ChangeListener remove(ChangeListener removee) {
		if (a==removee)
			return b;
		if (b==removee)
			return a;
		ChangeListener a2 = remove(a, removee);
		ChangeListener b2 = remove(b, removee);
		if (a2==a && b2==b) {
			return this;	// it wasn't here; don't waste memory consing
		}
		return add(a2, b2);
	}

	// the "constructor" that client code uses
	public static ChangeListener add(ChangeListener a, ChangeListener b) {
		if (a==null)
			return b;
		if (b==null)
			return a;
		return new ChangeEventMulticaster(a, b);
	}

	public static ChangeListener remove(ChangeListener list, ChangeListener removee) {
		if (list==removee || list==null) {
			return null;
		} else if (list instanceof ChangeEventMulticaster) {
			return ((ChangeEventMulticaster) list).remove(removee);
		} else {
			// "list" is actually some other listener, and removee isn't it.
			return list;
		}
	}

	public void stateChanged(ChangeEvent e) {
		// pass event down both lists (usually the left one is a singleton
		// and the right the rest of the list.)
		a.stateChanged(e);
		b.stateChanged(e);
	}
}
