#!/usr/bin/perl -w

# @INC = qw('/Volumes/Data/Users/Shared/.cpan/build/Tk-804.027/');
# @INC = qw('/opt/local/lib/perl5/vendor_perl/5.8.8/darwin-2level/');

use strict;

use Tk;

my $PI  = 22/7;
my $PI2 = $PI * 2;

&main();

sub main
{
	my $circles = Circles->new((circles=>20, diameter=>250));
	
	$circles->run();
}


package Circles;

sub new
{
	my ($class, %args) = @_;
	
	my $self = bless {}, ref($class) || $class;
	
	$self->_init(%args);
	
	return $self;
}

sub _init
{
	my ($self, %args) = @_;
	
	$self->{_circles}   = $args{circles}  || 10;
	$self->{_diameter}  = $args{diameter} || 250;
	$self->{_mw_width}  = 750;
	$self->{_mw_height} = 500;
	$self->{_offset}    = 0;
	$self->{_increment} = 5;
	$self->{_cirlist}   = [];
	$self->{_delay}     = 100;
	
	$self->{_window} = MainWindow->new(-title=>"Circles");
	$self->{_window}->minsize(750, 500);
	$self->{_canvas} = $self->{_window}->Canvas(-width=>$self->{_mw_width},-height=>$self->{_mw_height});
	$self->{_canvas}->pack (
		-fill   => 'both',
		-expand => 1,
		-anchor => 'nw');
	
	$self->drawCircles();
	
	$self->{_scale_circles} = $self->{_canvas}->Scale (
		-from       => 1,
		-to         => 50,
		-variable   => \$self->{_circles},
		-resolution => 1,
		-label      => "Circles",
		-orient     => "horizontal")->pack(-side=>'left', -fill=>"x", -expand=>1, -anchor=>"sw");
	
	$self->{_scale_circles} = $self->{_canvas}->Scale (
		-from       => 50,
		-to         => 1000,
		-variable   => \$self->{_diameter},
		-resolution => 1,
		-label      => "Diameter",
		-orient     => "horizontal")->pack(-side=>'left', -fill=>"x", -expand=>1, -anchor=>"sw");
	
	$self->{_scale_circles} = $self->{_canvas}->Scale (
		-from       => 1,
		-to         => 100,
		-variable   => \$self->{_increment},
		-resolution => 1,
		-label      => "Increment",
		-orient     => "horizontal")->pack(-side=>'left', -fill=>"x", -expand=>1, -anchor=>"sw");
	
	$self->{_scale_delay} = $self->{_canvas}->Scale (
		-from       => 50,
		-to         => 250,
		-variable   => \$self->{_delay},
		-resolution => 1,
		-label      => "Delay",
		-orient     => "horizontal",
		-command    => sub { $self->setRepeatDelay },
		-repeatdelay => 100
	)->pack(-side=>'left', -fill=>"x", -expand=>1, -anchor=>"sw");
	
	$self->{_repeat} = $self->{_canvas}->repeat($self->{_delay}, sub {$self->drawCircles});
}

sub setRepeatDelay
{
	my ($self) = @_;
	
	$self->{_repeat}->cancel();
	$self->{_canvas}->delete($self->{_repeat});
	$self->{_repeat} = $self->{_window}->repeat($self->{_delay}, sub { $self->drawCircles });
}

sub drawCircles
{
	my ($self) = @_;
	
	my $center_x = $self->{_mw_width}  / 2.0;
	my $center_y = ($self->{_mw_height} - 75) / 2.0;
	my $radius   = $self->{_diameter} / 2.0;
	my $cir_w    = 25;
	my $cir_h    = 25;
	my $increment = 360.0 / $self->{_circles};
	my $offset   = ($self->{_offset} += $self->{_increment}) % 360.0;
	
	# remove all of the existing circles from the canvas
	for (my $i = 0; $i <= $#{$self->{_cirlist}}; $i++) {
		$self->{_canvas}->delete($self->{_cirlist}[$i]);
	}
	$#{$self->{_cirlist}} = -1;
	
	my $center = $self->{_canvas}->createOval (
		$center_x - ($cir_w / 4.0),
		$center_y - ($cir_h / 4.0),
		$center_x + ($cir_w / 4.0),
		$center_y + ($cir_h / 4.0), -fill=>"green");
	
	for (my $i=0, my $angle=$offset; $i < $self->{_circles}; $i++, $offset+=$increment, $angle=$offset%360.0) {
		my $point_x = 0.0;
		my $point_y = 0.0;
		
		if ($angle == 0.0) {
			$point_x = $center_x;
			$point_y = $center_y - $radius;
		}
		elsif ($angle == 90.0) {
			$point_x = $center_x + $radius;
			$point_y = $center_y;
		}
		elsif ($angle == 180.0) {
			$point_x = $center_x;
			$point_y = $center_y + $radius;
		}
		elsif ($angle == 270.0) {
			$point_x = $center_x - $radius;
			$point_y = $center_y;
		}
		else {
			$point_x = $center_x + ($radius * sin($PI2 / (360.0 / $angle)));
			$point_y = $center_y - ($radius * cos($PI2 / (360.0 / $angle)));
		}
			
		$self->{_cirlist}[$i] = $self->{_canvas}->createOval (
			$point_x - ($cir_w / 2.0),
			$point_y - ($cir_h / 2.0),
			$point_x + ($cir_w / 2.0),
			$point_y + ($cir_h / 2.0), -fill=>"red");
	}
	
}

sub run
{
	my ($self) = @_;
	
	$self->{_window}->MainLoop();
}




1;
