
    package MainWindow;
    sub Signal {
        my ($self) = shift;
        return SignalView->new(-main=>$self);
    }
    package SignalView;
    use Signal;
    sub new {
        my $type = shift;
        my %params = @_;
        my $self = {};
        my $signal = Signal->new(%params);
        my $main = $params{-main};
        my $canvas;
        my $states = $signal->{'States'};
        my %views = ();
        $self->{'Interval'} = 500;
        $canvas = $main->Canvas(-width=>50,-height=>150);
        $x = 5; $y = 5;
        $r = 40;
        for $state ( @$states ) {
            $views{$state} = 
                $canvas->create('oval', $x, $y, $x+$r, $y+$r, 
                    -width => 1, -outline => 'black', -fill => 'black');
            $y += 50;
        }
        $canvas->pack(-side=>left);
        $self->{'MainWindow'}  = $main;
        $self->{'Canvas'}  = $canvas;
        $self->{'Views'}  = \%views;
        $self->{'Signal'}  = $signal;
        bless $self;
    }
    sub next {
        my ($self) = shift;
        my $state = $self->{'Signal'}->{'State'};
        my $view = $self->{'Views'}->{$state};
        my $canvas = $self->{'Canvas'};
        $canvas->itemconfigure($view,-fill=>'black');
        $state = $self->{'Signal'}->next();
        $view = $self->{'Views'}->{$state};
        $canvas->itemconfigure($view,-fill=>$state);
    }
    sub update {
        my ($self) = shift;
        $self->{'MainWindow'}->update();
    }
    sub run {
        my ($self) = shift;
        my %params = @_;
        my $main=$self->{'MainWindow'};
        if(defined($params{'Interval'})) {
            $self->{'Interval'} = $params{'Interval'};
        }
        if(! $self->{'Running'})  {
            $self->{'Running'} = 1;
            $main->after($self->{'Interval'},sub {$self->running()});
        }
    }
    sub running {
        my ($self) = shift;
        my $interval = $self->{'Interval'};
        if($self->{'Running'}) {
            $self->next();
            $self->update();
            $self->{'MainWindow'}->after($interval,sub {$self->running()});
        } 
    }
    sub stop {
        my ($self) = shift;
        $self->{'Running'} = 0;
    }
    package Main;
    use Tk;
    $main = MainWindow->new();
    $signal = $main->Signal();
    $signal->run();
    &MainLoop();


