package hep.aida.ref.event;

import java.util.*;
/**
 * A basic implementation of isObservable.
 * Although this class implements all the methods of IsObservable, it does
 * not explicitly implement the IsObservable interface. This is so that
 * ManagedObject can extend AIDAObservable, although not all ManagedObjects
 * implement IsObservable.
 *
 * @author tonyj
 * @version $Id: AIDAObservable.java,v 1.5 2004/10/12 00:19:21 serbo Exp $
 */
public abstract class AIDAObservable
{
   private List listeners;
   private Map hash;
   protected boolean isValid = false;
   private boolean isValidAfterNotify = false;
   private EventObject theEvent;
   
   protected AIDAObservable()
   {
   }
   protected void setIsValidAfterNotify(boolean value)
   {
      isValidAfterNotify = value;
   }
   public synchronized void addListener(AIDAListener l)
   {
      if (listeners == null) listeners = new ArrayList();
      listeners.add(l);
      if (theEvent == null) theEvent = createEvent();
      if (hash == null) hash = new HashMap();
      hash.put(l, new Boolean(true));
      isValid = true;
   }
   public synchronized void removeListener(AIDAListener l)
   {
      if (listeners != null) listeners.remove(l);
      if (listeners != null) hash.remove(l);
      if (listeners.isEmpty()) isValid = false;
   }
   public synchronized void removeAllListeners()
   {
      if (listeners != null) listeners.clear();
      if (hash != null) hash.clear();
      isValid = false;
   }
   public void setValid(AIDAListener l)
   {
       if (listeners != null) { 
           hash.put(l, new Boolean(true));
           isValid = true;
       }
   }
   protected EventObject createEvent()
   {
      return new EventObject(this);
   }
   /**
    * Method to be used by subclass that only fire a single event (theEvent)
    */
   protected void fireStateChanged()
   {
      fireStateChanged(theEvent);
   }
   protected synchronized void fireStateChanged(EventObject event)
   { 
      isValid = isValidAfterNotify;
      if (listeners != null)
      {
         for (int i = listeners.size(); i-->0; )
         {
            AIDAListener l = (AIDAListener) listeners.get(i);
            boolean listenerValid = ((Boolean) hash.get(l)).booleanValue();
            if (listenerValid) {
                l.stateChanged(event);
                hash.put(l, new Boolean(isValidAfterNotify));
            }
         }
      }
   }
}