use strict;
use warnings;
use Tk;

my $draw_item = 'rect';
my $thickness = 1;
my $message;
my ($startx, $starty);

my $mw = MainWindow->new();
$mw->geometry('800x600');
$mw->title("Malmal");

# Frame für die linke Kommandospalte
my $f = $mw->Frame(-relief => 'groove',
                   -bd     => 2,
                   -label  => 'Zeichnen')
             ->pack(-side  => 'left', -fill => 'y');

# Auswahl der Zeichenobjekte
$f->Radiobutton(-variable => \$draw_item,
                -text     => 'Rechteck',
                -value    => 'rect',
                -command  => \&bind_start)
     ->pack(-anchor => 'w');
$f->Radiobutton(-variable => \$draw_item,
                -text     => "Oval",
                -value    => "oval",
                -command  => \&bind_start)
     ->pack(-anchor => 'w');
$f->Radiobutton(-variable => \$draw_item,
                -text     => "Linie",
                -value    => "line",
                -command  => \&bind_start)
     ->pack(-anchor => 'w');

# Wahl der Linienbreite
$f->Label(-text => 'Linienbreite: ')->pack(-anchor => 'w');
$f->Entry(-textvariable => \$thickness)->pack(-anchor => 'w');

# Mausposition
$f->Label(-textvariable => \$message)
     ->pack(-side => 'bottom', -fill => 'x');

# rechts der Canvas zum Malen
my $c = $mw->Scrolled('Canvas', -cursor => 'crosshair', -background => 'white')
              ->pack(-side => 'left', -fill => 'both', -expand => 1);
my $canvas = $c->Subwidget('canvas');

# Bindung an den Mausknopf 
bind_start();

MainLoop;

sub bind_start 
  {
  # Bindung der Maus
  # falls schon eine 'moton'-Bindung existiert, nichts tun
  my @bindings = $canvas->Tk::bind("<Motion>");
  return if ($#bindings >= 0);
  $canvas->Tk::bind('<Motion>', [\&show_coords, Ev('x'), Ev('y')]);
  $canvas->Tk::bind("<Button-1>", [\&start_drawing, Ev('x'), Ev('y')]);
  }

sub start_drawing 
  {
  # nach dem ersten Mausklick 'folgt' das Grafikobjekt der Maus
  # --> typisches 'Aufziehen' wie im Malprogramm
  my ($canv, $x, $y) = @_;
  $x = $canv->canvasx($x);
  $y = $canv->canvasy($y);

  # Dicke muss Zahl sein
  $thickness = 1 if ($thickness !~ /[0-9]+/);

  if ($draw_item eq "rect") 
    {
    $canvas->createRectangle($x, $y, $x, $y,
       -width => $thickness, -tags => 'AktObjekt');
    } 
  elsif ($draw_item eq "oval") 
    {
    $canvas->createOval($x, $y, $x, $y,
       -width => $thickness, -tags => 'AktObjekt');
    } 
  elsif ($draw_item eq "line") 
    {
    $canvas->createLine($x, $y, $x, $y,
       -width => $thickness, -tags => 'AktObjekt');
    }

  $startx = $x; $starty = $y;
  # Die Bindung des Mausbuttons auf end_drawing() umschalten
  $canvas->Tk::bind('<Motion>', [\&size_item, Ev('x'), Ev('y')]);
  $canvas->Tk::bind('<Button-1>', [\&end_drawing, Ev('x'), Ev('y')]);
  }

sub show_coords
  {
  shift;
  $message = $_[0] . ', ' . $_[1];
  }

sub size_item 
  {
  # Maus verfolgen, Objketgroesse aendern
  my ($canv, $x, $y) = @_;
  $x = $canv->canvasx($x);
  $y = $canv->canvasy($y);
  # Koordinaten ausgeben
  $message = $startx . ', ' . $starty . ' -> ' 
           . $x . ', ' . $y;
  # Groesse anpassen, Objekt taggen
  $canvas->coords('AktObjekt', $startx, $starty, $x, $y);
  }

sub end_drawing 
  {
  my ($canv, $x, $y) = @_;
  $x = $canv->canvasx($x);
  $y = $canv->canvasy($y);
  # Objekt festnageln, Tag entfernen
  $canvas->coords('AktObjekt', $startx, $starty, $x, $y);
  $canvas->dtag('AktObjekt');
  # 'Motion'-Bindung entfernen 
  $canvas->Tk::bind('<Motion>', '');
    # Alles auf Anfang
  bind_start();
  }
