#!/usr/bin/perl -w
use strict;

my %ROW = (
    E24 => [100, 110, 120, 130, 150, 180, 200, 220, 240, 270, 300,
	   330, 360, 390, 430, 470, 510, 560, 620, 750, 820, 910,
	   1000, 1100],

#    E12 => [100, 120, 150, 180, 220, 270,
#	   330, 390, 470, 560, 680, 820,
#	   1000, 1200 ]
);

my %ROUNDUP;
for my $e (keys %ROW) {
    my $last = undef;
    for my $r (@{$ROW{$e}}) {
	$ROUNDUP{$e}{$last} = $r if $last;
	$last = $r;    
    }
}

sub log10($) {
    log(shift) / log(10);
}

sub roundR($$;$) {
    my ($r, $e, $roundup) = @_;
#    print STDERR "roundR($r, $e, $roundup)\n";

    my $prefix = 10**(int(log10($r))-2);
    my $wanted = $r / $prefix;

    my $best_f = undef;
    my $best_error = undef;
    for my $f (@{$ROW{$e}}) {
	my $error = abs($wanted - $f);
	if (!defined $best_error or $best_error > $error) {
	    $best_error = $error;
	    $best_f = $f;
	}
    }

    print STDERR "Warning, error was: $best_error (got ".$best_f*$prefix." for $r)\n" if $best_error;

    $best_f = $ROUNDUP{$e}{$best_f} if $roundup;

    return $best_f*$prefix;
}

sub RSequence($$$) {
    my ($e, $min,$max) = @_;

    $max = roundR($max, $e);
    $min = roundR($min, $e);

    my @out = ();
    my $r = $min;
    while ($r <= $max) {
	push @out, $r;
	$r = roundR($r, $e, 'up');	
    }

    return @out;
}

sub prettyR($) {
    my $r = shift;

    if ($r < 1000) {
	return "$r Ohm";

    } elsif ($r < 10**6) { # kilo Ohm
	$r = $r / 10**3;

	if ($r =~ /^(\d+)\.(\d+)$/) {
	    return "$1k$2";
	} else {
	    return "${r}k";
	}

    } else { # Mega Ohm
	$r = $r / 10**6;

	if ($r =~ /^(\d+)\.(\d+)$/) {
	    return "$1M$2";
	} else {
	    return "${r}M";
	}
    } 

}


my $r1min = 1000;
my $r1max = 10000;

my $r2min =  1800;
my $r2max = 47000;

print qq|<tr><th rowspan="2">V<sub>T</sub></th>|;
for my $er (sort keys %ROW) {
    print qq|<th colspan="4">$er</th>|;
}
print "</tr>\n";

print "<tr>";
for my $er (sort keys %ROW) {
    print qq|<th>V<sub>R</sub></th><th>V<sub>E</sub></th><th>R8</th><th class="sep">R9</th>|;
}
print "</tr>\n";

for my $v (5,5.2,6..20) {

    print "<tr><th>$v</th>";
    for my $er (sort keys %ROW) {
	my $best_e = undef;
	my $best_v = undef;
	my $best_r1 = undef;
	my $best_r2 = undef;
	
	for my $r1 (RSequence($er, $r1min,$r1max)) {
	    for my $r2 (RSequence($er, $r2min,$r2max)) {
		
		my $tv = 2.5/($r1/($r1+$r2));
		
		my $e = abs($tv-$v);
		if (!defined $best_e or $e < $best_e) {
		    $best_e = $e;
		    $best_r1 = $r1;
		    $best_r2 = $r2;
		    $best_v = $tv;
		}
	    }
	}
	
#    print "$v ~ $best_v @ $best_r1/$best_r2\n";    
	$best_v = int(100*$best_v)/100;
	$best_e = int(1000*($best_v-$v));
	
	$best_r1 = prettyR($best_r1);
	$best_r2 = prettyR($best_r2);
	print qq|<td>$best_v</td><td>$best_e</td><td>$best_r1</td><td class="sep">$best_r2</td>\t|;
    }
    print "</tr>\n"; 
   
#    for my $r1 (
}

