  /* Fichier clock.dark.c				*/
/* Module appele par le programme principal	*/
/* pour effectuer un effet defini..appele par	*/
/* loadseg					*/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <dos/dos.h>
#include <graphics/gfxmacros.h>
#include <graphics/rastport.h>
#include <graphics/displayinfo.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/diskfont_protos.h>

#include "/includes/struct.h"
#include "/includes/tom_gadget.h"

struct Library		*DiskfontBase;
extern  struct  GfxBase *GfxBase;

#define	VOID_ARG	void	__regargs

char	*p_text_info="   ClockV1.1\n\nChoose on of the three kind of clocks:\n\n- A digital (bad looking at the moment)\n- Aiguilles (also bad looking!)\n- Moderne: A little bit better\n\n      February 1993\n      By Thomas LANDSPURG";

WORD	areabuffer[25];
struct	AreaInfo	myarea;
struct	TmpRas	tmpras;

struct	RastPort	*rp;
struct	Screen		*s;
struct	TextAttr myta;

#define	WIDTH	640
#define	HEIGHT	256

UWORD  ScreenColors[] = {
    0x000,
    0xFFF,
    0xFE2,
    0x68B,
    0xF90,
    0x0F0,
    0x00F,
    0xF0F,
    0x000 };

struct NewScreen Screen= {
     0, 0, WIDTH, HEIGHT, 3,0,1,HIRES,CUSTOMSCREEN,NULL,NULL,NULL,NULL};

#define	RAYON	80
#define	CENTRE_X (RAYON+20)*2
#define	CENTRE_Y (RAYON+20)

#define	TAILLE_N    ((RAYON+20)*2)

struct NewWindow    Window = {
    WIDTH/2-(RAYON+20)*2,
    HEIGHT/2-(RAYON+20),
    (RAYON+20)*4,
    (RAYON+20)*2,0,1,
    IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_INTUITICKS,
/*    WFLG_SMART_REFRESH|WFLG_ACTIVATE,*/
    WFLG_SMART_REFRESH|WFLG_ACTIVATE|BORDERLESS,
    0l,0,0,0,0,5,5,-1,-1,CUSTOMSCREEN};

UBYTE         *TypeLabels[] = {
    "Digital",
    "Normal",
    "Modern",
    0l };

struct	TextAttr myta={"topaz                    ",0,0,0};
struct	tom_gadget	my_gadg[]={
	{"Type",	MX,	167,14,17,40,0, 0,0,0,(char *)TypeLabels},
	{"_seconds",	CHECKBOX,160, 46, 10,10,0,0,0,0,0},
	{"_Fonts",	FONT,    160, 66, 80,12,0,         0,0,0,(char *)&myta},
	{0,		END_LISTE,  0,  0,   0, 0, 0,0,0,0,0}};

static	short	int	cos[360]={
256,255,255,255,255,255,254,254,
253,252,252,251,250,249,248,247,
246,244,243,242,240,238,237,235,
233,232,230,228,226,223,221,219,
217,214,212,209,207,204,201,198,
196,193,190,187,184,181,177,174,
171,167,164,161,157,154,150,146,
143,139,135,131,127,124,120,116,
112,108,104,100,95,91,87,83,
79,74,70,66,61,57,53,48,
44,40,35,31,26,22,17,13,
8,4,0,-4,-8,-13,-17,-22,
-26,-31,-35,-40,-44,-48,-53,-57,
-61,-66,-70,-74,-79,-83,-87,-91,
-95,-100,-104,-108,-112,-116,-120,-124,
-128,-131,-135,-139,-143,-146,-150,-154,
-157,-161,-164,-167,-171,-174,-177,-181,
-184,-187,-190,-193,-196,-198,-201,-204,
-207,-209,-212,-214,-217,-219,-221,-223,
-226,-228,-230,-232,-233,-235,-237,-238,
-240,-242,-243,-244,-246,-247,-248,-249,
-250,-251,-252,-252,-253,-254,-254,-255,
-255,-255,-255,-255,-256,-255,-255,-255,
-255,-255,-254,-254,-253,-252,-252,-251,
-250,-249,-248,-247,-246,-244,-243,-242,
-240,-238,-237,-235,-233,-232,-230,-228,
-226,-223,-221,-219,-217,-214,-212,-209,
-207,-204,-201,-198,-196,-193,-190,-187,
-184,-181,-177,-174,-171,-167,-164,-161,
-157,-154,-150,-146,-143,-139,-135,-131,
-127,-124,-120,-116,-112,-108,-104,-100,
-95,-91,-87,-83,-79,-74,-70,-66,
-61,-57,-53,-48,-44,-40,-35,-31,
-26,-22,-17,-13,-8,-4,0,4,
8,13,17,22,26,31,35,40,
44,48,53,57,61,66,70,74,
79,83,87,91,95,100,104,108,
112,116,120,124,128,131,135,139,
143,146,150,154,157,161,164,167,
171,174,177,181,184,187,190,193,
196,198,201,204,207,209,212,214,
217,219,221,223,226,228,230,232,
233,235,237,238,240,242,243,244,
246,247,248,249,250,251,252,252,
253,254,254,255,255,255,255,255
};
static	short	int	centre_x,centre_y,old_x,old_y,rayon;
static	int	old_min,old_hour,old_sec;

VOID_ARG	aff_line(struct	RastPort	*rp,
		short	int	cx,
		short	int	cy,
		short	int	sx,
		short	int	sy,
		USHORT		angle)
{
	short	int	x,y;
	unsigned	short	int	angle_sin;
	angle=angle%360;
	angle_sin=(angle+360-90)%360;
	x=sx*cos[angle]-sy*cos[angle_sin];
	y=sy*cos[angle]+sx*cos[angle_sin];
	Draw(rp,cx+2*x/256,cy-y/256);

}

VOID_ARG	aff_aguille(struct	RastPort	*rp,
		short	int	size,
		USHORT		angle)
{
	short		int	d;
	unsigned	short	int	ang;

	ang=(360-angle)%360;
	d=size/10;
	Move(rp,centre_x,centre_y);
	aff_line(rp,centre_x,centre_y,-d,size-d,ang);
	aff_line(rp,centre_x,centre_y,0,size,ang);
	aff_line(rp,centre_x,centre_y,d,size-d,ang);
	Draw(rp,centre_x,centre_y);
}

VOID_ARG	aff_aguille_sec(struct	RastPort	*rp,
		short	int	size,
		USHORT		angle)
{
	short		int	d;
	unsigned	short	int	ang;

	ang=(360-angle)%360;
	d=size/10;
	Move(rp,centre_x,centre_y);
	aff_line(rp,centre_x,centre_y,0,size,ang);
	Move(rp,centre_x,centre_y);
	ang=(ang+180)%360;
	aff_line(rp,centre_x,centre_y,0,size/10,ang);
}

VOID_ARG	aff_aguille_pleine(struct	RastPort	*rp,
			short	int	size,
			short	int	div,
			USHORT		angle)
{
	short	int	x1,y1,x2,y2;

	x1=size*cos[(angle+360-90)%360];
	y1=size*cos[(angle+360-180)%360];
	x2=(x1)/div;
	y2=(y1)/div;
	x1>>=8;
	y1>>=8;
	x2>>=8;
	y2>>=8;

	AreaMove(rp,centre_x+2*y2,centre_y-x2);
/*	AreaDraw(rp,centre_x+2*(y2+x1),centre_y-x2+y1);*/
/*	AreaDraw(rp,centre_x+2*(-y2+x1),centre_y+x2+y1);*/

	AreaDraw(rp,centre_x+2*x1,centre_y+y1);

	AreaDraw(rp,centre_x-2*y2,centre_y+x2);
	AreaEnd(rp);
}

VOID_ARG	aff_time(struct	Window	*win)
{
   struct	RastPort	*rp;
   int	seconds,minutes,hours;
   char		buffer[40];
   struct	DateStamp	now;

   DateStamp(&now) ;

   seconds=(int)(now.ds_Tick/TICKS_PER_SECOND);


   if(seconds!=old_sec){

	rp=win->RPort;
	minutes = now.ds_Minute % 60 ;
	hours = now.ds_Minute / 10 ;	/* Je divise par 6 tt a l'heure */

	SPrintF(buffer,"Time:%02ld:%02ld:%02ld",hours/6,minutes,seconds);

	switch(my_gadg[0].value){
	    case 0:
		Move(rp,10,win->Height-10);
		Text(rp,buffer,4+3*3);
		old_sec=seconds;
		break;
	    case 1:
		SetDrMd(rp,JAM2);

		if( ( (old_sec!=seconds)&&(my_gadg[1].value!=FALSE))||
		    ( (old_min!=minutes)&&(my_gadg[1].value==FALSE))){

			SetDrMd(rp,COMPLEMENT);
			SetAPen(rp,2);

			if(my_gadg[1].value){
				if(old_sec!=-1){
					aff_aguille_sec(rp,rayon-10,360*old_sec/60);
				}
				aff_aguille_sec(rp,rayon-10,360*seconds/60);
				old_sec=seconds;	
			}

			if(minutes!=old_min){
				SetAPen(rp,3);
				if(old_min!=-1){
					aff_aguille(rp,rayon-10,360*old_min/60);
				}
				old_min=minutes;
				aff_aguille(rp,rayon-10,360*old_min/60);
			}

			if(hours!=old_hour){
				SetAPen(rp,2);
				if(old_hour!=-1){
					aff_aguille(rp,rayon-30,(360*old_hour/(12*6))%360);
				}
				old_hour=hours;
				aff_aguille(rp,rayon-30,(360*old_hour/(12*6))%360);
			}
		}

		break;
	    case 2:

		SetAPen(rp,3);
		SetDrMd(rp,JAM2);

		if( ( (old_sec!=seconds)&&(my_gadg[1].value!=FALSE))||
		    ( (old_min!=minutes)&&(my_gadg[1].value==FALSE))){

			SetAPen(rp,1);
			if((old_hour!=-1)&&(old_hour!=hours)){
				aff_aguille_pleine(rp,rayon-30,5,(360*old_hour/(12*6))%360);
			}
			if((old_min!=-1)&&(old_min!=minutes)){
				aff_aguille_pleine(rp,rayon-15,8,360*old_min/60);
			}
			if(old_sec!=-1){
				aff_aguille_pleine(rp,rayon-10,20,360*old_sec/60);
			}

			old_hour=hours;
			SetAPen(rp,6);
			aff_aguille_pleine(rp,rayon-30,5,(360*old_hour/(12*6))%360);

			old_min=minutes;
			SetAPen(rp,7);
			aff_aguille_pleine(rp,rayon-15,8,360*old_min/60);

			if(my_gadg[1].value!=FALSE){
				SetAPen(rp,5);
				aff_aguille_pleine(rp,rayon-10,20,360*seconds/60);
				old_sec=seconds;
			}

		}

		break;
	}
   }
}


VOID_ARG	init_clock(struct	Window	*win)
{
	short	int	i,x,y;
        struct TextFont *myfont;
	SHORT	len,h;
	char	debug2[100];
	centre_x=win->Width/2;
	centre_y=win->Height/2;
	centre_x=CENTRE_X;
	centre_y=CENTRE_Y;
	rayon=RAYON;
	old_x=0;
	old_y=0;
	old_min=-1;
	old_hour=-1;
	old_sec=-1;

	switch(my_gadg[0].value){
	    case 0:
		if(DiskfontBase&&(myta.ta_Name!=0)){
                    if (myfont = OpenDiskFont(&myta))
                    {
	                    SetFont(rp, myfont);
                            SetSoftStyle(rp,   myta.ta_Style ^ myfont->tf_Style,
                                      (FSF_BOLD | FSF_UNDERLINED | FSF_ITALIC));
		    }
		}
		if(myta.ta_Name!=0){
			h=myta.ta_YSize;
		}else{
			h=8;
		}
		h+=10;
		len=TextLength(rp,"Time:00:00:00",13);
		len+=20;
		SizeWindow(win,-(win->Width-len),-(win->Height-h));
		break;
	    case 1:
		SetAPen(win->RPort,3);
		SetDrMd(win->RPort,JAM2);
		SetAPen(win->RPort,4);
		for(i=0;i<12*3;i++){
			x=(rayon+10)*cos[(i*(360/12))%360];
			y=(rayon+10)*cos[(i*(360/12)+90)%360];
			Move(win->RPort,centre_x+2*x/256,centre_y+y/256);
			x=(x*9)/10;
			y=(y*9)/10;
			Draw(win->RPort,centre_x+2*x/256,centre_y+y/256);
		}
		break;
	    case 2:
		SetDrMd(win->RPort,JAM2);
		SetAPen(win->RPort,3);
		AreaMove(win->RPort,centre_x,centre_y);
		AreaEllipse(win->RPort,centre_x,centre_y,(rayon+10)*2,rayon+10);
		DrawEllipse(win->RPort,centre_x,centre_y,(rayon+10)*2,rayon+10);
		AreaEnd(win->RPort);

		SetAPen(win->RPort,1);
		AreaMove(win->RPort,centre_x,centre_y);
		AreaEllipse(win->RPort,centre_x,centre_y,(rayon-10)*2,rayon-10);
		AreaEnd(win->RPort);
		DrawEllipse(win->RPort,centre_x,centre_y,(rayon-10)*2,rayon-10);
		break;
	}
}

void	dark()
{
   struct	IntuiMessage	*msg;
   ULONG		class,depth;
   struct	Window	*w_time;
   UWORD	px,py,tx,ty;
   static	UWORD	sx=1;
   static	UWORD	sy=1;
   static	UWORD	oldpy=0;
   static	UWORD	oldpx=0;

/*
   switch(my_gadg[0].value){
	case 0:
	case 1:
		depth=2;
		break;
	case 2:
		depth=3;
		break;
   }
   Screen.Depth=depth;
*/

   if (( s = OpenScreen(&Screen ))!=NULL){

	rp = &(s->RastPort);

	SetRast(rp,0);
	Window.Screen=s;
	Window.Width=TAILLE_N*2;
	Window.Height=TAILLE_N;
	LoadRGB4(&s->ViewPort,ScreenColors,1<<3);

	if (  w_time = OpenWindow(&Window )){
		FreeSprite (0);
		GfxBase->SpriteReserved|=1;
		rp=w_time->RPort;
/*
		RefreshWindow( w_time, 0l );
*/
		InitArea(&myarea,areabuffer,10);
		rp->AreaInfo=&myarea;
		rp->TmpRas=(struct TmpRas *)InitTmpRas(&tmpras,AllocRaster(WIDTH,HEIGHT),RASSIZE(WIDTH,HEIGHT));
	
		init_clock(w_time);

		px=w_time->LeftEdge<<3;
		py=w_time->TopEdge<<3;
		sx=1;

		while(tst_end()==FALSE){
			WaitPort(w_time->UserPort);
			while((msg=(struct IntuiMessage *)GetMsg(w_time->UserPort))!=0){
				class=msg->Class;
				ReplyMsg((struct Message *)msg);
				switch(class){
					case	INTUITICKS:
						aff_time(w_time);

						px+=sx;
						py+=sy;
						tx=px>>3;
						ty=py>>3;
						if(px<0){
							px=0;
							sx=-sx;
						}
						if(py<0){
							py=0;
							sy=-sy;
						}
						if(tx+w_time->Width>=s->Width){
							px-=sx;
							sx=-sx;
						}
						if(ty+w_time->Height>=s->Height){
							py-=sy;
							sy=-sy;
						}
						if((oldpx!=tx)||(oldpy!=ty)){
/*							MoveWindow(w_time,tx-oldpx,ty-oldpy);*/
							oldpx=tx;
							oldpy=ty;
						}

						break;

					case	REFRESHWINDOW:
/*						RefreshWindow( w_time, 0l );
*/
						init_clock(w_time);
						break;
					default:
						break;
				}
			}
		}
	}
	if ( w_time)CloseWindow( w_time );
	FreeRaster(tmpras.RasPtr,WIDTH,HEIGHT);
	CloseScreen(s);
   }
}

void	proc_init()
{
        DiskfontBase = OpenLibrary("diskfont.library", 37L);
}

void	proc_save()
{
}
void	proc_end()
{
	if(DiskfontBase)CloseLibrary(DiskfontBase);
}

