#!/bin/perl

# This program searches the KnotDB database for knot types without a strutplot
# then generates corresponding PDF strutplots of them in the /mugshots directory.

use strict;
use warnings;
use File::Slurp;
use File::Path;
use Data::Dumper;
use File::Copy;
use Getopt::Long;
use Cwd;

print "mkStrutplots: Updated to new directory structure!\n\n";

my $forcerefresh = '';

GetOptions ( 'forcerefresh|force' => \$forcerefresh );

# We start by loading the database.

my $cwd;
$cwd = getcwd;
#open(DB,'KnotDB.pl');
my $DBFILE = read_file("${cwd}/knotdb/KnotDB.pl") or die("Couldn't open $cwd/knotdb/KnotDB.pl");
my %knots;

eval($DBFILE);

my %wknots = %knots;

my $numkeys = keys ( %wknots );
print "We have $numkeys entries in the original database. Looking for knot types.\n";

# first, a pass to remove files from the hash

my $key;

foreach $key ( sort(keys %wknots) ) {

    if ($key =~ /.vect/) {

      # Since strutplots are no longer associated with filenames, delete if present
      if (defined $knots{$key}{strutplot}) {

	delete $knots{$key}{strutplot};
	print "Deleted strutplot record from $key";

      }
      
      delete $wknots{$key};

    } elsif (defined($wknots{$key}{strutplot}) && !$forcerefresh) {

      delete $wknots{$key};

    }

}

my $newname;
my $tarname;
my $xname;

print "Preparing workspace and copying out files which need strutplots:";

if (-d "${cwd}/strutplotworking") { 
  rmtree("${cwd}/strutplotworking/") or die("Couldn't clear old ${cwd}/strutplotworking/"); 
}
mkdir ("${cwd}/strutplotworking/") or die("Couldn't create ${cwd}/strutplotworking/");

chdir("${cwd}/tars") or die("Couldn't chdir to ${cwd}/tars\n");

foreach $key ( keys %wknots ) {

    $newname = "${cwd}/strutplotworking/kl_".$key.".vect";
    $tarname = "kl_${key}.tar.gz";
    $xname = "./kl_${key}/".$wknots{$key}{filename};
    
    `tar -xzf $tarname $xname`;
    
    copy($xname,$newname) or die("File can't be copied to ".$newname);
    rmtree("./kl_${key}/") or die("Couldn't remove ./kl_${key}/\n");

    print"$xname -> $newname\n";

}

print "DONE!\n";
$numkeys = keys ( %wknots );
print "\n\nThere seem to be $numkeys knot types in the database to create new strutplots for. Generating strutplots now.\n";

my $stplotname;
my $pdfname;
my $filename;

my $throttle = 0;
my $cmdstring;
my $output;

my $strutfilename;
my @kapparange;
my $kinkregions;
my $straight;

chdir "${cwd}/strutplotworking" or die "Couldn't change to ${cwd}/strutplotworking: $_";

foreach $key ( keys %wknots ) {

    $throttle++;

    $filename = "${cwd}/strutplotworking/kl_".$key.".vect";
    print "Processing knot type $key, represented by filename $filename.\n";

    $stplotname = $filename;
    $stplotname =~ s/.vect/.stplot.eps/;

    $strutfilename = $filename;
    $strutfilename =~ s/.vect/.struts/;

    print "   Making strutplot $stplotname.\n";

    if (-e "../struts/".$strutfilename) {
	
	print `strutplot --strutfile=../struts/$strutfilename $filename --make-eps --nokey`;

    } else {
	
	#  print "strutplot --strutsize=0.6 $filename -e 1e-4 --make-eps";
	print `strutplot $filename --make-eps --nokey --DataComments`;

    }

    $pdfname = $filename;
    $pdfname =~ s/.vect/.pdf/;

    print "   Converting EPS $stplotname to PDF $pdfname.\n";
    $output = `epstopdf $stplotname --hires --outfile=$pdfname 2>1`;

    print "$output\n";

    print "   Parsing $stplotname to extract data.\n";

    open PLOTFILE, "<$stplotname" or die("Couldn't open $stplotname");
    while (<PLOTFILE>) {

	if (/Curvature Range: \[(\d+.\d+), (\d+.\d+)\]/) { 

	    $knots{$key}{klo} = $1;
	    $knots{$key}{khi} = $2;

	}

	if (/Struts: (\d+)/) {

	    $knots{$key}{struts} = $1;

	}

	if (/Kink Regions: (\d+)/) {

	    $knots{$key}{kinks} = $1;

	}

	if (/Straight Length: (\d+.\d+)/) {

	    $knots{$key}{straight} = $1;

	}

    }

    close(PLOTFILE);
#    print @lines;
#    print $output."\n";

    if ($output =~ /Error/) { die("epstopdf call failed: $output.\n"); }

    my $newpdfname = $pdfname;
    $newpdfname =~ s/\/.+\///g;
    $newpdfname = "${cwd}/strutplots/".$newpdfname;

    print "   Moving PDF strutplot $pdfname to $newpdfname.\n";
    move($pdfname,$newpdfname) or die("Couldn't move $pdfname to $newpdfname.\n");

    print "   Updating KnotDB.pl\n";

    $knots{$key}{strutplot} = $newpdfname;
    $knots{$key}{strutplot} =~ s/\/.+\///g; # remove path data 

    print "   Deleting $stplotname\n";

    unlink $stplotname or die("$_");
    unlink $pdfname;

    print "   Adding $newpdfname to svn.\n";
    print `svn add $newpdfname`;

    if ($throttle > 100) { 

      $throttle = 0;
      print `chdir ${cwd}; svn commit -m \"added strutplots\"; chdir ${cwd}/strutplotworking/`;

    }
    
}
 
print "Updating ${cwd}/knotdb/KnotDB to reflect new strutplots...\n";

rename "${cwd}/knotdb/KnotDB.pl","${cwd}/knotdb/KnotDB.spold.pl" or die("Unable to rename ${cwd}/knotdb/KnotDB.pl to ${cwd}/knotdb/KnotDB.spold.pl \n");
open(KNOTDB,">${cwd}/knotdb/KnotDB.pl") or die "Unable to create Knot database at ${cwd}/knotdb/KnotDB.pl";
print KNOTDB Data::Dumper->Dump([\%knots],['*knots']),"\n";
close KNOTDB;

