{ Copyright (c) 1991 by Hans-Jrgen Schloarek }

unit graftool;
{ Objektorientierte Programmierung }

interface

uses Graph, Crt;

type
  linieptr = ^linie;

  Linie = object
    xr1,yr1,xr2, yr2 : Integer;
    Sichtbar:boolean;
    constructor Init(InitX, InitY, Initx1, Inity1 : Integer);
    destructor Entfernen;
    procedure Sicht;virtual;
    procedure Unsicht;virtual;
    function Istsichtbar:boolean;
    function gehx:integer;
    function gehy:integer;
    function gehx1:integer;
    function gehy1:integer;
    procedure Move_to(rx, ry, rx1, ry1:integer);
    procedure Verschieben(diff:Integer);virtual;
    procedure RGroesser(Gdiffx : Integer);
    procedure RKleiner(Kdiffx : Integer);
  end;

  PunktPtr = ^punkt;

  Punkt = object
    Sichtbar : Boolean;
    x,y:integer;
    constructor Init(InitX, InitY : Integer);
    destructor Entfernen; virtual;
    procedure Sicht; virtual;
    procedure Unsicht; virtual;
    function Istsicht : Boolean;
    function GehX : Integer;
    function GehY : Integer;
    procedure moveto(neux, neuy:integer);
    procedure Verschieb(Diff : Integer); virtual;
  end;

  KreisPtr = ^Kreis;

  Kreis = object (Punkt)
    Radius : Integer;
    constructor Init(InitX, InitY : Integer;
                     InitRadius : Integer);
    procedure Sicht; virtual;
    procedure Unsicht; virtual;
    procedure Groesser(Gdiff : Integer);
    procedure Kleiner(Kdiff : Integer);
  end;

  Ellipseptr = ^Ellipse;

  Ellipse = object (Kreis)
    Startw, Endw: word;
    XRadius, YRadius : Integer;
    constructor Init(InitX, InitY : Integer;
    InitStart, InitEnd:word; InitXRadius, InitYRadius : Integer);
    procedure Sicht; virtual;
    procedure Unsicht; virtual;
    procedure EGroesser(Gdiffx, Gdiffy : Integer);
    procedure EKleiner(Kdiffx, Kdiffy : Integer);
  end;

  rechteckptr = ^rechteck;

  rechteck = object (linie)
     constructor Init(Initx, Inity, Initx1, Inity1:integer);
     procedure Sicht;virtual;
     procedure Unsicht;virtual;
     procedure rgroesser(gdiffx:integer);
     procedure rkleiner(kdiffx:integer);
     end;

var
    graphdriver,graphmode:integer;

implementation

                   { Punkte-Methoden Implementieren }

constructor Punkt.Init(InitX, InitY : Integer);
begin
  x := InitX;
  y := InitY;
  Sichtbar := False;
end;

destructor Punkt.Entfernen;
begin
  Unsicht;
end;

procedure Punkt.Sicht;
begin
  Sichtbar := True;
  PutPixel(X, Y, GetColor);
end;

procedure Punkt.Unsicht;
begin
  Sichtbar := False;
  PutPixel(X, Y, GetBkColor);
end;

function Punkt.Istsicht : Boolean;
begin
  Istsicht := Sichtbar;
end;

function Punkt.GehX : Integer;
begin
  GehX := X;
end;

function Punkt.GehY : Integer;
begin
  GehY := Y;
end;

procedure Punkt.MoveTo(NeuX, NeuY : Integer);
begin
  unsicht;
  X := NeuX;
  Y := NeuY;
  sicht;
end;

function GetDelta(var DeltaX : Integer;
                  var DeltaY : Integer) : Boolean;
var
  KeyChar : Char;
  Quit : Boolean;
begin
  DeltaX := 0; DeltaY := 0;  { 0 Position unverndert }
  GetDelta := True;          { True = Verschiebung }
  repeat
    KeyChar := ReadKey;      { Tastendruck lesen }
    Quit := True;            { zulssige Taste }
    case Ord(KeyChar) of
       0: begin          { 0 = erweiteter Tastaturcode }
            KeyChar := ReadKey;  { erweiterten Code lesen }
            case Ord(KeyChar) of
             72: DeltaY := -1;   { Cursor nach oben; dec Y }
             80: DeltaY := 1;    { Cursor nach unten; inc Y }
             75: DeltaX := -1;   { Cursor nach links; dec X }
             77: DeltaX := 1;    { Cursor nach rechts; inc X }
             else Quit := False; { andere Tasten ignorieren }
            end; { case }
          end;
      13: GetDelta := False; { Return = keine Verschiebung }
      else Quit := False;
     end;  { case }
  until Quit;       { Schleifenende wenn Quit = true }
end;

procedure Punkt.Verschieb(Diff : Integer);
var
  DeltaX, DeltaY : Integer;
  FigurX, FigurY : Integer;
begin
  Sicht;             { Figur darstellen }
  FigurX := GehX;    { Figuranfangsposition }
  FigurY := GehY;

                     { Verschiebungsschleife }
  while GetDelta(DeltaX, DeltaY) do
  begin
    FigurX := FigurX + (DeltaX * Diff);
    FigurY := FigurY + (DeltaY * Diff);
    MoveTo(FigurX, FigurY); { Figur verschieben }
  end;
end;

            { Kreis-Methoden Implementieren }

constructor Kreis.Init(InitX, InitY : Integer;
                        InitRadius : Integer);
begin
  Punkt.Init(InitX, InitY);
  Radius := InitRadius;
end;

procedure Kreis.Sicht;
begin
  Sichtbar := True;
  Graph.Circle(X, Y, Radius);
end;

procedure Kreis.Unsicht;
var
  AltColor : Word;
begin
  AltColor := Graph.GetColor;
  Graph.SetColor(GetBkColor);
  Sichtbar := False;
  Graph.Circle(X, Y, Radius);
  Graph.SetColor(Altcolor);
end;

procedure Kreis.Groesser(Gdiff : Integer);
begin
  unsicht;
  Radius := Radius + Gdiff;
  if Radius < 0 then Radius := 0;
  Sicht;
end;

procedure Kreis.Kleiner(Kdiff : Integer);
begin
  Groesser(-Kdiff);
end;

            { Ellipse-Methoden Implementieren }

constructor Ellipse.Init(InitX, InitY : Integer;
InitStart, InitEnd : word; InitXRadius, InitYRadius : Integer);

begin
  Punkt.Init(InitX, InitY);
  Startw := InitStart;
  Endw   := InitEnd;
  XRadius:= InitXRadius;
  YRadius:= InitYRadius;
end;

procedure Ellipse.Sicht;
begin
  Sichtbar := True;
  Graph.Ellipse(X, Y, Startw, Endw, XRadius, YRadius);
end;

procedure Ellipse.Unsicht;
var
  AltColor : Word;
begin
  AltColor := Graph.GetColor;
  Graph.SetColor(GetBkColor);
  Sichtbar := False;
  Graph.Ellipse(X, Y, Startw, Endw, XRadius, Yradius);
  Graph.SetColor(Altcolor);
end;

procedure Ellipse.EGroesser(Gdiffx, Gdiffy : Integer);
begin
  unsicht;
  XRadius := XRadius + Gdiffx;
  if XRadius < 0 then XRadius := 0;
  YRadius := YRadius + GdiffY;
  if YRadius < 0 then YRadius := 0;
  Sicht;
end;

procedure Ellipse.EKleiner(Kdiffx, Kdiffy : Integer);
begin
  EGroesser(-Kdiffx, -kdiffy);
end;

            { Rechteck-Methoden Implementieren }

constructor linie.Init(InitX, InitY, Initx1, Inity1 : Integer);
begin
  xr1 := Initx;
  yr1 := Inity;
  xr2 := Initx1;
  yr2 := Inity1;
  sichtbar:=false;
end;

function linie.gehx:integer;
begin
gehx:=xr1;
end;

function linie.gehy:integer;
begin
gehy:=yr1;
end;

function linie.gehx1:integer;
begin
gehx1:=xr2;
end;

function linie.gehy1:integer;
begin
gehy1:=yr2;
end;

procedure linie.Sicht;

begin
  Sichtbar := True;
  Graph.line(xr1, yr1, xr2, yr2);
end;

procedure linie.Unsicht;
var
  AltColor : Word;
begin
  AltColor := Graph.GetColor;
  Graph.SetColor(GetBkColor);
  Sichtbar := False;
  Graph.line(xr1, yr1, xr2, yr2);
  Graph.SetColor(Altcolor);
end;

function linie.Istsichtbar : Boolean;
begin
  Istsichtbar := Sichtbar;
end;

destructor linie.Entfernen;
begin
  Unsicht;
end;

procedure linie.Move_To(rX, rY, rx1, ry1 : Integer);
begin
  unsicht;
  xr1 := rX;
  yr1 := rY;
  xr2 := rx1;
  yr2 := ry1;
  sicht;
end;

procedure linie.Verschieben(Diff : Integer);
var
  DeltaX, DeltaY : Integer;
  FiguX, FiguY : Integer;
  Figux1,Figuy1 : Integer;
begin
  sicht;
  FiguX := Gehx;    { Figuranfangsposition }
  Figuy := Gehy;
  Figux1:= Gehx1;                   { Verschiebungsschleife }
  Figuy1:= Gehy1;
  while GetDelta(DeltaX, DeltaY) do
  begin
    move_to(FiguX, FiguY, Figux1, Figuy1); { Figur verschieben }
    FiguX := FiguX + (DeltaX * Diff);
    FiguY := FiguY + (DeltaY * Diff);
    Figux1:= Figux1 + (DeltaX * Diff);
    Figuy1:= Figuy1 + (DeltaY * Diff);
    move_to(FiguX, FiguY, Figux1, Figuy1); { Figur verschieben }
  end;
end;

procedure linie.RGroesser(Gdiffx : Integer);
begin
  unsicht;
  xr2 := xr2 + Gdiffx;
  if xr2 <= xr1 then xr2 := xr1;
  Sicht;
end;

procedure linie.RKleiner(Kdiffx : Integer);
begin
  RGroesser(-Kdiffx);
end;

constructor rechteck.Init(Initx, Inity, Initx1, Inity1:integer);
begin
  linie.Init(Initx, Inity, Initx1, Inity1);
end;

procedure rechteck.Sicht;

begin
  Sichtbar := True;
  Graph.rectangle(xr1, yr1, xr2, yr2);
end;

procedure rechteck.Unsicht;
var
  AltColor : Word;
begin
  AltColor := Graph.GetColor;
  Graph.SetColor(GetBkColor);
  Sichtbar := False;
  Graph.rectangle(xr1, yr1, xr2, yr2);
  Graph.SetColor(Altcolor);
end;

procedure rechteck.RGroesser(Gdiffx : Integer);
begin
  unsicht;
  xr2:= xr2 + Gdiffx;
  yr2:= yr2 + gdiffx;
  if xr2 <= xr1 then xr2 := xr1;
  if yr2 <= yr1 then yr2 := yr1;
  Sicht;
end;

procedure rechteck.RKleiner(Kdiffx : Integer);
begin
  RGroesser(-Kdiffx);
end;

begin          { Initialisierungsteil }
     graphdriver:=detect;
     initgraph(graphdriver,graphmode,'');
     if Graphresult <> grok then
        begin
        writeln('--- Programmabbruch wegen Grafikfehler: ',
                Grapherrormsg(graphdriver));
        Halt(1);
        end;
      setwritemode(xorput);
end.
