{
 Programm       : Plot_site
 Beschreibung   : Liest eine Plotterdatei ein und
                  wertet diese im richtigen Seiten-
                  verh„ltnis aus (gibt sie auch aus)
 Autor          : Lampacher Martin & Theiner Stefan
 Klasse         : 3IB
 Datum          : 16.03.05
 Auftraggeber   : Prof. Jrgen Kofler
}

PROGRAM
 Plotter;
USES
 Crt,Graph;
TYPE
 Teingabe = (P,U,D,E,Z,Pu,Ko,Sk);
 {
  Eingabem”glichkeiten:
  P = Zeichen 'p'
  U = Zeichen 'u'
  D = Zeichen 'd'
  E = Zeichen 'e'
  Z = Ziffer von 0 bis 9
  Pu= Punkt wird eingelesen
  Ko= Komma wird eingelesen
  Sk= Semikolon wird eingelesen
 }
 Tzustand = (start,zp,zu,zd,ze,fa,
             zi ,zipu ,nk ,zw ,zi2 ,zi2pu ,nk2,
             zid,zipud,nkd,zwd,zi2d,zi2pud,nk2d);
 {
  Zust„nde:
   zp, zu, zd, ze : Das Zeichen nach dem z wurde eingelesen
   fa             : Zustand fr den Farbwechsel
   zi,zipu...     : Werden fr das korrekte Einlesen der Zahlen
                    ben”tigt:
     -zi          : Eine Ziffer wurde eingelesen
     -zipu        : Ziffer und ein Punkt wurde eingelesen
     -nk          : Ziffern nach dem Komma werden eingelesen
     -zi2         : Beginne mit dem Einlesen der 2. Koordinate
     -zi2pu       : Ein Punkt bei der 2. Ziffer eingelesen
     -nk2         : Nachkommastellen der 2. Ziffer einlesen
  zid, zipud...   : Entsprechen den obigen Zust„nden, werden aber
                    fr PenDown verwendet
 }

{
 Funktion       : Convert
 Beschreibung   : Wandelt das eingelesene Zeichen in den
                  dazugeh”rigen Eingabentyp um
 Eingabeparam.  : ch, ein Character, das umgewandelt wird
 Funktionswert  : Eingabentyp, wird fr den Automaten verwendet
}
FUNCTION Convert(ch : CHAR) : Teingabe;
 BEGIN
  CASE ch OF
   'p' : Convert := P;
   'u' : Convert := U;
   'd' : Convert := D;
   'e' : Convert := E;
   '0','1','2','3','4','5','6','7','8','9' :
         Convert := Z;
   '.' : Convert := Pu;
   ',' : Convert := Ko;
   ';' : Convert := Sk;
  END;
 END;

PROCEDURE Format(op1,op2   : STRING;
                 xneu,yneu : INTEGER;
                 VAR xf,yf : INTEGER);
 VAR
  xr,yr     : REAL;
  x,y,code  : INTEGER;
 BEGIN
  Val(op1,xr,code);
  Val(op2,yr,code);
  {  x:op1=640:xneu 320 }
  x := ROUND(xr);
  y := ROUND(yr);
{  xf := ((640) DIV xneu) * x;
  yf := ((480) DIV yneu) * y;}
  xf := ((x) DIV xneu) * 640;
  yf := ((y) DIV yneu) * 480;

 END;

{
 Prozedur       : Zeichne
 Beschreibung   : Zeichnet eine Linie zu den
                  Koordinaten op1, op2; wandelt diese
                  aber zuerst um. Entspricht PD
 Eingabeparam.  : op1, op2 vom Typ String, sind Koordinaten
                  xneu,yneu von Typ Integer, sind die
                  Seitenl„ngen, die der Benutzer angegeben hat
}
PROCEDURE Zeichne(op1,op2 : STRING;
                  xneu,yneu : INTEGER);
 VAR
  x,y : INTEGER;
 BEGIN
  Format(op1,op2,xneu,yneu,x,y);
  LineTo(x,y);
 END;

{
 Prozedur       : Gehezu
 Beschreibung   : Geht zu den gegebenen
                  Koordinaten op1, op2; wandelt diese
                  aber zuerst um. Entspricht PU
 Eingabeparam.  : op1, op2 vom Typ String, sind Koordinaten
                  xneu,yneu von Typ Integer, sind die
                  Seitenl„ngen, die der Benutzer angegeben hat
}
PROCEDURE Gehezu(op1,op2 : STRING;
                 xneu,yneu : INTEGER);
 VAR
  x,y : INTEGER;
 BEGIN
  Format(op1,op2,xneu,yneu,x,y);
  MoveTo(x,y);
 END;

{
 Prozedur       : Arbeit
 Beschreibung   : Fhrt alle Operationen mit Hilfe
                  der anderen Funktionen um
 Eingabeparam.  : xneu,yneu sind die Seitenl„ngen,
                  die der Benutzer eingibt
}
PROCEDURE Arbeit(xneu,yneu : INTEGER);
 VAR
  i, forb, code     : INTEGER;
  ch                : CHAR;        {Eingelesenes Zeichen  }
  op1,op2,befehl    : STRING;      {op1, op2 = Koordinaten}
  datei             : TEXT;
  zustand           : Tzustand;
  eingabe           : Teingabe;
 BEGIN
  forb := 1;
  zustand := start;
  {Einlesen der Datei}
  Assign(datei,'H:\PROGRA~1\PLOTTER\test2.hpg');
  Reset(datei);
  WHILE NOT(eof(datei)) DO
   BEGIN
    ReadLn(datei,befehl);
    op1     := '';
    op2     := '';
    FOR i := 1 TO Length(befehl) DO
     BEGIN
      ch := befehl[i];
      eingabe := Convert(ch);
      {Hier werden alle Zust„nde mit den m”glichen
       Eingaben durchgelaufen                     }
      CASE zustand OF
       start : BEGIN
                IF eingabe = P THEN
                 zustand := zp
                ELSE
                 zustand := start;
               END;
       zp    : CASE eingabe OF
                U : zustand := zu;
                D : zustand := zd;
                E : zustand := ze;
               ELSE
                zustand := start;
               END;
       ze    : IF (eingabe = Z) THEN
                BEGIN
                 Val(befehl[i],forb,code);
                 {Farbcodes befinden sich im Zahlen-
                  bereich von eins bis fnf         }
                 IF (1 <= forb) AND (forb <= 5) THEN
                  zustand := fa
                 ELSE
                  zustand := start;
                END
               ELSE
                zustand := start;
       fa    : BEGIN
                {Hier werden die Zeichenfarben gestellt}
                IF (eingabe = Sk) THEN
                 CASE forb OF
                  1 : SetColor(8);
                  2 : SetColor(blue);
                  3 : SetColor(red);
                  4 : SetColor(yellow);
                  5 : SetColor(green);
                 END;
                zustand := start;
               END;
       zd    : IF (eingabe = Z) THEN
                BEGIN
                 zustand := zid;
                 op1 := op1 + ch;
                END
               ELSE
                zustand := start;
       zu    : IF (eingabe = Z) THEN
                BEGIN
                 zustand := zi;
                 op1 := op1 + ch;
                END
               ELSE
                zustand := start;
       zi     : CASE eingabe OF
                 Z  : BEGIN
                       zustand := zi;
                       op1 := op1 + ch;
                      END;
                 Ko : BEGIN
                       zustand := zi2;
                      END;
                 Pu : BEGIN
                       zustand := zipu;
                       op1 := op1 + '.'
                      END;
                 ELSE
                  zustand := start;
                END;
       zipu    : IF (eingabe = Z) THEN
                  BEGIN
                   zustand := nk;
                   op1 := op1 + ch;
                  END
                 ELSE
                  zustand := start;
       nk      : IF (eingabe = Ko) THEN
                  BEGIN
                   zustand := zw;
                  END
                 ELSE
                  IF (eingabe = Z) THEN
                   BEGIN
                    op1 := op1 + ch;
                    zustand := nk;
                   END
                  ELSE
                   zustand := start;
       zw      : IF (eingabe = Z) THEN
                  BEGIN
                   zustand := zi2;
                   op2 := op2 + ch;
                  END;
       zi2     : IF (eingabe = Z) THEN
                  op2 := op2 + ch
                 ELSE
                  IF (eingabe = Pu) THEN
                   BEGIN
                    zustand := zi2pu;
                    op2 := op2 + '.';
                   END
                  ELSE
                   IF (eingabe = Sk) THEN
                    BEGIN
                     zustand := start;
                     Gehezu(op1,op2,xneu,yneu);
                    END
                   ELSE
                    zustand := start;
       zi2pu   : IF (eingabe = Z) THEN
                  BEGIN
                   op2 := op2 + ch;
                   zustand := nk2;
                  END
                 ELSE
                  zustand := start;
       nk2     : IF (eingabe = Z) THEN
                  op2 := op2 + ch
                 ELSE
                  IF (eingabe = Sk) THEN
                   BEGIN
                    zustand := start;
                    Gehezu(op1,op2,xneu,yneu);
                   END
                  ELSE
                   zustand := start;
       zid    : CASE eingabe OF
                 Z  : BEGIN
                       zustand := zid;
                       op1 := op1 + ch;
                      END;
                 Ko : BEGIN
                       zustand := zi2d;
                      END;
                 Pu : BEGIN
                       zustand := zipud;
                       op1 := op1 + '.';
                      END;
                 ELSE
                  zustand := start;
                END;
       zipud   : IF (eingabe = Z) THEN
                  BEGIN
                   zustand := nkd;
                   op1 := op1 + ch;
                  END
                 ELSE
                  zustand := start;
       nkd     : IF (eingabe = Ko) THEN
                  BEGIN
                   zustand := zwd;
                  END
                 ELSE
                  IF (eingabe = Z) THEN
                   BEGIN
                    op1 := op1 + ch;
                    zustand := nkd;
                   END
                  ELSE
                   zustand := start;
       zwd     : IF (eingabe = Z) THEN
                  BEGIN
                   zustand := zi2d;
                   op2 := op2 + ch;
                  END;
       zi2d    : IF (eingabe = Z) THEN
                  op2 := op2 + ch
                 ELSE
                  IF (eingabe = Pu) THEN
                   BEGIN
                    zustand := zi2pud;
                    op2 := op2 + '.';
                   END
                  ELSE
                   IF (eingabe = Sk) THEN
                    BEGIN
                     zustand := start;
                     Zeichne(op1,op2,xneu,yneu);
                    END
                   ELSE
                    zustand := start;
       zi2pud  : IF (eingabe = Z) THEN
                  BEGIN
                   op2 := op2 + ch;
                   zustand := nk2d;
                  END
                 ELSE
                  zustand := start;
       nk2d    : IF (eingabe = Z) THEN
                  op2 := op2 + ch
                 ELSE
                  IF (eingabe = Sk) THEN
                   BEGIN
                    zustand := start;
                    Zeichne(op1,op2,xneu,yneu);
                   END
                  ELSE
                   zustand := start;

       END;{END von CASE }
      END; {END von FOR  }
   END;    {END von WHILE}
  {Lesen von Datei abgeschlossen}
  Close(datei);
 END;

VAR
 gDriver, gMode,ErrCode,xneu,yneu : INTEGER;
 datei : TEXT;
BEGIN
 ClrScr;
  Write  ('Xneu : ');
  ReadLn (xneu);
  Write  ('Yneu : ');
  ReadLn (yneu);
 {Einstellen des Grafikmodus}
 gDriver := Detect;
 ErrCode := GraphResult;
 {Der letzte Parameter ist '' weil ich egavga.bgi
  im gleichen Ordner habe, wie die Pascal-File.
  Also muss egavga.bgi im Falle einer Pfad„nderung
  mitkopiert werden!!       }
 InitGraph (gDriver,gMode,'');
 IF ErrCode = grOk THEN
  BEGIN
   ClearDevice;
   {Aufruf der Plotterprozedur}
   Arbeit(xneu,yneu);
  END
 ELSE
  {Falls ein Fehler beim Grafikmodus auftritt,
   wird er ausgegeben                         }
  WriteLn ('Graphics error: ',GraphErrorMsg(ErrCode));
 ReadKey;
 CloseGraph;
END.
