(*---------------------------------------------------------------------------
    :Program.    Ecce.mod     (Ecce [Lat.] = "Siehe, da !")
    :Author.     Norbert Süßdorf
    :Address.    Körnerstraße 6, D 6840 Lampertheim 1
    :Phone.      06206/2212
    :Shortcut.   [N.S]
    :Version.    1.0
    :Date.       16-Nov-88
    :Copyright.  PD
    :Language.   Modula-II
    :Translator. M2Amiga
    :Imports.    
    :UpDate.     none.
    :Contents.   'More'-ähnlich, primitiver aber mausgesteuert.
                 (sorry, mein erstes, mehr oder weniger brauchbares M2-Prog.)
    :Remark.     Usage: Ecce <File>
---------------------------------------------------------------------------*)
MODULE Ecce;
FROM SYSTEM    IMPORT ADR,ADDRESS,LONGSET;
FROM Intuition IMPORT OpenWindow,CloseWindow,NewWindow,WindowPtr,
                      IDCMPFlags,IDCMPFlagSet,WindowFlags,WindowFlagSet,
                      ScreenFlags,ScreenFlagSet,Gadget,OnGadget,
                      GadgetFlags,GadgetFlagSet,ActivationFlags,
                      IntuiMessage,boolGadget,ActivationFlagSet,IntuiText,
                      DisplayBeep;
FROM Graphics  IMPORT RectFill,RastPortPtr,RastPort,Text,Move,SetAPen,SetBPen,
                      TextAttr,TextAttrPtr,TextFontPtr,OpenFont,FontStyleSet,
                      FontFlagSet,FontFlags,SetFont,jam1; 
FROM ASCII     IMPORT eol,eof;
FROM Arts      IMPORT Terminate;
FROM Arguments IMPORT NumArgs,GetArg;
FROM Dos       IMPORT Delay,Open,Close,oldFile,Read,FileHandlePtr;
FROM Exec      IMPORT GetMsg,ReplyMsg,WaitPort;

TYPE ZeiKette  = ARRAY [0..255] OF CHAR;
     Gadgetptr = POINTER TO Gadget;
     
VAR NeuesFenster               : NewWindow;
    NeuesFensterPtr            : WindowPtr;
    Datei                      : FileHandlePtr;
    rpPtr                      : RastPortPtr;
    Gadget0,Gadget1            : Gadget;
    GadgetText0,GadgetText1    : IntuiText;
    class                      : IDCMPFlagSet;
    IntuiMsg                   : POINTER TO IntuiMessage;
    Seite,Code,e,z             : CARDINAL;
    len,count                  : INTEGER;
    Leng                       : LONGINT;
    Zeichen                    : CHAR;
    SLen                       : ARRAY [0..255] OF LONGINT;
    SatzLen                    : ARRAY [1..24] OF CARDINAL;
    Buffer                     : ARRAY [0..2500] OF CHAR;
    Satz                       : ARRAY [1..24] OF ZeiKette;
    DateiName                  : ARRAY [0..79] OF CHAR;   

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

PROCEDURE InitTextGadget;

BEGIN
  
  WITH GadgetText0 DO
    frontPen:=2; backPen:=3; drawMode:=jam1; leftEdge:=80; topEdge:=1;
    nextText:=NIL; iText:=ADR("Vorhergehende Seite");
   END;
  
  WITH GadgetText1 DO
    frontPen:=2; backPen:=3; drawMode:=jam1; leftEdge:=96; topEdge:=1;
    nextText:=NIL; iText:=ADR("Nächste Seite");
  END;   
  
  WITH Gadget0 DO
   nextGadget := ADR(Gadget1);
   leftEdge := 4; topEdge := 206; width := 315; height := 10;
   flags := GadgetFlagSet{};
   activation := ActivationFlagSet{relVerify};
   gadgetType := boolGadget; gadgetRender := NIL; selectRender := NIL ;
   gadgetText := ADR(GadgetText0);
   mutualExclude := LONGSET{};
   specialInfo := NIL;
   gadgetID := 1; userData := NIL;
  END;
  
  WITH Gadget1 DO
   nextGadget := NIL;
   leftEdge := 321; topEdge := 206; width := 315; height := 10;
   flags := GadgetFlagSet{};
   activation := ActivationFlagSet{relVerify};
   gadgetType := boolGadget; gadgetRender := NIL; selectRender := NIL ;
   gadgetText := ADR(GadgetText1);
   mutualExclude := LONGSET{};
   specialInfo := NIL;
   gadgetID := 2; userData := NIL;
   END;
  
END InitTextGadget;  
          
(*-----------------------------------------------------------------------*)

PROCEDURE NimmFont(Hoehe : CARDINAL; rp : RastPortPtr);
 
 VAR NeuerFontAttr : TextAttr;
 VAR NeuFontPtr    : TextFontPtr;
    
BEGIN
     
     WITH NeuerFontAttr DO
       name := ADR("topaz.font");
      ySize := Hoehe;
      style := FontStyleSet{};
      flags := FontFlagSet{romFont};
     END;
   
   NeuFontPtr := OpenFont(ADR(NeuerFontAttr));
   
   IF NeuFontPtr = NIL THEN 
      CloseWindow(NeuesFensterPtr); Terminate(0);
   END (*IF*);
   
   SetFont(rp,NeuFontPtr);

END NimmFont;    

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

PROCEDURE MachFenster(): RastPortPtr;

  VAR MeinRastPortPtr : ADDRESS;
 
BEGIN     
    
    WITH NeuesFenster DO
      leftEdge := 0;
      topEdge := 38;
      width := 640;
      height := 218;
      detailPen := 0;
      blockPen := 1;
      idcmpFlags := IDCMPFlagSet{closeWindow,gadgetUp,rawKey};
      flags := WindowFlagSet{windowClose,windowDrag,windowDepth,activate,
                             wbenchWindow};
      firstGadget := ADR(Gadget0);
      checkMark := NIL;
      title := ADR("Ecce 1.0(m2Amiga PD-Softw. by N.Süßdorf) [HELP] » Hilfe");
      screen := NIL;
      bitMap := NIL;
      minWidth := 300;
      minHeight := 150;
      maxWidth := 300;
      maxHeight := 150;
      type := ScreenFlagSet{wbenchScreen};
     END;

    NeuesFensterPtr := OpenWindow(NeuesFenster);
    
    IF NeuesFensterPtr = NIL THEN Terminate(0); END (*IF*);
    
    MeinRastPortPtr := NeuesFensterPtr^.rPort; 

    RETURN MeinRastPortPtr;

END MachFenster;

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

PROCEDURE HelpMessage;

BEGIN
     
     Move(rpPtr,20,40);
     Text(rpPtr,ADR("Dieses Programm stellt ASCII-Dateien auf"),40);      
     Move(rpPtr,20,50);
     Text(rpPtr,ADR("dem Bildschirm zum Lesen dar."),29);
     Move(rpPtr,20,70);
     Text(rpPtr,ADR("Verwendung im CLI: ecce <Dateiname>"),35);  
     Move(rpPtr,20,80);
     Text(rpPtr,ADR("Workbench: Klick auf Datei, SHIFT + Doppelklick auf Ecce."),57);
     Move(rpPtr,20,95);
     Text(rpPtr,ADR("Tastatur: q = Ende, Cursortasten (up)+(down) zum Blättern."),58);  
       Delay(400);

END HelpMessage;

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

PROCEDURE Message;

BEGIN

 Move(rpPtr,20,70);
 Text(rpPtr,ADR("Ecce : ' Datei enthält überlange Zeilen, muß abbrechen ! '"),58); 

END Message;

(*-----------------------------------------------------------------------*)
      
PROCEDURE CloseDown;
 
BEGIN
  
  CloseWindow(NeuesFensterPtr); Close(Datei);

END CloseDown; 

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

PROCEDURE ClearFenster(rp : RastPortPtr);

BEGIN
 
 SetAPen(rp,1); SetBPen(rp,0);
 RectFill(rp,4,11,635,204);
 SetAPen(rp,2); SetBPen(rp,1);

END ClearFenster; 

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

PROCEDURE ReOpen;

BEGIN
  
  Close(Datei);
  Datei := Open(ADR(DateiName),oldFile);
  IF Datei = NIL THEN 
    CloseDown ;Terminate(0);
  END (* IF *);

END ReOpen;

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

PROCEDURE ReadZeile;

BEGIN     (* In dieser Schleife werden Zeilen zeichenweise gelesen und
             Returns, Tabulatorzeichen und Dateiendezeichen aufgespürt.
             Diese Zeichen sind für die Funktion 'Text' aus Graphics
             unverdaulich und werden durch NULL bzw. " " ersetzt. Zeilen,
             die länger als 79 Zeichen sind, werden innerhalb der Zeichen-
             kette gekürzt. Die Variable 'SLen' enthält die Anzahl
             a l l e r , pro Fensterseite gelesener Dateizeichen, denn
             'SLen' wird beim zurückblättern benötigt.                   *)
  e:=0;
LOOP
 Leng := Read(Datei,ADR(Zeichen),1);SLen[Seite] := SLen[Seite]+Leng;
  IF (Zeichen = eol) OR (Zeichen = eof) THEN
   IF e > 120 THEN
     EXIT;
   ELSIF e > 78 THEN e := 78 ; END (*IF*);
     SatzLen[z]:= e;Satz[z,e] := CHAR(0);EXIT;
   END (*IF*);
    IF Zeichen = CHAR(9) THEN Zeichen := CHAR(32); END (*IF*);
  Satz[z,e] := Zeichen; e := e+1;
END (*LOOP*);

END ReadZeile;

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

PROCEDURE WriteZeile;

BEGIN

    Move(rpPtr,5,10+8*z);
    Text(rpPtr,ADR(Satz[z]),SatzLen[z]);

END WriteZeile;

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

PROCEDURE LiesSeite;

BEGIN
 
 Seite := Seite+1; z := 1; SLen[Seite] := 0;
 LOOP
  ReadZeile ;
  IF e > 120 THEN EXIT; END (*IF*);
  WriteZeile;
  IF Zeichen = eof THEN EXIT ; END (*IF*);
  z := z+1;
  IF z = 25 THEN EXIT ; END (*IF*);
 END (*LOOP*);
 
END LiesSeite;

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

BEGIN    
       
       InitTextGadget;
       rpPtr := MachFenster();
       NimmFont(8,rpPtr);
     
     SetAPen(rpPtr,3); SetBPen(rpPtr,1);
     RectFill(rpPtr,4,206,318,215);
     RectFill(rpPtr,321,206,635,215);
     ClearFenster(rpPtr); Seite := 0 ;
    
    IF NumArgs() = 0 THEN 
      HelpMessage;
      CloseWindow(NeuesFensterPtr); Terminate(0);
    END (*IF*);
  
          GetArg(1,DateiName,len);
  
  Datei := Open(ADR(DateiName),oldFile);
  
  IF Datei = NIL THEN CloseDown ;Terminate(0); END (*IF*);
      
     LiesSeite;
  IF e > 120 THEN 
    ClearFenster(rpPtr); Message ; Delay(300);
    CloseDown; Terminate(0);
  END (*IF*);
        
          OnGadget(ADR(Gadget0),NeuesFensterPtr,NIL);

    LOOP
      WaitPort(NeuesFensterPtr^.userPort); 
      IntuiMsg := GetMsg(NeuesFensterPtr^.userPort);

      WHILE IntuiMsg # NIL DO
         class := IntuiMsg^.class; Code := IntuiMsg^.code;
         ReplyMsg(IntuiMsg);
         IF (closeWindow IN class) THEN
            EXIT ;
         ELSIF (gadgetUp IN class) OR (rawKey IN class) THEN			
          IF (IntuiMsg^.iAddress = ADR(Gadget0)) OR (Code = 204) OR (Code = 223) THEN
            IF (Seite > 1) OR (Code = 223) THEN
                IF Code = 223 THEN
                  ClearFenster(rpPtr);HelpMessage;Seite := Seite+1;
                END (*IF*);
               
               (* Zum Zurückblättern wird die Datei geschlossen und neu
                  geöffnet. Dadurch wird mit 'Read' wieder am Dateianfang
                  begonnen.                                               *)
                  
               ReOpen; ClearFenster(rpPtr);
               Seite := Seite-1; 
              FOR count := 0 TO Seite-1 DO
                 
                 (* In dieser Schleife werden die bis zum Ende der v o r-
                    vorhergehenden Seite gelesenen Zeichen seitenweise in
                    einen Dummy-Puffer 'Buffer' eingelesen, um 'Read' lese-
                    bereit für die vorhergehende Seite zu positionieren.  *)
                    
                Leng := Read(Datei,ADR(Buffer),SLen[count]);
              END (*FOR*);
              Seite:= Seite-1; LiesSeite;
            ELSIF Seite = 1 THEN
             DisplayBeep(NIL);
            END (*IF*);
          ELSIF (IntuiMsg^.iAddress = ADR(Gadget1)) OR (Code = 205) THEN
            IF (Leng = 0) OR (Zeichen = eof) OR (Seite = 255) THEN
              DisplayBeep(NIL);
            ELSE 
              ClearFenster(rpPtr); LiesSeite;
                  IF e > 120 THEN
                    ClearFenster(rpPtr); Message;
                    Delay(300); EXIT;
                  END (*IF*);
            END (*IF*);
          ELSIF (Code = 144) THEN
            EXIT;
          END (*IF*); 
         END (*IF*);
         IntuiMsg := GetMsg(NeuesFensterPtr^.userPort);
      END (*WHILE*);
   
   END (*LOOP*);

CloseDown;

END Ecce.

