package mit.event ;

public class Event
extends java.util.EventObject
{
	private static java.util.Random random = new java.util.Random( System.currentTimeMillis() ) ; 
	private static java.util.Vector validRaisers = null ;
	public static void invalidate() { validRaisers = null ; }

	public Event( mit.event.Raiser source ) 
	{
		super( source ) ;
	}
	public void raise()
	{
		try
		{
			if( hasListeners() )
			{
				distributeEvent() ;
			}
		}
		catch( Exception ex )
		{
			ex.printStackTrace() ;
		}
	}

	private boolean hasListeners()
	{
		validateListeners() ;
		mit.event.RaiserAdapter r = ( ( mit.event.Raiser ) getSource() ).getRaiserAdapter() ;
		java.util.Hashtable listeners = r.getListeners() ;
		java.util.Vector eventListeners = null ;
		if( listeners.containsKey( this.getClass() ) )
		{
			eventListeners = ( java.util.Vector ) listeners.get( this.getClass() ) ;
			if( null != eventListeners )
			{
				return ! eventListeners.isEmpty() ;
			}
		}
		else
		{
			if( findListeners( findTop() ) )
			{
				listeners = r.getListeners() ;
				if( listeners.containsKey( this.getClass() ) )
				{
					eventListeners = ( java.util.Vector ) listeners.get( this.getClass() ) ;
					if( null != eventListeners )
					{
						return ! eventListeners.isEmpty() ;
					}
				}
			}
		}
		return false ;
	}

	private void distributeEvent()
	{
		mit.event.RaiserAdapter r = ( ( mit.event.Raiser ) getSource() ).getRaiserAdapter() ;
		java.util.Hashtable listeners = r.getListeners() ;
		if( listeners.containsKey( this.getClass() ) )
		{
			java.util.Vector eventListeners = ( java.util.Vector ) listeners.get( this.getClass() ) ;
			if( null != eventListeners )
			{
				java.util.Enumeration enum = eventListeners.elements() ;
				while( enum.hasMoreElements() )
				{
					mit.event.Listener listener = ( mit.event.Listener ) enum.nextElement() ;
					listener.eventRaised( this ) ;
				}
			}
		}
	}

	private synchronized void validateListeners()
	{
		if( null == validRaisers )
		{
			validRaisers = new java.util.Vector() ;
		}
		mit.event.RaiserAdapter r = ( ( mit.event.Raiser ) getSource() ).getRaiserAdapter() ;
		if( null != r )
		{
			if( ( null == r.getEventId() ) || ! validRaisers.contains( r.getEventId() ) )
			{
				r.setEventId( new Double( random.nextDouble() ) ) ;
				validRaisers.addElement( r.getEventId() ) ;
				r.setListeners( null ) ;
			}
			if( null == r.getListeners() )
			{
				r.setListeners( new java.util.Hashtable() ) ;
			}
		}
	}

	private Object findTop()
	{
		Object top = getSource() ;
		while( top != null )
		{
			if( top instanceof mit.event.EventControl )
			{
				mit.event.EventControlAdapter eventControlAdapter
				= ( ( mit.event.EventControl ) top ).getEventControlAdapter() ;
				if( null != eventControlAdapter )
				{
					if( eventControlAdapter.isContained( this.getClass() ) )
					{
						return top ;
					}
				}
			}
			if( top instanceof mit.event.Adapter )
			{
				mit.event.Adapter adapter = ( mit.event.Adapter ) top ;
				if( null != adapter.getOwner() )
				{
					top = adapter.getOwner() ;
					continue ;
				}
				else
				{
					return top ;
				}
			}
			if( top instanceof mit.event.Tenent )
			{

				mit.event.TenentAdapter tenentAdapter
					= ( ( mit.event.Tenent ) top ).getTenentAdapter() ;
				if( null != tenentAdapter )
				{
					if( null != tenentAdapter.getOwner() )
					{
						top = tenentAdapter.getOwner() ;
						continue ;
					}
					else
					{
						return top ; 
					}
				}
			}
			if( top instanceof java.awt.Component )
			{
				if( null != ( ( java.awt.Component ) top ).getParent() )
				{
					top = ( ( java.awt.Component ) top ).getParent() ;
					continue ;
				}
				else
				{				
					return top ;
				}
			}
			else
			{
				return top ; 
			}
		}
		return getSource() ;
	}

	private boolean findListeners( Object top )
	{
		boolean foundListeners = false ;
		if( top instanceof mit.event.Owner )
		{
			mit.event.OwnerAdapter ownerAdapter
			= ( ( mit.event.Owner ) top ).getOwnerAdapter() ;
			if( null != ownerAdapter )
			{
				if( null != ownerAdapter.tenents )
				{
					boolean foundEATL = findTenentListeners( ownerAdapter.tenents ) ;
					foundListeners = foundListeners || foundEATL ;
				}
			}
		}
		if( top instanceof java.awt.Container )
		{
			boolean foundCL = findContainerListeners( ( java.awt.Container ) top ) ;
			foundListeners = foundListeners || foundCL ;
		}
		if( top instanceof mit.event.Listener )
		{
			boolean foundL = findListener( ( mit.event.Listener ) top ) ;
			foundListeners = foundListeners || foundL ;
		}
		return foundListeners ;
	}

	private boolean findListener( mit.event.Listener top )
	{
		mit.event.ListenerAdapter listenerAdapter = top.getListenerAdapter() ;
		if( listenerAdapter.isHandled( this.getClass() ) )
		{
			mit.event.RaiserAdapter r = ( ( mit.event.Raiser ) getSource() ).getRaiserAdapter() ;
			if( null != r )
			{
				if( null == r.getListeners() )
				{
					r.setListeners( new java.util.Hashtable() ) ;
				}
				java.util.Vector rEventListeners
				= ( java.util.Vector ) r.getListeners().get( this.getClass() ) ;
				if( null == rEventListeners )
				{
					rEventListeners = new java.util.Vector() ;
					r.getListeners().put( this.getClass() , rEventListeners ) ;
				}
				if( null != rEventListeners )
				{
					if( ! rEventListeners.contains( top ) )
					{
						rEventListeners.addElement( top ) ;
					}
					return true ;
				}
			}
		}
		return false ;
	}

	private boolean findTenentListeners( java.util.Vector tenents )
	{
		boolean foundTenentListeners = false ;
		java.util.Enumeration enumTenents = tenents.elements() ;
		while( enumTenents.hasMoreElements() )
		{
			Object tenent = enumTenents.nextElement() ;
			if( ! isExcluded( tenent ) )
			{
				boolean foundL = findListeners( tenent ) ;
				foundTenentListeners = foundTenentListeners || foundL ;
			}
		}
		return foundTenentListeners ;
	}

	private boolean findContainerListeners( java.awt.Container top )
	{
		boolean foundContainerListeners = false ;
		java.awt.Component[] comps = ( ( java.awt.Container ) top ).getComponents() ;
		for( int i = 0 ; comps.length != i ; i ++ )
		{
			if( ! isExcluded( comps[ i ] ) )
			{
				boolean foundCL = findListeners( comps[ i ] ) ;
				foundContainerListeners = foundContainerListeners || foundCL ;
			}
		}
		return foundContainerListeners ;
	}

	private boolean isExcluded( Object obj )
	{
		if( obj instanceof mit.event.EventControl )
		{
			mit.event.EventControlAdapter eventControlAdapter
			= ( ( mit.event.EventControl ) obj ).getEventControlAdapter() ;
			if( null != eventControlAdapter )
			{
				if( eventControlAdapter.isExcluded( this.getClass() ) )
				{
					return true ;
				}
			}
		}
		return false ;
	}

}
