#!/usr/bin/perl

# stub.org interactive artwork (img.cgi)
# Everything (c) Copyright 2000 Adrian Ward @ stub.org (ade@stub.org)
# http://stub.org/

use CGI qw/:standard/;
use GD;

$seed=param('seed');
$scale=param('scale');
$panes=param('panes');
$slide=param('slide');

#stopgap added by AG, 7.22.00
if($panes>10) {$panes=10;}
if($slide>100) {$slide=100;}
if($scale>100) {$scale=100;}

srand $seed;

@obj=qw(

	0,0 1,0 2,0 5,0 8,0 10,0 11,0 12,0 14,0 15,0 16,0
	19,0 20,0 23,0 27,0 29,0 30,0 31,0 0,1 3,1 5,1 8,1
	11,1 16,1 18,1 21,1 23,1 24,1 26,1 27,1 29,1 0,2
	1,2 2,2 5,2 6,2 7,2 8,2 11,2 15,2 18,2 21,2 23,2
	25,2 27,2 29,2 30,2 31,2 0,3 2,3 5,3 8,3 11,3 14,3
	18,3 21,3 23,3 27,3 29,3 0,4 3,4 5,4 8,4 10,4 11,4
	12,4 14,4 15,4 16,4 19,4 20,4 23,4 27,4 29,4 30,4 31,4

       );

$gif=new GD::Image(500,320);

$bg   =$gif->colorAllocate(32 ,32 ,32 );
$dark =$gif->colorAllocate(16 ,16 ,16 );
$black=$gif->colorAllocate(0  ,0  ,0  );
$top  =$gif->colorAllocate(128,128,192);
$front=$gif->colorAllocate(192,192,255);
$side =$gif->colorAllocate(64 ,64 ,128);
$line =$gif->colorAllocate(32 ,32 ,64 );

for (sort pseudoZDepth @obj) {
 split(/,/);
 $d = int(rand($scale))*2;
 $x = 75+(($_[0]-($_[1]/2))*12);
 $y =  50+(($_[1]+($_[0]/2))*12);
 block($x,$y,$d);
}


for (1..$panes) {
 $x  = 100+rand(300);
 $y  = 100+rand(120);
 $nx = $x;
 $ny = $y;
 if (rand(50)<25) {
  $nx-=int(rand($slide));
 } else {
  $ny-=int(rand($slide));
 }
 $new=new GD::Image(100,100);
 $new->copy($gif,0,0,$x,$y,100,100);
 $gif->filledRectangle($x,$y,$x+100,$y+100,$bg);
 $gif->rectangle($x,$y,$x+100,$y+100,$line);
 $gif->copy($new,$nx,$ny,0,0,100,100);
 if ($nx < $x) {
  $gif->line($nx+100,$y+50,$x +100,$y+50,$line);
  $gif->line($nx+102,$y+50,$nx+106,$y+48,$line);
  $gif->line($nx+102,$y+50,$nx+106,$y+52,$line);
 } else {
  $gif->line($x+50,$ny+100,$x+50,$y +100,$line);
  $gif->line($x+50,$ny+102,$x+48,$ny+106,$line);
  $gif->line($x+50,$ny+102,$x+52,$ny+106,$line);
 }
 $gif->rectangle($nx,$ny,$nx+100,$ny+100,$black);
}

$gif->transparent($bg);

print "Content-type: image/gif\nPragma: no-cache\n\n";

print $gif->gif;

sub block {

 my ($x,$y,$d)=@_;

 $shOfs=8;
 $shOfsH=$shOfs/2;

 # Shadow
 my $poly=new GD::Polygon;
 $poly->addPt($x    + $shOfsH,$y    + $shOfs);
 $poly->addPt($x-6  + $shOfsH,$y+12 + $shOfs);
 $poly->addPt($x+6  + $shOfsH,$y+18 + $shOfs);
 $poly->addPt($x+12 + $shOfsH,$y+6  + $shOfs);
 #$gif->filledPolygon($poly,$black);

 # Lines from Shadow up to Block
 # $gif->line($x+6 + $shOfsH,$y+18 + $shOfs,$x+10-($d/2),$y+25-($d),$dark);

 $x-=$d/2;
 $y-=$d;

 # Side
 my $poly=new GD::Polygon;
 $poly->addPt($x+10,$y+5 );
 $poly->addPt($x+5 ,$y+15);
 $poly->addPt($x+10,$y+25);
 $poly->addPt($x+15,$y+15);
 $gif->filledPolygon($poly,$side);

 # Front
 my $poly=new GD::Polygon;
 $poly->addPt($x-5 ,$y+10);
 $poly->addPt($x   ,$y+20);
 $poly->addPt($x+10,$y+25); 
 $poly->addPt($x+5 ,$y+15);
 $gif->filledPolygon($poly,$front);

 # Top
 my $poly=new GD::Polygon;
 $poly->addPt($x   ,$y   );
 $poly->addPt($x-5 ,$y+10);
 $poly->addPt($x+5 ,$y+15);
 $poly->addPt($x+10,$y+5 );
 $gif->filledPolygon($poly,$top);

 # Outline
 my $poly=new GD::Polygon;
 $poly->addPt($x   ,$y   );
 $poly->addPt($x-6 ,$y+11);
 $poly->addPt($x-1 ,$y+20);
 $poly->addPt($x+11,$y+26);
 $poly->addPt($x+16,$y+16);
 $poly->addPt($x+10,$y+5 );
 $gif->polygon($poly,$black);

}

sub pseudoZDepth {
 # Yikes! This numeric-ascending sort block compares pseudo-z-depth derived from the x/y pairs in the list
 ((split(/,/,$a))[0]+(split(/,/,$a))[1])<=>((split(/,/,$b))[0]+(split(/,/,$b))[1])
}
