#!/usr/bin/perl

# Scanned synthesis table drawer. (draw-er)
# written april 2002 by Matthew Gilliard

use Tk;
use strict;
use vars qw($main);

my $i;
my $num_points = 128;
my $wdef = "x*2*pi";
my $main = new MainWindow;
my $pi = 3.14159265358979323846;
my $acc = 6;
my $i_temp;
my $num_lines = (@ARGV) ? $ARGV[0] : 5;

my @dp = (0,0,0,0,0,0,0,0,0,0);
my @min_y = (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
my @max_y = (1, 1, 1, 1, 1,1,1,1,1,1);
my @formula = ('sin w');
my @colours = ('red', 'blue', 'green', 'magenta', 'cyan', 'orange',
               'darkblue', 'purple', 'brown', 'black');
my @on = (1,0,0,0,0,0,0,0,0,0);
my @files = ('t.0', 't.1', 't.2', 't.3', 't.4', 't.5', 't.6', 't.7', 't.8', 't.9');

$main->Label(-text => 'Scanned synthesis table helper')->pack;

my $bf = $main->Frame->pack;

my $bft = $bf->Frame->pack(qw/-side top/);
my $bfb = $bf->Frame->pack(qw/-side bottom -fill x/);

my $ftl = $bft->Frame->pack(qw/-side left -fill y/);
my $ftr = $bft->Frame->pack(qw/-side right/);

my $c = $ftr->Canvas(
    relief => 'raised',
    width => 308,
    height => 311,
    cursor => 'top_left_arrow',
    );
$c->pack(qw/-side right/);

my $rect = $c->createRectangle(4,4,304,304, -fill => 'white');

# Number of points in table

for ($i=0; $i<$num_lines; $i++){
    my $ff = $main->Frame->pack;
    $ff->Label(-text => "y$i = ", -fg => $colours[$i])->pack(qw/-side left/);
    $ff->Checkbutton(-variable => \$dp[$i])->pack(qw/-side right/);
    $ff->Entry(-textvariable => \$files[$i], -width => 8)->pack(qw/-side right/);
    $ff->Checkbutton(-variable => \$on[$i], -command => sub{draw_formula($c)})->pack(qw/-side right/);
    $ff->Entry(-textvariable => \$max_y[$i], -width => 5)->pack(qw/-side right/);
    $ff->Entry(-textvariable => \$min_y[$i], -width => 5)->pack(qw/-side right/);
    my $form = $ff->Entry(
                          -textvariable => \$formula[$i],
                          )->pack(qw/-side right/);
}

my $f = $main->Frame->pack;

$f->Label(-text => 'Values:')->pack(qw/-side left/);
$f->Optionmenu(
               -options => [qw/4 8 16 32 64 128 256 512 1024 2048 4096 8192/],
               -textvariable => \$num_points,
               )->pack(qw/-side left/);


$f->Button(
                   -relief => 'raised',
                   -text => 'Redraw',
                   -command => sub{draw_formula($c);}
                   )->pack(qw/-side left/);

$f->Button(
                   -relief => 'raised',
                   -text => 'Output',
                   -command => sub{make_files($c);}
                   )->pack(qw/-side left/);

$f->Button(
              -relief => 'raised',
              -text => 'Exit',
              -command => sub{exit;}
              )->pack(qw/-side right/);

draw_formula($c);

# Start responding to user input.
MainLoop;

sub draw_formula(){
    my ($c) = @_;
    my $i;
    my $x;
    my $y;
    my $count;

    for ($count=0; $count<$num_lines; $count++){
        $c->delete("line$count");
    }

    for ($count=0; $count<$num_lines; $count++){

        if ($on[$count]){
            $i_temp = 0;
            my $nf = $formula[$count];
            $nf =~ s/w/$wdef/g;
            $nf =~ s/x/\$i_temp/g;
            $nf =~ s/pi/$pi/g;

            # Help from jpff with inlining of bit function
            $nf =~ s/bit\((.+?),(.+?),(.+?)\)/(((\3>\1)&&(\3<=\2))?1:0)/g;

            my $oldx=5;
            my $oldy=(eval($nf) - $min_y[$count])/($max_y[$count] - $min_y[$count]);
            $oldy = int 300-$oldy*299 +4;

            for ($i=1; $i<300; $i++){
                $x = $i+4;
                $i_temp = $i/300;
                $y = (eval($nf) - $min_y[$count]) / ($max_y[$count] - $min_y[$count]);
                $y = int 300-$y*299 +4;
                my $lne = $c->createLine($oldx, $oldy, $x, $y, -fill => $colours[$count]);
                $c->addtag("line$count", 'withtag', $lne);

                $oldx = $x;
                $oldy = $y;
            }
        }
    }
}

sub make_files(){
    my ($c) = @_;
    my $count;
    my $i;
    my $temp;
    my $y;

    for ($count=0; $count<$num_lines; $count++){
        if ($on[$count]){

            my $nf = $formula[$count];
            $nf =~ s/w/$wdef/g;
            $nf =~ s/x/\$temp/g;
            $nf =~ s/pi/$pi/g;
            $nf =~ s/bit\((.+?),(.+?),(.+?)\)/(((\3>\1)&&(\3<=\2))?1:0)/g;

            open (FILE, ">$files[$count]");

            for ($i=0; $i<$num_points; $i++){
                if (($i == 0) && ($dp[$count] != 0)){
                    print FILE "0\n";
                }else{
                    $temp = $i/($num_points-1);
                    $y = eval $nf;
                    $y = (int ($y * 10 ** $acc)) / 10 ** $acc;
                    print FILE "$y\n";
                }
            }
            close FILE;
        }
    }
}






