#!/usr/bin/perl
use GD;
use strict;
our(%params);
our($params);
our(@params);
require "../cgi-lib.pl";
ReadParse(*params);

# For half-curve right, inner teeth 222.45?, outer teeth 227.52?
# For half-curve left, inner teeth 223.55?, outer teeth 228.49125?

my($R,$D,$L,$ratio,$P,$S,$outer_teeth,$inner_teeth,$type);
my($pi) = 3.14159265359;

$S = 20; #Distance to Support from edge
$P = 28; #Perceived radius
$L = 32; #Length of straight track
$D = undef; #Distance out from ends (calculated)
$R = undef; #Actual radius (calculated)

$outer_teeth = 228;
$inner_teeth = 223;
$ratio = 48; # Pixels per stud

if($params{type} =~ /^straight$/) {
    $type = 'straight';
    $inner_teeth = 163;
    $outer_teeth = 163;
} elsif($params{type} =~ /^short$/) {
    $type = 'straight';
    $L = 8;
    $inner_teeth = 41;
    $outer_teeth = 41;
} elsif($params{type} =~ /^(stop|med|start)$/) {
    $type = 'straight';
    $L = 16;
    $inner_teeth = 82;
    $outer_teeth = 82;
} else {
    $type = 'curve';
}
if($params{s} =~ /^(\d+\.?\d*)$/ || $params{S} =~ /^(\d+\.?\d*)$/) {
    $S = $1;
}
if($params{p} =~ /^(\d+\.?\d*)$/ || $params{P} =~ /^(\d+\.?\d*)$/) {
    $P = $1;
}
if($params{l} =~ /^(\d+\.?\d*)$/ || $params{L} =~ /^(\d+\.?\d*)$/) {
    $L = $1;
}
if($params{outer_teeth} =~ /^\d+\.?\d*$/) {
    $outer_teeth = $params{outer_teeth};
}
if($params{inner_teeth} =~ /^\d+\.?\d*$/) {
    $inner_teeth = $params{inner_teeth};
}
if($params{ratio} =~ /^\d+\.?\d*$/) {
    $ratio = $params{ratio};
}

#Default value for standard curve
$R = ($P-$S) / (1-(sqrt(2)/2));
$D = $P - $R;

# Just in case we want to override them
if($params{r} =~ /^(\d+\.?\d*)$/ || $params{R} =~ /^(\d+\.?\d*)$/) {
    $R = $1;
}
if($params{d} =~ /^(\d+\.?\d*)$/ || $params{D} =~ /^(\d+\.?\d*)$/) {
    $D = $1;
}

my(%pal,$logy);
my($width,$height);
if($type eq "straight") {
    $width = ($L+2)*$ratio;
    $height = 6*$ratio;
} else {
    $width = ($R+$D+4)*$ratio;
    $height = ($R+$D+4)*$ratio;
}
my $img = new GD::Image($width,$height,1);
$img->fill(10,5,color(255,255,255));

my(@outer_in_pts) = ();
my(@outer_out_pts) = ();
my(@inner_in_pts) = ();
my(@inner_out_pts) = ();

if($type eq "straight") {
    my $outerDin = 2+(1/5);
    my $outerDout = 2+(2/5);
    my $innerDin = 2-(1/5);
    my $innerDout = 2-(2/5);
    my($i);

    $outer_in_pts[0] = { x => 0, y => $outerDin };
    for($i=0;$i<$outer_teeth;$i++) {
	$outer_in_pts[$i+1] = { x => ($i+1)*($L/$outer_teeth), y => $outerDin };
	$outer_out_pts[$i] = { x => ($i+0.5)*($L/$outer_teeth), y => $outerDout };
    }
    $inner_in_pts[0] = { x => 0, y => $innerDin };
    for($i=0;$i<$inner_teeth;$i++) {
	$inner_in_pts[$i+1] = { x => ($i+1)*($L/$inner_teeth), y => $innerDin };
	$inner_out_pts[$i] = { x => ($i+0.5)*($L/$inner_teeth), y => $innerDout };
    }


    for($i=0;$i<$outer_teeth;$i++) {
	$img->line($outer_in_pts[$i]{x}*$ratio,$outer_in_pts[$i]{y}*$ratio,
		   $outer_out_pts[$i]{x}*$ratio,$outer_out_pts[$i]{y}*$ratio,
		   color(0,0,0));
	$img->line($outer_in_pts[$i+1]{x}*$ratio,$outer_in_pts[$i+1]{y}*$ratio,
		   $outer_out_pts[$i]{x}*$ratio,$outer_out_pts[$i]{y}*$ratio,
		   color(0,0,0));
    }
    for($i=0;$i<$inner_teeth;$i++) {
	$img->line($inner_in_pts[$i]{x}*$ratio,$inner_in_pts[$i]{y}*$ratio,
		   $inner_out_pts[$i]{x}*$ratio,$inner_out_pts[$i]{y}*$ratio,
		   color(0,0,0));
	$img->line($inner_in_pts[$i+1]{x}*$ratio,$inner_in_pts[$i+1]{y}*$ratio,
		   $inner_out_pts[$i]{x}*$ratio,$inner_out_pts[$i]{y}*$ratio,
		   color(0,0,0));
    }
    $img->line($ratio*0,$ratio*0,
	       $ratio*$L,$ratio*0,
	       color(0,0,0));
    $img->line($ratio*0,$ratio*4,
	       $ratio*$L,$ratio*4,
	       color(0,0,0));
} else {
    my $outerRin = $R+(1/5);
    my $outerRout = $R+(2/5);
    my $innerRin = $R-(1/5);
    my $innerRout = $R-(2/5);
    
    my $outerLin = ($outerRin * 2 * $pi) / 4 + (2 * $D);
    my $outerLout = ($outerRout * 2 * $pi) / 4 + (2 * $D);
    my $innerLin = ($innerRin * 2 * $pi) / 4 + (2 * $D);
    my $innerLout = ($innerRout * 2 * $pi) / 4 + (2 * $D);
    
    # OK, start with the outer teeth
    $outer_in_pts[0] = { x => 0, y => ($D+$outerRin) };
    for(my $i=0;$i<$outer_teeth;$i++) {
	my($in_dist) = ($outerLin/$outer_teeth)*$i + ($outerLin/$outer_teeth);
	if($in_dist < $D) {
	    $outer_in_pts[$i+1] = { x => $in_dist, y => ($D+$outerRin) };
	} elsif($in_dist > ($outerLin-$D)) {
	    $outer_in_pts[$i+1] = { x => ($D+$outerRin), y => ($outerLin-$in_dist) };
	} else {
	    my $radians = $pi*($in_dist-$D)/($outerLin-(2*$D))/2;
	    $radians = ($pi/2) - $radians;
	    $outer_in_pts[$i+1] = { x => ($D+($outerRin*cos($radians))), y => ($D+($outerRin*sin($radians))) };
	}
	
	my($out_dist) = ($outerLout/$outer_teeth)*($i+0.5);
	if($out_dist < $D) {
	    $outer_out_pts[$i] = { x => $out_dist, y => ($D+$outerRout) };
	} elsif($out_dist > ($outerLout-$D)) {
	    $outer_out_pts[$i] = { x => ($D+$outerRout), y => ($outerLout-$out_dist) };
	} else {
	    my $radians = $pi*($out_dist-$D)/($outerLout-(2*$D))/2;
	    $radians = ($pi/2) - $radians;
	    $outer_out_pts[$i] = { x => ($D+($outerRout*cos($radians))), y => ($D+($outerRout*sin($radians))) };
	}
    }
    
    # Now, the inner teeth
    $inner_in_pts[0] = { x => 0, y => ($D+$innerRin) };
    for(my $i=0;$i<$inner_teeth;$i++) {
	my($in_dist) = ($innerLin/$inner_teeth)*$i + ($innerLin/$inner_teeth);
	if($in_dist < $D) {
	    $inner_in_pts[$i+1] = { x => $in_dist, y => ($D+$innerRin) };
	} elsif($in_dist > ($innerLin-$D)) {
	    $inner_in_pts[$i+1] = { x => ($D+$innerRin), y => ($innerLin-$in_dist) };
	} else {
	    my $radians = $pi*($in_dist-$D)/($innerLin-(2*$D))/2;
	    $radians = ($pi/2) - $radians;
	    $inner_in_pts[$i+1] = { x => ($D+($innerRin*cos($radians))), y => ($D+($innerRin*sin($radians))) };
	}
	
	my($out_dist) = ($innerLout/$inner_teeth)*($i+0.5);
	if($out_dist < $D) {
	    $inner_out_pts[$i] = { x => $out_dist, y => ($D+$innerRout) };
	} elsif($out_dist > ($innerLout-$D)) {
	    $inner_out_pts[$i] = { x => ($D+$innerRout), y => ($innerLout-$out_dist) };
	} else {
	    my $radians = $pi*($out_dist-$D)/($innerLout-(2*$D))/2;
	    $radians = ($pi/2) - $radians;
	    $inner_out_pts[$i] = { x => ($D+($innerRout*cos($radians))), y => ($D+($innerRout*sin($radians))) };
	}
    }
    # Draw outer points
    #my($i) = 0;
    #foreach my $pos (@outer_in_pts) {
    #    $img->setPixel($pos->{x}*$ratio,$pos->{y}*$ratio,color(255,0,0));
    #    $img->string(gdTinyFont,$pos->{x}*$ratio-10,$pos->{y}*$ratio-10,($i+1),color(255,0,0));
    #    $i++;
    #}
    my($i) = 0;
    foreach my $pos (@outer_out_pts) {
        $img->setPixel($pos->{x}*$ratio,$pos->{y}*$ratio,color(0,192,192));
	$img->line($pos->{x}*$ratio,$pos->{y}*$ratio,$pos->{x}*$ratio+5,$pos->{y}*$ratio+5,color(255,191,191));
        $img->string(gdTinyFont,$pos->{x}*$ratio+5,$pos->{y}*$ratio+5,($i+1),color(0,192,192));
        $i++;
    }
    # Draw outer teeth
    for(my $i=0;$i<$outer_teeth;$i++) {
	$img->line($ratio*$outer_in_pts[$i]{x},$ratio*$outer_in_pts[$i]{y},
		   $ratio*$outer_out_pts[$i]{x},$ratio*$outer_out_pts[$i]{y},
		   color(0,0,0));
	$img->line($ratio*$outer_out_pts[$i]{x},$ratio*$outer_out_pts[$i]{y},
		   $ratio*$outer_in_pts[$i+1]{x},$ratio*$outer_in_pts[$i+1]{y},
		   color(0,0,0));
    }
    # Draw inner points
    #my($i) = 0;
    #foreach my $pos (@inner_in_pts) {
    #    $img->setPixel($pos->{x}*$ratio,$pos->{y}*$ratio,color(255,0,0));
    #    $img->string(gdTinyFont,$pos->{x}*$ratio+5,$pos->{y}*$ratio+5,($i+1),color(255,0,0));
    #    $i++;
    #}
    my($i) = 0;
    foreach my $pos (@inner_out_pts) {
        $img->setPixel($pos->{x}*$ratio,$pos->{y}*$ratio,color(0,192,192));
	$img->line($pos->{x}*$ratio,$pos->{y}*$ratio,$pos->{x}*$ratio-10,$pos->{y}*$ratio-10,color(255,191,191));
        $img->string(gdTinyFont,$pos->{x}*$ratio-10,$pos->{y}*$ratio-10,($i+1),color(0,192,192));
        $i++;
    }
    # Draw outer teeth
    for(my $i=0;$i<$inner_teeth;$i++) {
	$img->line($ratio*$inner_in_pts[$i]{x},$ratio*$inner_in_pts[$i]{y},
		   $ratio*$inner_out_pts[$i]{x},$ratio*$inner_out_pts[$i]{y},
		   color(0,0,0));
	$img->line($ratio*$inner_out_pts[$i]{x},$ratio*$inner_out_pts[$i]{y},
		   $ratio*$inner_in_pts[$i+1]{x},$ratio*$inner_in_pts[$i+1]{y},
		   color(0,0,0));
    }
    
    # Make track edge points
    my(@outedge,@inedge);
    $outedge[0] = { x => 0, y => ($D+$R+2) };
    $inedge[0] = { x => 0, y => ($D+$R-2) };
    for(my $angle=90;$angle>=0;$angle-=0.1) {
	my $radians = $angle*$pi/180;
	push @outedge,{ x => ($D+($R+2)*cos($radians)), y => ($D+($R+2)*sin($radians)) };
	push @inedge,{ x => ($D+($R-2)*cos($radians)), y => ($D+($R-2)*sin($radians)) };
    }
    push @outedge,{ x => ($D+$R+2), y => 0 };
    push @inedge,{ x => ($D+$R-2), y => 0 };
    
    for(my $i=0;$i<$#outedge;$i++) {
	$img->line($ratio*$outedge[$i]{x},$ratio*$outedge[$i]{y},
		   $ratio*$outedge[$i+1]{x},$ratio*$outedge[$i+1]{y},
		   color(0,0,0));
	$img->line($ratio*$inedge[$i]{x},$ratio*$inedge[$i]{y},
		   $ratio*$inedge[$i+1]{x},$ratio*$inedge[$i+1]{y},
		   color(0,0,0));
    }
}

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

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"};
}

sub logit {
    $logy+=15;
    $img->string(gdTinyFont,10,$logy,$_[0],color(0,0,0));
}
