#!/usr/bin/perl -i.bak

# In case the version of File::Spec installed on this system is too old for File::Temp to use 
BEGIN {
    unshift(@INC, ".");
}


#todo: take off trailing linefeeds inside a \begin{graph}\end{graph}; they cause errors

use English;
use File::Temp qw/ :POSIX /;
use vars qw ($graphCounter $filenameBase);
$graphCounter = 0;



## get input
undef $INPUT_RECORD_SEPARATOR;
$file = <>;


#print STDERR "*********** I got: $file\n";

$DONT_CENTER  = 1;
#if ($file =~ /\\dontcentergraphs/) {$DONT_CENTER = 1;}

$file =~ s/\\dontcentergraphs//g;

## transform it

$file =~ s/\\begin{graph}\[nc\](.*?)\\end{graph}/processGraph($1, 'digraph', 0)/sge;
$file =~ s/\\begin{ugraph}\[nc\](.*?)\\end{ugraph}/processGraph($1, 'undirected graph', 0)/sge;

if (! $DONT_CENTER) {
    $file =~ s/\\begin{graph}(.*?)\\end{graph}/processGraph($1, 'digraph', 1)/sge;
    $file =~ s/\\begin{ugraph}(.*?)\\end{ugraph}/processGraph($1, 'undirected graph', 1)/sge;
} else {
    $file =~ s/\\begin{graph}(.*?)\\end{graph}/processGraph($1, 'digraph', 0)/sge;
    $file =~ s/\\begin{ugraph}(.*?)\\end{ugraph}/processGraph($1, 'undirected graph', 0)/sge;
}

#TODO: remove DONT_CENTER primitive... it's just for dana for this paper..

# print output
print $file; 


###############
# end of MAIN
###############

sub processGraph {
    my ($block, $type, $centered) = @_;



    $block =~ s/(\\begin{align\*?}.*?\\end{align\*?}\n?)/removeNewlines($1)/sge;
    $block =~ s/\\begin{align\*?}(.*?)\\end{align\*?}/\$\1\$/g;

    $block =~ s/((?:\$[^\$\n]*\$)*[^\$]*)\$([^\$]*)\$/$1.'$'.removeNewlines($2).'$'/ge;

#    print STDERR $block;

    my $l = length($block);
    $filenameBase = "easyLatexGraph${graphCounter}$l";

    if ($type eq 'digraph') {
	$block = "digraph $filenameBase {\n".$block."\n}";
	ladot($block, 'dot');
    }
    elsif ($type eq 'undirected graph') {
	$block = "graph $filenameBase {\n".$block."\n}";
	ladot($block, 'neato');
    }

    $graphCounter = $graphCounter + 1;
    rename("$filenameBase.ps", "$filenameBase.eps");

    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
     $atime,$mtime,$ctime,$blksize,$blocks)
	= stat("$filenameBase.tex");

    if (! $size) {
	unlink("$filenameBase.tex");
	if ($centered) {
	    return "\\begin{center}\\includegraphics{$filenameBase.eps}\\end{center}";
	} else {
	    return "\\includegraphics{$filenameBase.eps}";
	}
    }
    else
    {
	if ($centered) {
	    return "\\begin{center}\\input{$filenameBase.tex}\n\\includegraphics{$filenameBase.eps}\\end{center}";
	} else {
	    return "\\input{$filenameBase.tex}\n\\includegraphics{$filenameBase.eps}"; 
	}
    }
}

sub removeNewlines {
    my ($block) = @_;

    $block =~ s/\n//g;

    return $block;
}





# ladot version 2003-03-31
# by Brighten Godfrey
#


sub ladot {

    my ($block, $graphProgramName) = @_;

#    print STDERR "Ladot got:\n$block\n";

    my @lines = split(/\n/, $block);

    %paststubs = ();

    
    ($dotout, $dotoutFilename) = tmpnam();

# Open output file
#    open(DOTOUT, ">/tmp/$basename.dot");
    open(TEXOUT, ">$filenameBase.tex");
    
    foreach $line (@lines)
    {
	$line .= "\n";

	# process each TEX{...}TEX segment on this line
#    while ($line =~ /(TEX(\((\d+)\))?\{(.*?)\}TEX)/) {
	while ($line =~ /(\$.*?\$)(\((\d+)\))?/) {
#        print "LINE: $line";
	    $sizehint = $3;
#    print "SIZEHINT: $sizehint\n";
	    $tex = $1;
	    $stub = make_stub($tex, $sizehint);
	    $line =~ s/(\$.*?\$)(\((\d+)\))?/\"$stub\"/;
	    print TEXOUT "\\psfrag{$stub}[cc][cc]{$tex}\n";
        }
#    print "FINAL LINE: $line";
	print $dotout $line;
    }
    
    close($dotout);
    close(TEXOUT);

#    print STDERR "dot -Tps $dotoutFilename > $filenameBase.ps";
    system("$graphProgramName -Tps $dotoutFilename > $filenameBase.ps");
        
}

sub make_stub($$)
{
    # Make a placeholder (stub) for the TeX which will be substituted for the
    # real formatted TeX later.  This is tricky because the length of the stub
    # that we choose affects how Dot formats the PostScript.  We use the
    # heuristic that the length of the LaTeX code is correlated with the
    # amount of space needed to render the LaTeX code.

    if ($paststubs{$_[0]}) {
        return $paststubs{$_[0]};
    }

    my $length = int($_[1]);
    if ($length == 0) {
        # no sizehint given
        $length = sqrt(length($_[0]));
    }
#    print "LENGTH of $_[0]: $length\n";
    $stub_charset="-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    my $stub = "";
    for (my $i = 1; $i <= $length; $i++) {
        $stub .= substr($stub_charset, int(rand(length($stub_charset))), 1);
        #$stub = $stub . int(rand(length($stub_charset)));
        }
    #print "NEW STUB for $_[0]: $stub\n";
    $paststubs{$_[0]} = $stub;
    return $stub;
    }


