/*
 *This library is free software; you can redistribute it and/or
 *modify it under the terms of the GNU Lesser General Public
 *License as published by the Free Software Foundation; either
 *version 2.1 of the License, or (at your option) any later version.
 *
 *This library is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *Lesser General Public License for more details.
 *
 *You should have received a copy of the GNU Lesser General Public
 *License along with this library; if not, write to the Free Software
 *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* 
 * This software was written by Julian Selley (j.selley@man.ac.uk)
 * whilst at the University of Manchester as a Research Assistant. 
 *
 * The initial code base is copyright by the University of Manchester. 
 * Modifications to the initial code base are copyright of their 
 * respective authors, or their employers as appropriate. Authorship 
 * of the modifications may be determined from the ChangeLog placed 
 * at the end of this file
 */

package uk.ac.man.bioinf.sequence.event; // Package name inserted by JPack

import java.util.Vector;
import java.util.Enumeration;
import uk.ac.man.bioinf.sequence.event.SequenceEvent;


/**
 * SequenceListenerSupport.java
 *
 * This class provides support and handles the listeners to a specific
 * sequence. This ofcourse means there is one support object for one
 * sequence object.
 * @see AbstractSequence
 *
 * Created: Wed Feb 16 19:28:44 2000
 *
 * @author J Selley
 * @version $Id: SequenceListenerSupport.java,v 1.5 2001/04/11 17:04:43 lord Exp $
 */

public class SequenceListenerSupport 
{
  private Vector listeners, vetoableListeners;

  public SequenceListenerSupport()
  {
    listeners = new Vector();
    vetoableListeners = new Vector();
  }
  
  /**
   * There is really no point in making an event object if there are
   * no listeners. This method allows other classes to be intelligent
   * about the way it does things.
   * @return a <code>boolean</code> value
   */
  public boolean hasListeners()
  {
    return (listeners.size() > 0 || vetoableListeners.size() > 0);
  }
  
  /**
   * This function fires the sequence event to all the interested listeners.
   * It also fires to the vetoable listeners, which are stored separately, 
   * because the interface for VetoableSequenceListener extends the
   * SequenceListener interface.
   * @see VetoableSequenceListener
   * @see SequenceListener
   *
   * @param event the event to be fired
   */
  public void fireSequenceEvent(SequenceEvent event)
  {
    // enumerate through the listeners and exec the changeOccured function
    for (Enumeration i = listeners.elements(); i.hasMoreElements(); ) {
      ((SequenceListener)i.nextElement()).changeOccurred(event);
    }
    // also enumerate through the vetoable listeners
    // NB: VetoableSequenceListener extends SequenceListener
    for (Enumeration i = vetoableListeners.elements(); i.hasMoreElements(); ) {
      //System.out.println( "Next element is " + i.nextElement() );
      ((SequenceListener)i.nextElement()).changeOccurred(event);
    }
  }

  /**
   * This function fires the vetoable event to the vetoable listeners.
   *
   * @param event the event to be fired
   */
  public void fireVetoableSequenceEvent(VetoableSequenceEvent event)
    throws SequenceVetoException
  {
    // enumerate through vetoable listeners only
    for (Enumeration i = vetoableListeners.elements(); i.hasMoreElements(); ) {
      ((VetoableSequenceListener)i.nextElement()).vetoableChangeOccurred(event);
    }
  }

  /**
   * Adds a sequence listener object to a Vector of listeners.
   *
   * @param listener the sequence listener
   */
  public void addSequenceListener(SequenceListener listener)
  {
    if( listener == null )
      throw new NullPointerException( "Can not add null sequence listener" );
	
    if (listeners.contains(listener)) return;
    else listeners.addElement(listener);
  }

  /**
   * Removes a sequence listener.
   *
   * @param listener the sequence listener
   */
  public void removeSequenceListener(SequenceListener listener)
  {
    listeners.removeElement(listener);
  }

  /**
   * Adds a vetoable sequence listener to the Vector of listeners.
   *
   * @param listener the vetoable sequence listener
   */
  public void addVetoableSequenceListener(VetoableSequenceListener listener)
  {
    if( listener == null ) 
      throw new NullPointerException( "Can not add null sequence listener" );
    
    if (vetoableListeners.contains(listener)) return;
    else vetoableListeners.addElement(listener);
    addSequenceListener( listener );
  }

  /**
   * Removes a vetoable sequence listener.
   *
   * @param listener the vetoable sequence listener
   */
  public void removeVetoableSequenceListener(VetoableSequenceListener listener)
  {
    vetoableListeners.removeElement(listener);
    removeSequenceListener( listener );
  }
} // SequenceListenerSupport



/*
 * ChangeLog
 * $Log: SequenceListenerSupport.java,v $
 * Revision 1.5  2001/04/11 17:04:43  lord
 * Added License agreements to all code
 *
 * Revision 1.4  2000/09/15 17:06:17  lord
 * Now has a "hasListeners" method. The point behind this is that it
 * allows some serious performance speed ups. Classes using this class
 * were having to open create events even when there were no listeners.
 *
 * Revision 1.3  2000/06/27 16:09:49  lord
 * Null pointer checks in add/remove listener methods. This means that I
 * do not have to do the same check in the fire event methods
 *
 * Revision 1.2  2000/03/08 17:26:36  lord
 * To many changes to document
 *
 * Revision 1.1  2000/02/26 18:28:44  jns
 * Initial coding of file
 *
 *
 */
