key0-96/
key0-96/doc/key/
key0-96/doc/key/credits/
key0-96/doc/key/developers/
key0-96/doc/key/developers/resources/
key0-96/setup/caves/
key0-96/setup/help/
key0-96/setup/ruins/
key0-96/src/
key0-96/src/commands/
key0-96/src/events/
key0-96/src/hack/
key0-96/src/sql/
key0-96/src/swing/
key0-96/src/talker/forest/
key0-96/src/talker/objects/
key0-96/src/terminals/
/*
**               j###t  ########## ####   ####
**              j###t   ########## ####   ####
**             j###T               "###L J###"
**          ######P'    ##########  #########
**          ######k,    ##########   T######T
**          ####~###L   ####
**          #### q###L  ##########   .#####
**          ####  \###L ##########   #####"
**
**  $Id$
**
**  Class History
**
**  Date        Name         Description
**  ---------|------------|-----------------------------------------------
**  19Aug98     subtle       start of recorded history
**
*/

package key;

import key.events.*;
import key.util.LinkedList;

import java.io.IOException;
import java.io.DataOutput;
import java.io.DataInput;
import java.util.Enumeration;
import java.util.StringTokenizer;

public final class Scheduler extends Daemon
{
	private static final long serialVersionUID = 2876463129193477587L;
	
	public static final AtomicElement[] ELEMENTS =
	{
		AtomicElement.construct( Scheduler.class, Paragraph.class, "entries",
			AtomicElement.PUBLIC_ACCESSORS | AtomicElement.READ_ONLY |
			AtomicElement.GENERATED,
			"the entries in the scheduler" )
	};
	
	public static final AtomicStructure STRUCTURE = new AtomicStructure( Daemon.STRUCTURE, ELEMENTS );
	
	LinkedList list;
	
	public Scheduler()
	{
		super( false );
		
		setKey( "scheduler" );
		list = new LinkedList();
	}
	
	public void remove( Event evt )
	{
		list.remove( evt.getThis() );
	}
	
	public void add( Event evt )
	{
		LinkedList.Iterator lli = list.iterator();
		
		lli.first();
		
		while( lli.isValid() )
		{
			Event storedEvt = (Event) ((Reference)lli.element()).get();
			
			if( evt.isBefore( storedEvt ) )
			{
				lli.insertBefore( evt.getThis() );
				return;
			}
			
			lli.next();
		}
		
		list.append( evt.getThis() );
	}
	
	public static final TableParagraph.Column[] columns =
	{
		new TableParagraph.Column( "event", 40 ),
		new TableParagraph.Column( "at", 30 )
	};
	
	public Paragraph getEntries()
	{
		TableParagraph.Generator tp = new TableParagraph.Generator( columns );
		
		for( Enumeration e = list.elements(); e.hasMoreElements(); )
		{
			String[] rowContents = new String[ 2 ];
			
			Event o = (Event) ((Reference)e.nextElement()).get();
			
			rowContents[0] = o.getId();
			rowContents[1] = o.scheduledFor.toString();
			
			tp.appendRow( rowContents );
		}
		
		tp.setFooter( Integer.toString( list.count() ) + " entries" );
		
		return( tp.getParagraph() );
	}
	
	public void run()
	{
		while( true )
		{
			try
			{
				Thread.sleep( 10000 );  //  ten seconds
			}
			catch( InterruptedException e )
			{
			}
			
			//Log.debug( this, "scanned schedule with " + list.count() + " total events" );
			Reference r = (Reference) list.getFirstElement();

			if( r != null )
			{
				try
				{
					Event evt = (Event) r.get();
					
					if( evt != null )
					{
						if( evt.runNow() )
						{
							remove( evt );
							evt.run( this );
						}
					}
				}
				catch( OutOfDateReferenceException e )
				{
					System.out.println( "SCHEDULER: removed out of date reference: " + r.toString() );
					list.remove( r );
				}
			}
		}
	}
	
	public AtomicStructure getDeclaredStructure()
	{
		return( STRUCTURE );
	}
}