(*---------------------------------------------------------------------------
   :Program.    Kurve
   :Author.     Jörg Wesemann
   :Address.    Auf der Heide 10, 2807 Achim - Baden
   :Phone.      (0)4202 / 70658
   :Shortcut.   [jwe]
   :Version.    2.94
   :Date.       23.03.89
   :Copyright.  PD
   :Language.   Modula-II
   :Translator. M2Amiga
   :Imports.    none.
   :Update.     none.
   :Contents.   Löst Lineare Gleichungssysteme
   :Remark.     Copyright siehe DOC - File
---------------------------------------------------------------------------*)


IMPLEMENTATION MODULE LGSboss;

FROM SYSTEM 		IMPORT 	ADDRESS,ADR ;
FROM Graphics 		IMPORT 	Text,Move,jam1,RastPortPtr,Draw,SetAPen;
FROM Intuition 		IMPORT 	ScreenFlags,ScreenFlagSet,NewWindow,WindowPtr,
		      		IDCMPFlags,IDCMPFlagSet,WindowFlags,strGadget,
                                WindowFlagSet,OpenWindow,CloseWindow,Border,
                                IntuiMessage,Gadget,GadgetFlags,GadgetFlagSet,
                                ActivationFlags,boolGadget,ActivationFlagSet,
                                StringInfo,RefreshGadgets,IntuiText;
FROM Exec 		IMPORT 	GetMsg,ReplyMsg,WaitPort,FreeMem;
FROM Arts		IMPORT	Assert,BreakPoint,DebugProcedure,TermProcedure,
				RemoveDebugProc,Error;            
FROM InOut		IMPORT	WriteCard,WriteLn,ReadCard;

FROM WinHelp		IMPORT  OpenWin,CloseWin;
FROM Windows		IMPORT	WinGadSet,WriteS,WinGad,WriteL,WriteC;        
FROM LGSparser		IMPORT	LGSparse;
FROM RealConversions	IMPORT  RealToStr;
FROM MatrixLib		IMPORT	det,InitMatrix,InvMatrix,loeseLGS,Rg,SetEl,
				Tupel,MATRIX,IndexBereich,WriteMatrix,Spalten,
                                Zeilen;
FROM startupproc	IMPORT  Buffer,UndoBuffer,LGSstring;

                                                                
PROCEDURE LGSBoss;                                
                                                
    CONST
      loesung 		= 1;
      inverse		= 2;
      determinante	= 3;
      rang		= 4;
      quit		= 5;
      leerstring	= "           ";

    VAR
      rp					: RastPortPtr;
      LGSWindow,KomWindow,LoesWindow	  	: NewWindow ;
      LGSWindowPtr,KomWindowPtr,LoesWindowPtr	: WindowPtr ;
      class					: IDCMPFlagSet ;
      IntuiMsg    				: POINTER TO IntuiMessage ;
      gad 			: ARRAY [1..10],[1..11] OF Gadget ;
      komgad			: ARRAY [1..5] OF Gadget;
      komtext			: ARRAY [1..5] OF IntuiText;
      komrahmen			: Border;
      komxy			: ARRAY [0..9] OF INTEGER;
      Info 			: ARRAY [1..10],[1..10] OF StringInfo ;
      Rahmen			: ARRAY [1..10],[1..10] OF Border;
      xyFeld			: ARRAY [1..10],[1..10],[0..9]  OF INTEGER ;
      x,y,xk,yk,item		: CARDINAL;
      ok,bool			: BOOLEAN;
      welches			: POINTER TO Gadget;
      st			: LGSstring;
      z,s,x1,y1			: IndexBereich;
      LTupel			: Tupel;
      LGS			: MATRIX;
      dummy			: REAL;
  
  PROCEDURE CleanUp;
  
  BEGIN
    IF LGSWindowPtr #NIL THEN
      CloseWindow(LGSWindowPtr);
      LGSWindowPtr:= NIL;
    END;
    IF KomWindowPtr #NIL THEN
      CloseWindow(KomWindowPtr);
      KomWindowPtr:= NIL;
    END;
    IF LoesWindowPtr #NIL THEN
      CloseWin(LoesWindowPtr);
      LoesWindowPtr:= NIL;
    END;
  END CleanUp;
  
  
  PROCEDURE ClearBuffer;
  
  BEGIN
    FOR x1:= 1 TO 10 DO
      FOR y1:= 1 TO 10 DO
        Buffer[x1,y1]:= "";
      END;
    END;
  END ClearBuffer;
  
  
  PROCEDURE initmatrix;
  
  BEGIN
    z:= 1;
    s:= 1;
    FOR x1:= 1 TO 10 DO
      dummy:= LGSparse(Buffer[x1,1],1.0,bool);
      IF bool = TRUE THEN
        INC(s);
      END;
      dummy:= LGSparse(Buffer[1,x1],1.0,bool);
      IF bool = TRUE THEN
        INC(z);
      END;
    END;
    DEC(s);
    DEC(z);
    InitMatrix(LGS,z,s,0.00);
    FOR x1:= 1 TO s DO
      FOR y1:= 1 TO z DO
        dummy:= LGSparse(Buffer[x1,y1],1.00,bool);
        IF bool = TRUE THEN
          SetEl(LGS,y1,x1,dummy);
        ELSE
          BreakPoint(ADR("Parsen klappte nicht !"));
        END;
      END;
    END;
  END initmatrix;
  
  
  PROCEDURE loesen;
  
  BEGIN
    CASE loeseLGS(LGS,LTupel) OF
      |  -1 : WriteS(LoesWindowPtr,"Gleichungssystem nicht lösbar");
      	      WriteL(LoesWindowPtr);
      |   0 : WriteS(LoesWindowPtr,
       		     "Gleichungssystem hat unendlich viele Lösungen");
              WriteL(LoesWindowPtr);
      |   1 : WriteS(LoesWindowPtr,"Gleichungssystem eindeutig lösbar");
              WriteL(LoesWindowPtr);
              FOR x:= 1 TO s-1 DO
                WriteC(LoesWindowPtr,"X");
                RealToStr(REAL(x),st,1,1,FALSE,ok);
                WriteS(LoesWindowPtr,st);
                WriteS(LoesWindowPtr,"= ");
                RealToStr(LTupel[x],st,8,5,FALSE,ok);
                WriteS(LoesWindowPtr,st);
                WriteL(LoesWindowPtr);
              END;
     END;
     WriteL(LoesWindowPtr);
  END loesen;

  
PROCEDURE determ;

BEGIN
  IF Spalten(LGS) = Zeilen(LGS) THEN
    RealToStr(det(LGS),st,2,0,FALSE,ok);
    WriteS(LoesWindowPtr,"Determinate(Matrix) = ");
    WriteS(LoesWindowPtr,st);
  ELSE
    WriteS(LoesWindowPtr,"Zeilenanzahl <> Spaltenanzahl");
  END;  
  WriteL(LoesWindowPtr);
  WriteL(LoesWindowPtr);
END determ;

  
PROCEDURE rangcalc;

BEGIN
  RealToStr(FLOAT(Rg(LGS)),st,2,0,FALSE,ok);
  WriteS(LoesWindowPtr,"Rang(Matrix) = ");
  WriteS(LoesWindowPtr,st);
  WriteL(LoesWindowPtr);
  WriteL(LoesWindowPtr);
END rangcalc;
                

PROCEDURE initwindow;

BEGIN    
    WITH LGSWindow DO
      leftEdge:= 0; topEdge:= 0;       
      width:= 640; height:= 162;
      detailPen:= 0; blockPen:= 1;
      idcmpFlags:= IDCMPFlagSet{}; 
      flags:= WindowFlagSet{windowDepth};  
      firstGadget:= ADR(gad[1,1]);
      checkMark:= NIL;
      title:= ADR("Lineares Gleichungssystem");
      bitMap:= NIL;
      type:= ScreenFlagSet{wbenchScreen};
      minWidth:= 640; maxWidth:= 640;
      minHeight:= 162; maxHeight:= 162;
    END;
    WITH KomWindow DO
      leftEdge:= 402; topEdge:= 163;
      width:= 237; height:= 93;
      detailPen:= 0; blockPen:= 1;
      idcmpFlags:= IDCMPFlagSet{gadgetUp,closeWindow}; 
      flags:= WindowFlagSet{windowClose,windowDepth,activate};  
      firstGadget:= ADR(komgad[1]);
      checkMark:= NIL;
      title:= ADR("Kommando Eingabe");
      bitMap:= NIL;
      type:= ScreenFlagSet{wbenchScreen};
      minWidth:= 239; maxWidth:= 239;
      minHeight:= 93; maxHeight:= 93;     
    END;
    WITH LoesWindow DO
      leftEdge:= 0; topEdge:= 163;       
      width:= 400; height:= 93;
      detailPen:= 0; blockPen:= 1;
      idcmpFlags:= IDCMPFlagSet{}; 
      flags:= WindowFlagSet{windowDepth};  
      firstGadget:= NIL;
      checkMark:= NIL;
      title:= ADR("Lösungsausgabe");
      bitMap:= NIL;
      type:= ScreenFlagSet{wbenchScreen};
      minWidth:= 400; maxWidth:= 400;
      minHeight:= 93; maxHeight:= 93;
    END;
    WITH komrahmen DO
      leftEdge:= -1; topEdge:= -1; frontPen:= 1; backPen:= 0;
      drawMode:= jam1; count:= 5; xy:= ADR(komxy); nextBorder:= NIL;
    END;
    komxy[0]:= 0;  komxy[1]:= 0;  komxy[2]:= 61; komxy[3]:= 0;
    komxy[4]:= 61; komxy[5]:= 16; komxy[6]:= 0;  komxy[7]:= 16;
    komxy[8]:= 0;  komxy[9]:= 0;
    WITH komtext[1] DO
      frontPen:= 1; backPen:= 0; drawMode:= jam1; leftEdge:= 5; topEdge:= 3;
      iTextFont:= NIL; nextText:= NIL; iText:= ADR("Lösung");
    END;
    WITH komgad[1] DO
      nextGadget:= ADR(komgad[2]);;
      leftEdge:= 15; topEdge:= 15;
      width:= 60; height:= 15;
      flags:= GadgetFlagSet{};
      activation:= ActivationFlagSet{gadgImmediate,relVerify};
      gadgetType:= boolGadget;
      gadgetRender:= ADR(komrahmen); selectRender:= NIL;
      gadgetText:= ADR(komtext[1]); specialInfo:= NIL;
      gadgetID:= loesung;
      userData:= NIL;
    END;
    WITH komtext[2] DO
      frontPen:= 1; backPen:= 0; drawMode:= jam1; leftEdge:= 4; topEdge:= 3;
      iTextFont:= NIL; nextText:= NIL; iText:= ADR("CLEAR");
    END;
    WITH komgad[2] DO
      nextGadget:= ADR(komgad[3]);
      leftEdge:= 162; topEdge:= 15;
      width:= 60; height:= 15;
      flags:= GadgetFlagSet{};
      activation:= ActivationFlagSet{gadgImmediate,relVerify};
      gadgetType:= boolGadget;
      gadgetRender:= ADR(komrahmen); selectRender:= NIL;
      gadgetText:= ADR(komtext[2]); specialInfo:= NIL;
      gadgetID:= inverse;
      userData:= NIL;
    END;
    WITH komtext[3] DO
      frontPen:= 1; backPen:= 0; drawMode:= jam1; leftEdge:= 4; topEdge:= 3;
      iTextFont:= NIL; nextText:= NIL; iText:= ADR("Determ.");
    END;
    WITH komgad[3] DO
      nextGadget:= ADR(komgad[4]);
      leftEdge:= 15; topEdge:= 40;
      width:= 60; height:= 15;
      flags:= GadgetFlagSet{};
      activation:= ActivationFlagSet{gadgImmediate,relVerify};
      gadgetType:= boolGadget;
      gadgetRender:= ADR(komrahmen); selectRender:= NIL;
      gadgetText:= ADR(komtext[3]); specialInfo:= NIL;
      gadgetID:= determinante;
      userData:= NIL;
    END;
    WITH komtext[4] DO
      frontPen:= 1; backPen:= 0; drawMode:= jam1; leftEdge:= 5; topEdge:= 3;
      iTextFont:= NIL; nextText:= NIL; iText:= ADR("Rang");
    END;
    WITH komgad[4] DO
      nextGadget:= ADR(komgad[5]);
      leftEdge:= 162; topEdge:= 40;
      width:= 60; height:= 15;
      flags:= GadgetFlagSet{};
      activation:= ActivationFlagSet{gadgImmediate,relVerify};
      gadgetType:= boolGadget;
      gadgetRender:= ADR(komrahmen); selectRender:= NIL;
      gadgetText:= ADR(komtext[4]); specialInfo:= NIL;
      gadgetID:= rang;
      userData:= NIL;
    END;
    WITH komtext[5] DO
      frontPen:= 1; backPen:= 0; drawMode:= jam1; leftEdge:= 3; topEdge:= 3;
      iTextFont:= NIL; nextText:= NIL; iText:= ADR("Q U I T");
    END;
    WITH komgad[5] DO
      nextGadget:= NIL;
      leftEdge:= 89; topEdge:= 70;
      width:= 60; height:= 15;
      flags:= GadgetFlagSet{};
      activation:= ActivationFlagSet{gadgImmediate,relVerify};
      gadgetType:= boolGadget;
      gadgetRender:= ADR(komrahmen); selectRender:= NIL; 
      gadgetText:= ADR(komtext[5]); specialInfo:= NIL;
      gadgetID:= quit;
      userData:= NIL;
    END;
    FOR y:= 1 TO 10 DO
      FOR x:= 1 TO 10 DO
        WITH Rahmen[x,y] DO				
          leftEdge:= -1; topEdge:= -2;
          frontPen:= 1; backPen:= 0;
      	  drawMode:= jam1;
      	  count:= 5; xy:= ADR(xyFeld[x,y,0]);
      	  nextBorder:= NIL;
    	END;
    	xyFeld[x,y,0]:= 0;   xyFeld[x,y,1]:= 0;
    	xyFeld[x,y,2]:= 41;  xyFeld[x,y,3]:= 0;
    	xyFeld[x,y,4]:= 41;  xyFeld[x,y,5]:= 11;
    	xyFeld[x,y,6]:= 0;   xyFeld[x,y,7]:= 11;
    	xyFeld[x,y,8]:= 0;   xyFeld[x,y,9]:= 0;
        UndoBuffer[x,y]:= " ";
    	WITH Info[x,y] DO
      	  buffer:= ADR(Buffer[x,y]); undoBuffer:= ADR(UndoBuffer[x,y]);
      	  bufferPos:= 0; maxChars:= 9; dispPos:= 0;
    	END;
        yk:= y;
        xk := x + 1;
        IF x=10 THEN
          INC(yk);
          xk:= 1;
        END;
        WITH gad[x,y] DO			
      	  IF x*y <= 99 THEN
            nextGadget:= ADR(gad[xk,yk]);
      	  ELSE
            nextGadget:= NIL;
          END;
          leftEdge:= 20+62*(x-1); topEdge:= 14+15*(y-1);
      	  width:= 40; height:= 10;
          flags:= GadgetFlagSet{};
      	  activation:= ActivationFlagSet{toggleSelect,stringCenter};
      	  gadgetType:= strGadget;
      	  gadgetRender:= ADR(Rahmen[x,y]); selectRender:= NIL; 
      	  gadgetText:= NIL; specialInfo:= ADR(Info[x,y]);
      	  gadgetID:= 1;
      	  userData:= NIL;
    	END;
      END; (* of x *)
    END; (* of y   *)
    LGSWindowPtr:= OpenWindow(LGSWindow);
    Assert(LGSWindowPtr # NIL, ADR("LGS-Fenster nicht geöffnet"));
    KomWindowPtr:= OpenWindow(KomWindow);
    Assert(KomWindowPtr # NIL, ADR("Kom-Fenster nicht geöffnet"));
    OpenWin(LoesWindowPtr,0,163,400,93,"Lösungen",WinGadSet{arranging});
    Assert(LoesWindowPtr # NIL, ADR("Loes-Fenster nicht geöffnet")); 
    rp:= LoesWindowPtr^.rPort;
  END initwindow;
  
  BEGIN  (* main *)
    initwindow;
    LOOP
      WaitPort(KomWindowPtr^.userPort); 
      IntuiMsg:= GetMsg(KomWindowPtr^.userPort);
      class:= IntuiMsg^.class;
      welches:= IntuiMsg^.iAddress;
      ReplyMsg(IntuiMsg);
      item:= welches^.gadgetID;
      IF ( class=IDCMPFlagSet{gadgetUp} ) THEN
        initmatrix;
        CASE item OF
          |  loesung 		: loesen;
          |  inverse 		: ClearBuffer;
          			  CleanUp;
          			  initwindow;
          |  determinante 	: determ;
          |  rang 		: rangcalc;
          |  quit 		: EXIT;
        END;
      ELSIF ( class=IDCMPFlagSet{closeWindow} ) THEN
        EXIT;
      END;
    END;						(* LOOP 1	*)
    CleanUp;
END LGSBoss;

END LGSboss.
