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

int laufs=-1, laufz=-1;

FastLoad(FName)
UBYTE *FName;
{
   int fehler=FALSE, txan=meld;

   meld=FALSE;
   sprintf(buffer,"Loading %s!", FName);
   Meldung();
   if((fehler=Laden(FName)) == TRUE) {
      if(txan!=5) { NamenSetzen(FName); strcpy(titel,FName); }
      SText(); meld=FALSE;
   }
   return(fehler);
}
Speichern(fn, as, az, es, ez)
UBYTE *fn;
int as, az, es, ez;
{
   FILE *file;
   struct FileHandle *handle;
   int ln, i, st, e1, e2, txp=FALSE;

   if((ln=strlen(fn))>=4) {     /* File schon mit `.txp` - Endung */
      if((fn[ln-1]==80||fn[ln-1]==112)&&(fn[ln-2]==120||fn[ln-2]==88)&&
         (fn[ln-3]==84||fn[ln-3]==116)&&fn[ln-4]==46) txp=TRUE;
   }
   if(!txp && !br) strcat(fn, ".txp");
   if(bak) {   /* Backup-Mode ist an */
      if(handle=Open(fn, MODE_OLDFILE)) { /* File existiert */
         Close(handle); strcpy(buffer,fn); strcat(buffer, ".bak");
         DeleteFile(buffer); /* Altes Backup löschen */
         if(!Rename(fn,buffer)) {
            sprintf(buffer, "Can't open %s!", fn);
         }
      }
   }
   if(!(file=fopen((char *)fn,"w"))) {
      sprintf(buffer,"Can't open  %s!",fn);
      Meldung();
      return(FALSE);
   }
   else {
      sprintf(buffer, "Saving %s!", fn);
      Meldung(); ln=0;
      FOREVER {
         i=SL(as, az); st=SC(as,az,i);
         if(br && st) {
            for(e1=0,e2=0; e2<i; e2++) {
               if(a[as] [az] [e2] <9) continue;
               buffer[e1++] = a[as] [az] [e2];
            }
            buffer[e1]= EOS;
            fprintf(file, "%s\n", buffer);
            ln+= e1+1;
         }
         else {
            fprintf(file, "%s\n", a[as] [az]);
            ln += i+1;
         }
         az+=1;
         if(az>SEITE) {
            az=0; as+=1;
         }
         if(as>=es) {
            if(az>ez) break;
            if(as>es) break;
         }
      }
      fclose(file);
      if(blo<3) { NamenSetzen(fn); strcpy(titel,fn); }
      sprintf(buffer, "Length: %d Bytes", ln);
      Meldung();
      sicher = TRUE;
   }
   return(TRUE);
}
auto_frage(frage)
char *frage;
{
   request_text.IText = (UBYTE *)frage;
   return(AutoRequest(Fenster,&request_text,&ja_text,&nein_text,0,0,319,60));
}
SpeicherMangel()
{
   char *frage;

   sprintf(frage, "OUT OF MEMORY! The GURU is soon to come! Save file?");
   request_text.IText = (UBYTE *)frage;
   if(AutoRequest(Fenster,&request_text,&ja_text,&nein_text,0,0,640,256))
      Speichern("I_escaped_the_guru", 0,0,se,ze);
   Schluss();
   exit(FALSE);
}
TLoeschen(miteb)
int miteb;
{
   int i;

   FOREVER {
      FreeMem(a[se] [ze], SL(se,ze)+2);
      if(--ze<0) {
         ze=SEITE; if(--se<0) break;
      }
   }
   se=ze=s=z=0; x=MIX; y=MIY; if(miteb) ErstBel(s,z);
   SetAPen(RP,0);
   RectFill(RP,0,32,RRAND,YKOD+2);
   SetAPen(RP,1);
   ZSDisplay();
   sicher = TRUE;
}
TLaden(fname)
UBYTE *fname;
{
   TLoeschen(FALSE);

   if(!FastLoad(fname)) ErstBel(s,z);
   ZSDisplay();
   sprintf(buffer,"%s",str); Meldung();
}
TextAnhaengen(fname)
UBYTE *fname;
{
   int sealt=se, zealt=ze, salt=s, zalt=z, yalt=y;

   if(++ze>SEITE) {
      ze=0;
      if(++se>MAS) {
         ze=SEITE; se=MAS;
         sprintf(buffer, "%s", FehlerText[2]);
         Meldung();
         return(0);
       }
   }
   s = se; z = ze;
   meld=5; y=MIY+1;
   if(FastLoad(fname)==TRUE) {
      sicher = FALSE;
   }
   else {
      ze=zealt; se=sealt; z=zalt; s=salt; y=yalt;
   }
   ZSDisplay();
   sprintf(buffer, "%s",str);
   Meldung();
}
BlockLoeschen(as,az,es,ez)
int as,az,es,ez;
{
   int s1=es, z1=ez;

   FOREVER {                /* Löschen */
      FreeMem(a[es] [ez], SL(es,ez)+2);
      if(es==as && ez==az) break;
      if(--ez<0) { ez=SEITE; es--; }
   }
   if(s1==se && z1==ze) {                /* Blockende    == Textende    */
      if(!es && !ez) ErstBel(0,0);     /* Blockanfang  == Textanfang  */
      else {
         if(--az<0) { az=SEITE; as--; }
      }
   }
   else {                                /* Blockende    != Textende    */
      es=s1; if((ez=z1+1)>SEITE) { ez=0; es++; }
      FOREVER {
         a[as] [az] = a[es] [ez];
         if(es==se && ez==ze) break;
         if(++az>SEITE) { az=0; as++; }
         if(++ez>SEITE) { ez=0; es++; }
      }
   }
   se=as; ze=az; sicher=FALSE;
   if(meld>1) return(0);
   blo=0; MenueUeberwachung(0);
   if(!(bas>s || (s==bas && baz>z))) {
      if(BloPruef()) {
         s=bes;
         if((z=bez+1)>SEITE) { z=0; s++; }
      }
      for(s1=(bes-bas)*(SEITE+1)+bez-baz; s1>=0; s1--) {
         if(--z<0) { z=SEITE; s--; }
      }
      if(s<0) s=0; if(s==se && z>ze) z=ze;
      if(!s && z<=(MAY-MIY)) y=MIY+z;
   }
   SText(); ZSDisplay();
   sprintf(buffer, "Block deleted!");
   meld = TRUE;
}
BlockMarkieren()
{
   int len;

   if(!blo) blo=1;
   if(blo==2) {
      bes=s; bez=z;
      if(bes<bas) {
         len=bas; bas=bes; bes=len;
         len=baz; baz=bez; bez=len;
      }
      if(bes==bas) {
         if(bez<baz) {
            len=bez; bez=baz; baz=len;
         }
      }
      blo++; /* SText(); */
      ZSDisplay();
      sprintf(buffer, "End of block marked!");
      meld = TRUE;
      MenueUeberwachung(2);
   }
   else if(blo==1) {
      bas=s; baz=z; blo++;
      SetAPen(RP, 0); RectFill(RP, 0, y*8-8, RRAND, y*8-1);
      SetAPen(RP, 1); Rolling(); BloRel(0);
      sprintf(buffer, "Begin of block marked!");
      meld=TRUE;
      MenueUeberwachung(1);
   }
   return(0);
}
MarkierungLoeschen()
{
   MenueUeberwachung(0);
   blo=0; SText();
   ZSDisplay();
   sprintf(buffer, "Mark deleted!");
   meld=TRUE;
}
MenueUeberwachung(bl)
int bl;
{
   int len, h=SHIFTMENU(1);

   if(bl==3) {
      if(ein) EinItem[3].Flags |= CHECKED; else EinItem[3].Flags = CFLAG;
      if(!br) EinItem[4].Flags |= CHECKED; else EinItem[4].Flags = CFLAG;
      if(!au) EinItem[5].Flags |= CHECKED; else EinItem[5].Flags = CFLAG;
      if(bak) EinItem[6].Flags |= CHECKED; else EinItem[6].Flags = CFLAG;
   }
   if(bl==1) {
      /* Dokument: Laden, Anhängen, Löschen, 3*Speichern u. Drucken aus */
      OffMenu(Fenster, SHIFTMENU(0));
      OffMenu(Fenster, SHIFTMENU(0)|SHIFTITEM(6));
      for(len=1; len<=9; len=len+2)
         OffMenu(Fenster, SHIFTMENU(0)|SHIFTITEM(len));
      OffMenu(Fenster, SHIFTMENU(2));               /* Seitenlänge    aus */
      for(len=4;len<=6;len++)                       /* Ersetzen 3*    aus */
         OffMenu(Fenster, SHIFTMENU(4)|SHIFTITEM(len));
      OffMenu(Fenster, h|SHIFTITEM(7));             /* Block Laden    aus */
      OnMenu(Fenster,  h|SHIFTITEM(5));             /* Mark. Löschen   an */
   }
   if(bl==2) {
      OnMenu(Fenster, h|SHIFTITEM(2));              /* Block Kopieren  an */
      OnMenu(Fenster, h|SHIFTITEM(3));              /* Block Löschen   an */
      OnMenu(Fenster, h|SHIFTITEM(8));              /* Block Speichern an */
      OnMenu(Fenster, h|SHIFTITEM(10));             /* Block Drucken   an */
      OffMenu(Fenster, h);                          /* Block Markier. aus */
   }
   if(bl==0) {
      /* Dokument: Laden, Anhängen, Löschen, 3*Speichern u. Drucken an */
      OnMenu(Fenster, SHIFTMENU(0));
      OnMenu(Fenster, SHIFTMENU(0)|SHIFTITEM(6));
      for(len=1; len<=9; len=len+2)
         OnMenu(Fenster, SHIFTMENU(0)|SHIFTITEM(len));
      OnMenu(Fenster,  SHIFTMENU(2));               /* Seitenlänge     an */
      for(len=4;len<=6;len++)                       /* Ersetzen 3*     an */
         OnMenu(Fenster, SHIFTMENU(4)|SHIFTITEM(len));
      OnMenu(Fenster,  h|SHIFTITEM(7));             /* Block Laden     an */
      OnMenu(Fenster,  h);                          /* Block Markier.  an */
      OffMenu(Fenster, h|SHIFTITEM(5));             /* Mark. Löschen  aus */
      OffMenu(Fenster, h|SHIFTITEM(2));             /* Block Kopieren aus */
      OffMenu(Fenster, h|SHIFTITEM(3));             /* Block Löschen  aus */
      OffMenu(Fenster, h|SHIFTITEM(8));             /* Block Speich.  aus */
      OffMenu(Fenster, h|SHIFTITEM(10));            /* Block Drucken  aus */
   }
}
BLaden(fname)
UBYTE *fname;
{
   int es=se, ez=ze, ss=s, zz=z, sh, zh, blockende=FALSE;
   UBYTE buf[512];

   if(++ze>SEITE) {
      ze=0;
      if(++se>MAS) {
         ze=SEITE; se=MAS;
         sprintf(buffer, "%s", FehlerText[2]);
         Meldung();
         return(0);
      }
   }
   blo=3;
   if(!Laden(fname)) {
      se=es; ze=ez; blo=0;
   }
   else {
      if(!(s==es && z==ez)) { /* kein bloßes Anhängen */
         if(++ez>SEITE) { ez=0; es++; }
         bas=es; baz=ez;
         FOREVER {  /* Text scheibchenweise einfügen. 1 Scheibe <= 1 SEITE */
            bes=se; bez=ze;
            if(((bes-bas)*(SEITE+1)+bez-baz)>SEITE) {
               bes=bas+1; if((bez=baz-1)<0) { bez=SEITE; bes--; }
               sh=bes; if((zh=bez+1)>SEITE) { zh=0; sh++; }
            }
            else {
               blockende=TRUE; zh=(se-bas)*(SEITE+1)+ze-baz;
            }
            meld=2; BlockEinfuegen(bas,baz,bes,bez); BlockLoeschen(bas,baz,bes,bez);
            if(blockende) break;
            bas=sh; baz=zh;
            s++; if(--z<0) { z=SEITE; s--; }
         }
         for(sh=0, bes=s, bez=z; sh<=zh; sh++) {
            if(++bez>SEITE) { bez=0; bes++; }
         }
      }
      else { bes=se; bez=ze; }
      meld=sicher=FALSE; blo=3; MenueUeberwachung(1); MenueUeberwachung(2);
      bas=s=ss; baz=z=zz; if(++baz>SEITE) { baz=0; bas--; }
      SText();
      ZSDisplay();
      if(str[0] == 'B') sprintf(buffer, "%s Seite %d Zeile %d!",
                                str, bes+1, bez+1);
      else strcpy(buffer, str);
      Meldung();
   }
}
Textlaenge()
{
   int len,i, zaehler=0;

   for(len=0;len<=se;len++) {
      for(i=0;i<=SEITE;i++) {
         zaehler += SL(len,i) +1;
         if(len==se && i==ze) break;
      }
   }
   sprintf(buffer, "Length: %d End: page %d line %d!",
       zaehler, se+1, ze+1);
   meld=TRUE;
}
BlockEinfuegen(as,az,es,ez)
int as,az,es,ez;
{
   int bs=se, bz=ze, ps, pz, i, st;

   if((BloPruef()==TRUE)&&(!(bes==s && bez==z))&&meld!=2) {
      sprintf(buffer, "Cursor inside block!");
      meld=TRUE;
      return(0);
   }
   ze++; if(ze>SEITE) { ze=0; se++; }
   i= (MAS-se )*(SEITE+1)+SEITE-ze;     /* Anzahl der freien Zeilen */
   st=(es-as)*(SEITE+1)+ez-az;     /* Blocklänge     in Zeilen */
   se=bs; ze=bz;
   if(i<=0 || i<st) {
      sprintf(buffer, "Out of memory!");
      meld=TRUE;
      return(0);
   }
   for(ps=0; ps<=st; ps++) { if(++ze>SEITE) { ze=0; se++; } }
   ps=se; pz=ze;
   if(!(bs==s && bz==z)) {
      FOREVER {                                /* Text verschieben */
         a[ps] [pz] = a[bs] [bz];
         if(--bz<0) {bz=SEITE; bs--; }
         if(--pz<0) {pz=SEITE; ps--; }
         if(bs==s && bz==z) break;
      }
   }
   if(s<bas || (s==bas && z<baz)) {
      for(ps=0; ps<=st; ps++) {     /* Block mitverschoben ? */
         if(++baz>SEITE) { baz=0; bas++; }
         if(++bez>SEITE) { bez=0; bes++; }
      }
   }
   else if(meld==2 && (s<bes || (s==bes && z<=bez))) {
      for(ps=0; ps<=st; ps++) {     /* im Block mitverschoben ? */
         if(++bez>SEITE) { bez=0; bes++; }
      }
   }
   if(s<as || (s==as && z<az)) {
      for(ps=0; ps<=st; ps++) {     /* Block mitverschoben ? */
         if(++az>SEITE) { az=0; as++; }
         if(++ez>SEITE) { ez=0; es++; }
      }
   }
   ps=as; pz=az; bs=s; bz=z; if(++bz>SEITE) { bz=0; bs++; }
   FOREVER {
      st=SC(ps, pz, (i=SL(ps,pz)));
      ErstBelAend(bs, bz, st, i, ps, pz);
      if(ps==es && pz==ez) break;
      if(++pz>SEITE) { pz=0; ps++; }
      if(++bz>SEITE) { bz=0; bs++; }
   }
   sicher=FALSE;
   if(meld==2) return(1);
   SText(); ZSDisplay();
   sprintf(buffer, "Block copied!");
   meld=TRUE;
}
Schriftart(art)
int art;
{
   int i,r;

   if(!art||laufs!=s||(laufs==s && laufz!=z)) { laufs=s; laufz=z; stil=art; }
   else {
      if(art&4 && !(stil&4))   stil+=4;
      else if(art&4 && stil&4) stil-=4;
      if(art&2 && !(stil&2))   stil+=2;
      else if(art&2 && stil&2) stil-=2;
      if(art&1 && !(stil&1))   stil+=1;
      else if(art&1 && stil&1) stil-=1;
   }
   SetSoftStyle(RP, stil, AskSoftStyle(RP));
   if(blo>2) BlockSchrift();
   else {
      i=SL(s,z); r=SC(s,z,i);
      if(i-r>=x) {
         SpeicherSchrift();
         SetAPen(RP, 0);
         RectFill(RP, 0, y*8-8, RRAND, y*8-1);
         SetAPen(RP, 1);
         SonderDruck(y, SL(s,z), 0);
      }
   }
}
BlockSchrift()
{
   int i, r, len, st, su, ss=bas, zz=baz;

   FOREVER {
      r=0; su=st=SC(ss, zz, (i=SL(ss, zz)));
      while(st) {
         if(a[ss] [zz] [r] < 9) {
            for(len=r; len<i-su+st;len++) a[ss] [zz] [len]=a[ss] [zz] [len+1];
            st--;
         }
         else r++;
      }
      if(su) BelAend(ss, zz, 0, i-su, i);
      if(stil) {
         BelAend(ss, zz, 1, i-su+1, i-su);
         for(len=i-su; len>=0; len--)
            a[ss] [zz] [len+1] = a[ss] [zz] [len];
         a[ss] [zz] [0] = stil;
      }
      if(++zz>SEITE) { zz=0; ss++; }
      if(ss>bes || (ss==bes && zz>bez)) break;
   }
   sicher=FALSE;
   SText();
   ZSDisplay();
}
SpeicherSchrift()
{
   int st,i,r,o,q=0;

   oflag=FALSE;
   st=SC(s, z, (i=SL(s,z)));
   if(i) r=Testen(stil);
   else  r=0;
   if(r) {
      if(a[s] [z] [x+r-2] <9) {
         if(oflag) {
            for(o=x-1+r; o<=i-1; o++)
               a[s] [z] [o-1] = a[s] [z] [o];
            a[s] [z] [i-1] = EOS; st--;
            BelAend(s,z,st,i-1,i);
         }
         else {
            o=stil; if(!stil) o=8; a[s] [z] [x+r-2] = o;
         }
      }
      else {
         if(oflag) stil = 0;
         SpeicherStil(i, ++st, r);
      }
   }
   else {
      if(stil) SpeicherStil(i, ++st, r);
   }
}
SpeicherStil(i, st, r)
int i, st, r;
{
   int o;

   BelAend(s,z,st,i+1,i);
   if(i) {
      for(o=i; o>x-1+r; o--)
         a[s] [z] [o] = a[s] [z] [o-1];
   }
   a[s] [z] [i+1] = EOS; o=stil; if(!stil) o=8;
   a[s] [z] [x-1+r] = o;
}
Testen(vergleich)
int vergleich;
{
   int i=0, r=0;

   oflag=FALSE; letztes = 0; if(!vergleich) vergleich=8;
   while(i <= x-1+r) {
      if(a[s] [z] [i] <9) {
         r++;
         if((letztes=a[s] [z] [i]) == vergleich) oflag = TRUE;
         else oflag = FALSE;
      }
      i++;
   }
   return(r);
}
StilAn()
{
   SetSoftStyle(RP, stil, AskSoftStyle(RP));
}
StilAus()
{
   SetSoftStyle(RP,  0, AskSoftStyle(RP));
}
