#!/usr/bin/perl

use Data::Dumper;
use List::Util qw(min max);
use Math::Trig;
use POSIX;
use SVG;

$svgfile = "buffer.svg";

open SVGFILE,">$svgfile";

$scalefactor=1;
$width=1920*$scalefactor;
$height=1080*$scalefactor;
$width4=$width/4;
$height4=$height/4;

sub AV
{
  my $i=$_[0];
  my $scale=$_[1];
  my $av=$scale->{"min"}+($scale->{"max"}-$scale->{"min"})/$scale->{"ntic"}*$i;
  if(abs($av)<($scale->{"max"}-$scale->{"min"})*1e-7)
  {
    $av=0;
  }
  return $av;
}

sub SCALE
{
  my $min=$_[0];
  my $max=$_[1];
  my $ntic=$_[2];
#   print "min: $min max: $max ntic: $ntic\n";
  sub NDIG
  {
    my $x=$_[0];
    $x=1 if($x==0);
    return(POSIX::floor(log($x)/log(10)+1.0000001));
  }
  my $d=($max-$min)/$ntic;
  my $ld=log($d)/log(10);
  my $ild=POSIX::floor($ld);
  my $fld=10.0**($ld-$ild);
  my $tic=10.0**$ild;
  if($fld>5)
  {
    $tic = $tic*10;
  }
  elsif($fld>2)
  {
    $tic = $tic*5;
  }
  elsif($fld>1)
  {
    $tic = $tic*2;
  }
  $min = POSIX::floor($min/$tic)*$tic;
  $max = POSIX::floor($max/$tic+0.999999)*$tic;
  $ntic = POSIX::floor(($max-$min)/$tic+0.000001);
  my $dig1 = max(1,NDIG(max(abs($min),abs($max))));
  my $dig2 = max(1-NDIG($tic),0);
  my $r;
  $r->{"min"} = $min;
  $r->{"max"} = $max;
  $r->{"tic"} = $tic;
  $r->{"ntic"} = $ntic;
  $r->{"dig1"} = $dig1;
  $r->{"dig2"} = $dig2;
#   print Dumper($r);
  return $r;
}

sub WRITE
{
  my $x = $_[0];
  my $dig1 = $_[1];
  my $dig2 = $_[2];
  my $s = "";
  my $first=1;
  my $origx = $x;
  if($x<0)
  {
    $x=-$x;
    $s="-";
  }
  $x = ($x*10**$dig2+0.5)*10**(1-$dig1-$dig2);
  for(my $i=-$dig1; $i<=$dig2; $i++)
  {
    $first=0 if($i==-1);
    if($i==0)
    {
      $s .= "." if($dig2>0);
    }
    else
    {
      my $ch=POSIX::floor($x);
      $first=0 if($ch>0);
      $x = ($x-$ch)*10;
      $s .= $ch if($ch>0 || !$first);
    }
  }
  return $s;
}

open IN,"buffer.log";

$serial = 0;
$maxtime = 0;
$maxtapeid = 0;

while($l = <IN>)
{
  chomp($l);
  if($l =~ /\s*([0-9.]+)(	+)(.*)$/)
  {
    $sec[$serial] = $1;
    $maxtime = $1 if($1>$maxtime);
    $tapeid[$serial] = length($2);
    $maxtapeid = $tapeid[$serial] if($tapeid[$serial]>$maxtapeid);
    $r = $3;
    if($r =~ /^write (\d+) word/)
    {
      $operation[$serial] = $1;
    }
    elsif($r =~ /^read (\d+) word/)
    {
      $operation[$serial] = -$1;
    }
    else
    {
      next;
    }
    $serial++;
  }
}

#for($i=0;$i<$serial;$i++)
#{
#  print $sec[$i]."\t";
#  print $tapeid[$i]."\t";
#  print $operation[$i]."\n";
#}

$svg = SVG->new(width => $width, height => $height);

$y1min=0;
$y1max=$maxtapeid;
$ny1tic=10;
$nxtic=20;

$tapespeed = 36.0; # "/s
$gap = 0.75;
$wordlen = 7.0;
$bpi = 200.0;

$axisfontsize=20*$scalefactor;
$axistitlefontsize=30*$scalefactor;
$titlefontsize=40*$scalefactor;
$subtitlefontsize=30*$scalefactor;
$minorticksize=3*$scalefactor;
$majorticksize=5*$scalefactor;
$y1color="black";
$readcolor="green";
$barheight=40*$scalefactor;
$writecolor="red";
$black="black";
$xcolor=$black;
$white="white";
$linewidth=1;

$fontfile = [ qw( Arial Helvetica sans ) ];

print "y1min: $y1min y1max: $y1max\n";

$y1scale = SCALE($y1min, $y1max, $ny1tic);
print "maxtime: $maxtime\n";
$xscale = SCALE(0, $maxtime, $nxtic);

$txt ="Tape I/O";
$gtitle = $svg->group(id => 'gtitle',
    style => {stroke => 'none', fill => $black, 'font' => $fontfile, 'font-size' => $titlefontsize});
$gtitle->text(x => $width/2, y => $titlefontsize*2, style => {'text-anchor' => 'middle'})->cdata($txt);

$txt = "Red: Write Green: Read";
$gsubtitle = $svg->group(id => 'gsubtitle',
    style => {stroke => 'none', fill => $black, 'font' => $fontfile, 'font-size' => $subtitlefontsize});
$gsubtitle->text(x => $width/2, y => $titlefontsize*2+$subtitlefontsize*1.5, style => {'text-anchor' => 'middle'})->cdata($txt);

my $vxmin=0.01*$width;
my $vxmax=$width-0.01*$width;
my $vymin=5*$scalefactor+2*$titlefontsize+2*$subtitlefontsize;
my $vymax=$height-$axisfontsize*2-$axistitlefontsize*2-30*$scalefactor;

$vxmin+=5*$axistitlefontsize;
$gyaxis = $svg->group(id => 'gyaxis',
    style => {stroke => 'none', fill => $y1color, 'font' => $fontfile, 'font-size' => $axisfontsize});
for($i=0; $i<=$y1scale->{"ntic"};$i++)
{
  my $y0=AV($i, $y1scale);
  my $y=$vymax-($vymax-$vymin)/($y1scale->{"max"}-$y1scale->{"min"})*($y0-$y1scale->{"min"});
  $ytext=WRITE(AV($i,$y1scale),$y1scale->{"dig1"},$y1scale->{"dig2"});
  $gyaxis->text(x => $vxmin-$majorticksize*4, y => $y+$axisfontsize/2, style => {'text-anchor' => 'right'})->cdata($ytext);
  $gyaxis->line(x1 => $vxmin-$majorticksize,
                y1 => $y,
		x2 => $vxmin,
		y2 => $y, style => {stroke => $y1color});
}
$gyaxis->line(x1 => $vxmin,
	      y1 => $vymin,
	      x2 => $vxmin,
	      y2 => $vymax, style => {stroke => $y1color});

$txt = "Tape station number";
$tx = $vxmin-2*$axistitlefontsize;
$ty = ($vymax+$vymin)/2;

$gyaxis->text( style => {'text-anchor' => 'middle', 'font-size' => $axistitlefontsize},
	      transform => "translate($tx,$ty) rotate(-90)")->cdata($txt);

$readlist = "";
$writelist = "";
$gread = $svg->group(id => 'gread',
    style => {stroke => $readcolor, fill => $readcolor});
$gwrite = $svg->group(id => 'gwrite',
    style => {stroke => $writecolor, fill => $writecolor});
for($i=0;$i<$serial;$i++)
{
  $w = $operation[$i];
  $bwidth = (abs($w)*$wordlen/$bpi+$gap)/$tapespeed;
  $vwidth = (($vxmax-$vxmin)/($xscale->{"max"}-$xscale->{"min"})*$bwidth);
  $x=$sec[$i];
  $vx = ($vxmin+($vxmax-$vxmin)/($xscale->{"max"}-$xscale->{"min"})*($x-$xscale->{"min"}));
  $y=$tapeid[$i];
  $vy = ($vymax-($vymax-$vymin)/($y1scale->{"max"}-$y1scale->{"min"})*($y-$y1scale->{"min"}));
# print "vx: $vx vwidth: $vwidth vy: $vy barheight: $barheight\n";
  $point = "$vx,$vy ".($vx+$vwidth).",".($vy+$barheight);
  if($w<0)
  {
    $gread->rectangle(x => $vx,
	              y => $vy,
		      width => $vwidth,
		      height => $barheight);
  }
  else
  {
    $gwrite->rectangle(x => $vx,
	              y => $vy,
		      width => $vwidth,
		      height => $barheight);
  }
   
}
$gxaxis = $svg->group(id => 'gxaxis',
    style => {stroke => 'none', fill => $xcolor, 'font' => $fontfile, 'font-size' => $axisfontsize});
for($i=0; $i<=$xscale->{"ntic"};$i++)
{
  my $x=AV($i, $xscale);
  my $vx=$vxmin+($vxmax-$vxmin)/($xscale->{"max"}-$xscale->{"min"})*($x-$xscale->{"min"});
  $xtext=WRITE($x,$xscale->{"dig1"},$xscale->{"dig2"});
  $gxaxis->text(x => $vx, y => $vymax+$axisfontsize*2, style => {'text-anchor' => 'middle'})->cdata($xtext);
  $gxaxis->line(x1 => $vx,
                y1 => $vymax,
		x2 => $vx,
		y2 => $vymax+$majorticksize, style => {stroke => $xcolor});
}
$gxaxis->line(x1 => $vxmin,
	      y1 => $vymax,
	      x2 => $vxmax,
	      y2 => $vymax, style => {stroke => $xcolor});
$txt = "Time, sec.";
$gxaxis->text(x => ($vxmax+$vxmin)/2,
              y => $vymax+$axisfontsize+2*$axistitlefontsize,
	      style => {'text-anchor' => 'middle','font-size' => $axistitlefontsize})->cdata($txt);

print SVGFILE $svg->xmlify;
close SVGFILE;
exit;
