#!/usr/bin/perl

use GD::Simple;
use Math::Round;
use strict;
our(%params);
require "../cgi-lib.pl";
ReadParse(*params);

my(%pal);
my %primes = (
    2 => 1,
    3 => 1,
    5 => 1,
    7 => 1,
    11 => 1,
    13 => 1,
    17 => 1,
    19 => 1,
    23 => 1,
    29 => 1,
    31 => 1,
    37 => 1,
    41 => 1,
    43 => 1,
    47 => 1,
    53 => 1,
    59 => 1,
    61 => 1,
    67 => 1,
    71 => 1,
    73 => 1,
    79 => 1,
    83 => 1,
    89 => 1,
    97 => 1,
    );

my($radius) = 100;
my($spacing) = 50;
my($per_side) = 33;

my $width = ($radius*2)*($per_side) + $spacing*($per_side+1);
my $height = ($radius*2)*($per_side) + $spacing*($per_side+1);

my $img = GD::Simple->new($width,$height,1);
$img->fill(1,1,color(255,255,255));


#for(1..30) {
my($p1,$p2);
for($p1=1;$p1<=$per_side;$p1++) {
    for($p2=1;$p2<=$per_side;$p2++) {
	next if($p1*$p2 > 100);
	my $x = $p1*$spacing+$radius+$radius*($p1-1)*2;
	my $y = $p2*$spacing+$radius+$radius*($p2-1)*2;
	make_circle($x,$y,($p1*$p2),$radius);
    }
}

print "Content-Type: image/png\n\n";
print $img->png;

sub make_circle {
    my($x,$y,$number,$radius) = @_;
    my($factors) = get_prime_factors($number);
    #print "Prime factors of $number = ".join(", ",@{$factors})."\n";
    my($fcount) = scalar @{$factors};
    my(@factors) = sort @{$factors};
    my($degrees) = 360 / $fcount;
    my($L) = $radius/20;
    if($degrees == 360) {
	# 1 circle 
	$img->arc($x,$y,$radius*2,$radius*2,0,360,get_color($factors[0]));
	$img->arc($x,$y,$radius,$radius,0,360,get_color($factors[0]));
	$img->fill($x+$radius*0.75,$y,get_color($factors[0]));
    } else {
	my $angle = 0;
	my(@angles) = ();
	for(my $i=0;$i<$fcount;$i++) {
	    my($end) = $angle+$degrees;
	    $img->arc($x,$y,$radius*2,$radius*2,$angle-1,$end+1,get_color($factors[$i]));
	    $img->arc($x,$y,$radius,$radius,$angle-1,$end+1,get_color($factors[$i]));

	    my($s1x,$s1y,$s2x,$s2y);

	    $s1x = cos(to_rad($angle))*($radius/2);
	    $s1y = sin(to_rad($angle))*($radius/2);
	    $s2x = cos(to_rad($angle))*$radius;
	    $s2y = sin(to_rad($angle))*$radius;
	    
	    $img->line($x+$s1x,$y+$s1y,$x+$s2x,$y+$s2y,get_color($factors[$i]));

	    $s1x = cos(to_rad($end))*($radius/2);
	    $s1y = sin(to_rad($end))*($radius/2);
	    $s2x = cos(to_rad($end))*$radius;
	    $s2y = sin(to_rad($end))*$radius;
	    
	    $img->line($x+$s1x,$y+$s1y,$x+$s2x,$y+$s2y,get_color($factors[$i]));

	    $s1x = cos(to_rad(($angle+$end)/2))*($radius/1.5);
	    $s1y = sin(to_rad(($angle+$end)/2))*($radius/1.5);
	    ####$img->fill($s1x,$s1y,get_color($factors[$i]));

	    $img->fill($x+$s1x,$y+$s1y,get_color($factors[$i]));
	    #$img->setPixel($x+$s1x,$y+$s1y,get_color($factors[$i]));

	    push @angles,$angle;

	    $angle += $degrees;
	}
	foreach my $angle (@angles) {
	    my($endx) = $x+cos(to_rad($angle))*$radius;
	    my($endy) = $y+sin(to_rad($angle))*$radius;
	    my($polyx1) = $endx+$L*cos(to_rad(90+$angle));
	    my($polyy1) = $endy+$L*sin(to_rad(90+$angle));
	    my($polyx2) = $endx-$L*cos(to_rad(90+$angle));
	    my($polyy2) = $endy-$L*sin(to_rad(90+$angle));

	    ($endx) = $x+cos(to_rad($angle))*($radius/2.5);
	    ($endy) = $y+sin(to_rad($angle))*($radius/2.5);
	    my($polyx3) = $endx+$L*cos(to_rad(90+$angle));
	    my($polyy3) = $endy+$L*sin(to_rad(90+$angle));
	    my($polyx4) = $endx-$L*cos(to_rad(90+$angle));
	    my($polyy4) = $endy-$L*sin(to_rad(90+$angle));
	    
	    my($poly) = new GD::Polygon;
	    $poly->addPt($polyx1,$polyy1);
	    $poly->addPt($polyx2,$polyy2);
	    $poly->addPt($polyx4,$polyy4);
	    $poly->addPt($polyx3,$polyy3);
	    $img->filledPolygon($poly,color(255,255,255));
	}
    }
    #$img->string(gdGiantFont,$x,$y,$number,color(127,127,127));
    my($font) = '/home/dave/public_html/tmp/fonts/arial.ttf';
    my($width,$fontsize,$height);
    $fontsize = $radius / 2;
    while(!$width || ($width > ($radius*0.85))) {
	my @bounds = GD::Image->stringFT(color(127,127,127),$font,$fontsize,0,100,100,$number,{});
	$width = abs($bounds[2] - $bounds[0]) + 1;
	$height = abs($bounds[1] - $bounds[5]) + 1;
	$fontsize--;
    }
    $img->stringFT(color(127,127,127),$font,$fontsize,0,$x-($width/2)+2,$y+($height/2)-2,$number,{});
}

sub to_rad {
    return ($_[0]*3.14159)/180;
}

sub get_color {
    my($prime) = @_;
    if($prime == 1) {
	return color(223,223,223);
    } elsif($prime == 2) {
	return color(255,191,0);
    } elsif($prime == 3) {
	return color(0,191,0);
    } elsif($prime == 5) {
	return color(0,127,255);
    } elsif($prime == 7) {
	return color(127,0,127);
    } else {
	return color(255,0,0);
    }
}

sub get_prime_factors {
    my($n) = @_;
    if($n == 1) {
	return [ 1 ];
    }
    my(@factors) = ();
    while(!$primes{$n} && $n != 1) {
	my($flag) = 0;
	foreach my $p (keys %primes) {
	    if(!($n % $p)) {
		$n = $n / $p;
		push @factors,$p;
		$flag = 1;
	    }
	}
	if(!$flag) {
	    if($n == 1) {
		return \@factors;
	    }
	}
    }
    if($n != 1) {
	push @factors,$n;
    }
    return \@factors;
}

sub color {
    my($r,$g,$b) = @_;
    if(!defined($pal{"$r\_$g\_$b"})) {
        $pal{"$r\_$g\_$b"} = $img->colorAllocate($r,$g,$b);
    }
    return $pal{"$r\_$g\_$b"};
}
