######################################################################
# Stopwatch.pm
######################################################################
# Perl Power! - Michael Schilli 1998
######################################################################

######################################################################
# Stopwatch
######################################################################

package Stopwatch;

use Tk;                              # 'after()' - defined in Tk.pm
######################################################################
# $sw=Stopwatch->new(\&update_func, $update_time); - constructor
######################################################################
sub new {
    my $self = bless({}, shift);     

    $self->{'usrproc'}     = shift;  # user-defined callback
    $self->{'interval'}    = shift;  # update interval in seconds

    $self->{'running'}     = 0;

    $self->{'starttime'}   = 
    $self->{'stoptime'}    = time;

    # no update interval below 1 second
    if($self->{'interval'} < 1000) {  
        print "Stopwatch: No update intervals < 1000 accepted." .
              " Not started.\n";
        return undef;
    }

    $self->looper();                 # start loop process

    $self;                           # object reference
}

######################################################################
# $sw->looper(); - internal(!) loop function
######################################################################
sub looper {
    my $self = shift;
                                   # call user function
    &{$self->{'usrproc'}}($self) if $self->{'running'};

                                   # loop (no recursion)
    after($self->{'interval'}, sub { $self->looper()});      
}

######################################################################
# $sw->start(); - start stopwatch
######################################################################
sub start {
    my $self = shift;

    # set start time: eliminate time
    # between last stop and now
    unless($self->{'running'}) { 
        $self->{'starttime'} += time - $self->{'stoptime'};
    }

    $self->{'running'}   = 1;
}

######################################################################
# $sw->stop(); - stop stopwatch
######################################################################
sub stop {
    my $self = shift;

    $self->{'stoptime'} = time if $self->{'running'};

    $self->{'running'} = 0;
}

######################################################################
# $seccount=$sw->gettime(); - interrogate time on stopwatch
######################################################################
sub gettime {
    my $self = shift;

    time - $self->{'starttime'};
}

######################################################################
# $sw->reset(); - reset stopwatch
######################################################################
sub reset {
    my $self = shift;

    $self->{'starttime'} =
    $self->{'stoptime'}  = time;
}

1;

