#!/sw/bin/perl 

# Creates crossing number/ropelength plots in GnuPlot from KnotDB information.

use strict;
use warnings;
use Lingua::EN::Numbers qw(num2en num2en_ordinal);
use File::Slurp;
use Data::Dumper;
use POSIX;
use Getopt::Long;

sub make_safekey {

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

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

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

	} else {

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

	}


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

    return @retstuff;
	    
}

# First, load the database file.

my $DBFILE = read_file('KnotDB.pl');
my %knots;

eval($DBFILE);

my $noComposites= '';
my $key;

GetOptions ( 'nocomposites|noComposites' => \$noComposites);

if ($noComposites) {

  print "Called with noComposites; removing composites from DB.\n";

  foreach $key ( keys %knots ) {

    if (defined($knots{$key}{summands})) {

      delete $knots{$key};

    }

  }

}

open KDATA,">","crossing_number_vs_ropelength.dat" or die("Couldn't open data");

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

print "Making crossing number vs ropelength plot...\n";
print "Preprocessing knotDB.pl to remove files and knots with too many crossings...\n";

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

    if ($key !~ /vect/) {  # It is a knot and not a file

	#print "Processing key ".$key."\n";
	($cr,$comp,$ind) = &make_safekey($key);
	    
	if ($knots{$key}{cr} <= 10 and $knots{$key}{cr} > 0 and $key !~ /3_1_1/) {

	    print KDATA $cr." ".$knots{$key}{ropelength}." ".$comp."\n";	   

	} else {

	    delete $knots{$key};

	}

    } else {

	delete $knots{$key};

    }

}

close(KDATA);

print "Now sorting by crossing number....";

my @bycrossing;

foreach $key ( keys %knots ) {

    if (defined $knots{$key}{cr}) { push(@{ $bycrossing[$knots{$key}{cr}] },$key); }

}

print "done.\n";
print "Example: 5 crossing knots and links are @{ $bycrossing[5] }. \n";
print "Example: 9 crossing knots and links are @{ $bycrossing[9] }. \n";

#
# Plot error bars and averages
#

my @thiscr;
my $crnum;
my $lastkey;
my $max;
my $min;

print "Writing file of range data for ropelength/crossing number...";

open KDATA,">","crossing_number_vs_ropelength_ranges.dat" or die("Couldn't open data");

my $crkey;

foreach $crnum (2..10) {

    @thiscr = @{ $bycrossing[$crnum] };

    @thiscr = sort {
	
	return $knots{$a}{upperbound} <=> $knots{$b}{upperbound};

    } @thiscr;

    $min = $knots{$thiscr[0]}{upperbound};
    $max = $knots{$thiscr[-1]}{upperbound};

    foreach $crkey ( @thiscr ) {

	print KDATA "$crnum $knots{$crkey}{upperbound} $min $max \n";

    }

    print "$crnum crossing knots and links have ropelength in [ $min, $max ].\n";
    
}

close(KDATA);
print "done.\n";


#
# Now plot cr/Rop for KNOTS alone.
#

print "Making crossing number/ropelength plot for knots alone...\n";

open KDATA,">","crossing_number_vs_ropelength_knots.dat" or die("Couldn't open data");

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

    if ($key !~ /vect/) {  # It is a knot and not a file

	#print "Processing key ".$key."\n";
	($cr,$comp,$ind) = &make_safekey($key);
	    
	if ($cr <= 10 and $cr > 0 and $key !~ /3_1_1/ and $comp == 1) {

	    print KDATA $cr." ".$knots{$key}{ropelength}." ".$comp."\n";
	    
	}
    }

}

close(KDATA);

`gnuplot crossing_number_vs_ropelength.gnuplot`;
`ps2pdf -dEPSCrop crossing_number_vs_ropelength.eps crossing_number_vs_ropelength.pdf`;

#
# Make graph of all ropelengths
#

print "Making graph of ropelengths...\n";

open KDATA,">","ropelength_knots_links.dat" or die("Couldn't open data");

my @ropelengths;

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

    if ($key !~ /vect/) {  # It is a knot and not a file

	#print "Processing key ".$key."\n";

	if ($key !~ /3_1_1/) {
	    
	    push(@ropelengths,$knots{$key}{ropelength});

	}

    }

}

@ropelengths = sort{ $a <=> $b } @ropelengths;

my $guy;
my $knot_num = 1;

foreach $guy ( @ropelengths ) {

    print KDATA "$knot_num $guy \n";
    $knot_num++;

}

close(KDATA);

system("gnuplot ropelength_knots_links.gnuplot");

