{====================================================================}

PROCEDURE schreibrecord (VAR usrec, usmask; receintrzahl : byte);

CONST ivon    = ^['G4';   { inverses Bild an  }
      ivoff   = ^['G0';   { inverses Bild aus }

TYPE anystring = STRING [255];

VAR  temp      : anystring;
     i         : byte;
     maske     : ARRAY [1..255] OF RECORD
                                     xp, yp : byte;
                                     m      : STRING [80];
                                     l      : byte
                                   END
                 ABSOLUTE usmask;
     recfeld   : ARRAY [0..maxint] OF byte ABSOLUTE usrec;

{--------------------------------------------------------------------}

PROCEDURE copyrectemp (x:byte);

VAR i, s : integer;

BEGIN { copyrectemp }
  s := 0;
  FOR i := 1 TO x-1 DO
    s := s+maske [i].l+1;
  temp := '';
  FOR i := 1 TO recfeld [s] DO
    temp := temp+chr (recfeld [s+i])
END;  { copyrectemp }

{--------------------------------------------------------------------}

BEGIN { schreibrecord }
  FOR i := 1 TO receintrzahl DO
    WITH maske [i] DO
      BEGIN
        gotoxy (xp, yp);
        write (ivon, m, ivoff);
        copyrectemp (i);
        WHILE length (temp) < l DO
          temp := temp+'_';
        write (' ', temp)
      END
END;  { schreibrecord }

{====================================================================}

PROCEDURE liesrecord (VAR usrec, usmask; receintrzahl : byte);

{$V-}  { kein Range-Checking bei String-Uebergabe }

TYPE anystring = STRING [255];
     richtung  = (keine, fertig, rauf, runter);

VAR  temp      : anystring;
     selektor  : byte;
     weiter    : richtung;
     maske     : ARRAY [1..255] OF RECORD
                                     xp, yp : byte;
                                     m      : STRING [80];
                                     l      : byte
                                   END
                 ABSOLUTE usmask;
     recfeld   : ARRAY [0..maxint] OF byte ABSOLUTE usrec;

{--------------------------------------------------------------------}

PROCEDURE copyrectemp (x:byte);

VAR i, s : integer;

BEGIN { copyrectemp }
  s := 0;
  FOR i := 1 TO x-1 DO
    s := s+maske [i].l+1;
  temp := '';
  FOR i := 1 TO recfeld [s] DO
    temp := temp+chr (recfeld [s+i])
END;  { copyrectemp }

{--------------------------------------------------------------------}

PROCEDURE copytemprec (x:byte);

VAR i, s : integer;

BEGIN { copytemprec }
  s := 0;
  FOR i := 1 TO x-1 DO
    s := s+maske [i].l+1;
  recfeld [s] := length (temp);
  FOR i := 1 TO length (temp) DO
    recfeld [s+i] := ord (temp [i])
END;  { copytemprec }

{--------------------------------------------------------------------}

PROCEDURE eingabe (spalte, zeile : integer; VAR antwort : anystring;
                       maxlaenge : integer; VAR weiter  : richtung);

VAR cpos, i : integer;
    c       : char;

{....................................................................}

PROCEDURE beep;

BEGIN { beep }
  write (^G)
END;  { beep }

{....................................................................}

BEGIN { eingabe }
  gotoxy (spalte, zeile);
  cpos := length (antwort)+1;
  REPEAT
    gotoxy (spalte+cpos-1, zeile);
    read (kbd, c);
    CASE c OF
      ^M : weiter := fertig;
      ^E : weiter := rauf;
      ^X : weiter := runter;
      ^H : IF cpos > 1
             THEN
               BEGIN
                 cpos := pred (cpos);
                 gotoxy (spalte+cpos-1, zeile);
                 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..#126: 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;  { eingabe }

{--------------------------------------------------------------------}

BEGIN { liesrecord }
  selektor := 1;
  schreibrecord (usrec, maske, receintrzahl);
  REPEAT
    weiter := keine;
    copyrectemp (selektor);
    WITH maske [selektor] DO
      eingabe (xp+length (m)+1, yp, temp, l, weiter);
    copytemprec (selektor);
    IF weiter = rauf
      THEN
        IF selektor > 1
          THEN
            selektor := pred (selektor)
          ELSE
            selektor := receintrzahl;
    IF weiter = runter
      THEN
        IF selektor < receintrzahl
          THEN
            selektor := succ (selektor)
          ELSE
            selektor := 1;
    IF weiter = fertig
      THEN
        IF selektor <> receintrzahl
          THEN
            BEGIN
              selektor := succ (selektor);
              weiter := keine
            END
  UNTIL (selektor = receintrzahl) AND (weiter = fertig)
END;  { liesrecord }

{====================================================================}
