(*--------------------------------------------------------------------------
 :Program.    TabellenOps.mod
 :Author.     Marcus Stratmann
 :Address.    Böttcherstraße 13, D-4250 Bottrop-Kirchhellen
 :Phone.      02045/5191
 :Copyright.  Public Domain
 :Language.   MODULA-II
 :Translator. M2Amiga v3.3d
 :Imports.    DiskInOut, typdefs, IntuiOps
 :History.    V1.0,  26-Sep-89
 :History.    V1.1,  16-May-90
 :Contents.   Displays tables and evaluates data
--------------------------------------------------------------------------*)

IMPLEMENTATION MODULE TabellenOps;  (* $S- $R- $V- $F- *)

FROM Conversions IMPORT ValToStr;
FROM DiskInOut   IMPORT SetOutput, CloseOutput, WriteString, WriteLn, Done;
FROM Exec        IMPORT GetMsg, ReplyMsg;
FROM IntuiOps    IMPORT WriteWin, Fenster, WriteZahl, OeffneSpezFenster,
                        WaehleTabelle, SchliesseFenster, DruckerText,
                        KeineDaten, Linie;
FROM Intuition   IMPORT IDCMPFlags, IDCMPFlagSet, WindowFlags,
                        WindowFlagSet, WindowToFront, GadgetPtr,
                        IntuiMessagePtr, RemoveGadget, AddGadget,
                        RefreshGList;
FROM Strings     IMPORT Insert, last;
FROM SYSTEM      IMPORT ADDRESS, ADR;
FROM typdefs     IMPORT TP, Tabelle, Daten, TorePunkte, Tabellen, Namen,
                        TabellenBerechnet, DatenAusgewertet, AnzMan;


TYPE
  AusgabeTyp = ARRAY[0..70] OF CHAR;

VAR
  FensterTitel: ARRAY[1..3],[0..15] OF CHAR;


PROCEDURE DatenAuswertung;

  VAR
    i, j: CARDINAL;
    HeimTore, AuswTore, HeimPunkte, AuswPunkte: INTEGER;

  BEGIN
    FOR i := 1 TO AnzMan DO
      FOR j := 1 TO 7 DO
        TorePunkte.gsmt[i,j] := 0;
        TorePunkte.heim[i,j] := 0;
        TorePunkte.ausw[i,j] := 0;
      END;
    END;
    FOR i := 1 TO AnzMan DO
      FOR j := 1 TO AnzMan DO
        HeimTore := Daten[i,0,j];
        IF HeimTore > -1 THEN
          AuswTore := Daten[j,1,i];
          INC(TorePunkte.gsmt[i,1], HeimTore);
          INC(TorePunkte.heim[i,1], HeimTore);
          INC(TorePunkte.gsmt[i,2], AuswTore);
          INC(TorePunkte.heim[i,2], AuswTore);
          INC(TorePunkte.gsmt[j,1], AuswTore);
          INC(TorePunkte.ausw[j,1], AuswTore);
          INC(TorePunkte.gsmt[j,2], HeimTore);
          INC(TorePunkte.ausw[j,2], HeimTore);
          IF HeimTore > AuswTore THEN
            HeimPunkte := 2
          ELSIF HeimTore = AuswTore THEN
            HeimPunkte := 1
          ELSE
            HeimPunkte := 0
          END;
          AuswPunkte := (2 - HeimPunkte);
          INC(TorePunkte.gsmt[i,3], HeimPunkte);
          INC(TorePunkte.heim[i,3], HeimPunkte);
          INC(TorePunkte.gsmt[i,4], AuswPunkte);
          INC(TorePunkte.heim[i,4], AuswPunkte);
          INC(TorePunkte.gsmt[i,7-HeimPunkte]);
          INC(TorePunkte.heim[i,7-HeimPunkte]);
          INC(TorePunkte.gsmt[j,3], AuswPunkte);
          INC(TorePunkte.ausw[j,3], AuswPunkte);
          INC(TorePunkte.gsmt[j,4], HeimPunkte);
          INC(TorePunkte.ausw[j,4], HeimPunkte);
          INC(TorePunkte.gsmt[j,7-AuswPunkte]);
          INC(TorePunkte.ausw[j,7-AuswPunkte]);
        END;  (* IF HeimTore > -1 *)
      END;  (* FOR *)
    END;  (* FOR *)
    DatenAusgewertet := TRUE;
  END DatenAuswertung;


PROCEDURE BerechneTabellen;


  PROCEDURE TPnachTabelle(tp: TP; VAR tab: Tabelle);

    VAR
      i, l, vgl: INTEGER;


    PROCEDURE Groesser(tp1, tp2: ARRAY OF CARDINAL): BOOLEAN;

      VAR
        diff1, diff2, help1, help2: INTEGER;

      BEGIN
        IF tp1[2] > tp2[2] THEN
          RETURN TRUE;
        ELSIF tp2[2] > tp1[2] THEN
          RETURN FALSE
        ELSIF tp1[3] < tp2[3] THEN
          RETURN TRUE
        ELSIF tp2[3] < tp1[3] THEN
          RETURN FALSE
        ELSE
          help1 := tp1[0];          (* Nie wieder CARDINALs !!! *)
          help2 := tp1[1];
          diff1 := help1 - help2;
          help1 := tp2[0];
          help2 := tp2[1];
          diff2 := help1 - help2;
          IF diff1 > diff2 THEN
            RETURN TRUE;
          ELSIF diff2 > diff1 THEN
            RETURN FALSE;
          ELSIF tp1[0] > tp2[0] THEN
            RETURN TRUE
          ELSE
            RETURN FALSE;
          END;
        END;
      END Groesser;


    PROCEDURE Vertausche(ms1, ms2: CARDINAL);

      VAR
        temp: ARRAY[1..4] OF CARDINAL;  (* S, U, N sind unwichtig! *)
        temp2, i: CARDINAL;

      BEGIN
        FOR i := 1 TO 4 DO
          temp[i] := tp[ms1,i];
          tp[ms1,i] := tp[ms2,i];
          tp[ms2,i] := temp[i];
        END;
        temp2 := tab[ms1];
        tab[ms1] := tab[ms2];
        tab[ms2] := temp2;
      END Vertausche;


    BEGIN  (* TPnachTabelle *)
      FOR i := 1 TO AnzMan DO
        tab[i] := i;
      END;
      l := 1;
      REPEAT
        vgl := l;
        FOR i := l+1 TO AnzMan DO
          IF Groesser(tp[i], tp[vgl]) THEN
            vgl := i;
          END;
        END;
        IF l # vgl THEN
          Vertausche(l, vgl);
        END;
        INC(l);
      UNTIL l = AnzMan;
    END TPnachTabelle;


  BEGIN  (* BerechneTabellen *)
    IF NOT DatenAusgewertet THEN
      DatenAuswertung;
    END;
    TPnachTabelle(TorePunkte.gsmt, Tabellen.gsmt);
    TPnachTabelle(TorePunkte.heim, Tabellen.heim);
    TPnachTabelle(TorePunkte.ausw, Tabellen.ausw);
    TabellenBerechnet := TRUE;
  END BerechneTabellen;


PROCEDURE TabelleAusgeben(Nummer: CARDINAL; TabellenFenster: Fenster;
                          Statuszeile, Drucker: BOOLEAN);

  VAR
    i, m, zeile: CARDINAL;
    tab: Tabelle;
    daten: TP;
    Ausgabe: AusgabeTyp;
    ok: BOOLEAN;
    DruckFenster: Fenster;


  PROCEDURE Gleich(tp1, tp2: ARRAY OF CARDINAL): BOOLEAN;

    VAR
      i: CARDINAL;

    BEGIN
      FOR i := 0 TO 3 DO
        IF tp1[i] # tp2[i] THEN
          RETURN FALSE;
        END;
      END;
      RETURN TRUE;
    END Gleich;


  PROCEDURE MacheAusgabeZeile(v: CARDINAL; VAR out: AusgabeTyp);


    PROCEDURE AddZahl(zahl, laenge: INTEGER);

      VAR
        err: BOOLEAN;
        temp: ARRAY[0..5] OF CHAR;

      BEGIN
        ValToStr(zahl, FALSE, temp, 10, laenge, " ", err);
        Insert(out, last, temp);
      END AddZahl;


    BEGIN (* MacheAusgabeZeile *)
      out := "";
      AddZahl(i, 2);
      Insert(out, last, ". ");
      IF i > 1 THEN
        IF Gleich(daten[tab[i]], daten[tab[i-1]]) THEN
          out := "    ";
        END;
      END;
      Insert(out, last, Namen[m]);
      Insert(out, last, "                         ");
      out[29] := CHR(0);

      AddZahl((daten[m,3] + daten[m,4]) DIV 2, 3);
      AddZahl(daten[m,5], 3);
      AddZahl(daten[m,6], 3);
      AddZahl(daten[m,7], 3);

      AddZahl(daten[m,3], 4);
      Insert(out, last, ":");
      AddZahl(daten[m,4], 2);

      AddZahl(daten[m,1], 4);
      Insert(out, last, ":");
      AddZahl(daten[m,2], -4);

      IF daten[m,1] > daten[m,2] THEN
        Insert(out, last, "+");
        AddZahl(daten[m,1] - daten[m,2], 2);
      ELSIF daten[m,1] = daten[m,2] THEN
        Insert(out, last, "± 0");
      ELSE
        Insert(out, last, "-");
        AddZahl(daten[m,2] - daten[m,1], 2);
      END;
    END MacheAusgabeZeile;


  BEGIN  (* TabelleAusgeben *)
    IF NOT TabellenBerechnet THEN
      BerechneTabellen;
    END;
    CASE Nummer OF
    | 1: tab := Tabellen.gsmt;
         daten := TorePunkte.gsmt;
    | 2: tab := Tabellen.heim;
         daten := TorePunkte.heim;
    | 3: tab := Tabellen.ausw;
         daten := TorePunkte.ausw;
    END;
    IF Drucker THEN
      SetOutput("PRT:");
      ok := Done;
      IF ok THEN
        DruckFenster := NIL;
        DruckFenster := OeffneSpezFenster(230, 100, 180, 13, IDCMPFlagSet{},
                                          WindowFlagSet{}, NIL, NIL);
        WriteWin(DruckFenster, 6, 9, "Drucke");
        WriteWin(DruckFenster, 62, 9, FensterTitel[Nummer]);
      END;
    END;
    IF Drucker THEN
      Ausgabe := " [4m";
      Ausgabe[0] := CHR(27);
    ELSE
      Ausgabe := "";
    END;
    zeile := 10;
    Insert(Ausgabe, last, FensterTitel[Nummer]);
    Insert(Ausgabe, last, "                    ");
    IF Drucker THEN
      Ausgabe[34] := CHR(0);
    ELSE
      Ausgabe[30] := CHR(0);
    END;
    Insert(Ausgabe, last, "Sp  g  u  v  Punkte Tore  Diff");
    IF Drucker THEN
      IF ok THEN
        Insert(Ausgabe, last, " [24m");
        Ausgabe[64] := CHR(27);
        WriteString(Ausgabe);
        WriteLn;
      END
    ELSIF Statuszeile THEN
      WriteWin(TabellenFenster, 8, zeile, Ausgabe);
      Linie(TabellenFenster, 8, zeile + 3, 480, TRUE);
      INC(zeile, 12);
    END;
    FOR i := 1 TO AnzMan DO
      m := tab[i];
      MacheAusgabeZeile(m, Ausgabe);
      IF Drucker THEN
        IF ok THEN
          WriteString(Ausgabe);
          WriteLn;
        END;
      ELSE
        WriteWin(TabellenFenster, 8, zeile, Ausgabe);
        INC(zeile, 8);
      END;
    END;
    IF Drucker THEN
      WriteLn;
      CloseOutput;
      IF DruckFenster # NIL THEN
        SchliesseFenster(DruckFenster);
      END;
    END;
  END TabelleAusgeben;


PROCEDURE ZeigeTabellen;

  VAR
    Message: IntuiMessagePtr;
    calledGad: GadgetPtr;
    AuswahlFenster, TabFenster: Fenster;
    wahl, i, pos, aktuell: INTEGER;
    DruckerAusgabe: BOOLEAN;


  BEGIN (* ZeigeTabellen *)
    IF AnzMan = 0 THEN
      KeineDaten;
      RETURN;
    END;
    AuswahlFenster := NIL;
    TabFenster := NIL;
    TabFenster := OeffneSpezFenster(72, 50, 496, AnzMan * 8 + 20,
                                    IDCMPFlagSet{}, WindowFlagSet{}, NIL,
                                    NIL);
    IF TabFenster = NIL THEN
      RETURN;
    END;
    TabelleAusgeben(1, TabFenster, TRUE, FALSE);
    aktuell := 1;
    DruckerAusgabe := FALSE;
    wahl := WaehleTabelle(AuswahlFenster, 149, 12);
    IF AuswahlFenster # NIL THEN
      WHILE wahl # 0 DO
        IF (wahl > 0) AND ((wahl # aktuell) OR DruckerAusgabe) THEN
          TabelleAusgeben(wahl, TabFenster, TRUE, DruckerAusgabe);
          IF NOT DruckerAusgabe THEN
            aktuell := wahl;
          END;
        ELSIF wahl = -1 THEN
          calledGad := AuswahlFenster^.firstGadget;
          WHILE calledGad^.gadgetID # -1 DO
            calledGad := calledGad^.nextGadget;
          END;
          pos := RemoveGadget(AuswahlFenster, calledGad);
          DruckerAusgabe := NOT DruckerAusgabe;
          calledGad^.gadgetText^.iText := ADR(DruckerText[DruckerAusgabe]);
          pos := AddGadget(AuswahlFenster, calledGad, pos);
          RefreshGList(calledGad, AuswahlFenster, NIL, 1);
        END;
        wahl := WaehleTabelle(AuswahlFenster, 150, 12);
      END;
      SchliesseFenster(TabFenster);
      SchliesseFenster(AuswahlFenster);
    END;
  END ZeigeTabellen;


BEGIN  (* TabellenOps *)
  FensterTitel[1] := "Gesamtbilanz";
  FensterTitel[2] := "Heimbilanz";
  FensterTitel[3] := "Auswärtsbilanz";
END TabellenOps.
