/**************************************
 *                                    *
 * Programm: Zeit                     *
 * ================================== *
 *                                    *
 * Autor:  Datum:      Kommentar:     *
 * ------  ----------  ----------     *
 * KR      06.5.1991   Zeitansage     *
 *                     in Deutsch     *
 * Version: 1.11                      *
 * Betriebssystem: 1.2+               *
 * Devices: narrator.device           *
 *          timer.device              *
 **************************************/

/* History: */
/* Version 1.11  Eigene String-Routinen (6.5.91) */
/* Version 1.1   Eigene Routinen zum Lesen des timer.device (5.5.91) */
/* Version 1.03  Alerts statt Fehlermeldung - spart Speicher (4.5.91) */
/* Fehler 'und 0 Minuten' behoben */
/* Version 1.02  Öffnen der dos.library [Hoppla!] (22.4.91) */
/* Version 1.01  Samplefrequenz erhöht (21.4.91) */
/* Version 1.0   Erste lauffähige Version (21.4.91) */

#define SecondsPerMinute (ULONG)(60L)
#define SecondsPerHour (ULONG)(3600L)
#define SecondsPerDay (ULONG)(86400L)

#include <devices/timer.h>
#include <devices/narrator.h>

struct Time {
    ULONG           Hour;
    ULONG           Mins;
    ULONG           Secs;
};

struct Time     TD;
struct Time    *Time = &TD;

ULONG           Days_of_Months[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

BYTE            Kanal[4] =
{3, 5, 10, 12};

BOOL            NarDevOpen = FALSE;
BOOL            TimDevOpen = FALSE;
int             fehler;
extern struct DosLibrary *DOSBase;

struct MsgPort *narratorPort;
struct MsgPort *timerPort;
struct narrator_rb request;
struct timerequest treq;

char            buffer[32];
char            phoneme[128];

char           *a[26] =
{"NUH5LL", "AY5N", "TSVAY5", "DRAY5", "FIY5R", "FER5NF", "ZEH5KS", "ZIY5BIN", "AA5/CDT", "NOY5N",
 "TSEH5EHN", "EH5LF", "TSVER5LF", "DRAY5TSEHEHN", "FIY5RTSEHEHN", "FER5NFTSEHEHN", "ZEH5/CTSEHEHN", "ZIY5BTSEHEHN", "AA5/CDTSEHEHN", "NOY5NTSEHEHN",
 "NUH5LL", "TSEH5EHN", "TSVAA2NTSIXG", "DRAY2SIXG", "FIY2RTSIXG", "FER2NFTSIXG"};

/*
 * Die folgenden Routinen wurden dem Sourcecode des Sozobon-C-Compilers von
 * FISH 171 entnommen
 */

char           *
strcpy(dest, source)
    register char  *dest, *source;
{
    register char  *p = dest;

    while (*dest++ = *source++);
    return (p);
}

char           *
strcat(dest, source)
    register char  *dest, *source;
{
    register char  *p = dest;

    while (*dest)
        ++dest;
    while (*dest++ = *source++);
    return (p);
}

int
strlen(string)
    register char  *string;
{
    register int    n = 0;

    while (*string++)
        ++n;
    return (n);
}

/* Ende der übenommenen Routinen */

/**************************************
 *                                    *
 *  Funktion zur Ausgabe eines String *
 *  simpleprint()                     *
 *                                    *
 *  Eingabeparameter:                 *
 *  Zeiger auf Ausgabestring          *
 *                                    *
 *  Datum: 06. Mai 91                 *
 *  Autor: Kai Rode                   *
 *                                    *
 **************************************/
simpleprint(arg)
    char           *arg;
{
    Write(Output(), arg, strlen(arg));
}

/**************************************
 *                                    *
 *  Funktion zum Lesen der Systemzeit *
 *  und deren Umwandlung in ein       *
 *  'vernünftiges' Format:            *
 *  SysTime_to_Time()                 *
 *                                    *
 *  Erweiterungen:                    *
 *  - Datum umwandeln                 *
 *                                    *
 *  Eingabeparameter:                 *
 *  TimeRequest - Zeiger auf zu be-   *
 *  nutzende timerequest-Struktur     *
 *  Time - Zeiger auf zu füllende     *
 *         Struktur                   *
 *                                    *
 *  Rückgabeparameter:                *
 *  keine, Eingabeparameter werden    *
 *  verändert                         *
 *                                    *
 *  Datum: 5.5.91                     *
 *  Autor: Kai Rode                   *
 *                                    *
 **************************************/

VOID
SysTime_to_Time(TimeRequest, Time)
    struct timerequest *TimeRequest;
    struct Time    *Time;
{
    register ULONG  Hilf;
    register ULONG  SysTimeSecs;
    DoIO(TimeRequest);
    SysTimeSecs = ((TimeRequest->tr_time.tv_secs) % SecondsPerDay);
    Hilf = SysTimeSecs / SecondsPerHour;
    Time->Hour = Hilf;
    SysTimeSecs -= Hilf * SecondsPerHour;
    Hilf = SysTimeSecs / SecondsPerMinute;
    Time->Mins = Hilf;
    SysTimeSecs -= Hilf * SecondsPerMinute;
    Time->Secs = SysTimeSecs;
}

/**************************************
 *                                    *
 *  Funktion zum Umwandeln von Zahlen *
 *  im Bereich 0-59 in Phoneme:       *
 *  Numbercruncher()                  *
 *                                    *
 *  Erweiterungen:                    *
 *  - Unterstützung größerer Zahlen   *
 *                                    *
 *  Eingabeparameter:                 *
 *  z - zu wandelnde Zahl             *
 *                                    *
 *  Rückgabeparameter:                *
 *  keine, Veränderung globaler Var.  *
 *                                    *
 *  Datum: 21.April 1991              *
 *  Autor: Kai Rode                   *
 *                                    *
 **************************************/
void
Numbercruncher(z)
    short           z;
{
    if (z < 20) {
        strcpy(buffer, a[z]);
    } else if (z % 10 == 0) {
        strcpy(buffer, a[z / 10 + 20]);
    } else {
        strcpy(buffer, a[z % 10]);
        strcat(buffer, "UHND", strlen("UHND"));
        strcat(buffer, a[z / 10 + 20], strlen(a[z / 10 + 20]));
    }
}

/**************************************
 *                                    *
 *  Funktion zum Schließen aller be-  *
 *  nötigten Devices und Libraries    *
 *  CloseAll()                        *
 *                                    *
 *  Datum: 4.Mai 1991                 *
 *  Autor: Kai Rode                   *
 *                                    *
 *  Eingabeparameter:                 *
 *  Error - Null: kein Fehler         *
 *                                    *
 **************************************/
void
CloseAll(Error)
    int             Error;
{
    if (TimDevOpen == TRUE)
        CloseDevice(&treq);
    if (NarDevOpen == TRUE)
        CloseDevice(&request);
    if (narratorPort != NULL)
        DeletePort(narratorPort);
    if (Error != 0) {
        exit(Error);
    }
}

/**************************************
 *                                    *
 *  Funktion zum Öffnen aller benö-   *
 *  tigten Devices und Libraries      *
 *  OpenAll()                         *
 *                                    *
 *  Datum: 04. Mai   1991             *
 *  Autor: Kai Rode                   *
 *                                    *
 **************************************/
void
OpenAll()
{
    narratorPort = (struct MsgPort *) CreatePort("narr.port", 0);
    if (narratorPort == NULL) {
        Alert(0x00015a45, 0);
        CloseAll(20);
    }
    fehler = OpenDevice("narrator.device", 0, &request, 0);
    if (fehler != 0) {
        Alert(0x00045a45, 0);
        CloseAll(20);
    } else {
        NarDevOpen = TRUE;
    }
    timerPort = (struct MsgPort *) CreatePort("time.port", 0);
    if (timerPort == NULL) {
        Alert(0x00015a45, 0);
        CloseAll(20);
    }
    fehler = OpenDevice(TIMERNAME, UNIT_VBLANK, &treq, 0);
    if (fehler != 0) {
        Alert(0x15010000, 0);
        CloseAll(20);
    } else {
        TimDevOpen = TRUE;
    }
    treq.tr_node.io_Message.mn_ReplyPort = timerPort;
    treq.tr_node.io_Command = TR_GETSYSTIME;
}

void
main()
{
    register int    std, min, sek;
    OpenAll();
    simpleprint("Zeit V1.11 (c)1991 Kai Rode, FREEWARE.\n");
    SysTime_to_Time(&treq, Time);
    std = Time->Hour;
    min = Time->Mins;
    sek = Time->Secs;
    strcpy(phoneme, "IX3S IX4ST ");
    Numbercruncher(std);
    strcat(phoneme, buffer);
    strcat(phoneme, " UW5R");
    if (min != 0) {
        strcat(phoneme, " UH0ND ");
        if (min == 1) {
            strcat(phoneme, "AY5NEH MIXNUH5DTEH ");
        } else {
            Numbercruncher(min);
            strcat(phoneme, buffer);
            strcat(phoneme, " MIXNUH5DTIN.");
        }
    }
    request.message.io_Message.mn_ReplyPort = narratorPort;
    request.message.io_Command = CMD_WRITE;
    request.message.io_Data = (APTR) phoneme;
    request.message.io_Length = strlen(phoneme);
    request.ch_masks = Kanal;
    request.nm_masks = 4;
    request.sampfreq = 28000;
    DoIO(&request);
    CloseAll(0);
}
