(**************************************************************************


:Program.       MODULE AusgleichsgeradeV2

:Contents.      berechnet und zeichnet eine Ausgleichsgerade

:Usage.         AusgleichsgeradeV2


:Copyright.     © 1990, 1991 by

:Author.        Thomas Ansorge

:Address.       Dinkelackerring 55, W-6730 Neustadt, Deutschland


:Language.      Modula-2

:Translator.    M2Amiga V4.0 (deutsch)

:Imports.       OpenClose [Thomas Ansorge]


:Version.       Version 2.1 vom 20.04.1992

:History.       1.0 vom 23.12.1990 erste Version
:History.       1.1 vom 25.02.1991 mit bekanntem Parameter B
:History.       2.0 vom 01.04.1991 mit komplettem Intuition-Interface
:History.           anstelle des Ja/Nein-Spielchens in der Shell
:History.       2.1 vom 20.04.1992 zeichnet und druckt Ausgleichsgerade


**************************************************************************)


MODULE AusgleichsgeradeV2;

FROM Arts IMPORT Assert;

FROM ASCII IMPORT eol;

FROM Conversions IMPORT StrToVal, ValToStr;

FROM DosD IMPORT FileHandlePtr, newFile;

FROM DosL IMPORT Write;

FROM ExecD IMPORT MsgPortPtr;

FROM ExecL IMPORT CloseDevice, DoIO, GetMsg, OpenDevice, ReplyMsg, WaitPort;

FROM ExecSupport IMPORT CreateExtIO, DeleteExtIO;

FROM FileSystem IMPORT File;

FROM GraphicsD IMPORT jam2, FontFlags, FontFlagSet, FontStyles,
   FontStyleSet, RastPortPtr, TextFont, TextFontPtr, ViewModes, ViewModeSet,
   ViewPort, ViewPortPtr, TextAttr, TextAttrPtr;

FROM GraphicsL IMPORT Draw, Move, RectFill, SetAPen, SetRGB4;

FROM Heap IMPORT Allocate, Deallocate, Largest;

FROM IntuitionD IMPORT ActivationFlags, ActivationFlagSet, boolGadget,
   Border, BorderPtr, customScreen, Gadget, GadgetPtr, GadgetFlags,
   GadgetFlagSet, IDCMPFlags, IDCMPFlagSet, IntuiMessage, IntuiMessagePtr,
   IntuiText, IntuiTextPtr, NewScreen, NewWindow, Preferences, reqGadget,
   Requester, RequesterFlags, RequesterFlagSet, RequesterPtr, Screen,
   ScreenFlags, ScreenFlagSet, ScreenPtr, strGadget, StringInfo, Window,
   WindowFlags, WindowFlagSet, WindowPtr;

FROM IntuitionL IMPORT ActivateGadget, DrawBorder, PrintIText, OffGadget,
   OnGadget, RefreshGList, Request;

FROM LongRealConversions IMPORT RealToStr, StrToReal;

FROM MathLibLong IMPORT sqrt;

FROM OpenClose IMPORT Close, CloseFont, CloseScreen, CloseWindow, CreatePort,
   DeletePort, Open, OpenFont, OpenScreen, OpenWindow;

FROM Printer IMPORT dumpRPort, IODRPReq, IODRPReqPtr, printerName,
   Special, SpecialSet;

FROM String IMPORT Concat, Delete, FirstPos, Insert, Length;

FROM SYSTEM IMPORT ADDRESS, ADR, LONGSET;

(* --------------------------------------------------------------------- *)

CONST (* der Font *)
      FontName  = "topaz.font\o";
      FontHoehe = 9;

      (* der Screen *)
      Screentitel   = "Ausgleichsgerade Version 2.1d\o";
      Fenstertitel  = "© 1992 Thomas Ansorge, Dinkelackerring 55, W-6730 Neustadt\o";
      Fenstertitel2 = "die Daten der Ausgleichsgerade:\o";
      Fenstertitel3 = "die Grafik der Ausgleichsgeraden:\o";

      (* die Screenfarben: *)
      Blaugrau  = 0;
      Hellblau  = 1;
      Schwarz   = 2;
      Dunkelrot = 3;
      Weissrot  = 4;
      Weiss     = 5;
      Rot       = 6;
      Gelb      = 7;

      (* Fehlermeldungen bei Assert *)
      Speichermangel = "nicht genug freier Speicher!";

      (* für den Requester *)
      Ok   = "Ok\o";
      Ja   = "Ja\o";
      Nein = "Nein\o";

      (* für die Ausgabe *)
      PRT = "PRT:\o";

      (* für die Gadgets (Trick 17) *)
      Space3  = "   \o";
      Space8  = "        \o";
      Space9  = "         \o";
      Space10 = "          \o";
      Space16 = "                \o";
      Space27 = "                           \o";

      (* für die Zeichnung *)
      SpalteMax = 627;
      SpalteMin = 6;
      ZeileMax  = 179;
      ZeileMin  = 13;

TYPE (* alles wissenswerte über die Ausgleichsgerade *)
     AGerade = RECORD
                  N       : CARDINAL; (* Anzahl der Werte *)
                  M       : CARDINAL; (* momentan angezeigter Wert *)
                  Groesse : LONGINT; (* Größe des Speicherbereiches *)
                  Adresse : ADDRESS; (* Adresse der Wertepaare *)
                  Disk    : BOOLEAN; (* in dieser Form gespeichert? *)
                  Daten   : RECORD
                               A, B: LONGREAL; (* Parameter Y = AX + B *)
                               XM,
                               YM  : LONGREAL; (* Mittelwerte *)
                               XS,   (* Standardabweichung von X *)
                               YS,   (* dto. von Y *)
                               GS,   (* dto. der Geraden *)
                               AS,   (* dto. von A *)
                               BS  : LONGREAL; (* dto. von B *)
                               R   : LONGREAL; (* Korrelationskoeffizient *)
                            END (* RECORD Daten *);
                  BBekannt: BOOLEAN; (* B vorher bekannt? *)
               END (* RECORD AGerade *);

     AnAus = (An, Aus);

CONST LongStringMax = 255;
      StringMax     =  60;

TYPE LongString = ARRAY [0..LongStringMax] OF CHAR;
     String     = ARRAY [0..StringMax] OF CHAR;

TYPE Koordinate = (x, y);

VAR (* die aktuelle Ausgleichsgerade *)
    Gerade: AGerade;

    (* die Datei auf der Diskette *)
    GerDatei    : File;
    GerDateiname: LongString;

    (* zum Rechnen *)
    Wert: POINTER TO LONGREAL;
    XIQQ: LONGREAL; (* Summe (Xi - XM)² (Hilfsvariable) *)

    (* für den Font *)
    Attr: TextAttr;
    Font: TextFontPtr;

    (* für den Screen *)
    NBildschirm: NewScreen;
    Bildschirm : ScreenPtr;

    (* das Fenster mit den Gadgets auf dem Screen *)
    NFenster  : NewWindow;
    BFenster  : WindowPtr;
    Box       : ARRAY [1..23] OF Gadget;
    SInfo     : ARRAY [1..5] OF StringInfo;
    IText     : ARRAY [1..24] OF IntuiText;
    ILeer     : ARRAY [1..36] OF IntuiText;
    Rahmen    : ARRAY [1..12] OF Border;
    Ecken     : ARRAY [1..12], [1..10] OF INTEGER;
    XZahl,
    UXZahl,
    YZahl,
    UYZahl,
    YVonX,
    UYVonX    : ARRAY [0..15] OF CHAR;
    SPaarNr,
    USPaarNr,
    SMaxPaare,
    USMaxPaare: ARRAY [0..6] OF CHAR;
    MaxPaare,
    PaarNr    : LONGINT;

    (* Gadgets abfragen *)
    Nachricht: IntuiMessagePtr;
    Flags    : IDCMPFlagSet;
    GewGad   : GadgetPtr;

    (* 4 × IntuiText für den Requester *)
    ReqText: ARRAY [1..4] OF IntuiText;

    (* für den Ausdruck *)
    Ausgabe,
    SHilfe  : ARRAY [0..80] OF CHAR;
    BildReq : IODRPReqPtr;
    Datei   : FileHandlePtr;
    Port    : MsgPortPtr;
    Ziffern : CARDINAL; (* Anzahl Ziffern von N *)

    (* das GrafikFenster *)
    Breite  : LONGREAL;
    GFenster: WindowPtr;
    Hoehe   : LONGREAL;
    ISchrift: IntuiText;
    MBDurchA: LONGREAL;
    Schrift : ARRAY [0..9] OF CHAR;
    X       : INTEGER;
    XPixelBr: LONGREAL;
    XMin,
    XMax    : LONGREAL;
    Y       : INTEGER;
    YPixelBr: LONGREAL;
    YMin,
    YMax    : LONGREAL;

    (* Das Datenfenster *)
    DFenster  : WindowPtr;
    HilfsText : String;
    TextZeile : String;

    (* diverses *)
    i           : CARDINAL; (* Zähler in FOR-Schleifen *)
    Weiter      : CHAR; (* Hauptsache, Return gedrückt *)
    Hilfe,
    Hilfe2,
    Hilfe3      : LONGREAL; (* wird ab und zu gebraucht *)
    Programmende: BOOLEAN;
    Error       : BOOLEAN;
    ErstesMal   : BOOLEAN;

(* --------------------------------------------------------------------- *)

(* Damit man die Prozeduren leichter findet, sind sie alphabetisch   *)
(* geordnet. Die folgenden Prozeduren werden in anderen gebraucht    *)
(* und seien deshalb hier dem Compiler bekanntgemacht:               *)

PROCEDURE GadgetAn (Gad    : GadgetPtr;
                    Fenster: WindowPtr;
                    Req    : RequesterPtr); FORWARD;

PROCEDURE GadgetAus (Gad    : GadgetPtr;
                     Fenster: WindowPtr;
                     Req    : RequesterPtr); FORWARD;

(* --------------------------------------------------------------------- *)

PROCEDURE AktualisiereG (VAR Box1, Box2, Box3, Box4: Gadget;
                         VAR Fenster               : WindowPtr;
                             Nummer                : LONGINT;
                             Max                   : CARDINAL);

   (* aktualisiert die 4 Gadgets +, -, 10+, 10- *)

   BEGIN (* Prozedur AktualisiereG *)

   (* + ggf. an *)
   IF (Max - CARDINAL (Nummer) > 0) AND
      (gadgDisabled IN Box1.flags) THEN
      GadgetAn (ADR (Box1), Fenster, NIL);
   END (* IF (Max *);

   (* + ggf. aus *)
   IF (CARDINAL (Nummer) = Max) AND
      NOT (gadgDisabled IN Box1.flags) THEN
      GadgetAus (ADR (Box1), BFenster, NIL);
   END (* IF (Gerade.M *);

   (* - ggf. an *)
   IF (Nummer > 1) AND
      (gadgDisabled IN Box2.flags) THEN
      GadgetAn (ADR (Box2), Fenster, NIL);
   END (* IF Nummer *);

   (* - ggf. aus *)
   IF (Nummer = 1) AND
      NOT (gadgDisabled IN Box2.flags) THEN
      GadgetAus (ADR (Box2), Fenster, NIL);
   END (* IF (Nummer *);

   (* 10+ ggf. an *)
   IF (Max - CARDINAL (Nummer) > 9) AND
      (gadgDisabled IN Box3.flags) THEN
      GadgetAn (ADR (Box3), Fenster, NIL);
   END (* IF (Max *);

   (* 10+ ggf. aus *)
   IF (Max - CARDINAL (Nummer) < 10) AND
      NOT (gadgDisabled IN Box3.flags) THEN
      GadgetAus (ADR (Box3), Fenster, NIL);
   END (* IF (Max *);

   (* 10- ggf. an *)
   IF (Nummer > 10) AND
      (gadgDisabled IN Box4.flags) THEN
      GadgetAn (ADR (Box4), Fenster, NIL);
   END (* IF (Nummer *);

   (* 10- ggf. aus *)
   IF (Nummer < 11) AND
      NOT (gadgDisabled IN Box4.flags) THEN
      GadgetAus (ADR (Box4), Fenster, NIL);
   END (* IF (Nummer *);
END (* Prozedur *) AktualisiereG;

(* --------------------------------------------------------------------- *)

PROCEDURE AZiffern (Zahl: LONGINT): INTEGER;

   (* berechnet die Anzahl der Ziffern von Zahl *)

   BEGIN (* Funktion AZiffern *)

   IF Zahl > 9999 THEN
      RETURN 5;

   ELSE
      IF Zahl > 999 THEN
         RETURN 4;

      ELSE
         IF Zahl > 99 THEN
            RETURN 3;

         ELSE
            IF Zahl > 9 THEN
               RETURN 2;

            ELSE
               RETURN 1;
            END (* IF Zahl > 9 *);
         END (* IF Zahl > 99 *);
      END (* IF Zahl > 999 *);
   END (* IF Zahl > 9999 *);
END (* Funktion *) AZiffern;

(* --------------------------------------------------------------------- *)

PROCEDURE DrawCross (rPort: RastPortPtr;
                     x, y : INTEGER);

   (* zeichnet ein kleines Kreuz mit Mittelpunkt (x,y) *)

   BEGIN (* Prozedur DrawCross *)

   Move (rPort, x - 1, y);
   Draw (rPort, x + 2, y);

   Move (rPort, x, y - 1);
   Draw (rPort, x, y + 1);

   Move (rPort, x + 1, y - 1);
   Draw (rPort, x + 1, y + 1);
END DrawCross (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE Exponent (Wert: LONGREAL): BOOLEAN;

   (* entscheidet, ob Wert mit oder ohne Exponent ausgegeben wird    *)

   BEGIN (* Funktion Exponent *)

   Wert := ABS (Wert); (* Jetzt ist Wert >= 0.0 *)

   IF ((Wert < 1000.0) AND (Wert > 0.001)) OR (Wert = 0.0) THEN
      RETURN FALSE;

   ELSE
      RETURN TRUE;
   END (* IF (Wert *);
END Exponent (* Funktion *);

(* --------------------------------------------------------------------- *)

PROCEDURE GadgetAn (Gad    : GadgetPtr;
                    Fenster: WindowPtr;
                    Req    : RequesterPtr);

   (* schaltet ein Gadget an (etwas schneller als OnGadget allein) *)

   VAR NaechstesGad: GadgetPtr;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Prozedur GadgetAn *)

   (* alle folgenden ausblenden *)
   NaechstesGad := Gad^.nextGadget;
   Gad^.nextGadget := NIL;

   (* einschalten *)
   OnGadget (Gad, Fenster, Req);

   (* die folgenden wieder anhängen *)
   Gad^.nextGadget := NaechstesGad;

END GadgetAn (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE GadgetAus (Gad    : GadgetPtr;
                     Fenster: WindowPtr;
                     Req    : RequesterPtr);

   (* schaltet Gadgets schneller aus als OffGadget allein... *)

   VAR NaechstesGad: GadgetPtr;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Prozedur GadgetAus *)

   (* alle folgenden ausblenden *)
   NaechstesGad := Gad^.nextGadget;
   Gad^.nextGadget := NIL;

   (* ausschalten *)
   OffGadget (Gad, Fenster, Req);

   (* die folgenden wieder anhängen *)
   Gad^.nextGadget := NaechstesGad;

END GadgetAus (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE ImRastPort (element   : INTEGER;
                      koordinate: Koordinate
                     ): BOOLEAN;

   (* stellt fest, ob die Zeile/Spalte element im Rastport *)
   (* GFenster^.rPort^ darstellbar ist                     *)

   BEGIN (* Funktion ImRastPort *)

   IF koordinate = x THEN
      IF (element >= SpalteMin) AND (element <= (SpalteMax + SpalteMin)) THEN
         RETURN TRUE;

      ELSE (* IF element *)
         RETURN FALSE;
      END (* IF (element *);

   ELSE (* IF koordiante *)
      IF (element >= ZeileMin) AND (element <= (ZeileMax + ZeileMin)) THEN
         RETURN TRUE;

      ELSE (* IF element *)
         RETURN FALSE;
      END (* IF (element *);
   END (* IF koordinate *)
END ImRastPort (* Funktion *);

(* --------------------------------------------------------------------- *)

PROCEDURE InitGerade (VAR Gerade: AGerade);

   (* initialisiert den Record Gerade *)

   BEGIN (* Prozedur InitGerade *)

   WITH Gerade DO
      M := 0;
      N := 0;
      Groesse := 0;
      Adresse := NIL;
      Disk := FALSE;

      WITH Daten DO
         A := 0.0;
         B := 0.0;
         XM := 0.0;
         YM := 0.0;
         XS := 0.0;
         YS := 0.0;
         GS := 0.0;
         AS := 0.0;
         BS := 0.0;
         R := 0.0;
      END (* WITH Daten *);

      BBekannt := FALSE;
   END (* WITH Gerade *);
END InitGerade (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE Laenge (Zahl: INTEGER): INTEGER;

   (* ermittelt die Anzahl der Stellen von Zahl ohne Vorzeichen *)

   BEGIN (* Funktion Laenge *)

   IF Zahl < 0 THEN
      Zahl := - Zahl;
   END (* IF Zahl *);

   IF Zahl < 10 THEN
      RETURN 1;

   ELSE
      IF Zahl < 100 THEN
         RETURN 2;

      ELSE
         IF Zahl < 1000 THEN
            RETURN 3;

         ELSE
            IF Zahl < 10000 THEN
               RETURN 4;

            ELSE
               RETURN 5;
            END;
         END;
      END;
   END;
END Laenge (* Funktion *);

(* --------------------------------------------------------------------- *)

PROCEDURE MakeRequest (TextPos,
                       TextNeg,
                       ReqText : IntuiTextPtr;
                       Fenster : WindowPtr;
                       AnzGad  : CARDINAL     ): BOOLEAN;

   (* zeichnet einen Requester, wobei der Text automatisch zentriert *)
   (* wird (ReqText^.leftEdge = 0 setzen!)                           *)

   VAR Req     : Requester;
       ReqGad  : ARRAY [1..2] OF Gadget;
       StrPtr,
       StrPtr2 : POINTER TO ARRAY [0..80] OF CHAR;
       Rahmen  : ARRAY [1..3] OF Border;
       Ecken   : ARRAY [1..3], [1..10] OF INTEGER;
       Width   : INTEGER;
       ITextPtr: IntuiTextPtr;

       Nachricht: IntuiMessagePtr;
       Flags    : IDCMPFlagSet;
       AngGad   : GadgetPtr;
       Erfolg   : BOOLEAN;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Funktion MakeRequest *)

   (* Größe des Requesters *)
   ITextPtr := ReqText;
   StrPtr := ITextPtr^.iText;
   Width := INTEGER (Length (StrPtr^)) * 10 + 10;

   WHILE ITextPtr^.nextText # NIL DO
      ITextPtr := ITextPtr^.nextText;
      StrPtr := ITextPtr^.iText;

      IF 10 * INTEGER (Length (StrPtr^)) + 10 > Width THEN
         Width := 10 * INTEGER (Length (StrPtr^)) + 10;
      END (* IF Length *);
   END (* WHILE *);

   StrPtr := TextNeg^.iText;
   StrPtr2 := TextPos^.iText;

   (* Sind die beiden (?) Gadgets zusammen länger als der Text? *)
   IF AnzGad = 1 THEN
      IF 10 * INTEGER (Length (StrPtr2^) + 10) > Width THEN
         Width := 10 * INTEGER (Length (StrPtr2^) + 10);
      END (* IF Length *);

   ELSE (* AnzGad = 2 *)
      IF 10 * INTEGER (Length (StrPtr^) + Length (StrPtr2^) + 10) > Width
         THEN
         Width := 10 * INTEGER (Length (StrPtr^) + Length (StrPtr2^) + 10);
      END (* IF Length *);
   END (* IF AnzGad *);

   (* Rahmen um Requester *)
   Ecken [3, 1] := 0;         Ecken [3,  2] := 0;
   Ecken [3, 3] := Width - 1; Ecken [3,  4] := 0;
   Ecken [3, 5] := Width - 1; Ecken [3,  6] := 79;
   Ecken [3, 7] := 0;         Ecken [3,  8] := 79;
   Ecken [3, 9] := 0;         Ecken [3, 10] := 0;

   WITH Rahmen [3] DO
      leftEdge := 0;
      topEdge := 0;
      frontPen := 6;
      backPen := 0;
      drawMode := jam2;
      count := 5;
      xy := ADR (Ecken [3, 1]);
      nextBorder := NIL;
   END (* WITH Rahmen [2] *);

   (* Gadgets im Requester *)
   IF AnzGad = 2 THEN
      StrPtr := TextNeg^.iText;

      (* Rahmen drumherum *)
      Ecken [2, 1] := -1;                        Ecken [2,  2] := -2;
      Ecken [2, 3] := Length (StrPtr^) * 10 + 1; Ecken [2,  4] := -2;
      Ecken [2, 5] := Length (StrPtr^) * 10 + 1; Ecken [2,  6] := 10;
      Ecken [2, 7] := -1;                        Ecken [2,  8] := 10;
      Ecken [2, 9] := -1;                        Ecken [2, 10] := -2;

      Rahmen [2] := Rahmen [3];
      Rahmen [2].xy := ADR (Ecken [2, 1]);
   END (* IF AnzGad *);

   StrPtr := TextPos^.iText;

   Ecken [1, 1] := -1;                        Ecken [1,  2] := -2;
   Ecken [1, 3] := Length (StrPtr^) * 10 + 1; Ecken [1,  4] := -2;
   Ecken [1, 5] := Length (StrPtr^) * 10 + 1; Ecken [1,  6] := 10;
   Ecken [1, 7] := -1;                        Ecken [1,  8] := 10;
   Ecken [1, 9] := -1;                        Ecken [1, 10] := -2;

   Rahmen [1] := Rahmen [3];
   Rahmen [1].xy := ADR (Ecken [1, 1]);

   WITH ReqGad [2] DO
      nextGadget := NIL;
      width := Ecken [2, 3] - 1;
      height := 9;
      leftEdge := Width - 10 - width;
      topEdge := 60;
      flags := GadgetFlagSet {};
      activation := ActivationFlagSet {relVerify, endGadget};
      gadgetType := boolGadget + reqGadget;
      gadgetRender := ADR (Rahmen [2]);
      gadgetText := TextNeg;
      mutualExclude := LONGSET {};
      specialInfo := NIL;
      gadgetID := 2;
      userData := NIL;
   END (* WITH ReqGad [2] *);

   ReqGad [1] := ReqGad [2];
   ReqGad [1].width := Ecken [1, 3] - 1;

   IF AnzGad = 2 THEN
      ReqGad [1].nextGadget := ADR (ReqGad [2]);
      ReqGad [1].leftEdge := 10;

   ELSE (* IF AnzGad *)
      ReqGad [1].nextGadget := NIL;
      ReqGad [1].leftEdge := (Width - ReqGad [1].width) DIV 2;
   END (* IF AnzGad *);

   ReqGad [1].gadgetRender := ADR (Rahmen [1]);
   ReqGad [1].gadgetText := TextPos;
   ReqGad [1].gadgetID := 1;

   (* der Requester *)
   WITH Req DO
      olderRequest := NIL;
      leftEdge := (640 - Width) DIV 2;
      topEdge := 55;
      width := Width;
      height := 80;
      relLeft := 0;
      relTop := 0;
      reqGadget := ADR (ReqGad [1]);
      reqBorder := ADR (Rahmen [3]);
      reqText := ReqText;
      flags := RequesterFlagSet {};
      backFill := 4;
      reqLayer := NIL;
      imageBMap := NIL;
   END (* WITH Req *);

   (* Text zentrieren *)
   ITextPtr := Req.reqText;

   WHILE ITextPtr # NIL DO
      StrPtr := ITextPtr^.iText;
      ITextPtr^.leftEdge := (Width - 10 * INTEGER (Length (StrPtr^))) DIV 2;
      ITextPtr := ITextPtr^.nextText;
   END (* WHILE *);

   Erfolg := Request (ADR (Req), Fenster);

   Assert (Erfolg, ADR ("konnte Requester nicht öffnen!"));

   (* Requester abfragen *)
   REPEAT
      Flags := IDCMPFlagSet {};
      AngGad := NIL;

      WaitPort (Req.rWindow^.userPort);
      Nachricht := GetMsg (Req.rWindow^.userPort);

      IF Nachricht # NIL THEN
         Flags := Nachricht^.class;
         AngGad := Nachricht^.iAddress;
         ReplyMsg (Nachricht);
      END (* IF Nachricht # NIL *);
   UNTIL AngGad # NIL;

   RETURN (AngGad^.gadgetID = 1);
END (* Funktion *) MakeRequest;

(* --------------------------------------------------------------------- *)

PROCEDURE Positiv (Wert: LONGREAL;
                   Null: BOOLEAN
                  ): BOOLEAN;

   BEGIN (* Funktion Positiv *)

   IF Null THEN
      RETURN (Wert >= 0.0);

   ELSE (* IF Null *)
      RETURN (Wert > 0.0);
   END (* IF Null *);
END Positiv (* Funktion *);

(* --------------------------------------------------------------------- *)

PROCEDURE PrintText (Fenster   : WindowPtr;
                     Text      : ARRAY OF CHAR; (* <-> PrintIText *)
                     LeftOffset: INTEGER;
                     TopOffset : INTEGER);

   (* ein bequemes PrintIText *)

   VAR IText: IntuiText;

   (* ------------------------------------------------------------------ *)

   BEGIN (* PROCEDURE PrintText *)

   WITH IText DO
      frontPen := Fenster^.blockPen;
      backPen := Fenster^.detailPen;
      drawMode := jam2;
      leftEdge := 0;
      topEdge := 0;
      iTextFont := NIL;
      iText := ADR (Text);
      nextText := NIL;
   END (* WITH iText *);

   PrintIText (Fenster^.rPort, ADR (IText), LeftOffset, TopOffset);
END PrintText (* PROCEDURE *);

(* --------------------------------------------------------------------- *)

PROCEDURE RefreshGadList (Gad    : GadgetPtr;
                          Fenster: WindowPtr;
                          Req    : RequesterPtr;
                          Anz    : INTEGER      );

   (* erledigt das Refreshen etwas schneller... *)

   VAR LetztesGad,
       NaechstesGad: GadgetPtr;
       i           : INTEGER;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Prozedur RefreshGadList *)

   (* letztes zu refreshendes Gadget finden *)
   LetztesGad := Gad;

   FOR i := 1 TO (Anz - 1) DO
      LetztesGad := LetztesGad^.nextGadget;
   END (* FOR i *);

   (* alle nicht zu refreshenden Gadgets abhängen... *)
   NaechstesGad := LetztesGad^.nextGadget;
   LetztesGad^.nextGadget := NIL;

   (* refreshen... *)
   RefreshGList (Gad, Fenster, Req, Anz);

   (* ...und wieder anfügen *)
   LetztesGad^.nextGadget := NaechstesGad;

END RefreshGadList (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE RUmGadget (Box    : Gadget;
                     Mod    : AnAus;
                     Fenster: WindowPtr);

   (* zeichnet oder löscht einen Rahmen um eines der 6 linken        *)
   (* Toggleselectgadgets                                            *)

   VAR Ecken : ARRAY [1..10] OF INTEGER;
       Rahmen: Border;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Prozedur RUmGadget *)

   Ecken [1] := -3;  Ecken [ 2] := -3;
   Ecken [3] := 164; Ecken [ 4] := -3;
   Ecken [5] := 164; Ecken [ 6] := 12;
   Ecken [7] := -3;  Ecken [ 8] := 12;
   Ecken [9] := -3;  Ecken [10] := -3;

   WITH Rahmen DO
      leftEdge := Box.leftEdge;
      topEdge := Box.topEdge;

      IF Mod = An THEN
         frontPen := 7;
      ELSE (* IF Mod *)
         frontPen := 0;
      END (* IF Mod *);

      backPen := 0;
      drawMode := jam2;
      count := 5;
      xy := ADR (Ecken [1]);
      nextBorder := NIL;
   END (* WITH Rahmen *);

   DrawBorder (Fenster^.rPort, ADR (Rahmen), 0, 0);
END (* Prozedur *) RUmGadget;

(* --------------------------------------------------------------------- *)

PROCEDURE Schreibe (Datei     : FileHandlePtr;
                    String    : ARRAY OF CHAR;
                    Leerzeilen: CARDINAL      );

   (* Schreibt den String STRING in die Ausgabedatei und fügt eine   *)
   (* anzugebende Anzahl Leerzeilen dahinter ein.                    *)

   VAR Error: LONGINT;
       i    : CARDINAL;
       EOL  : CHAR;

   (* ------------------------------------------------------------------ *)

   BEGIN (* Prozedur Schreibe *)

   EOL := eol; (* damit das Ding eine Adresse bekommt und der        *)
               (* Compiler nicht meckert!                            *)

   Error := Write (Datei, ADR (String), Length (String));

   FOR i := 0 TO Leerzeilen DO
      Error := Write (Datei, ADR (EOL), 1);
   END (* FOR i *);
END Schreibe (* Prozedur *);

(* --------------------------------------------------------------------- *)

PROCEDURE Spalte (XWert: LONGREAL): INTEGER;

   (* ermittelt die Spalte in der Grafik für einen Punkt *)

   (* globale Variablen: XMin, XPixelBr *)

   BEGIN (* Funktion Spalte *)

   RETURN INTEGER ((XWert - XMin) / XPixelBr) + SpalteMin;
END Spalte (* Funktion *);

(* --------------------------------------------------------------------- *)

PROCEDURE Zeile (YWert: LONGREAL): INTEGER;

   (* ermittelt die Zeile in der Grafik für einen Punkt *)

   (* globale Variablen: YMax, YPixelBr *)

   BEGIN (* Funktion Zeile *)

   RETURN INTEGER ((YMax - YWert) / YPixelBr) + ZeileMin;
END Zeile (* Funktion *);

(* --------------------------------------------------------------------- *)
(* --------------------------------------------------------------------- *)

BEGIN (* Modul Ausgleichsgerade *)

(* zu Beginn... *)
Font := NIL;
BildReq := NIL;
Bildschirm := NIL;
BFenster := NIL;
DFenster := NIL;
GFenster := NIL;
Datei := NIL;
Programmende := FALSE;
ErstesMal := TRUE;

(* IntuiText für Requester initialisieren *)
WITH ReqText [4] DO
   (* Neg-Gadget *)
   frontPen := 3;
   backPen := 4;
   drawMode := jam2;
   leftEdge := 0;
   topEdge := 0;
   iTextFont := NIL;
   iText := NIL;
   nextText := NIL;
END (* WITH ReqText [4] *);

(* Pos-Gadget *)
ReqText [3] := ReqText [4];

(* Text, 2. Zeile *)
ReqText [2] := ReqText [3];
ReqText [2].topEdge := 40;

(* Text, 1. Zeile *)
ReqText [1] := ReqText [2];
ReqText [1].topEdge := 20;
ReqText [1].nextText := ADR (ReqText [2]);

(* Gerade initialisieren *)
InitGerade (Gerade);

(* der Font *)
WITH Attr DO
   name := ADR (FontName);
   ySize := FontHoehe;
   style := FontStyleSet {};
   flags := FontFlagSet {};
END (* WITH Attr *);

Font := OpenFont (ADR (Attr));

(* Variablenfelder initialisieren *)
(* die ganzen Texte *)
WITH IText [24] DO
   frontPen := 1;
   backPen := 0;
   drawMode := jam2;
   leftEdge := 220;
   topEdge := 80;
   iTextFont := ADR (Attr);
   iText := ADR ("Y(X=0):");
   nextText := NIL;
END (* WITH IText [24] *);

IText [23] := IText [24];
IText [23].leftEdge := 5;
IText [23].topEdge := 1;
IText [23].iText := ADR ("n. bek.");

ILeer [36] := IText [24];
ILeer [36].leftEdge := 0;
ILeer [36].topEdge := 1;
ILeer [36].iText := ADR (Space8);
ILeer [36].nextText := ADR (IText [23]);

ILeer [35] := ILeer [36];
ILeer [35].topEdge := 0;
ILeer [35].nextText := ADR (ILeer [36]);

IText [22] := IText [23];
IText [22].iText := ADR ("bekannt");

ILeer [34] := ILeer [36];
ILeer [34].nextText := ADR (IText [22]);

ILeer [33] := ILeer [35];
ILeer [33].nextText := ADR (ILeer [34]);

IText [21] := IText [22];
IText [21].leftEdge := 220;
IText [21].topEdge := 20;
IText [21].iText := ADR ("Anzahl der Paare:");
IText [21].nextText := ADR (IText [24]);

IText [20] := IText [21];
IText [20].topEdge := 40;
IText [20].iText := ADR ("Paar Nr.");
IText [20].nextText := ADR (IText [21]);

IText [19] := IText [20];
IText [19].leftEdge := 0;
IText [19].topEdge := 1;
IText [19].iText := ADR (" + ");
IText [19].nextText := NIL;

ILeer [32] := ILeer [34];
ILeer [32].iText := ADR (Space3);
ILeer [32].nextText := ADR (IText [19]);

ILeer [31] := ILeer [33];
ILeer [31].iText := ADR (Space3);
ILeer [31].nextText := ADR (ILeer [32]);

IText [18] := IText [19];
IText [18].iText := ADR (" - ");

ILeer [30] := ILeer [32];
ILeer [30].nextText := ADR (IText [18]);

ILeer [29] := ILeer [31];
ILeer [29].nextText := ADR (ILeer [30]);

IText [17] := IText [18];
IText [17].iText := ADR ("10+");

ILeer [28] := ILeer [30];
ILeer [28].nextText := ADR (IText [17]);

ILeer [27] := ILeer [29];
ILeer [27].nextText := ADR (ILeer [28]);

IText [16] := IText [17];
IText [16].iText := ADR ("10-");

ILeer [26] := ILeer [28];
ILeer [26].nextText := ADR (IText [16]);

ILeer [25] := ILeer [27];
ILeer [25].nextText := ADR (ILeer [26]);

IText [15] := IText [16];
IText [15].leftEdge := 5;
IText [15].iText := ADR ("Ausgleichsgerade berechnen");

ILeer [24] := ILeer [26];
ILeer [24].iText := ADR (Space27);
ILeer [24].nextText := ADR (IText [15]);

ILeer [23] := ILeer [25];
ILeer [23].iText := ADR (Space27);
ILeer [23].nextText := ADR (ILeer [24]);

IText [14] := IText [15];
IText [14].leftEdge := 5;
IText [14].iText := ADR ("Gerade zeichnen");

ILeer [22] := ILeer [24];
ILeer [22].iText := ADR (Space16);
ILeer [22].nextText := ADR (IText [14]);

ILeer [21] := ILeer [23];
ILeer [21].iText := ADR (Space16);
ILeer [21].nextText := ADR (ILeer [22]);

IText [13] := IText [14];
IText [13].leftEdge := 4;
IText [13].iText := ADR (" E N D E ");

ILeer [20] := ILeer [22];
ILeer [20].iText := ADR (Space10);
ILeer [20].nextText := ADR (IText [13]);

ILeer [19] := ILeer [21];
ILeer [19].iText := ADR (Space10);
ILeer [19].nextText := ADR (ILeer [20]);

IText [12] := IText [13];
IText [12].iText := ADR ("Speichern");

ILeer [18] := ILeer [20];
ILeer [18].nextText := ADR (IText [12]);

ILeer [17] := ILeer [19];
ILeer [17].nextText := ADR (ILeer [18]);

IText [11] := IText [13];
IText [11].iText := ADR ("  Laden  ");

ILeer [16] := ILeer [18];
ILeer [16].nextText := ADR (IText [11]);

ILeer [15] := ILeer [17];
ILeer [15].nextText := ADR (ILeer [16]);

IText [10] := IText [11];
IText [10].leftEdge := 0;
IText [10].iText := ADR (" Drucken ");

ILeer [14] := ILeer [16];
ILeer [14].iText := ADR (Space9);
ILeer [14].nextText := ADR (IText [10]);

ILeer [13] := ILeer [15];
ILeer [13].iText := ADR (Space9);
ILeer [13].nextText := ADR (ILeer [14]);

IText [9] := IText [10];
IText [9].iText := ADR (" Seitenvorschub ");

ILeer [12] := ILeer [14];
ILeer [12].iText := ADR (Space16);
ILeer [12].nextText := ADR (IText [9]);

ILeer [11] := ILeer [13];
ILeer [11].iText := ADR (Space16);
ILeer [11].nextText := ADR (ILeer [12]);

IText [8] := IText [9];
IText [8].iText := ADR ("Ausgleichsgerade");

ILeer [10] := ILeer [12];
ILeer [10].nextText := ADR (IText [8]);

ILeer [9] := ILeer [11];
ILeer [9].nextText := ADR (ILeer [10]);

IText [7] := IText [8];
IText [7].iText := ADR (" Seitenvorschub ");

ILeer [8] := ILeer [10];
ILeer [8].nextText := ADR (IText [7]);

ILeer [7] := ILeer [9];
ILeer [7].nextText := ADR (ILeer [8]);

IText [6] := IText [7];
IText [6].iText := ADR ("Daten der Gerade");

ILeer [6] := ILeer [8];
ILeer [6].nextText := ADR (IText [6]);

ILeer [5] := ILeer [7];
ILeer [5].nextText := ADR (ILeer [6]);

IText [5] := IText [6];
IText [5].iText := ADR (" Seitenvorschub ");

ILeer [4] := ILeer [6];
ILeer [4].nextText := ADR (IText [5]);

ILeer [3] := ILeer [5];
ILeer [3].nextText := ADR (ILeer [4]);

IText [4] := IText [5];
IText [4].iText := ADR ("   Wertepaare   ");

ILeer [2] := ILeer [4];
ILeer [2].nextText := ADR (IText [4]);

ILeer [1] := ILeer [3];
ILeer [1].nextText := ADR (ILeer [2]);

IText [3] := IText [4];
IText [3].topEdge := 20;
IText [3].leftEdge := 50;
IText [3].iText := ADR ("Ausdruck:");
IText [3].nextText := ADR (IText [20]);

IText [2] := IText [3];
IText [2].topEdge := 60;
IText [2].leftEdge := 220;
IText [2].iText := ADR ("X:");
IText [2].nextText := ADR (IText [3]);

IText [1] := IText [2];
IText [1].leftEdge := 410;
IText [1].iText := ADR ("Y:");
IText [1].nextText := ADR (IText [2]);

(* Stringinfos für 2× Longinteger- und 3× String-Gadgets *)
XZahl := "";
UXZahl := XZahl;
YZahl := "";
UYZahl := YZahl;
YVonX := "0.0";
UYVonX := YVonX;
SPaarNr := "0";
USPaarNr := SPaarNr;
SMaxPaare := "0";
USMaxPaare := SMaxPaare;

WITH SInfo [5] DO
   buffer := ADR (YVonX);
   undoBuffer := ADR (UYVonX);
   bufferPos := 0;
   maxChars := 16;
   dispPos := 0;
   longInt := 0;
   altKeyMap := NIL;
END (* WITH SInfo [5] *);

SInfo [4] := SInfo [5];
SInfo [4].buffer := ADR (XZahl);
SInfo [4].undoBuffer := ADR (UXZahl);

SInfo [3] := SInfo [4];
SInfo [3].buffer := ADR (YZahl);
SInfo [3].undoBuffer := ADR (UYZahl);

SInfo [2] := SInfo [3];
SInfo [2].buffer := ADR (SPaarNr);
SInfo [2].undoBuffer := ADR (USPaarNr);
SInfo [2].maxChars := 6;

SInfo [1] := SInfo [2];
SInfo [1].buffer := ADR (SMaxPaare);
SInfo [1].undoBuffer := ADR (USMaxPaare);

(* Rahmen *)
(* der große um Ausdruck *)
Ecken [1, 1] := 0;   Ecken [1,  2] := 0;
Ecken [1, 3] := 175; Ecken [1,  4] := 0;
Ecken [1, 5] := 175; Ecken [1,  6] := 140;
Ecken [1, 7] := 0;   Ecken [1,  8] := 140;
Ecken [1, 9] := 0;   Ecken [1, 10] := 0;

WITH Rahmen [1] DO
   leftEdge := 5;
   topEdge := 15;
   frontPen := 7;
   backPen := 0;
   drawMode := jam2;
   count := 5;
   xy := ADR (Ecken [1, 1]);
   nextBorder := NIL;
END (* WITH Rahmen [1] *);

(* Gadgets innerhalb des Ausdruck-Rahmens *)
Ecken [2, 1] := -1;  Ecken [2,  2] := -1;
Ecken [2, 3] := 160; Ecken [2,  4] := -1;
Ecken [2, 5] := 160; Ecken [2,  6] := 10;
Ecken [2, 7] := -1;  Ecken [2,  8] := 10;
Ecken [2, 9] := -1;  Ecken [2, 10] := -1;

Rahmen [2] := Rahmen [1];
Rahmen [2].leftEdge := 0;
Rahmen [2].topEdge := 0;
Rahmen [2].xy := ADR (Ecken [2, 1]);

(* Rahmen um DRUCKEN *)
Ecken [3, 1] := -1; Ecken [3,  2] := -1;
Ecken [3, 3] := 91; Ecken [3,  4] := -1;
Ecken [3, 5] := 91; Ecken [3,  6] := 10;
Ecken [3, 7] := -1; Ecken [3,  8] := 10;
Ecken [3, 9] := -1; Ecken [3, 10] := -1;

Rahmen [3] := Rahmen [2];
Rahmen [3].xy := ADR (Ecken [3, 1]);

(* Rahmen um LONGINT-Gadgets *)
Ecken [4, 1] := -1; Ecken [4,  2] := -2;
Ecken [4, 3] := 60; Ecken [4,  4] := -2;
Ecken [4, 5] := 60; Ecken [4,  6] := 10;
Ecken [4, 7] := -1; Ecken [4,  8] := 10;
Ecken [4, 9] := -1; Ecken [4, 10] := -2;

Rahmen [4] := Rahmen [3];
Rahmen [4].xy := ADR (Ecken [4, 1]);

(* Rahmen um String (LONGREAL) -Gadgets *)
Ecken [5, 1] :=  -1; Ecken [5,  2] := -2;
Ecken [5, 3] := 150; Ecken [5,  4] := -2;
Ecken [5, 5] := 150; Ecken [5,  6] := 10;
Ecken [5, 7] :=  -1; Ecken [5,  8] := 10;
Ecken [5, 9] :=  -1; Ecken [5, 10] := -2;

Rahmen [5] := Rahmen [4];
Rahmen [5].xy := ADR (Ecken [5, 1]);

(* senkrechte und waagrechte Linie (nachträglich geändert) *)
Ecken [6, 1] := 195; Ecken [6,  2] :=  20;
Ecken [6, 3] := 195; Ecken [6,  4] := 180;
Ecken [6, 5] := 195; Ecken [6,  6] := 160;
Ecken [6, 7] := 620; Ecken [6,  8] := 160;
Ecken [6, 9] := 620; Ecken [6, 10] := 160;

Rahmen [6] := Rahmen [5];
Rahmen [6].count := 4;
Rahmen [6].xy := ADR (Ecken [6, 1]);
Rahmen [6].nextBorder := ADR (Rahmen [1]);

(* Rahmen um 10+ und 10- und + und -*)
Ecken [7, 1] := -1; Ecken [7,  2] := -1;
Ecken [7, 3] := 31; Ecken [7,  4] := -1;
Ecken [7, 5] := 31; Ecken [7,  6] := 10;
Ecken [7, 7] := -1; Ecken [7,  8] := 10;
Ecken [7, 9] := -1; Ecken [7, 10] := -1;

Rahmen [7] := Rahmen [5];
Rahmen [7].xy := ADR (Ecken [7, 1]);

(* Rahmen um Eingabefeld rechts oben *)
Ecken [8, 1] := 0;   Ecken [8,  2] := 0;
Ecken [8, 3] := 424; Ecken [8,  4] := 0;
Ecken [8, 5] := 424; Ecken [8,  6] := 80;
Ecken [8, 7] := 0;   Ecken [8,  8] := 80;
Ecken [8, 9] := 0;   Ecken [8, 10] := 0;

Rahmen [8] := Rahmen [1];
Rahmen [8].leftEdge := 210;
Rahmen [8].xy := ADR (Ecken [8, 1]);
Rahmen [8].nextBorder := ADR (Rahmen [6]);

(* Rahmen um Ausgleichsgerade berechnen *)
Ecken [9, 1] :=  -1; Ecken [9,  2] := -1;
Ecken [9, 3] := 270; Ecken [9,  4] := -1;
Ecken [9, 5] := 270; Ecken [9,  6] := 10;
Ecken [9, 7] :=  -1; Ecken [9,  8] := 10;
Ecken [9, 9] :=  -1; Ecken [9, 10] := -1;

Rahmen [9] := Rahmen [7];
Rahmen [9].xy := ADR (Ecken [9, 1]);

(* Rahmen um Gerade zeichnen *)
Ecken [10,  1] :=  -1; Ecken [10,  2] := -1;
Ecken [10,  3] := 160; Ecken [10,  4] := -1;
Ecken [10,  5] := 160; Ecken [10,  6] := 10;
Ecken [10,  7] :=  -1; Ecken [10,  8] := 10;
Ecken [10,  9] :=  -1; Ecken [10, 10] := -1;

Rahmen [10] := Rahmen [9];
Rahmen [10].xy := ADR (Ecken [10, 1]);

(* Rahmen um Laden, Speichern, E N D E *)
Ecken [11, 1] :=  -1; Ecken [11,  2] := -1;
Ecken [11, 3] := 100; Ecken [11,  4] := -1;
Ecken [11, 5] := 100; Ecken [11,  6] := 10;
Ecken [11, 7] :=  -1; Ecken [11,  8] := 10;
Ecken [11, 9] :=  -1; Ecken [11, 10] := -1;

Rahmen [11] := Rahmen [10];
Rahmen [11].xy := ADR (Ecken [11, 1]);

(* Rahmen um bekannt, nicht bekannt *)
Ecken [12, 1] := -1; Ecken [12,  2] := -1;
Ecken [12, 3] := 80; Ecken [12,  4] := -1;
Ecken [12, 5] := 80; Ecken [12,  6] := 10;
Ecken [12, 7] := -1; Ecken [12,  8] := 10;
Ecken [12, 9] := -1; Ecken [12, 10] := -1;

Rahmen [12] := Rahmen [11];
Rahmen [12].xy := ADR (Ecken [12, 1]);

(* nicht bekannt *)
WITH Box [23] DO
   nextGadget := NIL;
   leftEdge := 548;
   topEdge := 80;
   width := 80;
   height := 10;
   flags := GadgetFlagSet {gadgDisabled};
   activation := ActivationFlagSet {relVerify, toggleSelect};
   gadgetType := boolGadget;
   gadgetRender := ADR (Rahmen [12]);
   selectRender := NIL;
   gadgetText := ADR (ILeer [35]);
   mutualExclude := LONGSET {};
   specialInfo := NIL;
   gadgetID := 23;
   userData := NIL;
END (* WITH Box [23] *);

(* bekannt *)
Box [22] := Box [23];
Box [22].nextGadget := ADR (Box [23]);
Box [22].leftEdge := 458;
Box [22].gadgetText := ADR (ILeer [33]);
Box [22].gadgetID := 22;

(* Wert für Y (X=0) *)
Box [21] := Box [22];

WITH Box [21] DO
   nextGadget := ADR (Box [22]);
   leftEdge := 294;
   width := 150;
   height := 9;
   activation := ActivationFlagSet {relVerify, stringRight};
   gadgetRender := ADR (Rahmen [5]);
   gadgetType := strGadget;
   gadgetText := NIL;
   specialInfo := ADR (SInfo [5]);
   gadgetID := 21;
END (* WITH Box [21] *);

(* E N D E *)
Box [20] := Box [22];
Box [20].nextGadget := ADR (Box [21]);
Box [20].leftEdge := 510;
Box [20].topEdge := 170;
Box [20].width := 100;
Box [20].activation := ActivationFlagSet {relVerify};
Box [20].gadgetRender := ADR (Rahmen [11]);
Box [20].gadgetText := ADR (ILeer [19]);
Box [20].gadgetID := 20;

(* Speichern *)
Box [19] := Box [20];
Box [19].nextGadget := ADR (Box [20]);
Box [19].leftEdge := 365;
Box [19].gadgetText := ADR (ILeer [17]);
Box [19].gadgetID := 19;

(* Laden *)
Box [18] := Box [19];
Box [18].nextGadget := ADR (Box [19]);
Box [18].leftEdge := 221;
Box [18].gadgetText := ADR (ILeer [15]);
Box [18].gadgetID := 18;

(* DRUCKEN *)
Box [17] := Box [18];
Box [17].nextGadget := ADR (Box [18]);
Box [17].leftEdge := 45;
Box [17].width := 90;
Box [17].gadgetRender := ADR (Rahmen [3]);
Box [17].gadgetText := ADR (ILeer [13]);
Box [17].gadgetID := 17;

(* Seitenvorschub *)
Box [16] := Box [17];
Box [16].nextGadget := ADR (Box [17]);
Box [16].topEdge := 140;
Box [16].leftEdge := 13;
Box [16].width := 160;
Box [16].activation := ActivationFlagSet {relVerify, toggleSelect};
Box [16].gadgetRender := ADR (Rahmen [2]);
Box [16].gadgetText := ADR (ILeer [11]);
Box [16].gadgetID := 16;

(* Ausgleichsgerade *)
Box [15] := Box [16];
Box [15].nextGadget := ADR (Box [16]);
Box [15].topEdge := 120;
Box [15].gadgetText := ADR (ILeer [9]);
Box [15].gadgetID := 15;

(* Seitenvorschub *)
Box [14] := Box [15];
Box [14].nextGadget := ADR (Box [15]);
Box [14].topEdge := 100;
Box [14].gadgetText := ADR (ILeer [7]);
Box [14].gadgetID := 14;

(* Daten der Gerade *)
Box [13] := Box [14];
Box [13].nextGadget := ADR (Box [14]);
Box [13].topEdge := 80;
Box [13].gadgetText := ADR (ILeer [5]);
Box [13].gadgetID := 13;

(* Seitenvorschub *)
Box [12] := Box [13];
Box [12].nextGadget := ADR (Box [13]);
Box [12].topEdge := 60;
Box [12].gadgetText := ADR (ILeer [3]);
Box [12].gadgetID := 12;

(* Wertepaare *)
Box [11] := Box [12];
Box [11].nextGadget := ADR (Box [12]);
Box [11].topEdge := 40;
Box [11].gadgetText := ADR (ILeer [1]);
Box [11].gadgetID := 11;

(* Gerade zeichnen *)
Box [10] := Box [17];
Box [10].nextGadget := ADR (Box [11]);
Box [10].topEdge := 140;
Box [10].leftEdge := 221;
Box [10].width := 160;
Box [10].gadgetRender := ADR (Rahmen [10]);
Box [10].gadgetText := ADR (ILeer [21]);
Box [10].gadgetID := 10;

(* Ausgleichsgerade berechnen *)
Box [9] := Box [10];
Box [9].nextGadget := ADR (Box [10]);
Box [9].topEdge := 120;
Box [9].width := 270;
Box [9].gadgetRender := ADR (Rahmen [9]);
Box [9].gadgetText := ADR (ILeer [23]);
Box [9].gadgetID := 9;

(* Wert Y: *)
Box [8] := Box [21];
Box [8].nextGadget := ADR (Box [9]);
Box [8].topEdge := 60;
Box [8].leftEdge := 435;
Box [8].width := 150;
Box [8].gadgetRender := ADR (Rahmen [5]);
Box [8].specialInfo := ADR (SInfo [3]);
Box [8].gadgetID := 8;

(* Wert X: *)
Box [7] := Box [8];
Box [7].nextGadget := ADR (Box [8]);
Box [7].leftEdge := 245;
Box [7].specialInfo := ADR (SInfo [4]);
Box [7].gadgetID := 7;

(* 10- *)
Box [6] := Box [9];
Box [6].nextGadget := ADR (Box [7]);
Box [6].leftEdge := 590;
Box [6].topEdge := 40;
Box [6].width := 30;
Box [6].gadgetRender := ADR (Rahmen [7]);
Box [6].gadgetText := ADR (ILeer [25]);
Box [6].gadgetID := 6;

(* 10+ *)
Box [5] := Box [6];
Box [5].nextGadget := ADR (Box [6]);
Box [5].leftEdge := 540;
Box [5].gadgetText := ADR (ILeer [27]);
Box [5].gadgetID := 5;

(* - *)
Box [4] := Box [5];
Box [4].nextGadget := ADR (Box [5]);
Box [4].leftEdge := 490;
Box [4].gadgetText := ADR (ILeer [29]);
Box [4].gadgetID := 4;

(* + *)
Box [3] := Box [4];
Box [3].nextGadget := ADR (Box [4]);
Box [3].leftEdge := 440;
Box [3].gadgetText := ADR (ILeer [31]);
Box [3].gadgetID := 3;

(* Wert von Paar Nr. *)
Box [2] := Box [7];

WITH Box [2] DO
   nextGadget := ADR (Box [3]);
   leftEdge := 327;
   topEdge := 40;
   width := 60;
   activation := activation + ActivationFlagSet {longint};
   gadgetRender := ADR (Rahmen [4]);
   specialInfo := ADR (SInfo [2]);
   gadgetID := 2;
END (* WITH Box [2] *);

(* Wert von Anzahl *)
Box [1] := Box [2];
Box [1].nextGadget := ADR (Box [2]);
Box [1].topEdge := 20;
Box [1].leftEdge := 400;
Box [1].specialInfo := ADR (SInfo [1]);
Box [1].gadgetID := 1;

(* Screen öffnen *)
WITH NBildschirm DO
   leftEdge := 0;
   topEdge := 0;
   width := 640;
   height := 200;
   depth := 3;
   detailPen := 0;
   blockPen := 1;
   viewModes := ViewModeSet {hires};
   type := customScreen;
   font := ADR (Attr);
   defaultTitle := ADR (Screentitel);
   gadgets := NIL;
   customBitMap := NIL;
END (* WITH NBildschirm *);

Bildschirm := OpenScreen (NBildschirm);

Assert (Bildschirm # NIL, ADR ("konnte Screen nicht öffnen!"));

(* Farben *)
SetRGB4 (ADR (Bildschirm^.viewPort), Blaugrau ,  4,  4,  5);
SetRGB4 (ADR (Bildschirm^.viewPort), Hellblau ,  9, 13, 15);
SetRGB4 (ADR (Bildschirm^.viewPort), Schwarz  ,  0,  0,  0);
SetRGB4 (ADR (Bildschirm^.viewPort), Dunkelrot,  5,  0,  0);
SetRGB4 (ADR (Bildschirm^.viewPort), Weissrot , 15, 14, 14);
SetRGB4 (ADR (Bildschirm^.viewPort), Weiss    , 15, 15, 15);
SetRGB4 (ADR (Bildschirm^.viewPort), Rot      , 15,  0,  0);
SetRGB4 (ADR (Bildschirm^.viewPort), Gelb     , 15, 15,  0);

(* Fenster öffnen *)
WITH NFenster DO
   leftEdge := 0;
   topEdge := 12;
   width := 640;
   height := 188;
   detailPen := Blaugrau;
   blockPen := Hellblau;
   idcmpFlags := IDCMPFlagSet {gadgetUp};
   flags := WindowFlagSet {windowDepth, activate};
   firstGadget := ADR (Box [1]);
   checkMark := NIL;
   title := ADR (Fenstertitel);
   screen := Bildschirm;
   bitMap := NIL;
   minWidth := width;
   minHeight := height;
   maxWidth := width;
   maxHeight := height;
   type := customScreen;
END (* WITH NFenster *);

BFenster := OpenWindow (NFenster);

Assert (BFenster # NIL, ADR ("konnte Fenster nicht öffnen"));

DrawBorder (BFenster^.rPort, ADR (Rahmen [8]), 0, 0);

PrintIText (BFenster^.rPort, ADR (IText [1]), 0, 0);

GadgetAn (ADR (Box [ 1]), BFenster, NIL);
GadgetAn (ADR (Box [20]), BFenster, NIL);
Error := ActivateGadget (ADR (Box [1]), BFenster, NIL);

REPEAT
   WaitPort (BFenster^.userPort);
   Nachricht := GetMsg (BFenster^.userPort);

   IF Nachricht # NIL THEN
      Flags := Nachricht^.class;
      GewGad := Nachricht^.iAddress;
      ReplyMsg (Nachricht);

      (* na, welches ist es denn? *)
      (* Die folgende CASE-Anweisung war ursprünglich recht klein und *)
      (* ist erst im Laufe der Zeit immer größer geworden. Ich        *)
      (* schreibe sie jetzt nicht mehr um!                            *)
      CASE GewGad^.gadgetID OF
         | 1: (* Anzahl der Paare *)
              Error := FALSE;

              IF NOT ErstesMal THEN
                 ReqText [1].iText := ADR ("Sind Sie sicher, daß Sie");
                 ReqText [2].iText := ADR ("von vorn beginnen wollen?");
                 ReqText [3].iText := ADR (Ja);
                 ReqText [4].iText := ADR (Nein);

                 (* alles von vorn? *)
                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       2                 );

                 IF Error THEN
                    IF Gerade.Adresse # NIL THEN
                       Deallocate (Gerade.Adresse);
                    END (* IF Gerade.Adresse *);

                    Gerade.Adresse := NIL;
                    InitGerade (Gerade);

                    IF DFenster # NIL THEN
                       CloseWindow (DFenster);
                       DFenster := NIL;
                    END (* IF DFenster *);

                    IF GFenster # NIL THEN
                       CloseWindow (GFenster);
                       GFenster := NIL;
                    END (* IF GFenster *);

                    FOR i := 11 TO 16 DO
                       EXCL (Box [i].flags, selected);
                    END (* FOR i *);

                    RefreshGList (ADR (Box [11]), BFenster, NIL, 6);

                    FOR i := 2 TO 23 DO
                       IF (NOT (gadgDisabled IN Box [i].flags)) AND
                          (i # 20) THEN
                          GadgetAus (ADR (Box [i]), BFenster, NIL);
                       END (* IF NOT *);
                    END (* FOR i *);

                    (* X und Y leeren *)
                    UXZahl := "";
                    UYZahl := "";
                    XZahl := UXZahl;
                    YZahl := UYZahl;

                    SInfo [3].numChars := 0;
                    SInfo [4].numChars := 0;

                    RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);

                 ELSE (* IF Error *)
                    (* Inhalt des Gadgets wiederherstellen... *)
                    ValToStr (Gerade.N, FALSE, SMaxPaare, 10,
                              AZiffern (Gerade.N), " ", Error);
                    USMaxPaare := SMaxPaare;

                    WITH SInfo [1] DO
                       bufferPos := 0;
                       dispPos := 0;
                       numChars := AZiffern (Gerade.N);
                       longInt := Gerade.N;
                    END (* WITH SInfo [1] *);
                    RefreshGadList (ADR (Box [1]), BFenster, NIL, 1);
                 END (* IF Error *);
              END (* IF NOT ErstesMal *);

              IF ErstesMal OR Error THEN
                 IF SInfo [1].longInt < 3 THEN
                    (* leider keine Ausgleichsgerade berechenbar *)
                    ReqText [1].iText :=
                    ADR ("Man braucht mindestens 2 Punkte für eine Gerade");
                    ReqText [2].iText :=
                       ADR ("und mindestens 3 für eine Ausgleichsrechnung!");
                    ReqText [3].iText := ADR (Ok);
                    Error := MakeRequest (ADR (ReqText [3]),
                                          ADR (ReqText [4]),
                                          ADR (ReqText [1]),
                                          BFenster,
                                          1                 );

                 ELSE (* IF SInfo *);
                    WITH Gerade DO
                       N := CARDINAL (SInfo [1].longInt);
                       Ziffern := CARDINAL (AZiffern (SInfo [1].longInt));
                       Groesse := 2 * N * SIZE (Wert^);

                       (* Speicher anfordern *)
                       Assert (Largest (FALSE) >= Groesse,
                               ADR (Speichermangel));

                       Allocate (Adresse, Groesse);
                       Assert (Adresse # NIL, ADR (Speichermangel));
                       Wert := Adresse;

                       M := 1;
                       SPaarNr := "1";
                       USPaarNr := SPaarNr;
                       RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);
                    END (* WITH Gerade *);

                    GadgetAn (ADR (Box [ 2]), BFenster, NIL);
                    GadgetAn (ADR (Box [ 7]), BFenster, NIL);
                    GadgetAn (ADR (Box [ 8]), BFenster, NIL);

                    SPaarNr := "1";
                    SInfo [2].longInt := 1;
                    RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

                    Error := ActivateGadget (ADR (Box [7]), BFenster, NIL);
                 END (* IF SInfo *);

                 ErstesMal := FALSE;
              END (* IF ErstesMal OR Error *);

         | 2: (* Paar Nr. *)
              (* Paar Nr. aktualisieren *)
              IF (SInfo [2].longInt < 1) OR
              (SInfo [2].longInt > LONGINT (Gerade.M)) THEN
                 ReqText [1].iText := ADR ("Ein Element mit dieser");
                 ReqText [2].iText := ADR ("Nummer gibt es nicht!");
                 ReqText [3].iText := ADR (Ok);
                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );

                 Error := FALSE;
                 StrToVal (USPaarNr, SInfo [2].longInt, Error, 10,
                           Error);
                 SPaarNr := USPaarNr;

                 WITH SInfo [2] DO
                    bufferPos := 0;
                    dispPos := 0;
                    numChars := AZiffern (longInt);
                 END (* WITH SInfo [2] *);

                 RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

              ELSE (* Nummer ok *)
                 USPaarNr := SPaarNr;

                 AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                                BFenster, SInfo [2].longInt, Gerade.M);

                 (* X: aktualisieren *)
                 Wert := Gerade.Adresse;
                 INC (Wert, (SInfo [2].longInt - 1) * 2 *
                             SIZE (Wert^));
                 RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^), Error);
                 UXZahl := XZahl;
                 SInfo [4].bufferPos := 0;
                 SInfo [4].dispPos := 0;
                 SInfo [4].numChars := 15;

                 (* Y: aktualisieren *)
                 INC (Wert, SIZE (Wert^));
                 RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^), Error);
                 UYZahl := YZahl;
                 SInfo [3].bufferPos := 0;
                 SInfo [3].dispPos := 0;
                 SInfo [3].numChars := 15;

                 RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);
              END (* IF SInfo [2].longInt *);

         | 3: (* + *)
              (* Paar Nr. aktualisieren *)
              INC (SInfo [2].longInt);
              ValToStr (SInfo [2].longInt, FALSE, SPaarNr, 10,
                        AZiffern (SInfo [2].longInt), "0", Error);
              USPaarNr := SPaarNr;

              WITH SInfo [2] DO
                 bufferPos := 0;
                 dispPos := 0;
                 numChars := AZiffern (longInt);
              END (* WITH SInfo [2] *);

              RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

              AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                             BFenster, SInfo [2].longInt, Gerade.M);

              (* X: aktualisieren *)
              Wert := Gerade.Adresse;
              INC (Wert, (SInfo [2].longInt - 1) * 2 * SIZE (Wert^));
              RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^), Error);
              UXZahl := XZahl;
              SInfo [4].bufferPos := 0;
              SInfo [4].dispPos := 0;
              SInfo [4].numChars := 15;

              (* Y: aktualisieren *)
              INC (Wert, SIZE (Wert^));
              RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^), Error);
              UYZahl := YZahl;
              SInfo [3].bufferPos := 0;
              SInfo [3].dispPos := 0;
              SInfo [3].numChars := 15;

              RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);

         | 4: (* - *)
              (* Paar Nr. aktualisieren *)
              DEC (SInfo [2].longInt);
              ValToStr (SInfo [2].longInt, FALSE, SPaarNr, 10,
                        AZiffern (SInfo [2].longInt), "0", Error);
              USPaarNr := SPaarNr;

              WITH SInfo [2] DO
                 bufferPos := 0;
                 dispPos := 0;
                 numChars := AZiffern (longInt);
              END (* WITH SInfo [2] *);

              RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

              AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                             BFenster, SInfo [2].longInt, Gerade.M);

              (* X: aktualisieren *)
              Wert := Gerade.Adresse;
              INC (Wert, ((SInfo [2].longInt - 1) * 2 * SIZE (Wert^)));
              RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^), Error);
              UXZahl := XZahl;
              SInfo [4].bufferPos := 0;
              SInfo [4].dispPos := 0;
              SInfo [4].numChars := 15;

              (* Y: aktualisieren *)
              INC (Wert, SIZE (Wert^));
              RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^), Error);
              UYZahl := YZahl;
              SInfo [3].bufferPos := 0;
              SInfo [3].dispPos := 0;
              SInfo [3].numChars := 15;

              RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);

         | 5: (* 10+ *)
              (* Paar Nr. aktualisieren *)
              INC (SInfo [2].longInt, 10);
              ValToStr (SInfo [2].longInt, FALSE, SPaarNr, 10,
                        AZiffern (SInfo [2].longInt), " ", Error);
              USPaarNr := SPaarNr;

              WITH SInfo [2] DO
                 bufferPos := 0;
                 dispPos := 0;
                 numChars := AZiffern (longInt);
              END (* WITH SInfo [2] *);

              RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

              AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                             BFenster, SInfo [2].longInt, Gerade.M);

              (* X: aktualisieren *)
              Wert := Gerade.Adresse;
              INC (Wert, (SInfo [2].longInt - 1) * 2 * SIZE (Wert^));
              RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^), Error);
              UXZahl := XZahl;
              SInfo [4].bufferPos := 0;
              SInfo [4].dispPos := 0;
              SInfo [4].numChars := 15;

              (* Y: aktualisieren *)
              INC (Wert, SIZE (Wert^));
              RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^), Error);
              UYZahl := YZahl;
              SInfo [3].bufferPos := 0;
              SInfo [3].dispPos := 0;
              SInfo [3].numChars := 15;

              RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);

         | 6: (* 10- *)
              (* Paar Nr. aktualisieren *)
              DEC (SInfo [2].longInt, 10);
              ValToStr (SInfo [2].longInt, FALSE, SPaarNr, 10,
                        AZiffern (SInfo [2].longInt), "0", Error);
              USPaarNr := SPaarNr;

              WITH SInfo [2] DO
                 bufferPos := 0;
                 dispPos := 0;
                 numChars := AZiffern (longInt);
              END (* WITH SInfo [2] *);

              RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

              AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                             BFenster, SInfo [2].longInt, Gerade.M);

              (* X: aktualisieren *)
              Wert := Gerade.Adresse;
              INC (Wert, (SInfo [2].longInt - 1) * 2 * SIZE (Wert^));
              RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^), Error);
              UXZahl := XZahl;
              SInfo [4].bufferPos := 0;
              SInfo [4].dispPos := 0;
              SInfo [4].numChars := 15;

              (* Y: aktualisieren *)
              INC (Wert, SIZE (Wert^));
              RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^), Error);
              UYZahl := YZahl;
              SInfo [3].bufferPos := 0;
              SInfo [3].dispPos := 0;
              SInfo [3].numChars := 15;

              RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);

         | 7: (* X-Gadget *)
              Wert := Gerade.Adresse;
              INC (Wert, (SInfo [2].longInt - 1) * 2 * SIZE (Wert^));

              StrToReal (XZahl, Wert^, Error);

              IF Error THEN
                 (* etwas schiefgelaufen *)
                 ReqText [1].iText := ADR ("Die Zahl bei X: ist");
                 ReqText [2].iText := ADR ("nicht reell!");
                 ReqText [3].iText := ADR (Ok);

                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );

                 XZahl := UXZahl;
                 RefreshGadList (ADR (Box [7]), BFenster, NIL, 1);
              ELSE (* IF Error *)
                 (* Y-Gadget aktivieren *)
                 Error := ActivateGadget (ADR (Box [8]), BFenster, NIL);
              END (* IF Error *);

         | 8: (* Y-Gadget *)
              Wert := Gerade.Adresse;
              INC (Wert, (SInfo [2].longInt - 1) * 2 * SIZE (Wert^) +
                         SIZE (Wert^));

              StrToReal (YZahl, Wert^, Error);

              IF Error THEN
                 (* etwas schiefgelaufen *)
                 ReqText [1].iText := ADR ("Die Zahl bei Y: ist");
                 ReqText [2].iText := ADR ("nicht reell!");
                 ReqText [3].iText := ADR (Ok);

                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );

                 YZahl := UYZahl;
                 Error := ActivateGadget (ADR (Box [8]), BFenster, NIL);
              ELSE (* IF Error *)
                 IF CARDINAL (SInfo [2].longInt) < Gerade.N THEN
                    (* PaarNr um eins erhöhen *)
                    INC (SInfo [2].longInt);
                    ValToStr (SInfo [2].longInt, FALSE, SPaarNr, 10,
                              AZiffern (SInfo [2].longInt), "0", Error);
                    USPaarNr := SPaarNr;

                    WITH SInfo [2] DO
                       bufferPos := 0;
                       dispPos := 0;
                       numChars := AZiffern (longInt);
                    END (* WITH SInfo [2] *);

                    RefreshGadList (ADR (Box [2]), BFenster, NIL, 1);

                    IF CARDINAL (SInfo [2].longInt) > Gerade.M THEN
                       (* das folgende Pärchen ist neu *)
                       UXZahl := "";
                       UYZahl := "";
                       XZahl := UXZahl;
                       YZahl := UYZahl;

                       SInfo [3].numChars := 0;
                       SInfo [4].numChars := 0;

                       Gerade.M := CARDINAL (SInfo [2].longInt);

                       INC (Wert, SIZE (Wert^));
                       Wert^ := 0.0;
                       INC (Wert, SIZE (Wert^));
                       Wert^ := 0.0;

                    ELSE (* IF CARDINAL *)
                       (* das folgende Pärchen wurde schon getippt *)
                       INC (Wert, SIZE (Wert^));
                       RealToStr (Wert^, XZahl, 15, 13, Exponent (Wert^),
                                  Error);
                       INC (Wert, SIZE (Wert^));
                       RealToStr (Wert^, YZahl, 15, 13, Exponent (Wert^),
                                  Error);

                       UXZahl := XZahl;
                       UYZahl := YZahl;

                       SInfo [3].numChars := 15;
                       SInfo [4].numChars := 15;
                    END (* IF CARDINAL *);

                    AktualisiereG (Box [3], Box [4], Box [5], Box [6],
                                   BFenster, SInfo [2].longInt,
                                   Gerade.M);

                    SInfo [3].bufferPos := 0;
                    SInfo [3].dispPos := 0;

                    SInfo [4].bufferPos := 0;
                    SInfo [4].dispPos := 0;

                    RefreshGadList (ADR (Box [7]), BFenster, NIL, 2);
                    Error := ActivateGadget (ADR (Box [7]), BFenster, NIL);
                 ELSE (* IF Gerade.M *)
                    (* alle Werte eingegeben! *)
                    GadgetAn (ADR (Box [ 9]), BFenster, NIL);
                    GadgetAn (ADR (Box [11]), BFenster, NIL);
                    GadgetAn (ADR (Box [12]), BFenster, NIL);
                    GadgetAn (ADR (Box [17]), BFenster, NIL);
                    GadgetAn (ADR (Box [22]), BFenster, NIL);
                    GadgetAn (ADR (Box [23]), BFenster, NIL);

                    Box [11].flags := Box [11].flags +
                                      GadgetFlagSet {selected};
                    RefreshGadList (ADR (Box [11]), BFenster, NIL, 1);

                    Box [23].flags := Box [23].flags +
                                      GadgetFlagSet {selected};
                    RefreshGadList (ADR (Box [23]), BFenster, NIL, 1);
                 END (* IF Gerade.M *);
              END (* IF Error *);

         | 9: (* Ausgleichsgerade berechnen *)
              ReqText [1].iText := ADR ("Sind Sie sicher, daß Sie die");
              ReqText [2].iText := ADR ("Eingabe abgeschlossen haben?");
              ReqText [3].iText := ADR (Ja);
              ReqText [4].iText := ADR (Nein);

              IF MakeRequest (ADR (ReqText [3]),
                              ADR (ReqText [4]),
                              ADR (ReqText [1]),
                              BFenster,
                              2                 ) THEN
                 GadgetAus (ADR (Box [ 2]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 3]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 4]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 5]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 6]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 7]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 8]), BFenster, NIL);
                 GadgetAus (ADR (Box [ 9]), BFenster, NIL);
                 GadgetAus (ADR (Box [21]), BFenster, NIL);
                 GadgetAus (ADR (Box [22]), BFenster, NIL);
                 GadgetAus (ADR (Box [23]), BFenster, NIL);

                 WITH Gerade.Daten DO
                    (* Mittelwert aller X und Y *)
                    XM := 0.0;
                    YM := 0.0;
                    Wert := Gerade.Adresse;

                    FOR i := 1 TO Gerade.N DO
                       XM := XM + Wert^;

                       INC (Wert, SIZE (Wert^));

                       YM := YM + Wert^;

                       IF i # Gerade.N THEN
                          INC (Wert, SIZE (Wert^));

                       ELSE (* IF i *)
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* FOR i *);

                    XM := XM / LONGREAL (Gerade.N);
                    YM := YM / LONGREAL (Gerade.N);

                    (* Summe (Xi - XM)² *)
                    XIQQ := 0.0;

                    FOR i := 1 TO Gerade.N DO
                       Hilfe := Wert^ - XM;
                       XIQQ := XIQQ + (Hilfe * Hilfe);

                       IF i # Gerade.N THEN
                          INC (Wert, 2 * SIZE (Wert^));

                       ELSE
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* FOR i *);

                    (* Standardabweichung aller X und Y *)
                    XS := sqrt (XIQQ / LONGREAL (Gerade.N - 1));
                    YS := 0.0;

                    INC (Wert, SIZE (Wert^));

                    FOR i := 1 TO Gerade.N DO
                       Hilfe := Wert^ - YM;
                       YS := YS + (Hilfe * Hilfe);

                       IF i # Gerade.N THEN
                          INC (Wert, 2 * SIZE (Wert^));

                       ELSE (* IF i *)
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* For i *);

                    YS := sqrt (YS / LONGREAL (Gerade.N - 1));

                    (* Parameter der Ausgleichsgeraden y = Ax + B *)
                    IF Gerade.BBekannt THEN
                       A := 0.0;

                       Hilfe2 := 0.0;

                       FOR i := 1 TO Gerade.N DO
                          Hilfe := Wert^;
                          Hilfe2 := Hilfe2 + Wert^;
                          Hilfe3 := Hilfe3 + (Wert^ * Wert^);
                          INC (Wert, SIZE (Wert^));

                          A := A + (Hilfe * Wert^);

                          IF i # Gerade.N THEN
                             INC (Wert, SIZE (Wert^));

                          ELSE (* IF i *)
                             Wert := Gerade.Adresse;
                          END (* IF i *);
                       END (* FOR i *);

                       A := (A - (B * Hilfe2)) / Hilfe3;

                    ELSE (* IF Gerade.BBekannt *)
                       A := 0.0;
                       B := 0.0;

                       FOR i := 1 TO Gerade.N DO
                          Hilfe := Wert^;
                          INC (Wert, SIZE (Wert^));

                          A := A + ((XM - Hilfe) * (YM - Wert^));

                          IF i # Gerade.N THEN
                             INC (Wert, SIZE (Wert^));

                          ELSE (* IF i *)
                             Wert := Gerade.Adresse;
                          END (* IF i *);
                       END (* FOR i *);

                       A := A / XIQQ;

                       B := YM - (A * XM);
                    END (* IF Gerade.BBekannt *);

                    (* St. der Parameter und der A.-Geraden *)
                    GS := 0.0;
                    AS := 0.0;
                    BS := 0.0;

                    FOR i := 1 TO Gerade.N DO
                       Hilfe := (A * Wert^) + B;

                       INC (Wert, SIZE (Wert^));

                       GS := GS + ((Wert^ - Hilfe) * (Wert^ - Hilfe));

                       IF i # Gerade.N THEN
                          INC (Wert, SIZE (Wert^));

                       ELSE
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* FOR i *);

                    GS := sqrt (GS / LONGREAL (Gerade.N - 2));

                    AS := sqrt (GS * GS / XIQQ);

                    IF Gerade.BBekannt THEN
                       BS := 0.0; (* ad definitionam *)

                    ELSE (* IF Gerade.BBekannt *)
                       BS := sqrt (((XM * XM / XIQQ) +
                               (1.0 / LONGREAL (Gerade.N))) * GS * GS);
                    END (* IF Gerade.BBekannt *);

                    (* Korrelationskoeffizient R *)
                    R := 0.0;

                    FOR i := 1 TO Gerade.N DO
                       Hilfe := Wert^ - XM;

                       INC (Wert, SIZE (Wert^));

                       R := R + (Hilfe * (Wert^ - YM));

                       IF i # Gerade.N THEN
                          INC (Wert, SIZE (Wert^));

                       ELSE
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* FOR i *);

                    R := R / (LONGREAL (Gerade.N - 1) * XS * YS);
                 END (* WITH Gerade.Daten *);

                 (* Gadgets aktivieren *)
                 GadgetAn (ADR (Box [13]), BFenster, NIL);
                 GadgetAn (ADR (Box [14]), BFenster, NIL);

                 Box [13].flags := Box [13].flags + GadgetFlagSet {selected};
                 Box [14].flags := Box [14].flags + GadgetFlagSet {selected};
                 RefreshGadList (ADR (Box [13]), BFenster, NIL, 2);
              END (* IF MakeRequest *);

              (* Daten der Gerade in ein Fenster schreiben *)

              WITH NFenster DO
                 leftEdge := 0;
                 topEdge := 8;
                 width := 640;
                 height := 192;
                 detailPen := Blaugrau;
                 blockPen := Hellblau;
                 idcmpFlags := IDCMPFlagSet {};
                 flags := WindowFlagSet {windowDepth, activate};
                 firstGadget := NIL;
                 checkMark := NIL;
                 title := ADR (Fenstertitel2);
                 screen := Bildschirm;
                 bitMap := NIL;
                 minWidth := width;
                 minHeight := height;
                 maxWidth := width;
                 maxHeight := height;
                 type := customScreen;
              END (* WITH NFenster *);

              DFenster := OpenWindow (NFenster);

              (* schreibe: Anzahl der Wertepaare, Parameter A und B, *)
              (* Standardabweichung von A, B und der Geraden sowie   *)
              (* den linearen Korrelationskoeffizienten              *)

              WITH Gerade DO
                 TextZeile := " Ausgleichsgerade Y = AX + B:";
                 PrintText (DFenster, TextZeile, 10, 21);

                 TextZeile := " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
                 PrintText (DFenster, TextZeile, 10, 31);

                 TextZeile := " Anzahl der Wertepaare           : ";
                 ValToStr (N, FALSE, HilfsText, 10, Laenge (N), " ",
                    Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 42);

                 TextZeile := " Mittelwert der X                : ";
                 RealToStr (Daten.XM, HilfsText, 15, 13,
                    Exponent (Daten.XM), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 53);

                 TextZeile := " Mittelwert der Y                : ";
                 RealToStr (Daten.YM, HilfsText, 15, 13,
                    Exponent (Daten.YM), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 64);

                 TextZeile := " Standardabweichung der X        : ";
                 RealToStr (Daten.XS, HilfsText, 15, 13,
                    Exponent (Daten.XS), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 75);

                 TextZeile := " Standardabweichung der Y        : ";
                 RealToStr (Daten.YS, HilfsText, 15, 13,
                    Exponent (Daten.YS), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 86);

                 TextZeile := " Parameter A                     : ";
                 RealToStr (Daten.A, HilfsText, 15, 13,
                    Exponent (Daten.A), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 97);

                 IF BBekannt THEN
                    TextZeile := " (vorher bekannter) Parameter B  : ";

                 ELSE (* IF BBekannt *)
                    TextZeile := " Parameter B                     : ";
                 END (* IF BBekannt *);

                 RealToStr (Daten.B, HilfsText, 15, 13,
                    Exponent (Daten.B), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 108);

                 TextZeile := " Standardabweichung von A        : ";
                 RealToStr (Daten.AS, HilfsText, 15, 13,
                    Exponent (Daten.AS), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 119);

                 TextZeile := " Standardabweichung von B        : ";
                 RealToStr (Daten.BS, HilfsText, 15, 13,
                    Exponent (Daten.BS), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 130);

                 TextZeile := " Standardabweichung der Geraden  : ";
                 RealToStr (Daten.GS, HilfsText, 15, 13,
                    Exponent (Daten.GS), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 142);

                 TextZeile := " linearer Korrelationskoeffizient: ";
                 RealToStr (Daten.R, HilfsText,15, 13,
                    Exponent (Daten.R), Error);
                 Concat (TextZeile, HilfsText);
                 PrintText (DFenster, TextZeile, 10, 153);
              END (* WITH Gerade *);

              GadgetAn (ADR (Box [10]), BFenster, NIL);

         |10: (* Gerade zeichnen *);

              IF GFenster # NIL THEN
                 CloseWindow (GFenster);
                 GFenster := NIL;
              END (* IF GFenster *);

              (* Grafik-Fenster öffnen *)
              WITH NFenster DO
                 leftEdge := 0;
                 topEdge := 4;
                 width := 640;
                 height := 196;
                 detailPen := Blaugrau;
                 blockPen := Hellblau;
                 idcmpFlags := IDCMPFlagSet {gadgetUp}; (* für die Requester *)
                 flags := WindowFlagSet {windowDepth, activate};
                 firstGadget := NIL;
                 checkMark := NIL;
                 title := ADR (Fenstertitel3);
                 screen := Bildschirm;
                 bitMap := NIL;
                 minWidth := width;
                 minHeight := height;
                 maxWidth := width;
                 maxHeight := height;
                 type := customScreen;
              END (* WITH NFenster *);

              GFenster := OpenWindow (NFenster);

              IF GFenster = NIL THEN
                 ReqText [1].iText := ADR ("Ich konnte das");
                 ReqText [2].iText := ADR ("Grafikfenster nicht öffnen!");
                 ReqText [3].iText := ADR (Ok);
                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );

              ELSE (* GFenster offen *)
                 (* größten und kleinsten X- und Y-Wert finden *)
                 Wert := Gerade.Adresse;
                 XMin := Wert^;
                 XMax := Wert^;

                 INC (Wert, SIZE (Wert^));
                 YMin := Wert^;
                 YMax := Wert^;

                 FOR i := 2 TO Gerade.N DO
                    INC (Wert, SIZE (Wert^));

                    IF Wert^ < XMin THEN
                       XMin := Wert^;

                    ELSE
                       IF Wert^ > XMax THEN
                          XMax := Wert^;
                       END (* IF Wert^ *);
                    END (* IF Wert^ *);

                    INC (Wert, SIZE (Wert^));

                    IF Wert^ < YMin THEN
                       YMin := Wert^;

                    ELSE
                       IF Wert^ > YMax THEN
                          YMax := Wert^;
                       END (* IF Wert^ *);
                    END (* IF Wert^ *);
                 END (* FOR i *);

                 Wert := Gerade.Adresse;

                 (* Schnittpunkt der Geraden mit der Y-Achse *)

                 IF NOT ((XMin <= 0.0) AND (XMax >= 0.0) AND
                    (Gerade.Daten.B >= YMin) AND
                    (Gerade.Daten.B <= YMax)) THEN
                    (* der Punkt Y(X=0) ist noch nicht im Bild *)
                    ReqText [1].iText := ADR ("Soll der Punkt Y(X=0)");
                    ReqText [2].iText := ADR ("eingezeichnet werden?");
                    ReqText [3].iText := ADR (Ja);
                    ReqText [4].iText := ADR (Nein);

                    IF MakeRequest (ADR (ReqText [3]),
                                    ADR (ReqText [4]),
                                    ADR (ReqText [1]),
                                    GFenster,
                                    2                 ) THEN

                       (* ja, er soll *)

                       IF XMin > 0.0 THEN
                          XMin := 0.0;
                       END (* IF XMin *);

                       IF XMax < 0.0 THEN
                          XMax := 0.0;
                       END (* IF XMax *);

                       IF YMin > Gerade.Daten.B THEN
                          YMin := Gerade.Daten.B;
                       END (* IF YMin *);

                       IF YMax < Gerade.Daten.B THEN
                          YMax := Gerade.Daten.B;
                       END (* IF YMax *);
                    END (* IF MakeRequest *);
                 END (* IF NOT *);

                 (* Schnittpunkt der Geraden mit der X-Achse *)

                 MBDurchA := - Gerade.Daten.B / Gerade.Daten.A; (* = X(Y=0) *)

                 IF NOT ((YMin <= 0.0) AND (YMax >= 0.0) AND
                    (XMin <= MBDurchA) AND (XMax >= MBDurchA)) THEN
                    (* der Punkt X(Y=0) ist noch nicht im Bild *)
                    ReqText [1].iText := ADR ("Soll der Punkt X(Y=0)");
                    ReqText [2].iText := ADR ("eingezeichnet werden?");
                    ReqText [3].iText := ADR (Ja);
                    ReqText [4].iText := ADR (Nein);

                    IF MakeRequest (ADR (ReqText [3]),
                                    ADR (ReqText [4]),
                                    ADR (ReqText [1]),
                                    GFenster,
                                    2                 ) THEN

                       (* ja, er soll *)

                       IF XMin > MBDurchA THEN
                          XMin := MBDurchA;
                       END (* IF XMin *);

                       IF XMax < MBDurchA THEN
                          XMax := MBDurchA;
                       END (* IF XMax *);

                       IF YMin > 0.0 THEN
                          YMin := 0.0;
                       END (* IF YMin *);

                       IF YMax < 0.0 THEN
                          YMax := 0.0;
                       END (* IF YMax *);
                    END (* IF MakeRequest *);
                 END (* IF NOT *);

                 Breite := XMax - XMin;
                 Hoehe := YMax - YMin;

                 (* kleiner Rand *)

                 XMax := XMax + (0.05 * Breite);
                 XMin := XMin - (0.05 * Breite);

                 YMax := YMax + (0.05 * Hoehe);
                 YMin := YMin - (0.05 * Hoehe);

                 Breite := XMax - XMin;
                 Hoehe := YMax - YMin;

                 (* ein Pixel ist... *)

                 XPixelBr := Breite / LONGREAL (SpalteMax);
                 YPixelBr := Hoehe / LONGREAL (ZeileMax);

                 (* Zum Zeichnen weißer Hintergrund *)
                 SetAPen (GFenster^.rPort, Weiss);

                 RectFill (GFenster^.rPort, Spalte (XMin) - 2, Zeile (YMax) - 1,
                    Spalte (XMax) + 2, Zeile (YMin) + 1);

                 (* Achsenkreuz zeichnen: *)

                 SetAPen (GFenster^.rPort, Schwarz);

                 (* X-Achse: *)
                 IF ImRastPort (Zeile (0.0), y) THEN
                    Move (GFenster^.rPort, Spalte (XMin), Zeile (0.0));
                    Draw (GFenster^.rPort, Spalte (XMax), Zeile (0.0));

                    (* Pfeil an X-Achse *)
                    Move (GFenster^.rPort, Spalte (XMax) - 4, Zeile (0.0) - 2);
                    Draw (GFenster^.rPort, Spalte (XMax), Zeile (0.0));
                    Draw (GFenster^.rPort, Spalte (XMax) - 4, Zeile (0.0) + 2);

                    (* Buchstabe X *)
                    Schrift := "x\o";

                    WITH ISchrift DO
                       frontPen := Schwarz;
                       backPen := Weiss;
                       drawMode := jam2;
                       leftEdge := SpalteMax - 9;
                       iTextFont := NIL;
                       iText := ADR (Schrift);
                       nextText := NIL;
                    END (* WITH ISchrift *);

                    IF Zeile (0.0) > (ZeileMin + 14) THEN
                       (* obendrüber *)
                       ISchrift.topEdge := Zeile (0.0) - 11;

                    ELSE (* IF Zeile *)
                       (* untendrunter *)
                       ISchrift.topEdge := Zeile (0.0) + 3;
                    END (* IF Zeile *);

                    PrintIText (GFenster^.rPort, ADR (ISchrift), 0, 0);
                 END (* IF ImRastPort *);

                 (* Y-Achse: *)
                 IF ImRastPort (Spalte (0.0), x) THEN
                    Move (GFenster^.rPort, Spalte (0.0), Zeile (YMax));
                    Draw (GFenster^.rPort, Spalte (0.0), Zeile (YMin));

                    Move (GFenster^.rPort, Spalte (0.0) + 1, Zeile (YMax));
                    Draw (GFenster^.rPort, Spalte (0.0) + 1, Zeile (YMin));

                    (* Pfeil an Y-Achse *)
                    Move (GFenster^.rPort, Spalte (0.0) - 4, Zeile (YMax) + 2);
                    Draw (GFenster^.rPort, Spalte (0.0), Zeile (YMax));
                    Draw (GFenster^.rPort, Spalte (0.0) + 1, Zeile (YMax));
                    Draw (GFenster^.rPort, Spalte (0.0) + 5, Zeile (YMax) + 2);

                    (* Buchstabe Y *)
                    Schrift := "y\o";

                    WITH ISchrift DO
                       frontPen := Schwarz;
                       backPen := Weiss;
                       drawMode := jam2;
                       topEdge := ZeileMin;
                       iTextFont := NIL;
                       iText := ADR (Schrift);
                       nextText := NIL;
                    END (* WITH ISchrift *);

                    IF Spalte (0.0) < (SpalteMax - 17) THEN
                       (* rechts *)
                       ISchrift.leftEdge := Spalte (0.0) + 8;

                    ELSE (* IF Zeile *)
                       (* links *)
                       ISchrift.leftEdge := Spalte (0.0) - 16;
                    END (* IF Zeile *);

                    PrintIText (GFenster^.rPort, ADR (ISchrift), 0, 0);
                 END (* IF ImRastPort *);

                 (* die Punkte: *)

                 FOR i := 1 TO Gerade.N DO
                    X := Spalte (Wert^);

                    IF (i = 1) OR (i = Gerade.N) THEN
                       (* auf X-Achse *)
                       IF ImRastPort (Zeile (0.0), y) THEN
                          DrawCross (GFenster^.rPort, X, Zeile (0.0));

                          RealToStr (Wert^, Schrift, 8, 6, Exponent (Wert^), Error);

                          WITH ISchrift DO
                             frontPen := Schwarz;
                             backPen := Weiss;
                             drawMode := jam2;

                             IF Zeile (0.0) <= ZeileMax THEN
                                topEdge := Zeile (0.0) + 4;

                             ELSE
                                topEdge := Zeile (0.0) - 11;
                             END (* IF Zeile *);

                             IF (X + 36) > SpalteMax THEN
                                leftEdge := SpalteMax - 90;

                             ELSE (* IF (X *)
                                IF (X - 36) < SpalteMin THEN
                                   leftEdge := SpalteMin;

                                ELSE (* IF (X - 36) *)
                                   leftEdge := X - 36;
                                END (* IF (X - 36 *);
                             END (* IF (X *);

                             iTextFont := NIL;
                             iText := ADR (Schrift);
                             nextText := NIL;
                          END (* WITH ISchrift *);

                          PrintIText (GFenster^.rPort, ADR (ISchrift), 0, 0);
                       END (* IF ImRastPort *);
                    END (* IF (i *);

                    INC (Wert, SIZE (Wert^));

                    Y := Zeile (Wert^);

                    IF (i = 1) OR (i = Gerade.N) THEN
                       (* Y-Achse *)
                       IF ImRastPort (Spalte (0.0), x) THEN
                          DrawCross (GFenster^.rPort, Spalte (0.0), Y);

                          RealToStr (Wert^, Schrift, 8, 6, Exponent (Wert^), Error);

                          WITH ISchrift DO
                             frontPen := Schwarz;
                             backPen := Weiss;
                             drawMode := jam2;

                             IF (Y - 4) < (ZeileMin + 10) THEN
                                topEdge := ZeileMin + 10;

                             ELSE (* IF (Y - 4 *)
                                topEdge := Y - 4;
                             END (* IF (Y - 4 *);

                             IF Spalte (0.0) < (SpalteMax - 80) THEN
                                leftEdge := Spalte (0.0) + 4;

                             ELSE (* IF Spalte *)
                                leftEdge := Spalte (0.0) - 80;
                             END (* IF Spalte *);

                             iTextFont := NIL;
                             iText := ADR (Schrift);
                             nextText := NIL;
                          END (* WITH ISchrift *);

                          PrintIText (GFenster^.rPort, ADR (ISchrift), 0, 0);
                       END (* IF ImRastPort *);
                    END (* IF (i *);

                    INC (Wert, SIZE (Wert^));

                    DrawCross (GFenster^.rPort, X, Y);
                 END (* FOR i *);

                 Wert := Gerade.Adresse;

                 (* Die Gerade *)

                 SetAPen (GFenster^.rPort, Rot);

                 IF ImRastPort (Zeile ((Gerade.Daten.A * XMin) + Gerade.Daten.B), y)
                    THEN
                    Move (GFenster^.rPort, Spalte (XMin),
                       Zeile ((Gerade.Daten.A * XMin) + Gerade.Daten.B));

                 ELSE (* IF ImRastPort *)
                    IF Gerade.Daten.A >= 0.0 THEN
                       Move (GFenster^.rPort, Spalte ((YMin - Gerade.Daten.B) /
                          Gerade.Daten.A), Zeile (YMin));

                    ELSE (* IF Gerade.Daten.A *)
                       Move (GFenster^.rPort, Spalte ((YMax - Gerade.Daten.B) /
                          Gerade.Daten.A), Zeile (YMax));
                    END (* IF Gerade.Daten.A *);
                 END (* IF ImRastPort *);

                 IF ImRastPort (Zeile ((Gerade.Daten.A * XMax) + Gerade.Daten.B), y)
                    THEN
                    Draw (GFenster^.rPort, Spalte (XMax),
                       Zeile ((Gerade.Daten.A * XMax) + Gerade.Daten.B));

                 ELSE (* IF ImRastPort *)
                    IF Gerade.Daten.A >= 0.0 THEN
                       Draw (GFenster^.rPort, Spalte ((YMax - Gerade.Daten.B) /
                          Gerade.Daten.A), Zeile (YMax));

                    ELSE (* IF Gerade.Daten.A *)
                       Draw (GFenster^.rPort, Spalte ((YMin - Gerade.Daten.B) /
                          Gerade.Daten.A), Zeile (YMin));
                    END (* IF Gerade.Daten.A *);
                 END (* IF ImRastPort *);

                 GadgetAn (ADR (Box [15]), BFenster, NIL);
                 GadgetAn (ADR (Box [16]), BFenster, NIL);

                 Box [15].flags := Box [15].flags + GadgetFlagSet {selected};
                 Box [16].flags := Box [16].flags + GadgetFlagSet {selected};
                 RefreshGadList (ADR (Box [15]), BFenster, NIL, 2);
              END (* IF GFenster = NIL *);

         |11: (* Wertepaare - nichts tun *);

         |12: (* Seitenvorschub - nichts tun *);

         |13: (* Daten der Gerade - nichts tun *);

         |14: (* Seitenvorschub - nichts tun *);

         |15: (* Ausgleichsgerade - nichts tun *);

         |16: (* Seitenvorschub - nichts tun *);

         |17: (* drucken *)
              Datei := Open (ADR (PRT), newFile);

              IF Datei # NIL THEN
                 Ausgabe :=
                 "[1m A U S G L E I C H S G E R A D E  Y = A X + B[0m";
                  Schreibe (Datei, Ausgabe, 1);
                  Wert := Gerade.Adresse;

                 IF selected IN Box [11].flags THEN
                    RUmGadget (Box [11], An, BFenster);

                    FOR i := 1 TO Gerade.N DO
                       Ausgabe := " X(";
                       ValToStr (i, FALSE, SHilfe, 10, Ziffern, " ",
                                 Error);
                       Concat (Ausgabe, SHilfe);
                       Concat (Ausgabe, ") = ");
                       RealToStr (Wert^, SHilfe, 12, 8,
                                  Exponent (Wert^), Error);
                       Concat (Ausgabe, SHilfe);
                       Concat (Ausgabe, ",  Y(");
                       ValToStr (i, FALSE, SHilfe, 10, Ziffern, " ",
                                 Error);
                       Concat (Ausgabe, SHilfe);
                       Concat (Ausgabe, ") = ");
                       INC (Wert, SIZE (Wert^));
                       RealToStr (Wert^, SHilfe, 12, 8,
                                  Exponent (Wert^), Error);
                       Concat (Ausgabe, SHilfe);
                       Concat (Ausgabe, ";");

                       Schreibe (Datei, Ausgabe, 0);

                       IF i # Gerade.N THEN
                          INC (Wert, SIZE (Wert^));

                       ELSE
                          Wert := Gerade.Adresse;
                       END (* IF i *);
                    END (* FOR i *);

                    RUmGadget (Box [11], Aus, BFenster);
                 END (* IF selected *);

                 Ausgabe := "";

                 IF selected IN Box [12].flags THEN
                    (* Seitenvorschub *)
                    RUmGadget (Box [12], An, BFenster);

                    Schreibe (Datei, " \f", 0);

                    RUmGadget (Box [12], Aus, BFenster);

                 ELSE (* IF selected *)
                    Schreibe (Datei, Ausgabe, 0);
                 END (* IF selected *);

                 IF selected IN Box [13].flags THEN
                    RUmGadget (Box [13], An, BFenster);

                    Ausgabe := " Anzahl der Wertepaare: ";
                    ValToStr (Gerade.N, FALSE, SHilfe, 10, Ziffern,
                              " ", Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Mittelwert der X-Werte: ";
                    RealToStr (Gerade.Daten.XM, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.XM), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Mittelwert der Y-Werte: ";
                    RealToStr (Gerade.Daten.YM, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.YM), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Standardabweichung der X-Werte: ";
                    RealToStr (Gerade.Daten.XS, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.XS), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Standardabweichung der Y-Werte: ";
                    RealToStr (Gerade.Daten.YS, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.YS), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe :=
                       " Parameter A der Ausgleichsgeraden: ";
                    RealToStr (Gerade.Daten.A, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.A), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Einheit des Parameters A: ";
                    Schreibe (Datei, Ausgabe, 1);

                    IF Gerade.BBekannt THEN
                       Ausgabe :=
                       " vorher bekannter Parameter B der Ausgleichsgeraden: ";

                    ELSE (* IF BBekannt *)
                       Ausgabe :=
                          " Parameter B der Ausgleichsgeraden: ";
                    END (* IF BBekannt *);

                    RealToStr (Gerade.Daten.B, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.B), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe := " Einheit des Parameters B: ";
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe :=
                    " (N-1) - Standardabweichung des Parameters A: ";
                    RealToStr (Gerade.Daten.AS, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.AS), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe :=
                    " (N-1) - Standardabweichung des Parameters B: ";
                    RealToStr (Gerade.Daten.BS, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.BS), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe :=
                      " Standardabweichung der Ausgleichsgeraden: ";
                    RealToStr (Gerade.Daten.GS, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.GS), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    Ausgabe :=
                       " linearer Korrelationskoeffizient R: ";
                    RealToStr (Gerade.Daten.R, SHilfe, 12, 8,
                               Exponent (Gerade.Daten.R), Error);
                    Concat (Ausgabe, SHilfe);
                    Schreibe (Datei, Ausgabe, 1);

                    RUmGadget (Box [13], Aus, BFenster);
                 END (* IF selected *);

                 Ausgabe := "";

                 IF selected IN Box [14].flags THEN
                    (* Seitenvorschub *)
                    RUmGadget (Box [14], An, BFenster);

                    Schreibe (Datei, " \f", 0);

                    RUmGadget (Box [14], Aus, BFenster);
                 ELSE (* IF selected *)
                    Schreibe (Datei, Ausgabe, 0);
                 END (* IF selected *);

                 Close (Datei);
                 Datei := NIL;

                 (* die Gerade als Grafik *)

                 IF GFenster # NIL THEN
                    IF selected IN Box [15].flags THEN
                       Port := CreatePort (ADR ("Ausgleichsgerade drucken\o"), 0);
                       BildReq := CreateExtIO (Port, SIZE (BildReq^));

                       IF BildReq # NIL THEN
                          OpenDevice (ADR (printerName), 0, BildReq, LONGSET {});

                          WITH BildReq^ DO
                             command := dumpRPort;
                             rastPort := GFenster^.rPort;
                             colorMap := Bildschirm^.viewPort.colorMap;
                             modes := Bildschirm^.viewPort.modes;
                             srcX := 5;
                             srcY := 13;
                             srcWidth := 630;
                             srcHeight := 180;
                             destCols := 0;
                             destRows := 0;
                             special := SpecialSet {fullCols, aspect, noFormFeed};
                          END (* With BildReq^ *);

                          RUmGadget (Box [15], An, BFenster);
                          DoIO (BildReq); (* drucken... *)
                          RUmGadget (Box [15], Aus, BFenster);

                          CloseDevice (BildReq);
                          DeleteExtIO (BildReq);
                          BildReq := NIL;
                       END (* IF BildReq *);

                       DeletePort (Port);
                       Port := NIL;
                    END (* IF selected *);
                 END (* IF GFenster *);

                 IF selected IN Box [16].flags THEN
                    Datei := Open (ADR (PRT), newFile);

                    IF Datei # NIL THEN
                       (* Seitenvorschub *)
                       RUmGadget (Box [16], An, BFenster);

                       Schreibe (Datei, " \f", 0);

                       RUmGadget (Box [16], Aus, BFenster);

                       Close (Datei);
                       Datei := NIL;
                    END (* IF Datei *);
                 END (* IF selected *);

              ELSE (* IF Datei *)
                 ReqText [1].iText :=
                    ADR ("Ich kann nicht drucken,");
                 ReqText [2].iText :=
                    ADR ("Ihr Drucker ist nicht erreichbar!");
                 ReqText [3].iText := ADR (Ok);
                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );
              END (* IF Datei *);

         |18: (* Laden, noch nicht implementiert *);

         |19: (* Speichern, noch nicht implementiert *);

         |20: (* Ende *)
              ReqText [1].iText := ADR ("Wollen Sie das Programm");
              ReqText [2].iText := ADR ("wirklich beenden?");
              ReqText [3].iText := ADR (Ja);
              ReqText [4].iText := ADR (Nein);

              Programmende := MakeRequest (ADR (ReqText [3]),
                                           ADR (ReqText [4]),
                                           ADR (ReqText [1]),
                                           BFenster,
                                           2                 );

         |21: (* Y(X=0) eingegeben *)
              StrToReal (YVonX, Gerade.Daten.B, Error);

              IF Error THEN
                 (* etwas schiefgelaufen *)
                 ReqText [1].iText :=
                    ADR ("Die Zahl bei Y(X=0) ist");
                 ReqText [2].iText := ADR ("nicht reell!");
                 ReqText [3].iText := ADR (Ok);

                 Error := MakeRequest (ADR (ReqText [3]),
                                       ADR (ReqText [4]),
                                       ADR (ReqText [1]),
                                       BFenster,
                                       1                 );

                 YVonX := UYVonX;
                 RefreshGadList (ADR (Box [21]), BFenster, NIL, 1);
              ELSE (* IF Error *)
                 UYVonX := YVonX;
              END (* IF Error *);

         |22: (* B bekannt! *)
              IF NOT Gerade.BBekannt THEN
                 (* "n. bek." löschen *)
                 Box [22].flags := Box [22].flags +
                                   GadgetFlagSet {selected};
                 Box [23].flags := Box [23].flags -
                                   GadgetFlagSet {selected};

                 RefreshGadList (ADR (Box [22]), BFenster, NIL, 2);

                 (* Y(X=0) aktivieren *)
                 GadgetAn (ADR (Box [21]), BFenster, NIL);
                 Error := ActivateGadget (ADR (Box [21]), BFenster, NIL);

                 Gerade.BBekannt := TRUE;
              ELSE (* das Gadget soll angewählt bleiben! *)
                 Box [22].flags := Box [22].flags +
                                   GadgetFlagSet {selected};
                 RefreshGadList (ADR (Box [22]), BFenster, NIL, 1);
              END (* IF NOT *);

         |23: (* B nicht bekannt *)
              IF Gerade.BBekannt THEN
                 (* "bekannt" löschen *)
                 Box [22].flags := Box [22].flags -
                                   GadgetFlagSet {selected};
                 Box [23].flags := Box [23].flags +
                                   GadgetFlagSet {selected};

                 RefreshGadList (ADR (Box [22]), BFenster, NIL, 2);

                 (* Y(X=0) deaktivieren *)
                 GadgetAus (ADR (Box [21]), BFenster, NIL);

                 Gerade.BBekannt := FALSE;
              ELSE (* das Gadget soll angewählt bleiben! *)
                 Box [23].flags := Box [23].flags +
                                   GadgetFlagSet {selected};
                 RefreshGadList (ADR (Box [23]), BFenster, NIL, 1);
              END (* IF NOT *);
      END (* CASE GewGad^.gadgetID *);
   END (* IF Nachricht *);
UNTIL Programmende;

(* --------------------------------------------------------------------- *)

CLOSE; (* aufräumen... *)

IF BFenster # NIL THEN
   CloseWindow (BFenster);
   BFenster := NIL;
END (* IF BFenster *);

IF DFenster # NIL THEN
   CloseWindow (DFenster);
   DFenster := NIL;
END (* IF DFenster *);

IF GFenster # NIL THEN
   CloseWindow (GFenster);
   GFenster := NIL;
END (* IF GFenster *);

IF Bildschirm # NIL THEN
   CloseScreen (Bildschirm);
   Bildschirm := NIL;
END (* IF Bildschirm *);

IF Font # NIL THEN
   CloseFont (Font);
   Font := NIL;
END (* IF Font *);

IF Gerade.Adresse # NIL THEN
   Deallocate (Gerade.Adresse);
   Gerade.Adresse := NIL;
END (* IF Gerade.Adresse *);

IF Datei # NIL THEN
   Close (Datei);
   Datei := NIL;
END (* IF Datei *);

IF BildReq # NIL THEN
   CloseDevice (BildReq);
   DeleteExtIO (BildReq);
   BildReq := NIL;
END (* IF BildReq *);

END AusgleichsgeradeV2 (* Modul *).
