#!/usr/bin/perl -w

use strict;

my $infn = "hourglass.out";
my $MIN_TIME = 0;
my $MAX_TIME = 10000;
my $make_eps;
my $make_ps;
my $make_png;

sub usage {
    print "usage: render_trace.pl\n";
    print "  -h -- print usage info\n";
    print "  -i input_file_name\n";
    print "  -r start_time end_time (in ms)\n";
    print "  -e -- produce encapsulated postscript (requires jgraph)\n";
    print "  -p -- produce postscript (requires jgraph)\n";
    print "  -g -- produce both postscript and png (requres jgraph and gs and imagemagick)\n";
    exit (0);
}

my $i;

sub expect_arg {
    $i++;
    if (!defined($ARGV[$i])) {
	print "oops -- expected arg at position ".($i+1)."\n\n";
	usage ();
    }
    return $ARGV[$i];
}

for ($i=0; $i<scalar(@ARGV); $i++) {

    if ($ARGV[$i] eq "-p") {
	$make_ps = 1;
	next;
    }

    if ($ARGV[$i] eq "-e") {
	$make_eps = 1;
	next;
    }

    if ($ARGV[$i] eq "-g") {
	$make_png = 1;
	$make_ps = 1;
	$make_eps = 1;
	next;
    }

    if ($ARGV[$i] eq "-h") {
	usage ();
    }

    if ($ARGV[$i] eq "-i") {
	$infn = expect_arg ();
	next;
    }

    if ($ARGV[$i] eq "-r") {
	$MIN_TIME = expect_arg ();
	$MAX_TIME = expect_arg ();
	next;
    }

    print "oops: unknown arg \"$ARGV[$i]\" at position ".($i+1)."\n\n";
    usage ();
}

my $rootfn = $infn;
($rootfn =~ s/\.out$//);

my $jgrfn = $rootfn.".jgr";

print "input file name  = $infn\n";
print "output file name = $jgrfn\n";
print "start time = $MIN_TIME\n";
print "end time   = $MAX_TIME\n";

my $nthreads = -1;
my $str = "";

open INF, "<$infn" or die "couldn't open input file!";

while (my $line = <INF>) {

    if ($line =~ /^numthreads: ([0-9]+)$/) {
	$nthreads = $1;
    }

    if ($line =~ /^tracerec: ([0-9]+) ([0-9\.]+) ([0-9\.]+) [0-9\.]+ [0-9\.]+$/) {
	
	my $thread = $1;
	my $start = $2;
	my $end = $3;
	
	next if ($end < $MIN_TIME);
	next if ($start > $MAX_TIME);

	if ($start < $MIN_TIME) {
	    $start = $MIN_TIME;
	}

	if ($end > $MAX_TIME) {
	    $end = $MAX_TIME;
	}

	my $nthread = $thread+1;
		
	$str .= "newline poly linethickness 0.0 pfill 0.8 pts\n";
	$str .= "  $start $thread\n";
	$str .= "  $end $thread\n";
	$str .= "  $end $nthread\n";
	$str .= "  $start $nthread\n\n";
    }
}

open OUTF, ">$jgrfn" or die "couldn't open output file!";

print OUTF "newgraph\n";
print OUTF "xaxis size 2.5 min $MIN_TIME max $MAX_TIME label fontsize 9 : Time (ms)\n";
print OUTF "yaxis size 1.0 label fontsize 9 : Thread Number\n";
print OUTF "  min 0\n";
print OUTF "  max $nthreads\n";
print OUTF "  hash 0\n";

for (my $i=0; $i<$nthreads; $i++) {
    print OUTF "  hash_label at ".($i+0.5)." : $i\n";
}

print OUTF $str;

close OUTF;

my $epsfn;
if ($make_eps) {
    $epsfn = $rootfn.".eps";
    print "making encapsulated postscript file $epsfn\n";
    system "jgraph < $jgrfn > $epsfn";
}

my $psfn;
if ($make_ps) {
    $psfn = $rootfn.".ps";
    print "making postscript file $psfn\n";
    system "jgraph -P -L < $jgrfn > $psfn";
}

if ($make_png) {
    die if (!$make_ps);
    my $pngfn = $rootfn.".png";
    my $tmpfn = $rootfn.".ppm";
    print "making png file $pngfn\n";
    system "gs -sDEVICE=ppm -dTextAlphaBits=4 -dImageAlphaBits=4 -r300 -sOutputFile=$tmpfn -q - < $psfn";
    system "convert -crop 0x0 -rotate 270 -border 20x20 -bordercolor white $tmpfn $pngfn";
    unlink $tmpfn;
}


syntax highlighted by Code2HTML, v. 0.9.1