/*

    CAL.c

    -- Einfacher Kalender für die Workbench --

    -- Aztec C 3.4a	Läuft *nicht* auf Lattice! (??)

    by	Dietmar Till  11-Mar-89 - 14-May-89

*/




#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <devices/timer.h>
#include <libraries/diskfont.h>

#include <functions.h>		/* Aztec specific ! */
#include <time.h>

/* ==================================================================== */
/* ========================= USER DEFINES ============================= */
/* ==================================================================== */

#define SCREENTITLE "CALENDAR V1.2 (C) CopyRight 1989, MAXON\0"

#define MAX_TIME 250000L     /* Zeit zwischen Updates */

/* ==================================================================== */
/* ==================================================================== */
/* ==================================================================== */

struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;

struct Window *MyWin=NULL;

struct IntuiMessage *imess=NULL;
struct RastPort *MyRP;

struct TextFont *topaz9_font, *topaz8_font;

struct timerequest *tir=NULL, *CreateExtIO();
struct MsgPort *tirport=NULL, *CreatePort();    /* Port für timer.device */

void OpenStuff(), CloseStuff();                 /* forward references */
void Mark_Current(), Update_Win();


char *mon_names[] = {				/* Namen der einzelnen */
    "January",                                  /* Monate              */
    "February",                                 /* Wer will, kann sie  */
    "March",                                    /* ins Deutsche über-  */
    "April",                                    /* setzen              */
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};

struct TextAttr Topaz9Attr = {			/* Topaz 9 Font */
    (STRPTR)"topaz.font", TOPAZ_SIXTY,
    FS_NORMAL, FPF_ROMFONT
};

struct TextAttr Topaz8Attr = {			/* Topaz 8 Font */
    (STRPTR)"topaz.font", TOPAZ_EIGHTY,
    FSF_BOLD, FPF_ROMFONT
};

struct NewWindow MyNw = {			/* Window */
    100,100, 231,95,-1,-1, CLOSEWINDOW,
    SMART_REFRESH|NOCAREREFRESH|WINDOWDRAG|
    WINDOWDEPTH|WINDOWCLOSE, NULL,
    NULL, NULL, NULL, NULL,
    0,0,0,0, WBENCHSCREEN
};

_main()
/* Keine Standard Ein-Ausgabe, darum Aztec _main() nicht er-*/
/* forderlich -> geringere Codegröße			    */

{
    int act_day1=0, act_day2=0, act_mon1=0, act_mon2=0;
    static struct tm *mytm;
    ULONG mics, secs, class, sigmask;
    USHORT code;
    char ct[10];

    OpenStuff();                /* Libaries öffnen ... etc */

    CurrentTime(&secs,&mics);   /* aktuelle Zeit ermitteln */
    mytm = localtime(&secs);    /* in tm-struct umwandeln  */
    Update_Win(mytm);           /* Windows updaten         */
    act_day1=mytm->tm_mday;


    sigmask = 1L << MyWin->UserPort->mp_SigBit | 1L << tirport->mp_SigBit;

    FOREVER
    {
	tir->tr_node.io_Command = (UWORD)TR_ADDREQUEST;
	tir->tr_time.tv_secs = 0L;
	tir->tr_time.tv_micro = MAX_TIME;

	SendIO(tir);      /* asynchroner i/o */

	Wait(sigmask);    /* auf timer/intui-msg warten */

	if (GetMsg(tirport)) {

	    CurrentTime(&secs,&mics);   /* akt. Zeit */
	    mytm=localtime(&secs);

	    /* Überprüfen: ist der Fensterinhalt noch
	     * aktuell (Tag, Monat) ?
	     */

	    act_day2=mytm->tm_mday;
	    act_mon2=mytm->tm_mon;
	    if(act_day2 != act_day1 || act_mon2 != act_mon1)
		Update_Win(mytm);  /* nicht mehr aktuell */
	    act_day1=act_day2;
	    act_mon1=act_mon2;

	    /* Aktuelle Zeit in Format hh:ss:mm
	     * ausdrucken in oberen Fensterrand
	     */

	    sprintf(ct,"%02d:%02d:%02d\0",mytm->tm_hour,
		mytm->tm_min, mytm->tm_sec);

	    SetFont(MyRP,topaz8_font);

	    SetAPen(MyRP,1L);
	    SetDrMd(MyRP,JAM2);
	    Move(MyRP,30L,7L);
	    Text(MyRP,ct,(LONG)strlen(ct));

	}

	if(imess = (struct IntuiMessage *)GetMsg(MyWin->UserPort))  {

	    class = imess->Class;
	    code = imess->Code;

	    ReplyMsg(imess);

	    switch(class) {    /* Close-Gadget ... */

		case CLOSEWINDOW:   CloseStuff();
				    break;
	    }
	}
    }
}


VOID Mark_Current(x,y)   /* Aktuelles Datum markieren */
    LONG x,y;
{
    static SHORT bpairs[] = {
	0,0,30,0,30,10,0,10,0,0
    };
    static struct Border Mark_it = {
	0,0,3,1,JAM1,5,bpairs,NULL
    };
    DrawBorder(MyRP, &Mark_it,(long)x+4L,(long)y-8L);
}


VOID Update_Win(mytm)    /* Routine, die den Fensterinhalt zeichnet */
    struct tm *mytm;
{
    register int i, first_wd, days;
    register long x,y;
    static char buf[4], buf2[25];
    static char title[]="Su Mo Tu We Th Fr Sa\0";

    /* Standard Einstellungen für den Rastport */

    Move(MyRP,0L,0L);
    ClearScreen(MyRP);
    SetRast(MyRP,2L);
    SetAPen(MyRP,1L);
    SetDrMd(MyRP, JAM1);
    SetFont(MyRP,topaz9_font);

    /* erster Tag im Monat war ein ? */

    first_wd=first_d_m(mytm->tm_wday,mytm->tm_mday);

    /* Wieviele Tage hat der Monat ? */

    days= days_p_m(mytm->tm_mon,mytm->tm_year);

    for(i=1;i<=days;i++)
    {
	sprintf(buf,"%3d",i);

	x=((long)(first_wd+i-1)%7L)*30L+5L;
	y=((long)(first_wd+i-1)/7L)*10L+29L;

	/* Aktuelles Datum markieren */
	if(i == mytm->tm_mday) Mark_Current(x,y);

	if((first_wd+i-1) % 7)
	    SetAPen(MyRP,1L);
	else			/* Sonntage in rot */
	    SetAPen(MyRP,3L);

	Move(MyRP,(long)x,(long)y);
	Text(MyRP,buf,3L);
    }

    /* Titelzeile */

    Move(MyRP,15L,18L);
    SetAPen(MyRP,1L);
    Text(MyRP,title,(long)strlen(title));

    /* Monat & Jahr printen */

    sprintf(buf2,"%-16s19%2d\0",mon_names[mytm->tm_mon],mytm->tm_year);
    Move(MyRP,15L,90L);
    Text(MyRP,buf2,(long)strlen(buf2));

    RefreshWindowFrame(MyWin);  /* wegen SetRast(..,..) */

}


int first_d_m(wday, mday)  /* Erster Tag im Monat war ein .. */
    int wday, mday;
{
    int i, f_wday=wday;

    for(i=mday;i>1;i--) {     /* einfach herunterzählen */
	--f_wday;
	if(f_wday < 0) f_wday=6;
    }
    return(f_wday);
}

int days_p_m(mon, year)  /* Tage pro Monat */
     int mon, year;
{
    static int dpm[12] =    /* Tage pro Monat */
	{31,28,31,30,31,30,31,31,30,31,30,31};

    if(mon==1 && year%4==0 )     /* Schaltjahr */
	dpm[1] = 29;

    return(dpm[mon]);
}



VOID OpenStuff()    /* Das Übliche */
{
    if((IntuitionBase = (struct IntuitionBase *)
	OpenLibrary("intuition.library",0L)) == NULL)
	    exit(FALSE);

    if((GfxBase = (struct GfxBase *)
	OpenLibrary("graphics.library",0L)) == NULL)
	    CloseStuff();

    if(!(MyWin=(struct Window *)OpenWindow(&MyNw)))
	CloseStuff();

    tirport = CreatePort(0L,0L);
    if(!tirport) CloseStuff();

    tir = CreateExtIO(tirport,(long)sizeof(struct timerequest));
    if(tir == NULL)  CloseStuff();

    if (OpenDevice(TIMERNAME,UNIT_VBLANK,tir,0L))
	CloseStuff();

    SetWindowTitles(MyWin,(LONG)-1,(UBYTE *)SCREENTITLE);

    MyRP=MyWin->RPort;	    /* Rastport */

    /* Default Font Settings : */

    topaz9_font = (struct TextFont *)OpenFont(&Topaz9Attr);
    topaz8_font = (struct TextFont *)OpenFont(&Topaz8Attr);

}


VOID CloseStuff()   /* Alles schliessen, ende ... */
{
    if (tir) {
	    AbortIO(tir);
	    WaitIO(tir);
	    CloseDevice(tir);
	    DeleteExtIO(tir);
    }
    if (tirport)       DeletePort(tirport);
    if (MyWin)         CloseWindow(MyWin);
    if (IntuitionBase) CloseLibrary(IntuitionBase);
    if (GfxBase)       CloseLibrary(GfxBase);
    exit(TRUE);
}


/**/

