#!/usr/bin/perl
#use Mooix::Thing;
#use Fcntl q{:flock};
run sub {
        my $this=shift;
        %_=@_;
 
	# Not always.
	return $this if rand > 0.80;
	
	# Set the ball to be bouncing. Note this is done while the ball is
	# still locked for movement by the caller. Use a unique id in the
	# bouncing field since this method might be called while it's
	# already running.
	return if $this->bouncing;
	my $id=$$;
	$this->bouncing($id);
	
	# After forking to the background, the ball won't be locked for
	# movement anymore (since the caller holds the lock only until this
	# method returns).
        return $this unless $this->background;
        
        # If it is inside a container, it may bounce its way out.
	while ($this->location->location && ! $this->location->closed) {
		last if rand() <= .333;
		
		# Lock and check same as in loop below.
		my $lock=$this->getlock(LOCK_EX);
		return unless $this->bouncing eq $id;
			
		my $oldloc = $this->location;
		$this->msg('bounce_off', %_);
		$this->physics->move(object => $this, to => $oldloc->location) || last;
		$this->bouncing($id); # moving the ball interrupts bouncing
		
		close $lock;
		sleep(1);
	}
        
        for (1..rand(3)) {
		# Lock the ball for movement. Then check to see if the
		# bounce was interrupted by something.
		my $lock=$this->getlock(LOCK_EX);
		return unless $this->bouncing eq $id;

                $this->msg('bounce', %_);

		close $lock; # allow someone to intercept the bouncing ball
		sleep(1);    # while we sleep
        }

	# The bouncing is done, lock just in case.
	my $lock=$this->getlock(LOCK_EX);
	$this->bouncing(0);
}
