#!/afs/athena/contrib/perl5/perl

if($#ARGV != 1) {
    print "life.pl prob max\n";
    exit;
}
use Tk;

my $win = MainWindow->new;
my $graph = MainWindow->new;

my $c = $win->Canvas(-height => 310, -width => 310);
my $g = $graph->Canvas(-height => 310, -width => 310);

$c->pack();
$g->pack();
$g->Tk::bind("<1>" => \&fillgrid);

$c->Tk::bind("<1>" => \&placedot);
$c->Tk::bind("<2>" => \&clearall);
$c->Tk::bind("<3>" => \&pause);

&fillgrid;

sub placedot {
    my $e = $c->XEvent;
    $px = int((5+$e->x)/10);
    $py = int((5+$e->y)/10);
    if(!$$grid[$px][$py]){
	$$grid[$px][$py] = 1;
	&newcell($px, $py);
    }
    else{
	$$grid[$px][$py] = 0;
	&diecell($px, $py);
    }
}

sub pause {
    if($paused){
	$paused = 0;
    }
    else{
	$paused = 1;
    }
}

sub clearall {
for $i (1..30){
    for $j (1..30){
	$$grid[$i][$j] = 0;
	&diecell($i, $j);
    }
}

}

sub fillgridtest {
for $i (1..30){
    for $j (1..30){
	&diecell($i, $j);
    }
}
    $$grid[10][10] = 1;
    $$grid[10][11] = 1;
    $$grid[10][9] = 1;
    &newcell(10,10);
    &newcell(10,9);
    &newcell(10,11);
}

sub fillgrid {
    $cct=0;
srand;
for $i (1..30){
    for $j (1..30){
	if ((rand(1) > $ARGV[0]) && ($cct < $ARGV[1])){
	    ${$grid[$i]}[$j] = 1;
	($cct++);
	&newcell($i, $j);
    }
    else{
	&diecell($i, $j);
    }
    }
}
}

while(1){
    if($paused){
	$c->update;
	$g->update;
	next;
    }
for $i (1..30){
    for $j (1..30){
	${$oldgrid[$i]}[$j] = ${$grid[$i]}[$j];
    }
}

for $i (0..31){
    ${$oldgrid[0]}[$i] = ${$grid[30]}[$i];
    ${$oldgrid[31]}[$i] = ${$grid[1]}[$i];
    ${$oldgrid[$i]}[0] = ${$grid[$i]}[30];
    ${$oldgrid[$i]}[31] = ${$grid[$i]}[1];
}

    ${$oldgrid[0]}[0] = ${$grid[30]}[30];
    ${$oldgrid[0]}[31] = ${$grid[30]}[1];
    ${$oldgrid[31]}[0] = ${$grid[1]}[30];
    ${$oldgrid[31]}[31] = ${$grid[1]}[1];


$pop=0;
$agetot=0;
for $i (1..30){
    for $j (1..30){
	$n = 0;
	$n ++ if  ${$oldgrid[$i]}[$j-1];
	$n ++ if  ${$oldgrid[$i-1]}[$j-1];
	$n ++ if  ${$oldgrid[$i+1]}[$j-1];
	$n ++ if  ${$oldgrid[$i]}[$j+1];
	$n ++ if  ${$oldgrid[$i-1]}[$j+1];
	$n ++ if  ${$oldgrid[$i+1]}[$j+1];
	$n ++ if  ${$oldgrid[$i-1]}[$j];
	$n ++ if  ${$oldgrid[$i+1]}[$j];

if($n == 3){
    &newcell($i, $j);
}
elsif($n == 2) {
    &agecell($i, $j);
}
elsif($n != 2){
    &diecell($i, $j);
}


if(${$grid[$i]}[$j]){
$pop++;
$agetot += ${$grid[$i]}[$j];
}
}
}
$c->update;
$t++;
&graphpop($t, $pop, $agetot);
}
MainLoop;

sub graphpop {
    my($time, $pop, $a) = @_;
    if($pop == 0) {
	&fillgrid();;
	return;
    }
    $aa = 300-(3*($a-$pop)/$pop);
    $max = 60;
    $pop = (300-($pop));
    if($#gp > $max){
	foreach $gp (@gp){
	    $g->move($gp, -5, 0);
	}
	$dme = shift(@gp);
	$g->delete($dme);
	$time = $max;
    }
    if($#gp2 > $max){
	foreach $gp2 (@gp2){
	    $g->move($gp2, -5, 0);
	}
	$dme = shift(@gp2);
	$g->delete($dme);
	$time = $max;
    }
    push(@gp, $g->create(oval, $time*5, $pop, ($time*5)+5, $pop+5));
    push(@gp2, $g->create(oval, $time*5, $aa, ($time*5)+5, $aa+5, -fill => "red"));
    $g->update;
    if($aa < 0) {
	&fillgrid();
    }
}

sub newcell {
    my($i, $j) = @_;
    if(!${$cells[$i]}[$j]){
	${$cells[$i]}[$j] = $c->create(oval, ($i*10)-5, ($j*10)-5, 
				($i*10)+5, ($j*10)+5, -fill => "red");
   }
        ${$grid[$i]}[$j] = 1 unless ${$grid[$i]}[$j];
&agecell($i, $j);

}

sub diecell {
    my($i, $j) = @_;
    if(${$cells[$i]}[$j]) {
    $c->delete(${$cells[$i]}[$j]);
undef ${$cells[$i]}[$j];
    }
               ${$grid[$i]}[$j] = 0;
}

sub agecell {
    my($i, $j) = @_;

    if(${$grid[$i]}[$j]){
    $gage = ${$grid[$i]}[$j];
$cel = ${$cells[$i]}[$j];

if($gage == 1){
    $c->itemconfigure($cel, -fill => "gray10");
}
elsif($gage == 2){
    $c->itemconfigure($cel, -fill => "gray25");
}
elsif($gage == 3){
    $c->itemconfigure($cel, -fill => "gray40");
}
elsif($gage == 4){
    $c->itemconfigure($cel, -fill => "gray60");
}
elsif($gage == 5){
    $c->itemconfigure($cel, -fill => "gray80");
}
elsif($gage == 6){
    $c->itemconfigure($cel, -fill => "gray90");
}
elsif($gage > 6){
    $c->itemconfigure($cel, -fill => "white");
}
    ${$grid[$i]}[$j]++;

}


}
