#!/usr/bin/perl

use GD;
use strict;


my %gColors;

sub drawPix($$$$$$)
{
    my ($im,$x,$y,$r,$g,$b) = (@_);
    my $key = sprintf("%02x%02x%02x",$r,$g,$b);
    my $co = $gColors{$key};
    if(!defined($co))
    {
        $co = $im->colorAllocate($r,$g,$b);
        $gColors{$key} = $co;
        print "defining $key = $co\n";
    }
    $im->setPixel($x,$y,$co);
}

my $gWidth = 0;
my $gHeight = 0;
my @gPoints;

sub startPix($$)
{
    my ($width,$height) = (@_);
    $gWidth = $width;
    $gHeight = $height;
}

# add the next point. you keep track of the count.
sub addPt($$$;$)
{
    my ($r,$g,$b,$count) = (@_);
    my %rgb;
    $rgb{r} = $r;
    $rgb{g} = $g;
    $rgb{b} = $b;
    $count = 1 unless $count;
    while($count-- > 0)
    {
        push(@gPoints,\%rgb);
    }
}

sub repeatPt()
{
    my $p = @gPoints[$#gPoints];
    push(@gPoints,$p);
}

sub finishLine()
{
    while(scalar(@gPoints) % $gWidth)
    {
        repeatPt();
    }
}

sub finish()
{
    while(scalar(@gPoints) < $gWidth * $gHeight)
    {
        repeatPt();
    }
}

sub show()
{
    for(my $y = 0; $y < $gHeight; $y++)
    {
        for(my $x = 0; $x < $gWidth; $x++)
        {
            my $ix = $y * $gWidth + $x;
            my $rgb = @gPoints[$ix];
            my $s = sprintf(" (%3d,%3d,%3d)",
                    $rgb->{r},
                    $rgb->{g},
                    $rgb->{b});
            print $s;
        }
        print "\n" x 2;
    }
}
sub render($$$;$)
{
    my ($name,$renderWidth,$renderHeight,$flip) = (@_);
    my $im = new GD::Image($renderWidth,$renderHeight);
    for(my $y = 0; $y < $renderHeight; $y++)
    {
        for(my $x = 0; $x < $renderWidth; $x++)
        {
            my $srcX = int($x * $gWidth / $renderWidth);
            my $srcY = int($y * $gHeight / $renderHeight);
            
            if($flip)
            {
                $srcX = ($gWidth - 1) - $srcX;
            }

            my $ix = $srcY * $gWidth + $srcX;

            my $rgb = @gPoints[$ix];
            my $s = sprintf(" (%3d,%3d,%3d)",
                    $rgb->{r},
                    $rgb->{g},
                    $rgb->{b});
            drawPix($im,$x,$y,
                    $rgb->{r},
                    $rgb->{g},
                    $rgb->{b});
        }
    }
    open(PICTURE, ">${name}.gif") or die("Cannot open file for writing");
    binmode PICTURE;
    print PICTURE $im->gif;
    close PICTURE;
    print `qt_export ${name}.gif ${name}.tga --loadsettings=tga24.st --replacefile`;
}

sub mapRangeInt($$$$$)
{
    my ($v,$srcLow,$srcHigh,$dstLow,$dstHigh) = (@_);
    
    $v -= $srcLow;
    $v = $v * ($dstHigh - $dstLow) / ($srcHigh - $srcLow);
    $v += $dstLow;
    $v = int($v + 0.5);

    return $v;
}


sub putRing($$$$$;$$)
{
    my ($pointCount,$radius,$centerX,$centerY,$z,$angleStart,$angleStop) = (@_);
    $angleStart = 0 unless $angleStart;
    $angleStop = 360 unless $angleStop;
    my $angleSpan = $angleStop - $angleStart;

    $pointCount--; # we loop inclusive below...
    if($angleSpan == 360)
    {
        # full circle, roll back by one increment
        $angleSpan -= $angleSpan / $pointCount;
    }

    my $T = 57.29577951;
    $angleStart /= $T;
    $angleStop /= $T;
    $angleSpan /= $T;


    for(my $p = 0; $p <= $pointCount; $p++)
    {
        my $bump = 0;
        # so squares are bigger, not diamonds.
        $bump = 0.5 if($pointCount < 5);
        my $theta = $angleStart + ($p + $bump) * $angleSpan / $pointCount;
        my $x = $centerX + $radius * cos($theta);
        my $y = $centerY + $radius * sin($theta);
        addPt($x,$y,$z);
    }
}

return 1;

# ok
