/*
 *          printerE.c             © by Martin Steppler
 */

extern LONG FileSelect();
extern VOID ReleaseFileSelect();
BYTE pfadundfile[PATHSTRSIZE+FILESTRSIZE+12];
struct FSRequest MyFSReq;
/* DEFINES */
#define MAUSKLICK while((nclass=message()) != MOUSEBUTTONS);
#define DRAWGAD    1
#define ZAHLGADI   2
#define ZAHLGADII  3
#define ZAHLGADIII 4
#define ZAHLGADIV  5
#define ZAHLGADV   6
#define ZAHLGADVI  7
#define OK         8
#define STOP       9
#define SUCHEN     10
#define ERSETZEN   11
#define GROSSKLEIN 12

/* VARIABLEN */
union Drucker *DruckerReq;     /* für die Druckerausgabe */
union Drucker {
   struct IOStdReq drucker_std;
   struct IODRPReq drucker_drp;
   struct IOPrtCmdReq drucker_pcr;
};
struct MsgPort *DP;
extern union Drucker *CreateExtIO();

UBYTE itaein[] = { 27,'[','3',    'm',EOS },
      itaaus[] = { 27,'[','2','3','m',EOS },
      untein[] = { 27,'[','4',    'm',EOS },
      untaus[] = { 27,'[','2','4','m',EOS },
      fetein[] = { 27,'[','4', 34,'z',EOS },
      fetaus[] = { 27,'[','3', 34,'z',EOS };

int    spa,zei;
static int nclass;
static int first=0, fahne=0;   /* flags */
static unsigned char backup[32]   = EOS, upback [32]   = EOS;
static unsigned char suchen[32]   = EOS, suchII [32]   = EOS;
static unsigned char ersetzen[32] = EOS, ersetzII [32] = EOS;
static UBYTE zgad1[5]=EOS, undozgad1[5];
static UBYTE zgad2[5]=EOS, undozgad2[5];
static UBYTE zgad3[5]=EOS, undozgad3[5];
static UBYTE zgad4[5]=EOS, undozgad4[5];
static UBYTE zgad5[5]=EOS, undozgad5[5];
static UBYTE zgad6[6]=EOS, undozgad6[6];

static struct Window       *fenster2;
static struct RastPort       *RP1;

static struct StringInfo infoN3={      /* Info für Gehezu */
   (UBYTE *) backup, (UBYTE *) upback, 0,31,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo infoN2={      /* Info für Suchen */
   (UBYTE *) suchen, (UBYTE *) suchII, 0,31,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo infoN1={      /* Info für Ersetzen */
   (UBYTE *) ersetzen, (UBYTE *) ersetzII, 0,31,0,0,0,0,0,0,0,0,NULL };

static struct StringInfo info1={    /* Info für ZAHLGADI */
   (UBYTE *)zgad1,(UBYTE *)undozgad1, 0,4,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo info2={    /* Info für ZAHLGADII */
   (UBYTE *)zgad2,(UBYTE *)undozgad2, 0,4,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo info3={    /* Info für ZAHLGADIII */
   (UBYTE *)zgad3,(UBYTE *)undozgad3, 0,4,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo info4={    /* Info für ZAHLGADIV */
   (UBYTE *)zgad4,(UBYTE *)undozgad4, 0,4,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo info5={    /* Info für ZAHLGADV */
   (UBYTE *)zgad5,(UBYTE *)undozgad5, 0,4,0,0,0,0,0,0,0,0,NULL };
static struct StringInfo info6={    /* 2. Info für ZAHLGADV */
   (UBYTE *)zgad6,(UBYTE *)undozgad6, 0,5,0,0,0,0,0,0,0,0,NULL };

struct IntuiText oktext = {
   BLAU, WEISS, JAM2, 0, 0, NL, (UBYTE *) "  OKAY  ", NL };
struct IntuiText stoptext = {
   ROT,  WEISS, JAM2, 0, 0, NL, (UBYTE *) "  STOP  ", NL };
struct IntuiText grosstext = {
   BLAU,  WEISS, JAM2, 0, 0, NL, (UBYTE *) "OFF", NL };


static struct Gadget *gaddy;

static struct Gadget Gad2={        /* Textgadget */
   NULL, 12, 28, 237, 8,         /* 115 */
   GADGHCOMP,RELVERIFY,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&infoN3,DRAWGAD,NULL };
static struct Gadget Gad3={        /* Textgadget Suchen */
   NULL, 96, 28, 237, 8,
   GADGHCOMP,RELVERIFY,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&infoN2,SUCHEN,NULL };
static struct Gadget Gad4={        /* Textgadget Ersetzen */
   &Gad3, 96, 50, 237, 8,
   GADGHCOMP,RELVERIFY,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&infoN1,ERSETZEN,NULL };
static struct Gadget grossgad ={   /* Groß/Klein */
    &Gad4,308,72,24,8,GADGHCOMP,RELVERIFY,BOOLGADGET,0,NULL,
    &grosstext,EOS,NULL,GROSSKLEIN,NULL};

static struct Gadget IntGad6={           /* 6. Intgadget */
   NULL, 110, 28, 40, 8,           /* Gehe zur x. Zeile */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info6,ZAHLGADVI,NULL };
static struct Gadget okgad  ={
   NULL,53,149,64,8,
   GADGHCOMP,RELVERIFY,BOOLGADGET,0,NULL,
   &oktext,EOS,NULL,OK,NULL };
static struct Gadget stopgad ={
   &okgad,223,149,64,8,GADGHCOMP,RELVERIFY,BOOLGADGET,0,NULL,
   &stoptext,EOS,NULL,STOP,NULL};
static struct Gadget IntGad5={           /* 5. Intgadget */
   &stopgad, 42, 130, 32, 8,           /* Papierlänge */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info5,ZAHLGADV,NULL };
static struct Gadget IntGad4={           /* 4. Intgadget */
   &IntGad5, 267, 84, 32, 8,           /* rechter Rand */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info4,ZAHLGADIV,NULL };
static struct Gadget IntGad3={           /* 3. Intgadget */
   &IntGad4, 153, 84, 32, 8,           /* linker Rand */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info3,ZAHLGADIII,NULL };
static struct Gadget IntGad2={           /* 2. Intgadget */
   &IntGad3, 267, 40, 32, 8,           /* bis Seite */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info2,ZAHLGADII,NULL };
static struct Gadget IntGad1={           /* 1. Intgadget */
   &IntGad2, 153, 40, 32, 8,           /* von Seite */
   GADGHCOMP,RELVERIFY|LONGINT|GADGIMMEDIATE,STRGADGET,
   NULL,NULL,NULL,0,
   (APTR)&info1,ZAHLGADI,NULL };

static struct NewWindow FensterVereinbarung = { /* Fenster */
   145,16,350,168,-1,-1,
   MOUSEBUTTONS|GADGETDOWN|GADGETUP,
   BORDERLESS|ACTIVATE,
   &Gad2,NULL,NULL,NULL,NULL,0,0,0,0,
   CUSTOMSCREEN };

message()
{
   int nklasse=0;
   if(nachricht2 = (struct IntuiMessage *)GetMsg(fenster2->UserPort)) {
      nklasse = nachricht2->Class;
      gaddy   = (struct Gadget *)nachricht2->IAddress;
      ReplyMsg(nachricht2);
   }
   return(nklasse);
}
print(text, col, xpos, ypos)
char *text;
int col, xpos, ypos;
{
   SetAPen(RP1, col);  SetDrMd(RP1, JAM1);
   Move(RP1, xpos, ypos); Text(RP1, text, strlen(text));
}
block(col,x1,y1,x2,y2)
int col,x1,y1,x2,y2;
{
   SetAPen(RP1, col); SetDrMd(RP1, JAM1); RectFill(RP1, x1,y1,x2,y2);
}
disk(anzeige)
char *anzeige;
{
   MyFSReq.titlestr = (BYTE *)anzeige;
   if(FileSelect(&MyFSReq)) {
      if(!MyFSReq.fullname[0]) return(FALSE);
      return(TRUE);
   }
   return(FALSE);
}
MaskeSetzen()    /* Druckerfenster zeichnen */
{
   int i,k;
   block(2,10,5,350,168);
   block(1,0,0,340,163);
   for(i=0;i<2;i++) {
      block(2,i*170+51,148,i*170+118,157);
     /*  block(0,i*170+50,148,i*170+120,158); */
   }
   /* print("OK",1,75,156);
   print("STOP",1,239,156); */
   for(i=0;i<4;i++) {
      block(2, 8,i*20+19,96,(i+1)*20+19);
      block(0,10,i*20+20,94,(i+1)*20+18);
   }
   print("NLQ",1,40,32);
   print("Pica",1,36,52);
   print("Elite",1,32,72);
   print("Condensed",1,16,92);
   block(2,8,107,96,127);
   block(0,10,108,94,126);
   print("paper-",1,28,116);
   print("length", 1,28,124);
   block(2,8,127,96,139);
   block(0,10,128,94,138);
   for(k=0;k<2;k++) {   /* Wenn Blockmodus, dann keine Seitenabfrage */
      for(i=0;i<2;i++) {
         if(!(blo>0 && (i==0 || i==1) && (k==0 || k==1))) {
             block(2,114*k+104,i*16+19,114*k+219,i*16+35);
             block(0,114*k+106,i*16+20,114*k+217,i*16+34);
         }
         block(2,114*k+104,i*16+63,114*k+219,i*16+79);
         block(0,114*k+106,i*16+64,114*k+217,i*16+78);
         block(2,57*k+104+i*114,127,57*k+162+i*114,139);
         block(0,57*k+106+i*114,128,57*k+160+i*114,138);
      }
   }
   print("ON", 1,125,136); print("ON", 1,125+114,136);
   print("OFF",1,178,136); print("OFF",1,178+114,136);
   if(blo==0) { print("from page",1,125,30);
      print("to page",1,248,30); }
   print("left margin",1,117,74);
   print("right martin",1,227,74);
   block(2,104,107,333,127);
   block(0,106,108,331,126);
   print("numbering of",1,170,116);
   print("pages",1,141,124);
   print("lines",1,255,124);
}
Hell2(zahl)  /* complementäre Darstellung des jeweiligen Gadgets */
int zahl;
{
   SetDrMd(RP1, COMPLEMENT);
   if(zahl<=3)
      RectFill(RP1,10,zahl*20+20,94,(zahl+1)*20+18);
   else if(zahl<=5)
      RectFill(RP1,57*(zahl-4)+220,128,57*(zahl-4)+274,138);
   else
      RectFill(RP1,(zahl-6)*57+106,128,(zahl-6)*57+160,138);
   SetDrMd(RP1, JAM1);
}
drucken(anzeige, anfse, anfze, seit, zeile)  /* Druckroutine */
char *anzeige;
int anfse, anfze, seit, zeile; /* Übergabe der maximal druckbaren Zeilen */
{
   int xa,xb,xc,ende,st,i,ii,r,os;
   char c;

   spa=seit; zei=zeile;
   zg2=spa+1;
   if(zg1>zg2)   zg1=1;
   if(blo==0) {
      strcpy(zgad1,itoa(zg1));
      strcpy(zgad2,itoa(zg2));
   }
   strcpy(zgad3,itoa(zg3));
   strcpy(zgad4,itoa(zg4));
   strcpy(zgad5,itoa(zg5));
   if(blo==0) FensterVereinbarung.FirstGadget = &IntGad1;
   else       FensterVereinbarung.FirstGadget = &IntGad3;
   FensterVereinbarung.Screen = Scheibe;
   if(!(fenster2 = (struct Window *)OpenWindow(&FensterVereinbarung))) {
      FensterVereinbarung.FirstGadget = &Gad2;
      return(0);
   }
   RP1 = fenster2->RPort;
   MaskeSetzen();
   if(blo==0) RefreshGadgets(&IntGad1,fenster2,NULL);
   else       RefreshGadgets(&IntGad3,fenster2,NULL);
   xb = strlen(anzeige)*8;
   xa = 170 - xb /2;
   block(2,xa-19,3,xa+xb+19,15);
   block(0,xa-17,4,xa+xb+17,14);
   print(anzeige,1,xa,12);
   Hell2(schrift); Hell2(znum); Hell2(snum+6);
   ende = checkit();
   CloseWindow(fenster2);
   FensterVereinbarung.FirstGadget = &Gad2;
   if(blo==0) {
      strcpy(zgad1,itoa(zg1));
      strcpy(zgad2,itoa(zg2));
   }
   strcpy(zgad3,itoa(zg3));
   strcpy(zgad4,itoa(zg4));
   strcpy(zgad5,itoa(zg5));
   if(ende==2) return(0); /* 2 -> Stopgadget im Printerfenster */
   DP=(struct MsgPort *)CreatePort(0,0); /* prt: öffnen */
   DruckerReq=(union Drucker *)
       CreateExtIO(DP,sizeof(union Drucker));
   if(OpenDevice("printer.device",0,DruckerReq,0) != 0) {
      sprintf(buffer, "Kann printer.device nicht öffnen!");
      Meldung();
      DeleteExtIO(DruckerReq, sizeof(union Drucker));
      DeletePort(DP);
      return(0);
   }        /* Schriftart u. Rand einstellen */
   sprintf(hel, "%cc%c[%d;%ds",27,27,zg3,zg4);  /* Reset + l. + r. Rand */
   switch(schrift) {
      case 0:  sprintf(buffer, "%c[2%cz",27,34);      /* NLQ */
          strcat(hel, buffer); break;
      case 1:  sprintf(buffer, "%c[0m",27);           /* Pica */
          strcat(hel, buffer); break;
      case 2:  sprintf(buffer, "%c[2w",27);           /* Elite */
          strcat(hel, buffer); break;
      case 3:  sprintf(buffer, "%c[4w", 27);          /* Schmal */
          strcat(hel, buffer); break;
   }
   xa =zg1-1; xb=0; xc=anfze; if(znum==5) znum=0; else znum=1;
   if(blo>0)  xa=anfse;
   while((ende=ausdruck(hel))==1) ;
   if(!ende) goto fin;
   FOREVER {  /* Hauptdruckroutine */
      if(xb==0) {  /* Anfang einer Textseite */
         if(blo>0)
            sprintf(buffer, "(P)rint block or (A)bort!");
         else
            sprintf(buffer, "Page %d! (S)kip (A)bort (P)rint!",xa+1);
         Meldung();
sleep:   while((c=ConsoleGetKey())<=0) ;
         if((c == 's' || c == 'S') && !(blo>0)) {
            xa++; if(xa>zg2-1) { ende=1; break; }
            continue;
         }
         else if(c=='a' || c=='A') { ende =1; break; }
         else if(c!='p' && c!='P') goto sleep;
      }
      if(SC(xa,xc,(i=SL(xa,xc)))) { st=8;   /* Steuercodes in Zeile */
         if(znum) { sprintf(buffer, "%4d ",znum++); ii=5; }
         else ii=0;
         for(r=0; r<=i-1; r++) {
            if(a[xa] [xc] [r] <9) {
               buffer[ii] = EOS;
               if(!br) { ii+=SetzeStil(a[xa] [xc] [r],st); st=a[xa] [xc] [r]; }
            }
            else buffer[ii++] = a[xa] [xc] [r];
            if(r==i-1 && a[xa] [xc] [r] == '­') buffer[ii-1]='-';
         }
         buffer[ii]=EOS; ii+=SetzeStil(8,st);
         buffer[ii++]=27; buffer[ii++] = 'E'; buffer[ii]=EOS;
      }
      else if(znum) sprintf(buffer,"%4d %s\n", znum++, a[xa] [xc]);
      else sprintf(buffer, "%s\n", a[xa] [xc]);
      if(!(ende=ausdruck(buffer))) break;
      else if(ende==1) continue;
      xb++; xc++;
      if(xa==zg2-1 && xc>zei) { ende=2; break; }
      if(xc>SEITE)  { xc=0; xa++; if(xa>zg2-1) {ende=2; break; } }
      if(xb>SEITE) { linefd(xb,xa); xb=0; }
   }
fin:  if(ende==2) linefd(xb,xa);
   if(ende) CloseDevice(DruckerReq);
   znum = (znum) ? 4:5;
   sprintf(buffer, "Finished printing!");
   Meldung();
}
linefd(xb,xa)    /* Papier zum Anfang der nächsten Seite schieben */
int xb,xa;       /* und Seitenmarkierung anbringen                */
{
   int i,r;

   sprintf(hel, "\n");
   if(zg5>xb) {
      while(ausdruck(hel)) {
         xb++;
         if(!snum && xb==zg5-9) {
            sprintf(buffer,"- %d -\n", xa+1);
            for(r=0, i=(zg4-zg3-strlen(buffer))/2; r<i; r++) hel[r] = 32;
            hel[r] = EOS; strcat(hel, buffer);
            if(!ausdruck(hel)) break;
            sprintf(hel, "\n"); xb++;
         }
         if(xb==zg5) break;
      }
   }
}
SetzeStil(neu,alt)
int neu,alt;
{
   int i=0;

   if(neu&4 && !(alt&4))      { strcat(buffer,itaein); i+=4; }
   else if(!(neu&4) && alt&4) { strcat(buffer,itaaus); i+=5; }
   if(neu&2 && !(alt&2))      { strcat(buffer,fetein); i+=5; }
   else if(!(neu&2) && alt&2) { strcat(buffer,fetaus); i+=5; }
   if(neu&1 && !(alt&1))      { strcat(buffer,untein); i+=4; }
   else if(!(neu&1) && alt&1) { strcat(buffer,untaus); i+=5; }
   return(i);
}
ausdruck(ausdr)   /* Senden einer Textzeile zum Drucken und Fehlerabfrage */
UBYTE *ausdr;
{
   char c;

   DruckerReq->drucker_std.io_Command = CMD_WRITE;
   DruckerReq->drucker_std.io_Data    = (APTR) ausdr;
   DruckerReq->drucker_std.io_Length  = strlen(ausdr);
   DruckerReq->drucker_pcr.io_Command = CMD_WRITE;
   if(DoIO(DruckerReq)) {
      sprintf(buffer, "ERROR! (A)bort or (T)ry again?");
      Meldung();
wi1:  if((c=ConsoleGetKey()) == 'a' || c=='A') {
         DeleteExtIO(DruckerReq, sizeof(union Drucker));
         DeletePort(DP);
         return(0);
      }
      else if(c=='t' || c=='T')   return(1);
      goto wi1;
   }
   return(2);
}

checkit()  /* Betätigung eines Gadgets überprüfen */
{
   int ende = 0, gnr;

   while(ende==0){
      nclass = message();
      switch(nclass){
         case GADGETDOWN:
            break;
         case GADGETUP:
            switch(gaddy->GadgetID) {
               case ZAHLGADI:    /* je nach Gadget, die Richtigkeit der */
                  pruefzg1();    /* Eingabe überprüfen */
                  break;
               case ZAHLGADII:
                  pruefzg2();
                  break;
               case ZAHLGADIII:
                  pruefzg3();
                  break;
               case ZAHLGADIV:
                  pruefzg4();
                  break;
               case ZAHLGADV:
                  pruefzg5();
                  break;
               case OK:
                  pruefalles(); ende++;
                  break;
               case STOP:
                  ende=2;
                  break;
            }
            break;
         case MOUSEBUTTONS:
            gnr=Mausabfrage();
            if(gnr>=0 && gnr<=3) {  /* Schriftart ausgewählt */
               if(schrift!=gnr) {
                  Hell2(schrift); schrift=gnr; Hell2(schrift);
               }
            }
            else if(gnr>=4 && gnr<=5) {  /* Zeilennummerierung An/Aus */
               if(znum!=gnr) {
                  Hell2(znum); Hell2(znum=gnr);
               }
            }
            else if(gnr>=6 && gnr<=7) { /* Seitennummerierung An/Aus */
               if(snum+6!=gnr) {
                  Hell2(snum+6); Hell2(gnr); snum=gnr-6;
               }
            }
            break;
         default:
            break;
      }
   }
   return(ende);
}
pruefalles()
{
   if (blo==0) {
      pruefzg1();
      pruefzg2();
   }
   pruefzg3();
   pruefzg4();
   pruefzg5();
}

Mausabfrage()  /* Überprüfung, ob bei Betätigung der linken Maustaste ein */
{          /* Gadget angewählt wurde */
   int i,xk,yk;

   xk=fenster2->MouseX;
   yk=fenster2->MouseY;
   if(xk>10 && xk<94){
      for(i=0;i<4;i++){       /* Schriftart */
         if(yk>i*20+20 && yk<(i+1)*20+18) return(i);
      }
   }
   if(yk>128 && yk<138){
      for(i=0;i<2;i++) {   /* Zeilennummerierung an/aus */
         if(xk>57*i+106 && xk<57*i+160) return(i+6);
         if(xk>57*i+220 && xk<57*i+274) return(i+4);
      }
   }
   return(8);
}
pruefzg1() /* Richtigkeit der Eingaben in die IntegerGadgets überprüfen */
{      /* von Seite */
   int zg1alt = zg1;
   zg1 = atoin(zgad1);
   if(zg1<1 || zg1>zg2) {
      zg1 = zg1alt;
      strcpy(zgad1,itoa(zg1));
      RefreshGadgets(&IntGad1,fenster2,NULL);
   }
}
pruefzg2()            /* bis Seite */
{
   int zg2alt = zg2;
   zg2 = atoin(zgad2);
   if(zg2<zg1 || zg2>spa+1) {
      zg2 = zg2alt;
      strcpy(zgad2,itoa(zg2));
      RefreshGadgets(&IntGad1,fenster2,NULL);
   }
}
pruefzg3()           /* linker Rand */
{
   int zg3alt = zg3;
   zg3 = atoin(zgad3);
   if(zg3<0 || zg3>zg4) {
      zg3 = zg3alt;
      strcpy(zgad3,itoa(zg3));
      if(blo>0) RefreshGadgets(&IntGad3,fenster2,NULL);
      else   RefreshGadgets(&IntGad1,fenster2,NULL);
   }
}
pruefzg4()           /* rechter Rand */
{
   int zg4alt = zg4;
   zg4 = atoin(zgad4);
   if(zg4<zg3 || zg4>137) {
      zg4 = zg4alt;
      strcpy(zgad4,itoa(zg4));
      if(blo>0) RefreshGadgets(&IntGad3,fenster2,NULL);
      else   RefreshGadgets(&IntGad1,fenster2,NULL);
   }
}
pruefzg5()         /* Papierlänge */
{
   int zg5alt = zg5;
   zg5 = atoin(zgad5);
   if(zg5<1 || zg5>72) {
      zg5 = zg5alt;
      strcpy(zgad5,itoa(zg5));
      if(blo>0) RefreshGadgets(&IntGad3,fenster2,NULL);
      else   RefreshGadgets(&IntGad1,fenster2,NULL);
   }
}
itoa(n)          /* Integer in ASCII-String umwandeln */
int n;
{
   UBYTE nach[5];
   int i=0, k, l, signum=FALSE;

   if(n<0) { signum=TRUE; n=-n; }
   do nach[i++] = n % 10 + '0'; while(n /= 10);
   if(signum) nach[i++] = '-';
   nach[i] = EOS;
   for(i=0, k=strlen(nach)-1; i<k; i++, k--) {
      l = nach[i]; nach[i] = nach[k]; nach[k] = l;
   }
   return((int)nach);
}
atoin(von)    /* ASCII-String in Integer umwandeln */
UBYTE *von;
{
   int n, signum=1;

   while(*von == ' ') von++;
   if(*von == '+' || *von == '-')
      signum = (*von++ == '+') ? 1 : -1;
   for(n=0; *von >= '0' && *von <= '9'; ++von)
      n = 10 * n + *von - '0';
   return(signum * n);
}
einstell(anzeige, flaggy, seit, zeil)  /* Seitenlänge o. Textbreite */
UBYTE *anzeige;              /* einstellen */
int flaggy, seit, zeil;
{
   int xa,xb,ende=0,erinnern=zg5;

   if(flaggy) zg5=MAX; else zg5=SEITE+1;
   strcpy(zgad5,itoa(zg5));

   FensterVereinbarung.LeftEdge = 242; FensterVereinbarung.TopEdge = 74;
   FensterVereinbarung.Width = 156; FensterVereinbarung.Height = 52;
   IntGad5.LeftEdge = 65; IntGad5.TopEdge = 28;
   FensterVereinbarung.FirstGadget = &IntGad5;
   FensterVereinbarung.Screen = Scheibe;
   if(!(fenster2 = (struct Window *)OpenWindow(&FensterVereinbarung))) {
      tschuess();
      return(0);
   }
   RP1 = fenster2->RPort;
   block(2,10,5,156,52);
   block(1,0,0,146,47);
   xb = strlen(anzeige)*8;
   xa = 73 - xb /2;
   block(2,xa-19,3,xa+xb+19,15);
   block(0,xa-17,4,xa+xb+17,14);
   print(anzeige,1,xa,12);
   block(2,45,25,101,37);
   block(0,47,26,99,36);
   RefreshGadgets(&IntGad5,fenster2,NULL);
   ActivateGadget(&IntGad5,fenster2,NULL );
   while(!ende){
      if(message() == GADGETUP && gaddy->GadgetID == ZAHLGADV) ende++;
   }
   CloseWindow(fenster2);
   zg5 = atoin(zgad5);
   if(flaggy==0 && zg5>=10 && zg5<=72) Seitenlaenge(zg5);
   else if(flaggy==1 && zg5>=10 && zg5<=ABSMAX) Textbreite(zg5);
   tschuess();
   zg5 = erinnern;
}
Gehezu(faehnrich)
int faehnrich;
{
   int xa,xb,ende=0, laen1;

   if(faehnrich==3)      sprintf(hel, "Replace");
   else if(faehnrich==2) sprintf(hel, "Find");
   else if(faehnrich==1) {
      sprintf(hel, "Go to line x");
      FensterVereinbarung.FirstGadget = &IntGad6;
   }
   else {
      sprintf(hel, "Go to ...");
      FensterVereinbarung.FirstGadget = &Gad2;
   }
   if(faehnrich>=2) {
      FensterVereinbarung.Width = 354; FensterVereinbarung.Height = 96;
      FensterVereinbarung.FirstGadget = &grossgad;
      FensterVereinbarung.LeftEdge = 143; FensterVereinbarung.TopEdge = 52;
   }
   else {
      FensterVereinbarung.Width = 270; FensterVereinbarung.Height = 52;
      FensterVereinbarung.LeftEdge = 185; FensterVereinbarung.TopEdge = 74;
   }
   FensterVereinbarung.Screen = Scheibe;
   if(!(fenster2 = (struct Window *)OpenWindow(&FensterVereinbarung))) {
      tschuess();
      return(0);
   }
   RP1 = fenster2->RPort;
   xb = strlen(hel)*8;
   if(faehnrich>=2) {
      block(2,10,5,354,96); block(1,0,0,344,91);
      xa = 172 - xb /2;
   }
   else {
      block(2,10,5,270,52); block(1,0,0,260,47);
      xa = 130 - xb /2;
   }
   block(2,xa-19,3,xa+xb+19,15); block(0,xa-17,4,xa+xb+17,14);
   print(hel,1,xa,12);
   if(faehnrich>=2) {
      block(2,92,25,336,37); block(0,94,26,334,36);
      block(2,92,47,336,59); block(0,94,48,334,58);
      block(2,306,71,333,80); /* block(0,306,70,334,80); */
      print("Find:",2,10,34);
      print("Replace:",2,10,56);
      print("Case-sensitive:",2,10,79);

      RefreshGadgets(&grossgad,fenster2,NULL);
      ActivateGadget(&Gad3,fenster2,NULL);
      while(!ende) {
         if(message() == GADGETUP) {
            if(gaddy->GadgetID == GROSSKLEIN) {
               if(++grokle==1) {
                  strcpy(grosstext.IText,"ON");
                  grosstext.LeftEdge=4;
                  block(1,308,72,331,79);
               }
               else {
                  grokle=0; strcpy(grosstext.IText,"OFF");
                  grosstext.LeftEdge=0;
               }
               RefreshGadgets(&grossgad,fenster2,NULL);
               ActivateGadget(&Gad3,fenster2,NULL);
            }
            else if(gaddy->GadgetID == SUCHEN) {
               if(faehnrich==2) ende++;
               else {
                  RefreshGadgets(&grossgad,fenster2,NULL);
                  ActivateGadget(&Gad4,fenster2,NULL);
               }
            }
            else if(gaddy->GadgetID == ERSETZEN) ende++;
         }
      }
   }
   else if(faehnrich) { block(2,106,25,154,37); block(0,108,26,152,36);
      RefreshGadgets(&IntGad6,fenster2,NULL);
      ActivateGadget(&IntGad6,fenster2,NULL);
      while(!ende){
         if(message() == GADGETUP && gaddy->GadgetID == ZAHLGADVI) ende++;
      }
   }
   else { block(2,8,25,252,37);   block(0,10,26,250,36);
      RefreshGadgets(&Gad2,fenster2,NULL);
      ActivateGadget(&Gad2,fenster2,NULL);
      while(!ende){
        if(message() == GADGETUP && gaddy->GadgetID == DRAWGAD) ende++;
      }
   }
   CloseWindow(fenster2); tschuess();
   if(faehnrich>=2) Suchen(faehnrich-2);
   else if(faehnrich) {
      laen1=atoin(zgad6); ende = se*(SEITE+1)+ze+1;
      if(laen1<1 || laen1>ende) {
         sprintf(buffer, "Line %s doesn't exist!",zgad6);
        if(meld != TRUE) { Meldung(); meld=FALSE; }
      }
      else {
         if(laen1>72) {
            xa = laen1 / (SEITE +1); xb = laen1 % (SEITE +1)-1; }
         else {
            xa =0; xb=laen1-1; }
         y=MIY; s=xa; z=xb; x=MIX; off=0; meld=FALSE; SText();
         ZSDisplay(); meld=FALSE;
      }
   }
   else {
      ende=0;
      if(laen1=strlen(backup)) {
         for(xa=0;xa<=se;xa++) {
            for(xb=0;xb<=SEITE;xb++) {
               if(xb>ze && xa==se) break;
               if(laen1<=SL(xa,xb))
                  ende = StrVer(backup, a[xa] [xb]);
                if(ende) break;
            }
            if(ende) break;
         }
      }
      if(!ende) {
         sprintf(buffer, "%s not found!", backup);
         if(meld != TRUE) { Meldung(); meld=FALSE; }
      }
      else {
         y=MIY; s=xa; z=xb; x=MIX; off=0; meld=FALSE; SText();
         ZSDisplay(); meld=FALSE;
      }
   }
}
tschuess()
{
   FensterVereinbarung.FirstGadget = &Gad2;
   FensterVereinbarung.Width = 350; FensterVereinbarung.Height = 168;
   FensterVereinbarung.LeftEdge =155; FensterVereinbarung.TopEdge = 16;
   IntGad5.LeftEdge = 42; IntGad5.TopEdge = 130;
}
StrVer(s,t)
UBYTE *s, *t;
{
   int gleich = 0, laenge;

   laenge = strlen(s);
   FOREVER {
      if(*t<9 || *s++ == *t++) gleich++;
      else { gleich = 0; break; }
      if(gleich==laenge) break;
   }
   return(gleich);
}
StrVerII(s,t,ls,lt,pos)
UBYTE *s, *t;
int ls,lt,pos;
{
   int gleich=FALSE, xneu=1;
   UBYTE *alts;

   alts=s;
   if(pos) {
      if((lt-=pos)>=ls) {
         while(gleich<pos) { if(*t<9) t++; t++; gleich++; }
      }
      xneu=pos+1; gleich=FALSE;
   }
   FOREVER {
      if(ls>lt) break;
      if(*t<9) t++;
      if(*s == *t) gleich++;
      else if(!grokle && *s>=65 && *s<=90 && *t>=97 && *t<=122 && *s==*t-32)
         gleich++;
      else if(!grokle && *s>=97 && *s<=122 && *t>=65 && *t<=90 && *s-32==*t)
         gleich++;
      else {
         if(gleich) { xneu+=gleich; lt-=gleich; s=alts; gleich=FALSE; }
         else       { xneu++; lt--; t++; }
         continue;
      }
      if(gleich==ls) { x=xneu; break; }
      s++; t++;
   }
   return(gleich);
}
Suchen(auswahl)
int auswahl;
{
   int ende=0, len, l2, xa=s, xb=z, st;
   char c;

   if(len=strlen(suchen)) {
      if(xa==s && xb==z && (l2=SL(xa,xb))) {
         ende = StrVerII(suchen, a[xa] [xb], len, l2-SC(xa,xb,l2), x);
      }
      if(!(ende || (xa==se && xb==ze))) {
         FOREVER {
            if(auswahl<=1) {
               if(ende || (xa==se && xb==ze)) break;
               if(++xb>SEITE) { xb=0; xa++; }
            }
            else {
               if(ende || (!xa && !xb)) break;
               if(--xb<0) { xb=SEITE; xa--; }
            }
            if(l2=SL(xa,xb))
               ende = StrVerII(suchen, a[xa] [xb], len, l2-SC(xa,xb,l2),0);
         }
      }
   }
   if(!ende) {
      sprintf(buffer, "%s not found!", suchen);
      if(meld != TRUE) { Meldung(); meld=FALSE; }
   }
   else {
      s=xa; z=xb; meld=FALSE;
      y=MIY; SText();
      ZSDisplay(); meld=FALSE;
      if(auswahl==1 || auswahl==3) {                 /* ERSETZEN */
         SetAPen(RP, 3); SetDrMd(RP, INVERSVID|COMPLEMENT);
         Move(RP, (x-1)*8, y*8-2);
         for(ende=0; ende<len; ende++) buffer[ende] = ' '; buffer[ende] = EOS;
         Text(RP, buffer, len);
         SetAPen(RP, 1); SetDrMd(RP, JAM2);
         sprintf(buffer, "Replace == RETURN! Abort == SPACE!");
         Meldung();
         do {
            if((c=ConsoleGetKey())==13) {
               if(strlen(ersetzen)) {
                  xa=Testen(stil); x+=(len-1); xb=Testen(stil); x-=(len-1);
                  st=SC(s,z,(l2=SL(s,z)));
                  a[s] [z] [x+xa-1]=EOS;
                  sprintf(buffer, "%s%s", a[s] [z], ersetzen);
                  a[s] [z] += (x+len+xb-1); strcat(buffer, a[s] [z]);
                  a[s] [z] -= (x+len+xb-1); st+=(xa-xb);
                  if((ende=strlen(buffer))!=l2) BelAend(s,z,st,ende,l2);
                  strcpy(a[s] [z], buffer);
                  if(ende-st>MAX) {
                     l2=x;
                     while(ende-st>MAX) {
                        ende--;
                        for(;ende>=0;ende--) {
                           if(a[s] [z] [ende] <9) st--;
                           if(a[s] [z] [ende] == 32) {
                              x = ende+2-st; break;
                           }
                        }
                     }
                     if(x>ABSMAX||ende<0) x=MAX;   /* voll ohne space */
                     xa=s; xb=z; meld=500; CarRet(); meld=FALSE; s=xa; z=xb; x=l2;
                  }
                  y=MIY; SText();
                  ZSDisplay(); meld=FALSE;
               }
            }
            else if(c==32) { ZSDisplay();
               SetAPen(RP, 3); SetDrMd(RP, INVERSVID|COMPLEMENT);
               Move(RP, (x-1)*8, y*8-2);
               for(ende=0; ende<len; ende++) buffer[ende] = ' '; buffer[ende] = EOS;
               Text(RP, buffer, len);
               SetAPen(RP, 1); SetDrMd(RP, JAM2);
            }
         }  while(c!=13 && c!=32);
      }
   }
}
ConsoleGetKey()
{
   int len=0;
   UBYTE KeyBuffer[10];

   Wait(1 << Fenster -> UserPort -> mp_SigBit);
   while((nachricht2=(struct IntuiMessage *) GetMsg(Fenster->UserPort))!=0L) {
      if (!(nachricht2->Class != RAWKEY || (nachricht2->Code & IECODE_UP_PREFIX))) {
         len = DeadKeyConvert(nachricht2, KeyBuffer, sizeof(KeyBuffer), NULL);
         if(len==1) len=KeyBuffer[0];
         else len=1;
      }
      else if(nachricht2->Class == MOUSEBUTTONS) len=-1;
      ReplyMsg(nachricht2);
   }
   return(len);
}
