(*    Bibliotheks-Modul MASKE.BIB                                           *)
(*       Erlaubt die bildschirmorientierte Eingabe von Record.              *)
(*       Setzt die Eingabeprozedure LiesZeichen voraus.                     *)
(*    Ein Maskeneintrag sieht folgenderma~en aus                            *)
(*       record x,y : byte; m : string(.80.); l : byte end                  *)
(*       Dabei ist x/y die Cursorposition, an der die Meldung m ausgegeben  *)
(*       wird, l ist die maximale Eintragsl{nge.                            *)
(*    Eine Maske ist ein beliebig dimensioniertes Feld (max 127) von solchen*)
(*    Maskeneintr{gen, die in Reihenfolge und Gr|~e dem einzulesenden       *)
(*    Record entsprechen m}ssen. N{heres siehe Turbo-Special 1              *)
(*                                                                          *)
(*    (p CopyRecTemp)                                                       *)
(*    (p CopyTempRec)                                                       *)
(*    p SchreibRecord(Record,Maske,FeldAnzahl)                              *)
(*    p LiesRecord(Record,Maske,FeldAnzahl)                                 *)
(****************************************************************************)

   PROCEDURE CopyRecTemp(x:byte; VAR UsE; VAR Zeile; VAR UsM);
     VAR Eintr : ARRAY[0..maxint] OF char ABSOLUTE UsE;
         Maske : ARRAY[1..127] OF RECORD x,y:byte; m:STRING[80]; l:byte END
                   ABSOLUTE UsM;
         z     : STRING[127] ABSOLUTE Zeile;
         i,s   : integer;
     BEGIN
       s:=0; FOR i:=1 TO x-1 DO s:=s+Maske[i].l+1; z:='';
       FOR i:=0 TO ord(Eintr[s]) DO z[i]:=Eintr[s+i]
     END;

   PROCEDURE CopyTempRec(x:byte; VAR UsE; VAR Zeile; VAR UsM);
     VAR Eintr : ARRAY[0..maxint] OF char ABSOLUTE UsE;
         Maske : ARRAY[1..127] OF RECORD x,y:byte; m:STRING[80]; l:byte END
                   ABSOLUTE UsM;
         z     : STRING[127] ABSOLUTE Zeile;
         i,s   : integer;
     BEGIN
       s:=0; FOR i:=1 TO x-1 DO s:=s+Maske[i].l+1;
       FOR i:=0 TO ord(z[0]) DO Eintr[s+i]:=z[i]
    END;

(****************************************************************************)
(*              Schreibt einen beliebigen Record mit Maske                  *)
(****************************************************************************)
PROCEDURE SchreibRecord(VAR UsRec, UsMask; RecEintrZahl : byte);
    VAR  temp     : STRING[127];
         i        : byte;
         Maske    : ARRAY [1..127] OF RECORD x,y:byte; m: STRING[80];
                                             l:byte END
                    ABSOLUTE UsMask;
   BEGIN (* SchreibRecord *)
     FOR i:= 1 TO RecEintrZahl DO
       WITH Maske[i] DO
         BEGIN
           gotoxy(x,y); lowvideo; write(M); normvideo;
           CopyRecTemp(i,Usrec,temp,UsMask);
           WHILE length(temp)<l DO temp:=temp+'_';
           write(temp)
           END
   END;
(****************************************************************************)
(*               LiesRecord mit Maske                                       *)
(****************************************************************************)
PROCEDURE LiesRecord(VAR UsRec, UsMask; RecEintrZahl : byte);

     TYPE Richtung = (keine,fertig,rauf,runter,finis);

     VAR  selektor : byte;
          weiter   : Richtung;
          temp     : STRING[127];
          Maske    : ARRAY [1..127] OF RECORD x,y:byte; m:STRING[80];
                                              l:byte END
                     ABSOLUTE UsMask;

 PROCEDURE Eingabe(Spalte, Zeile : integer; VAR Antw;
                   MaxLaenge : integer; VAR weiter : Richtung);
   VAR   CPos, i   : integer;
         c         : char;
         Antwort   : STRING[127] ABSOLUTE Antw;

   PROCEDURE beep;
     BEGIN write(^G,^G) END;

   PROCEDURE SetCursor;
     BEGIN
       gotoxy(1+(Spalte+CPos-2) MOD 80,Zeile+((Spalte+CPos-2) DIV 80))
     END;

   BEGIN
     gotoxy(Spalte,Zeile); CPos:=length(Antwort)+1;
     REPEAT
       SetCursor; LiesZeichen(c);
       CASE c OF
         ^[  : weiter := finis;
         ^M  : weiter := fertig;
         ^E  : weiter := rauf;
         ^X  : weiter := runter;
         ^A  : CPos:=1;
         ^F  : CPos:=length(Antwort)+1;
         ^H  : IF CPos >1
                 THEN BEGIN
                        CPos:=pred(CPos); SetCursor;
                        delete(Antwort,CPos,1);
                        write(copy(Antwort,CPos,length(Antwort)-CPos+1),'_');
                      END
                 ELSE beep;
         ^G  : IF CPos>0
                 THEN BEGIN
                        delete(Antwort,CPos,1);
                        write(copy(Antwort,CPos,length(Antwort)-CPos+1),'_');
                      END
                 ELSE beep;
         ^S   : IF CPos>1 THEN CPos:=pred(CPos) ELSE beep;
         ^D   : IF CPos<= length(Antwort) THEN CPos:=succ(CPos) ELSE beep;
         ^Y   : BEGIN
                  gotoxy(Spalte,Zeile); CPos:=0;
                  WHILE CPos<length(Antwort) DO
                    BEGIN write('_'); CPos:=succ(CPos) END;
                  Antwort:=''; CPos:=1
                END;
   #32..#255  : IF length(Antwort)<MaxLaenge
                  THEN BEGIN
                        insert(c,Antwort,CPos);
                        write(copy(Antwort,Cpos,length(Antwort)-CPos+1));
                        CPos:=succ(CPos)
                      END
                  ELSE beep;
      END
    UNTIL weiter<>keine
  END;

 BEGIN (* LiesRecord *)
   selektor:=1;
   SchreibRecord(UsRec,UsMask,RecEintrZahl);
     REPEAT
       weiter:=keine;
       CopyRecTemp(selektor,UsRec,temp,Usmask);
       WITH Maske[selektor] DO Eingabe(x+length(M),y,temp,l,weiter);
       CopyTempRec(selektor,UsRec,temp,UsMask);
       IF weiter=rauf THEN IF selektor>1 THEN selektor:=pred(selektor)
                                         ELSE selektor:=RecEintrZahl;
       IF weiter=runter THEN IF selektor<RecEintrZahl
                               THEN BEGIN selektor:=succ(selektor);
                                    weiter:=keine END;
     UNTIL ((selektor=RecEintrZahl) AND (weiter=fertig)) OR
           (weiter=finis);
 END;

