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

use English;
use Tk;

$height=400;
$width=400;

$plotwin = MainWindow->new();

$canvas = $plotwin->Canvas(-height => $height,
			  -width => $width,
			      -background => "white");

$canvas->pack();
srand;
@partygoer = ();
@cols = ("red", "blue", "green", "yellow", "purple", "black");

for $i (0..5){
    $col = @cols[$i];
    &newPerson(\%{$partygoer[$i]}, rand($width-20), rand($height-20), $col);
}

sub likes {
    my($pa, $pb) = @_;
    &associate(\%{$partygoer[$pa]}, \%{$partygoer[$pb]}, 30, 70);
}

sub dislikes {
    my($pa, $pb) = @_;
    &associate(\%{$partygoer[$pa]}, \%{$partygoer[$pb]}, 100, 250);
}

sub nocollide {
    foreach $p (@partygoer){
	foreach $o (@partygoer){
	    if($p != $o){
		&associate(\%{$p}, \%{$o}, 0, 1000);
	    }
	}
    }
}


&nocollide();
&likes(0, 1);
&likes(0, 2);
&likes(0, 3);

&likes(4, 1);
&likes(4, 2);
&likes(4, 3);

&dislikes(4, 0);
&dislikes(0,4);

&likes(1, 2);
&likes(2, 3);
&likes(3, 1);

&likes(5, 0);
&likes(5, 4);

&dislikes(1,5);
&dislikes(2,5);
&dislikes(3,5);


if(0){
&associate(\%{$partygoer[0]}, \%{$partygoer[1]}, 0, 2);
&associate(\%{$partygoer[0]}, \%{$partygoer[2]}, 0, 2);
&associate(\%{$partygoer[0]}, \%{$partygoer[3]}, 0, 2);
&associate(\%{$partygoer[1]}, \%{$partygoer[3]}, 0, 3);
&associate(\%{$partygoer[2]}, \%{$partygoer[0]}, 3, 5);
&associate(\%{$partygoer[3]}, \%{$partygoer[0]}, 10, 100);

&associate(\%{$partygoer[1]}, \%{$partygoer[0]}, 2, 50000);
}

while(1) {
    $n = 0;
    foreach $p (@partygoer) {
	$wanderlust = $mx = $my = 0;
	foreach $a (@{${$p}{"a"}}) {
	     ($min, $max) = @{${$p}{$a}};
             $dist = &distance($p, $a);
             $px = ${$p}{'x'};
             $py = ${$p}{'y'};
             $ax = ${$a}{'x'};
             $ay = ${$a}{'y'};
    
             next if(($dist > $min) && ($dist < $max));
if($pinned{$p}==0){
if(($dist < $min) || ($dist < 30)){
    # Move away!
    $mx +=int( $min/(($px-$ax)/10));
    $my +=int($min/(($py-$ay)/10));
}
if($dist > $max){
    $mx -=int(($px-$ax)/10);
    $my -=int(($py-$ay)/10);
}
}
else{
    $mx = $pmx{$p};
    $my = $pmy{$p};
    $pinned{$p}++;
    if($pinned{$p} > 50){
	$pinned{$p}=0;
    }
}
$maxspeed = 1;
if($maxspeed) {
$mx = 4 if $mx > 4;
$mx = -4 if $mx < -4;
$my = 4 if $my > 4;
$my = -4 if $my < -4;
}
}    

if($mx==0 && $my==0){
    $idle{$p}++;
    if($idle{$p}>30){
	$mx = int(rand(6)-3);
	$my = int(rand(6)-3);
    }
}
else{
    $idle{$p}=0;
}

if($px+$mx > ($width-15)){
    $pinned{$p} = 1;
    $pmx{$p} = -3;
    $pmy{$p} = 0;
    $mx = 0;
}
elsif($px+$mx < 15){
    $pinned{$p} = 1;
    $pmx{$p} = 3;
    $pmy{$p} = 0;
    $mx = 0;
}

if($py+$my > ($height-15)){
    $pinned{$p} = 1;
    $pmy{$p} = -3;
    $pmx{$p} = 0;
    $my = 0;
}
elsif($py+$my < 15){
    $pinned{$p} = 1;
    $pmy{$p} = 3;
    $pmx{$p} = 0;
    $my = 0;
}
    $canvas->move(${$p}{'blob'}, $mx, $my);
${$p}{'x'}+=$mx;
    ${$p}{'y'}+=$my;
    $plotwin->update;
    }
    $plotwin->update;
}

MainLoop;

sub pickwander {
    $wmx = rand(4)-2;
    $wmy = rand(4)-2;
}

sub continuewander {
    $mx = $wmx;
    $my = $wmy;
}

sub distance {
    my($p1, $p2) = @_;
    $xdif = ${$p1}{'x'} - ${$p2}{'x'};
    $ydif = ${$p1}{'y'} - ${$p2}{'y'};
return sqrt( ($xdif*$xdif) + ($ydif*$ydif) );
}

sub associate {
    ($p1, $p2, $min, $max) = @_;
    push(@{${$p1}{"a"}}, $p2);
    @{${$p1}{$p2}} = ($min, $max);
	 return $p1;
}

sub newPerson {
    my($person, $x, $y, $color) = @_;
    ${$person}{'blob'} = $canvas->create("oval", $x, $y, ($x+15), ($y+15), "-fill", $color, "-tags", "item");
    ${$person}{'x'} = $x;
    ${$person}{'y'} = $y;
}


