/* Lc BioZII
Blink from lib:c.o+bioZII.o LIB lib:lcm.lib lib:lc.lib lib:amiga.lib to RAM:BioZII DEFINE __main=__tinymain NODEBUG SMALLDATA SMALLCODE VERBOSE */

#include <stdio.h>
#include <math.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <devices/printer.h>
#include <devices/prtbase.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include "ram:BioZReq.c"


#define bisex(x) ((x%4)==0)
#define pi ((float) 3.141593)

UBYTE vers[]="\0$VER: BioZII v1.1 (17.06.93)";
int hauteur[2]={256,200},Axe[2]={100,90},comm[2]={180,150},comm2[2]={20,14},
    comm3[2]={190,155},amp[2]={50,45};

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *Window;
struct Screen *Screen, *WBScreen;
struct IconBase *IconBase=NULL;

struct IntuiMessage *Message;
struct RastPort *RPort;
struct DiskObject *DiskObj=0;

int hardcopy();

char *inter[3][3][3][3],*probleme=NULL,name[100],*fichier=NULL,
     *phy=NULL,*emo=NULL,*cer=NULL,*MyMsg=NULL,*Mess[2]={NULL,NULL},
     *azaaz=NULL,*bio=NULL;
int j[3],m[3],a[3],axe=100,lar=20,mois[13]={31,28,31,30,31,30,31,31,30,31,30,31};
int jv,ph[3],em[3],ce[3],MyErr=0,mode=0;

BOOL DMReq=FALSE,First=TRUE,Date=FALSE;

char *fill(ch2,n,m)
char *ch2;
int n;
{
	char *ch;
	ch=(char*)malloc(n+m);
	stccpy(ch,ch2,n);
	return(ch);
}
	
void LoadComment()
{
	int i,j,k,l;
	char a[80],*m;
	FILE *MyFile;
	
	MyFile=fopen(fichier,"r");

	for(i=0;i<=17;i+=1)
	{
		if(MyFile==NULL) m=NULL; else m=fgets(a,sizeof(a),MyFile);
		if(m!=NULL)
		{
			switch(i)
			{
				case 0 : NewScreen.DefaultTitle=fill(a,min(strlen(a),77),0);					 
					 break;
				case 1 : NewWindow.Title=fill(a,min(strlen(a),74),0);
					 break;
				case 2 : bio=fill(a,min(strlen(a),35),1);
					 strcat(bio," ");
					 break;
				case 3 : azaaz=fill(a,min(strlen(a),11),1);
					 strcat(azaaz," ");
					 break; 
				case 4 : phy=fill(a,min(strlen(a),16),0);
					 break;
				case 5 : emo=fill(a,min(strlen(a),16),0);
					 break;
				case 6 : cer=fill(a,min(strlen(a),16),0);
					 break;
				case 7 : IText7.IText=fill(a,min(strlen(a),23),0);
					 break;
				case 8 : IText6.IText=fill(a,min(strlen(a),23),0);
					 break;
				case 9 : Mess[0]=fill(a,min(strlen(a),73),0);
					 break;
				case 10: Mess[1]=fill(a,min(strlen(a),73),0);
					 break;
				case 11: probleme=fill(a,min(strlen(a),77),0);  
					 break;
				case 12: MyMsg=fill(a,min(strlen(a),73)),0;
					 break;
				case 13: IText8.IText=fill(a,min(strlen(a),6),0);
					 IText8.LeftEdge-=4*(strlen(a)-5);
					 break;
				case 14: IText4.IText=fill(a,min(strlen(a),11),0);
					 IText4.LeftEdge=(92-7*strlen(a))/2;
					 break;
				case 15: IText5.IText=fill(a,min(strlen(a),16),0);
					 break;
				case 16: if(Gadget4SInfo.Buffer==NULL) Gadget4SInfo.Buffer=fill(a,9,0);
					 Gadget4SInfo.UndoBuffer=fill(a,9,0);
					 break;
				case 17: IText20.IText=fill(a,min(strlen(a),20),0);
					 break;
			}
		}
	}

	if(Mess[0]==NULL) Mess[0]="Date de prédiction invalide !";
	if(Mess[1]==NULL) Mess[1]="Date de naissance invalide !";
	if(NewScreen.DefaultTitle==NULL) NewScreen.DefaultTitle="BioZ II v1.1     créé par Mikaël ZAJAC        mis à jour le 17/06/93";
	if(NewWindow.Title==NULL) NewWindow.Title="Biorythmes";
	if(bio==NULL) bio="Biorythmes du ";
	if(azaaz==NULL) azaaz=" né(e) le ";
	if(phy==NULL) phy="Physique";
	if(emo==NULL) emo="Emotionnel";
	if(cer==NULL) cer="Cérébral";
	if(IText7.IText==NULL) IText7.IText="Date de prédiction :";
	if(IText6.IText==NULL) IText6.IText="Date de naissance : ";
	if(Mess[0]==NULL) Mess[0]="Date de prédiction invalide !";
	if(Mess[1]==NULL) Mess[1]="Date de naissance invalide !";
	if(probleme==NULL) probleme="      Commentaire introuvable !";
	if(MyMsg==NULL) MyMsg="Erreur d'acces à l'Imprimante";
	if(IText8.IText==NULL) IText8.IText="Mois";
	if(IText4.IText==NULL) IText4.IText="Imprimer";
	if(IText5.IText==NULL) IText5.IText="Prénom et Nom :";
	if(Gadget4SInfo.Buffer==NULL) Gadget4SInfo.Buffer="jj/mm/aa";
	if(Gadget4SInfo.UndoBuffer==NULL) Gadget4SInfo.UndoBuffer="jj/mm/aa";
	if(IText20.IText==NULL) IText20.IText="Impression en cours...";

	for(i=0;i<=2;i+=1)
		for(j=0;j<=2;j+=1)
			for(k=0;k<=2;k+=1)
				for(l=0;l<=2;l+=1)
				{
					if(MyFile==NULL) m=NULL; else m=fgets(a,sizeof(a),MyFile);
					if(m!=NULL)
					{
						inter[i][j][k][l]=fill(a,min(strlen(a),77),0);
					}
					else if(l==0) inter[i][j][k][l]=probleme; else inter[i][j][k][l]="";
				}
	
	fclose(MyFile);
}

void swap(x,y)
int *x,*y;
{
	int z;
	z=*x;
	*x=*y;
	*y=z;
}

char *search(aa)
char *aa;
{
	int i=0;
	while(aa[i++]!='|') if(i>strlen(aa)) break;
	if(i>strlen(aa)) return(NULL); else  return(&aa[i]);
}

float Nom()
{
	char *Value=0;
	if(IconBase!=NULL && (DiskObj!=0 && strlen(Gadget2SIBuff)>=1))
	{
		Value=FindToolType(DiskObj->do_ToolTypes,Gadget2SIBuff);
		if(Value!=0)
		{
			free(Gadget4SInfo.Buffer);
			Gadget4SInfo.Buffer=fill(Value,9,0);
			if(search(Value)!=NULL) stccpy(Gadget2SIBuff,search(Value));
		}
	}
	if(Value!=0) return(1); else return(0);
}

void Args()
{
	char *Value;
	IconBase=(struct IconBase *)OpenLibrary(ICONNAME,0);
	if(IconBase!=NULL)
	{
		DiskObj=GetDiskObject(name);
		if(DiskObj!=0)
		{
/*			Value=FindToolType(DiskObj->do_ToolTypes,"MONITOR");
			if(MatchToolValue(Value,"NTSC")) mode=1; */
			Value=FindToolType(DiskObj->do_ToolTypes,"DATE");
			if(MatchToolValue(Value,"USA")) Date=TRUE;
			Value=FindToolType(DiskObj->do_ToolTypes,"START");
			if(Value!=0)
			{
				strncpy(Gadget2SIBuff,Value,min(strlen(Value),24));
				Value=FindToolType(DiskObj->do_ToolTypes,Gadget2SIBuff);
				if(Value!=0)
				{
					free(Gadget4SInfo.Buffer);
					Gadget4SInfo.Buffer=fill(Value,9,0);
					if(search(Value)!=NULL) stccpy(Gadget2SIBuff,search(Value));
				}
			}
			Value=FindToolType(DiskObj->do_ToolTypes,"FILE");
			if(Value!=0 && fichier==NULL)
			{
				fichier=(char*)malloc(strlen(Value)+1);
				strcpy(fichier,Value);
			}
		}
		if(fichier==NULL)
		{
			fichier=(char*)malloc(9);
			strcpy(fichier,"français");
		}
	}
}
	

void colors(col)
int col;
{
	USHORT cmap[3][8]={ {0x0AAA,0x0000,0x0FFF,0x000F,0x0F0F,0x0FF0,0x0000,0x0F00 },
			    {0x0FFF,0x0000,0x0FFF,0x00FF,0x0F0F,0x00F0,0x0000,0x0F00 },
			    {0x0FFF,0x0000,0x0FFF,0x0000,0x0000,0x0000,0x0000,0x0F00 }};
	LoadRGB4(&Screen->ViewPort,&cmap[col],8);
}

int init()
{
	LoadComment();
	if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0))==NULL) return(0);
	if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0))==NULL) return(1);
	if( GfxBase->DisplayFlags & NTSC ) mode=1;
	axe=Axe[mode];
	NewScreen.Height=hauteur[mode];
	if((Screen=(struct Screen *) OpenScreen(&NewScreen))==NULL) return(2);
	NewWindow.Screen=Screen;
	NewWindow.Height=hauteur[mode]-12;
	if((Window=(struct Window *)OpenWindow(&NewWindow))==NULL) return(3);
	RPort=Window->RPort;
	colors(0);
	MyReq.TopEdge=(hauteur[mode]-24-MyReq.Height)/2;
	MyReq2.TopEdge=(hauteur[mode]-24-MyReq2.Height)/2;
	if(!Request(&MyReq,Window)) return(4);
	return(-1);
}

void cleanup(l)
int l;
{
	switch(l)
	{
		case 4:	CloseWindow(Window);
		case 3:	CloseScreen(Screen);
		case 2:	CloseLibrary(GfxBase);
		case 1:	CloseLibrary(IntuitionBase);
		case 0: exit(0);
			break;
	}
}

void sdate(to,day,month,year)
int day,month,year;
char to[9];
{
	int i;
	if(Date) sprintf(to,"%2d/%2d/%2d",month,day,year);
	else	 sprintf(to,"%2d/%2d/%2d",day,month,year);
	for(i=0;i<=9;i++)
		if(to[i]==' ') to[i]='0';
}
	
	

int strdate(ch,ch2,x,y)
int x,y;
char *ch2,ch[9];
{
	char *ch3;
	sdate(Gadget3SIBuff,j[1],m[1],a[1]);
	SetAPen(RPort,1);
	ch3=(char *)malloc(strlen(ch2)+strlen(ch)+1);
	strcpy(ch3,ch2);
	strcat(ch3,ch);
	Move(RPort,x,y);
	Text(RPort,ch3,strlen(ch3));
	free(ch3);
	return(0);
}

void Chemin(L)
BPTR L;
{
	struct FileInfoBlock Block;
	if(ParentDir(L)!=NULL)
		Chemin(ParentDir(L));

	if(Examine(L,&Block))
	{
		strcat(fichier,Block.fib_FileName);
		if(ParentDir(L)==NULL)
			strcat(fichier,":");
		else
			strcat(fichier,"/");
	}
}

main(argc,argv)
int argc;
char **argv;
{
	int val=1;
	struct WBStartup *msg;
	
	if(argc!=0)
		strcpy(name,argv[0]);
	else
	{
		msg=(struct WBStartup *) argv;
		strcpy(name,msg->sm_ArgList[0].wa_Name);
		if(msg->sm_NumArgs==2)
		{
			fichier=(char*)malloc(300);
			Chemin(msg->sm_ArgList[1].wa_Lock);
			strcat(fichier,msg->sm_ArgList[1].wa_Name);
		}

	}
		
	if(argc==2)
	{
		fichier=(char*)malloc(strlen(argv[1])+1);
		strcpy(fichier,argv[1]);
	}


	Args();
	dates();
	cleanup(init());
	fin();
	plmo:
	if(val==1)
	{
		SetAPen(RPort,0);
		RectFill(RPort,7,22,635,hauteur[mode]-16);
		joursvecus(1,j[1]);
		joursvecus(2,1);
		dessine();
	}
	if((val=fin())!=0) goto plmo;	
	if(argc==0 && msg->sm_NumArgs==2) free(fichier);
}

int dates()
{
	char d[8];
	getclk(d);
	sdate(Gadget3SIBuff,d[3],d[2],d[1]+80);
	a[1]=d[1]+80;
	m[1] = d[2];
	j[1] = d[3];
	return(0);
}
	
void dates2()
{
	char *pn=NULL;
	pn=fill(Gadget2SIBuff,strlen(Gadget2SIBuff)+1,strlen(azaaz)+1);
	if(strlen(Gadget2SIBuff)<1)
	{
		free(pn);
		pn=fill(IText6.IText,strlen(IText6.IText)+1,2);
		strcat(pn," ");
	}
	else
		strcat(pn,azaaz);
	SetAPen(RPort,0);
	RectFill(RPort,7,12,635,22);
	strdate(Gadget4SInfo.Buffer,pn,10,19);
	free(pn);
	pn=NULL;
	Move(RPort,350,19);
	SetAPen(RPort,3);
	Text(RPort,phy,strlen(phy));
	Move(RPort,500,19);
	SetAPen(RPort,5);
	Text(RPort,emo,strlen(emo));
}

int joursvecus(c,day)
int c,day;
{
	int za,av,mv,mm=0,ab=0,mmm=0;
	av=(a[1]-1-a[2])*365;
	for(mv=m[2];mv<=12;mv++)
		mm+=mois[mv];
	for(mv=m[1]-1;mv>=1;mv--)
		mmm+=mois[mv-1];
	av+=(mois[m[2]-1]-j[2]);
	for(za=a[2]+1;za<a[1];za++)
		if (bisex(za)) ab++; 
	if ( m[2]<3 && bisex(a[2])) ab++;
	if ( m[1]>2 && bisex(a[1])) ab++;
	jv=av+mm+mmm+ab+day;
	ph[c]=jv%23;
	em[c]=jv%28;
	ce[c]=jv%33;
	return(jv);
}

int dessine()
{
	int i,n;
	char z[3]="";
	
	if(m[1]==2 && bisex(a[1])) mois[m[1]-1]=29;
	lar=620-620%mois[m[1]-1];
	
	SetAPen(RPort,1);
	Move(RPort,10,axe);
	Draw(RPort,lar+10,axe);
	
	for(i=0;i<=mois[m[1]-1];i++)
	{	
		n=i/2;
		SetAPen(RPort,1);
		Move(RPort,(lar/mois[m[1]-1])*i+10,axe-3);
		Draw(RPort,(lar/mois[m[1]-1])*i+10,axe+3);
		if(i<mois[m[1]-1])
		{
			if(i==n*2) Move(RPort,(lar/mois[m[1]-1])*i+13,axe-3);
			else       Move(RPort,(lar/mois[m[1]-1])*i+13,axe+9);
			sprintf(z,"%2d",i+1);
			if(z[0]==' ') z[0]='0';
			Text(RPort,z,2);
		}
	}
	
	sinusoide(ph[2],23,1);
	sinusoide(em[2],28,3);
	sinusoide(ce[2],33,2);
	
	SetAPen(RPort,1);
	Move(RPort,(j[1]*lar/mois[m[1]-1])+10-((lar/mois[m[1]-1])/2),axe-amp[mode]-5);
	Draw(RPort,(j[1]*lar/mois[m[1]-1])+10-((lar/mois[m[1]-1])/2),axe+amp[mode]+5);
	Move(RPort,425,29);
	SetAPen(RPort,4);
	Text(RPort,cer,strlen(cer));
	strdate(&Gadget3SIBuff,bio,10,29);
		
	interpretation();
	mois[1]=28;
	return(0);
}

void verif()
{
	if (j[1]>29 && m[1]==2 && bisex(a[1])) j[1]=29;
	if (j[1]>mois[m[1]-1] && (m[1]!=2 || !bisex(a[1]))) 
		j[1]=mois[m[1]-1];
}

int fin()
{
	int Code,i,jj,mm,aa;
	long Class;
	float k;
	APTR Adresse;	

	wxt:
	Wait(1<<Window->UserPort->mp_SigBit);
	while(Message=(struct IntuiMessage *)GetMsg(Window->UserPort))
	{
		Class=Message->Class;
		Code=Message->Code;
		Adresse=Message->IAddress;
		ReplyMsg(Message);
		switch(Class)
		{
			case REQSET:
				ActivateGadget(&Gadget2,Window,&MyReq);
				break;
			case GADGETUP:
				k=0;
				if(Adresse==(APTR)&Gadget2) k=(float) Nom();
				i=sscanf(Gadget3SIBuff,"%d%*c%d%*c%d",&j[1],&m[1],&a[1]);
				if(Date) swap(&j[1],&m[1]);
				if( i!= 5 || (j[1]>mois[m[1]-1] &&  (m[1]!=2 || !bisex(a[1])))
					|| m[1]>13 || m[1]<1 || j[1]<1 ||
					(m[1]==2 && bisex(a[1]) && j[1]>29))
					MyErr=1;
				
				i=sscanf(Gadget4SInfo.Buffer,"%d%*c%d%*c%d",&j[2],&m[2],&a[2]);
				if(Date) swap(&j[2],&m[2]);
				if ( i!= 5 || (j[2]>mois[m[2]-1] &&  (m[2]!=2 || bisex(a[2])))
					|| m[2]>13 || m[2]<1 || j[2]<1 ||
					(m[2]==2 && bisex(a[2]) && j[2]>29))
					MyErr=2;
				else
					if(j[1]+100*m[1]+10000*a[1]<j[2]+100*m[2]+10000*a[2])
						MyErr=1;
					else
						sdate(Gadget4SInfo.Buffer,j[2],m[2],a[2]);
				if(Adresse==(APTR)&Gadget2 && k==0) ActivateGadget(&Gadget4,Window,&MyReq);
				if(k==1) RefreshGadgets(&Gadget4,Window,&MyReq);
				if(Adresse==(APTR)&Gadget4 || k==1) ActivateGadget(&Gadget3,Window,&MyReq);
	
				if(!DMReq) DMReq=SetDMRequest(Window,&MyReq);
				if(Adresse==(APTR)&Gadget5 || Adresse==(APTR)&Gadget6 || Adresse==(APTR)&Gadget7 || Adresse==(APTR)&Gadget1)
					if(MyErr!=0)
					{
						BAD.IText=&Mess[MyErr-1][0];
						if(MyErr==1) strcpy(&Gadget3SIBuff,&UNDOBUFFER2);
						else strcpy(Gadget4SInfo.Buffer,Gadget4SInfo.UndoBuffer);
						MyErr=0;
						if(DMReq)
						{
							ClearDMRequest(Window);
							DMReq=FALSE;
						}
						AutoRequest(Window, &BAD, NULL, &OK, NULL, NULL, 320, 72);
						Request(&MyReq,Window);
					}
					else
					{
						
						if(Adresse==(APTR)&Gadget5)
						{
							mplus();
							verif();
							dates2();
							RefreshGadgets(&Gadget3,Window,&MyReq);
						}
						
						if(Adresse==(APTR)&Gadget6)
						{
							jj=j[1]; mm=m[1]; aa=a[1];
							mmoins();
							verif();
							if(j[1]+100*m[1]+10000*a[1]<j[2]+100*m[2]+10000*a[2]) 
							{
								j[1]=jj; m[1]=mm; a[1]=aa;
								return(2);
							}
							else
							{
								dates2();
								RefreshGadgets(&Gadget3,Window,&MyReq);
							}
						}
						if(Adresse==(APTR)&Gadget7)
						{
							dates2();
							if(First)
							{
								Gadget1.Flags=NULL;
								Gadget5.Flags=NULL;
								Gadget6.Flags=NULL;
							}
						}
						if(Adresse==(APTR)&Gadget1)
						{
							hardcopy();
							colors(0);
							ModifyIDCMP(Window,CLOSEWINDOW|RAWKEY|GADGETUP|REQSET|MOUSEBUTTONS);
							DMReq=SetDMRequest(Window,&MyReq);
						}
						return(1);
					}
				else
				{
					MyErr=0;
				}
				break;
			case RAWKEY:
				jj=j[1]; mm=m[1]; aa=a[1];
				switch(Code)
				{
					case 206:
						if((m[1]==2 && bisex(a[1]) && j[1]==29) || (!(m[1]==2 && bisex(a[1])) && j[1]==mois[m[1]-1]))  { j[1]=0; mplus(); }
						j[1]+=1;
						return(1);
						break;
					case 207:
						if (j[1]==1)
							if(bisex(a[1]) && m[1]==3) { mmoins(); j[1]=30; }
							else { mmoins(); j[1]=mois[m[1]-1]+1; }
						j[1]-=1;
						if(j[1]+100*m[1]+10000*a[1]<j[2]+100*m[2]+10000*a[2]) 
						{ 
							j[1]=jj; m[1]=mm; a[1]=aa;
							return(2);
						}
						else return(1);
						break;
					case 222:
						a[1]+=1;
						return(1);
						break;
					case 202:
						a[1]-=1;
						if(j[1]+100*m[1]+10000*a[1]<j[2]+100*m[2]+10000*a[2])
						{
							j[1]=jj; m[1]=mm; a[1]=aa;
							return(2);
						}
						else return(1);
						break;
					case 204:
						mplus();
						verif();
						return(1);
						break;
					case 205:
						mmoins();
						verif();
						if(j[1]+100*m[1]+10000*a[1]<j[2]+100*m[2]+10000*a[2]) 
						{
							j[1]=jj; m[1]=mm; a[1]=aa;
							return(2);
						}
						else return(1);
						break;	
				}
				break; 
			
			case CLOSEWINDOW: 
				if (DMReq) ClearDMRequest(Window);
				CloseWindow(Window);
				CloseScreen(Screen);
				CloseLibrary(GfxBase);
				CloseLibrary(IntuitionBase);
				if(DiskObj!=0) FreeDiskObject(DiskObj);
				if(IconBase!=NULL) CloseLibrary(IconBase);
				return(0);
				break;
			case MOUSEBUTTONS:
				if(Code==104)
				{
					k=.5+((Window->MouseX)-10)/(lar/mois[m[1]-1]);
					j[1]=k+1;
					if (j[1]<1) j[1]=1;
					verif();
					return(1);
				}
				break;
		}
	}
	goto wxt;
}

int mplus()
{
		if (m[1]++==12) { m[1]=0;	a[1]+=1; }
		return(0);
}

int mmoins()
{
		if (m[1]--==1) { m[1]=13;	a[1]-=1; }
		return(0);
}

int sinusoide(aa,bb,c)
int aa,bb,c;
{
	double x,xx,yy;
	int i=0,xxx,yyy;
	SetAPen(RPort,c+2);
	xxx=sin(aa*2*pi/bb)*-amp[mode]+axe;
	Move(RPort,10+(lar/mois[m[1]-1])/2,xxx);

	for( x=0; x<=2*pi*(mois[m[1]-1]-1)/bb; x=x+(2*pi/bb))
	{	
		xx=(.5+i++)*(lar/mois[m[1]-1])+10;
		yy=(sin(x+aa*2*pi/bb))*-amp[mode]+axe;
		xxx=xx;
		yyy=yy;
		Draw(RPort,xxx,yyy); 
		Move(RPort,xxx,yyy);
	} 
	switch(c)
	{
		case 1: Text(RPort,&"P",1); break;
		case 2: Text(RPort,&"C",1); break;
		case 3: Text(RPort,&"E",1);
	}
	return(0);
}

int interpretation()
{
	int az,ez,rz;
		
	if (ph[1]==0 || ph[1]==12 || ph[1]==23) az=0;
	if (ph[1]<12 && ph[1]>0) az=1;
	if (ph[1]>12 && ph[1]<23) az=2;
	if (em[1]==0 || em[1]==14 || em[1]== 28) ez=0;
	if (em[1]<14 && em[1]>0) ez=1;
	if (em[1]>14 && em[1]<28) ez=2;
	if (ce[1]==0 || ce[1]==16 ||ce[1]== 33) rz=0;
	if (ce[1]<16 && ce[1]>0) rz=1;
	if (ce[1]>16 && ce[1]<33) rz=2;
	SetAPen(RPort,1);
	if(strlen(inter[az][ez][rz][2])!=0)
	{
		Move(RPort,17,comm[mode]);
		Text(RPort,inter[az][ez][rz][0],strlen(inter[az][ez][rz][0]));
		Move(RPort,17,comm[mode]+comm2[mode]);
		Text(RPort,inter[az][ez][rz][1],strlen(inter[az][ez][rz][1]));
		Move(RPort,17,comm[mode]+2*comm2[mode]);
		Text(RPort,inter[az][ez][rz][2],strlen(inter[az][ez][rz][2]));
	}
	else
	{
		Move(RPort,17,comm3[mode]);
		Text(RPort,inter[az][ez][rz][0],strlen(inter[az][ez][rz][0]));
		Move(RPort,17,comm3[mode]+comm2[mode]);
		Text(RPort,inter[az][ez][rz][1],strlen(inter[az][ez][rz][1]));
	}
	return(0);	
}

void ErrDev()
{
	BAD.IText=MyMsg;
	AutoRequest(Window, &BAD, NULL, &OK, NULL, NULL, 320, 72);
}

int hardcopy()
{
	char MyMsg[50]="";
	static UBYTE *ErrorText[] =
	{
 		"PDERR_NOERR",
		"PDERR_CANCEL",
		"PDERR_NOTGRAPHICS",
		"INVERTHAM",		/* OBSOLETE */
		"BADDIMENSION",
		"DIMENSIONOVFLOW",	/* OBSOLETE */
		"INTERNALMEMORY",
		"BUFFERMEMORY",	
		"IOERR_OPENFAIL",
		"IOERR_ABORTED",
		"IOERR_NOCMD",
		"IOERR_BADLENGTH"
	};	
	struct PrinterData *PD;
	BOOL STOP=TRUE;
	int MyErr;
	ULONG Signal;
	union printerIO
	{
		struct IOStdReq ios;
		struct IODRPReq iodrp;
		struct IOPrtCmdReq iopc;
	};
	union printerIO *request;
	struct MsgPort *printerPort;
	if(DMReq)
	{
		ClearDMRequest(Window);
		DMReq=FALSE;
	}
	ModifyIDCMP(Window,GADGETUP);
	Request(&MyReq2,Window); 
	if(printerPort=(struct MsgPort *) CreatePort("printer.port",0))
	{
		if(request=(union printerIO *)CreateExtIO(printerPort,sizeof(union printerIO)))
		{
			if(!(OpenDevice("printer.device",0,request,0)))
			{
				PD=(struct PrinterData *)request->iodrp.io_Device;
				if(PD->pd_Preferences.PrintShade==0)
					colors(2);
				else
					colors(1);
				
				request->iodrp.io_Command=PRD_DUMPRPORT;
				request->iodrp.io_RastPort=RPort;
				request->iodrp.io_ColorMap=Screen->ViewPort.ColorMap;
				request->iodrp.io_Modes=NewScreen.ViewModes;
				request->iodrp.io_SrcX=6;
				request->iodrp.io_SrcY=12;
				request->iodrp.io_SrcWidth=628;
				request->iodrp.io_SrcHeight=hauteur[mode]-34;
				request->iodrp.io_DestCols=NULL;
				request->iodrp.io_DestRows=NULL;
				request->iodrp.io_Special=SPECIAL_CENTER|SPECIAL_ASPECT|SPECIAL_DENSITY7|SPECIAL_FULLCOLS;
	
				SendIO(request);
				Signal=Wait(1<<Window->UserPort->mp_SigBit|1<<printerPort->mp_SigBit);
				if(Signal & (1<<Window->UserPort->mp_SigBit))
				{
					while(Message=(struct IntuiMessage *)GetMsg(Window->UserPort))
						ReplyMsg(Message);
					AbortIO(request);
			  		WaitIO(request);
					STOP=FALSE;
				}
				if(Signal & (1<<printerPort->mp_SigBit))
					while(GetMsg(printerPort));
				if(request->iodrp.io_Error !=0)
				{
					MyErr =request->iodrp.io_Error;
			                if (MyErr < 0) MyErr=MyErr*-1 +7;
					sprintf(MyMsg,"Erreur : %s",ErrorText[MyErr]);
					BAD.IText=MyMsg;
					if(MyErr!=9) AutoRequest(Window, &BAD, NULL, &OK, NULL, NULL, 320, 72);
				}
				CloseDevice((struct IORequest*)request);
			}
			else ErrDev();
			
			DeleteExtIO((struct IORequest*)request);
		}
		else	ErrDev();
		DeletePort(printerPort);
		if(STOP) EndRequest(&MyReq2,Window);
	}
	return(0);
}