#!/bin/perl

# This program pulls a distribution copy of our dataset, together with a text file of ropelength data.
#

use strict;
use warnings;
use File::Slurp;
use File::Path;
use Data::Dumper;
use File::Copy;
use Lingua::EN::Numbers qw(num2en num2en_ordinal);
use Cwd;

sub make_safekey {

    my $key = $_[0];
    my $safekey;
    my $texkey;

    my $cr;
    my $ind;
    my $comp;

    my $safeone;
    my $safetwo;
    my $safethree;
    
    if ( $key !~ /.vect/ ) {  #this is a knot type
	
	if ( $key =~ /(\d+)_(\d+)_(\d+)/ ) { # a link
	    
	    $safeone = $1; $safetwo = $2; $safethree = $3;

	    $cr = num2en($safeone); $comp = num2en($safetwo); $ind = num2en($safethree);
	    $cr =~ s/\s/\-/g; $comp =~ s/\s/\-/g; $ind =~ s/\s/\-/g;
	   
	    $cr =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge;
	    $comp =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge;
	    $ind =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge;
	    
	    $safekey = $cr.$comp.$ind;
	    $safekey =~ s/-//g;
	    $texkey = $safeone."^{".$safetwo."}_{".$safethree."}";

	    $cr = $safeone; $comp = $safetwo; $ind = $safethree;
	    
	} elsif ( $key =~ /(\d+)_(\d+)/ ) { # a knot
	
	    $safeone = $1; 
	    $safetwo = $2;
	    
	    $texkey = $safeone."_{".$safetwo."}";
    
	    $cr = num2en($safeone); $ind = num2en($safetwo);
	    $cr =~ s/\s/\-/g; $ind =~ s/\s/\-/g;

	    $cr =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge;
	    $ind =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge;
	    

	    $safekey = $cr.$ind;
	    $safekey =~ s/-//g;
	
	    $cr = $safeone; $comp = 1; $ind = $safetwo;

	} else {

	    print "FAILED to match key ".$key."\n";

	}


    }
	
    my @retstuff = ($safekey,$texkey,$cr,$comp,$ind);

    return @retstuff;
	    
}

my $cwd;
$cwd = getcwd;

my $tarname;
my $xname;
my $filename;

# We start by loading the database.

my $DBFILE = read_file("${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 best representatives of knot types.\n";

# first, a pass to remove files from the hash

my $key;

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

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

	delete $wknots{$key};

    } 

}

delete $wknots{'0_1'};
delete $wknots{'0_2_1'};
delete $wknots{'0_3_1'};
delete $wknots{'0_4_1'};
delete $wknots{'3_1_1'};

$numkeys = keys ( %wknots );
print "Found $numkeys knot types in the database.\n";
print "Extracting and renaming best example of each and copying to ./best.\n";

my $newname;

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

foreach $key ( keys %wknots ) {

    $newname = "${cwd}/best/".$key."_best.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 "Refreshed ./best directory.\n";
print "Now making _curvature.txt files for each knot...\n";

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

my @besties;
@besties = <*_best.vect>;
my $file;

foreach $file (@besties) {

  my $curvaturefile;
  $curvaturefile = $file;
  $curvaturefile =~ s/best\.vect/curvature.txt/g;
  `plcurvature -o $curvaturefile $file`;

}

chdir("${cwd}") or die("Couldn't chdir back to ${cwd}");

print "Now creating data file ./best/ropelength_data.txt \n";

my $safekey;
my $texkey;
my $cr;
my $comp;
my $ind;

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

    ($safekey,$texkey,$cr,$comp,$ind) = &make_safekey($key);

    # Now some formatting modifications for the table.

    $wknots{$key}{ropelength} = sprintf("%2.4f",$knots{$key}{ropelength} + 0.00005);
    $wknots{$key}{upperbound} = sprintf("%2.4f",$knots{$key}{upperbound} + 0.00005);
    
    $wknots{$key}{tex} = $texkey;
    $wknots{$key}{cr} = $cr;
    $wknots{$key}{comp} = $comp;
    $wknots{$key}{index} = $ind;
   
}

my @knotlist = sort{ 

		     if (($wknots{$a}{cr} <=> $wknots{$b}{cr}) eq 0 ) {

			 if (($wknots{$a}{comp} <=> $wknots{$b}{comp}) eq 0 ) {

			     return $wknots{$a}{index} <=> $wknots{$b}{index};

			 }

			 return $wknots{$a}{comp} <=> $wknots{$b}{comp};

		     }

		     return $wknots{$a}{cr} <=> $wknots{$b}{cr};

		     } keys( %wknots );



open TEXTFILE, ">${cwd}/best/ropelength_data.txt" or die("Couldn't open ${cwd}/best/ropelength_data.txt\n");

print TEXTFILE "# This file contains summary data from \" Knot Tightening By Constrained Gradient Descent \" by Ashton, Cantarella, Piatek, Rawdon.\n";
print TEXTFILE "# and \" The Shapes of Tight Composite Knots \" by Cantarella, La Pointe, Rawdon.\n";
print TEXTFILE "# Knot type Polygonal Ropelength Ropelength Bound Edges Residual Writhe \n";

foreach $key ( @knotlist ) {

    print TEXTFILE "$key \t $wknots{$key}{ropelength} \t $wknots{$key}{upperbound} \t $wknots{$key}{edges} \t $wknots{$key}{residual} \t $wknots{$key}{writhe} \n";

  }

close TEXTFILE;

chdir($cwd) or die("Couldn't change back to $cwd\n");

print "Now making archive for distribution...\n";

print `mkdir ropelengthdata`;
print `cp ./best/*.vect ./ropelengthdata/`;
print `cp ./best/*.txt ./ropelengthdata/`;
print `tar -cvzf ropelengthdata.tgz ./ropelengthdata/`;
print `rm -fr ropelengthdata`;

#print "Now updating the web page...\n";

# Get password from the user.

#my $password;

#print "Password (for dreamhost):";
#$password = <STDIN>;
#chomp($password);

##open Writer '|scp ropelengthdata.tgz ropelength_data.txt cantarel@jasoncantarella.com:\"~/jasoncantarella.com/downloads/\" ');
#print Writer "$password\n";
 
die("done");
