;/* Little NeXT style calender by Juha Tuominen, 1992
;	v1.1 22-Jun-92 little smaller now
;	v1.2 30-Jul-92 supports and needs locale.library
;	v1.3 03-Dec-92 autoscaling depending on screen font height
;	v1.3b 05-Dec-92 ARGH! there was a small bug in 1.3.... sorry

lc -j73 -v -y -ba xcale.c
blink lib:cback.o+xcale.o to xcale lib lib:lc.lib+lib:amiga.lib
quit

*/

#include <exec/types.h>
#include <libraries/diskfont.h>
#include <libraries/dos.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <libraries/locale.h>
#include <utility/hooks.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <stdlib.h>

#define VERSTAG		"\0$VER: XCale 1.3b (05-Dec-92)"
#define VSTRING		"XCale"

long _stack=16384;
char *_procname=VSTRING;
long _priority=5;
long _BackGroundIO=FALSE;

void MemCleanup() {}

UBYTE	versiontag[]=VERSTAG;
BOOL	keepgoing=TRUE,mode=FALSE,lastside=TRUE;
char	datestring[20],aika[10];
int		dsp=0,offset;
struct	LocaleBase *LocaleBase=NULL;
struct	Locale *localepointer=NULL;
struct	IntuitionBase *IntuitionBase=NULL;
struct	Window *window=NULL;
struct	Library *DiskfontBase=NULL;
struct	GfxBase *GfxBase=NULL;
struct	Hook	hook;
struct	NewWindow mywindow = 
{	100,
	100,
	70,
	76,
	0,1,
	CLOSEWINDOW | MOUSEBUTTONS,
	SMART_REFRESH | WINDOWDRAG | WINDOWCLOSE | WINDOWDEPTH | RMBTRAP,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	WBENCHSCREEN

};

/* Iff2Src conversion: src:c/xcale.iff */

UWORD chip data[488] =
{
	/* Plane 0 */
	0x0000,0x0000,0x0000,0x0000,
	0x7FFF,0xFFFF,0xFFFF,0xFF00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x7FFF,0xFFFF,0xFFFF,0xFE00,
	0x4000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0010,0x0000,
	0x0000,0x0000,0x0018,0x0000,
	0x0000,0x0000,0x001C,0x0000,
	0x0000,0x0000,0x001E,0x0000,
	0x0000,0x0000,0x001F,0x0000,
	0x0000,0x0000,0x001F,0x8000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x0000,0x0000,0x003F,0xC000,
	0x0000,0x0000,0x003F,0xC000,
	0x0000,0x0000,0x007F,0xC000,
	0x003F,0xFFFF,0xFFFF,0xC000,
	0x0000,0x0000,0x001F,0xC000,
	0x003F,0xFFFF,0xFFFF,0xC000,
	0x001F,0xFFFF,0xFFFF,0xC000,
	0x000F,0xFFFF,0xFFFF,0xC000,
	0x0007,0xFFFF,0xFFFF,0xC000,
	0x0003,0xFFFF,0xFFFF,0xC000,
	0x0000,0x0000,0x0000,0x0000,
	/* Plane 1 */
	0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0100,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x3FFF,0xFFFF,0xFFFF,0xFF00,
	0x7FFF,0xFFFF,0xFFFF,0xFF00,
	0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,
	0x003F,0xFFFF,0xFFE0,0x0000,
	0x003F,0xFFFF,0xFFE0,0x0000,
	0x003F,0xFFFF,0xFFE0,0x0000,
	0x003F,0xFFFF,0xFFE0,0x0000,
	0x003F,0xFFFF,0xFFE2,0x0000,
	0x003F,0xFFFF,0xFFE3,0x0000,
	0x003F,0xFFFF,0xFFE3,0x8000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x007F,0xFFFF,0xFFE3,0xC000,
	0x007F,0xFFFF,0xFFE3,0xC000,
	0x007F,0xFFFF,0xFFE3,0xC000,
	0x00FF,0xFFFF,0xFFE3,0xC000,
	0x01FF,0xFFFF,0xFFE3,0xC000,
	0x003F,0xFFFF,0xFFE3,0xC000,
	0x0000,0x0000,0x0003,0xC000,
	0x0000,0x0000,0x0003,0xC000,
	0x0000,0x0000,0x0003,0xC000,
	0x000F,0xFFFF,0xFFFF,0xC000,
	0x0007,0xFFFF,0xFFFF,0xC000,
	0x0003,0xFFFF,0xFFFF,0xC000,
	0x0000,0x0000,0x0000,0x0000
};


struct Image im =
{
	0,0,
	57,61,
	2,
	&data[0],
	0xff,0x0,
	NULL
};

void __saveds __asm addchr(register __a1 APTR);
void cleanexit(int);
void openthings(void);
void changefont(char *,int);
void convert_datestamp(struct DateStamp);
void initgraphics(char *,char *,int);
void inittime(char *);
void flickersecs(BOOL,BOOL);


void __saveds __asm addchr(register __a1 APTR c)
{	if(dsp<20)
		datestring[dsp++]=(char)c;
}

void cleanexit(int error)
{
	if(window) CloseWindow(window);
	if(DiskfontBase) CloseLibrary(DiskfontBase);
	if(localepointer) CloseLocale(localepointer);
	if(LocaleBase) CloseLibrary((struct Library *)LocaleBase);
	if(GfxBase) CloseLibrary(GfxBase);
	if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	XCEXIT(error);
}


void openthings(void)
{
	if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33L)))
		cleanexit(30);
	if(!(IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",33L)))
		cleanexit(30);
	if(!(LocaleBase=(struct LocaleBase *)OpenLibrary("locale.library",38L)))
		cleanexit(25);
	if(!(localepointer=(struct Locale *)OpenLocale("ENV:Sys/locale.prefs")))
		cleanexit(21);
	if(!(DiskfontBase=OpenLibrary("diskfont.library", 33L)))
		cleanexit(30);
	if(!(window=OpenWindow(&mywindow)))
		cleanexit(27);

	if(offset=window->WScreen->BarHeight-8)
		SizeWindow(window,0,offset);
}



void changefont(char *fontname, int fontsize)
{	struct	TextAttr	textattr;
	struct	TextFont	*textfont;

	textattr.ta_Name=fontname;
	textattr.ta_YSize=fontsize;
	textattr.ta_Style=FS_NORMAL;
	textattr.ta_Flags=FPF_ROMFONT | FPF_DISKFONT;

	if(textfont=(struct TextFont *)OpenDiskFont(&textattr))
	{	SetFont(window->RPort,textfont);
		if(window->RPort->TxHeight!=fontsize)
			cleanexit(20);
	}
	else
		cleanexit(10);
}

void convert_datestamp(struct DateStamp v)
{	char 	time[10];
	unsigned int year,day;
	unsigned char month[4];
	static unsigned int oldyear, oldday;
	static unsigned char oldmonth[4];

	dsp=0;
	FormatDate(localepointer,"%H",&v,&hook);
	sprintf(time,"%s ",datestring);
	dsp=0;
	FormatDate(localepointer,"%M",&v,&hook);
	strcat(time,datestring);
	dsp=0;
	FormatDate(localepointer,"%y",&v,&hook);
	year=atoi(datestring);
	dsp=0;
	FormatDate(localepointer,"%b",&v,&hook);
	strcpy(month,datestring);
	dsp=0;
	FormatDate(localepointer,"%e",&v,&hook);
	day=atoi(datestring);
	dsp=0;
	FormatDate(localepointer,"%A",&v,&hook);


	if(oldday!=day || strcmp(month,oldmonth) || oldyear!=year)
	{	initgraphics(month,datestring,day);
		oldday=day;
		strcpy(oldmonth,month);
		oldyear=year;
		strcpy(aika," ");
	}

	if(strcmp(time,aika))
	{	inittime(time);
		strcpy(aika,time);
	}
	if(v.ds_Tick/50<30)
	{	if(!lastside)
		{	flickersecs(FALSE,TRUE);
			lastside=TRUE;
		}
		flickersecs(TRUE,mode);
	}
	else
	{	if(lastside)
		{	flickersecs(TRUE,TRUE);
			lastside=FALSE;
		}
		flickersecs(FALSE,mode);
	}
	mode=!mode;
}


void flickersecs(BOOL upper,BOOL on)
{	int ypos=22+offset;

	if(upper)
		ypos-=4;

	if(on)
	{	SetAPen(window->RPort,1);
		RectFill(window->RPort,34,ypos+1,35,ypos+2);
		SetAPen(window->RPort,2);
		RectFill(window->RPort,33,ypos,34,ypos+1);
	}
	else
	{	SetAPen(window->RPort,3);
		RectFill(window->RPort,33,ypos,35,ypos+2);
	}
}

void inittime(char *time)
{
	changefont("sunsmall.font",14);
	SetDrMd(window->RPort,JAM2);
	SetAPen(window->RPort,3);
	RectFill(window->RPort,10,15+offset,60,26+offset);
	Move(window->RPort,15,26+offset);
	SetAPen(window->RPort,1);
	SetBPen(window->RPort,3);
	Text(window->RPort,time,5);
	SetDrMd(window->RPort,JAM1);
	Move(window->RPort,14,25+offset);
	SetAPen(window->RPort,2);
	Text(window->RPort,time,5);
	SetAPen(window->RPort,2);
	Move(window->RPort,14,30+offset);
	Draw(window->RPort,55,30+offset);
	flickersecs(TRUE,TRUE);
	flickersecs(FALSE,TRUE);
}

void initgraphics(char *month, char *dayofweek, int day)
{	char temp[4];

	SetDrMd(window->RPort,JAM1);
	Delay(25);	/* if we don't wait, Intuition screws up, don't know why.. */
	DrawImage(window->RPort,&im,6,12+offset);
	changefont("sunfont.font",16);
	Move(window->RPort,21,54+offset);
	SetAPen(window->RPort,1);
	SetBPen(window->RPort,2);
	sprintf(temp,"%02d",day);
	Text(window->RPort,temp,2);
	changefont("blob.font",8);
	Move(window->RPort,24,40+offset);
	Text(window->RPort,dayofweek,3);
	Move(window->RPort,23,63+offset);
	Text(window->RPort,month,3);
	ScrollRaster(window->RPort,1,0,21,61+offset,45,64+offset);
}

void _main(char *arguments)
{
	struct	DateStamp v;
	struct	IntuiMessage *msg=NULL;
	int		i,j=0;
	char	temp1[20];

	hook.h_Entry=(APTR)addchr;

	for(i=0;i<strlen(arguments);i++)
	{	if(arguments[i]==32 || arguments[i]==13 || arguments[i]==10)
		{	if(!strncmp(temp1,"-x",2))
				mywindow.LeftEdge=atoi(temp1+2);
			if(!strncmp(temp1,"-y",2))
				mywindow.TopEdge=atoi(temp1+2);
			j=0;
		}
		else
		{	temp1[j++]=arguments[i];
			temp1[j]=0;
		}
	}

	openthings();

	while(keepgoing)
	{	if(msg=(struct IntuiMessage *)GetMsg(window->UserPort))
		{	ReplyMsg((struct Message *)msg);
			if(msg->Class==CLOSEWINDOW)
				keepgoing=FALSE;
		}
		else
		{	DateStamp(&v);
			convert_datestamp(v);
			Delay(49);
		}
		if(SetSignal(0,0) & SIGBREAKF_CTRL_C)
			break;
	}
	cleanexit(0);
}
