package javacodebook.thread.crontab;

import java.util.*;

/**
 * Eine minimalistische Cron-Tabelle
 * @author  Mark Donnermeyer
 */
public class Crontab
{
    private static Crontab crontab = null;
    private static int id = 0;
    
    private Vector entries;
    private CronDaemon daemon;
    
    private Crontab()
    {
        entries = new Vector();
        daemon = new CronDaemon(this);
        daemon.start();
    }
    
    /**
     * Die Crontab ist ein sog. Singleton. Das heisst, es kann in einer 
     * Anwendung max ein Objekt der Klasse geben. Mit getInstance() wird dieses
     * Objekt gelesen.
     */
    public static Crontab getInstance()
    {
        if (crontab == null)
            crontab = new Crontab();
        return crontab;
    }
    
    /**
     * Setzt einen neuen Eintrag in die Crontab.
     * @param hour Die Stunde (0-23) zu der der Eintrag ausgeführt werden soll.
     * Ein negativer Wert bedeutet, dass der Eintrag zu jeder vollen Stunde
     * ausgeführt wird.
     * @param weekday Der Wochentag, an dem der Eintrag ausgeführt werden soll.
     * Als Wert kann eine Konstante aus der Klasse Calendar genommen werden
     * (z.B. Calendar.SUNDAY). Ein negativer Wert bedeutet, dass der Eintrag
     * jeden Tag ausgeführt wird.
     * @param command das auszuführende Kommando
     * @param parameter Eine Reihe von Parametern, die dem Kommando bei der
     * Ausführung übergeben werden
     * @returns Die von der Crontab vergebene ID für den Eintrag
     */
    public synchronized int addEntry(int hour, int weekday, Command command, Hashtable parameter)
    {
        int tmpId = id++;
        CrontabEntry entry = new CrontabEntry(tmpId, hour, weekday, command, parameter);
        entries.addElement(entry);
        return tmpId;
    }
    
    /**
     * Setzt einen neuen Eintrag in die Crontab.
     * @param hour Die Stunde (0-23) zu der der Eintrag ausgeführt werden soll.
     * Ein negativer Wert bedeutet, dass der Eintrag zu jeder vollean Stunde
     * ausgeführt wird.
     * @param weekday Der Wochentag, an dem der Eintrag ausgeführt werden soll.
     * Als Wert kann eine Konstante aus der Klasse Calendar genommen werden
     * (z.B. Calendar.SUNDAY). Ein negativer Wert bedeutet, dass der Eintrag
     * jeden Tag ausgeführt wird.
     * @param command das auszuführende Kommando
     * @returns Die von der Crontab vergebene ID für den Eintrag
     */
    public synchronized int addEntry(int hour, int weekday, Command command)
    {
        int tmpId = id++;
        CrontabEntry entry = new CrontabEntry(tmpId, hour, weekday, command, null);
        entries.addElement(entry);
        return tmpId;
    }
    
    /**
     * Einen Eintrag aus der Crontab loeschen.
     * @param die ID des zu löschenden Eintrages
     */
    public synchronized void removeEntry(int id)
    {
        for (int index=entries.size()-1; index>=0; index--)
        {
            CrontabEntry entry = (CrontabEntry)entries.elementAt(index);
            if (entry.id == id)
            {
                entries.removeElementAt(index);
                break;
            }
        }
    }
    
    /**
     * Einen Eintrag in der Crontab lesen.
     * @param die ID des zu löschenden Eintrages
     */
    public synchronized CrontabEntry getEntry(int id)
    {
        CrontabEntry entry = null;
        for (int index=entries.size()-1; index>=0; index--)
        {
            entry = (CrontabEntry)entries.elementAt(index);
            if (entry.id == id)
                break;
        }
        return entry;
    }
    
    /**
     * Alle Einträge in der Crontab auflisten
     */
    public synchronized Enumeration listEntries()
    {
        return entries.elements();
    }
}

