#!/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;
use Cwd;

my $cwd;
$cwd = getcwd;

require "${cwd}/bin/tightknot_common.pl";

my $composites;
GetOptions ( 'includecomposites' => \$composites );

# First, load the database file.

my $DBFILE = read_file("${cwd}/knotdb/KnotDB.pl");
my %knots;
my %wknots;
eval($DBFILE);

%wknots = %knots;

print "Making writhe plots...\n";
print "Preprocessing knotDB.pl...\n";

my $key;

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

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

	if (defined $knots{$key}{summands} && !($composites)) {

	    delete $knots{$key};

	}
    
    } else {
	    
	delete $knots{$key};
	
    }

}

my @keyarray;
@keyarray = keys ( %knots );
@keyarray = sort { $knots{$a}{sortorder} <=> $knots{$b}{sortorder} } @keyarray;

print "We have ".scalar @keyarray." knot types to process writhes for...\n";

open(WRDATA,">${cwd}/data/flatwrithe_knots.dat");

foreach $key (@keyarray) {

  if (!defined($knots{$key}{writhe})) {

    print "Writhe not defined for $key.\n";

  } else {

    if ($knots{$key}{comp} == 1) {

      my $remainder;
      $remainder = (7*$knots{$key}{writhe})/4;
      $remainder = $remainder - int($remainder);
      
      print WRDATA "$key $knots{$key}{writhe} ".($knots{$key}{writhe} * (7/4))." $remainder \n";

    }

  }

 }

close(WRDATA);

open(WRDATA,">${cwd}/data/flatwrithe_links.dat");

foreach $key (@keyarray) {

  if (!defined($knots{$key}{writhe})) {

    print "Writhe not defined for $key.\n";

  } else {

    if ($knots{$key}{comp} == 3) {

      my $remainder;
      $remainder = (7*$knots{$key}{writhe})/4;
      $remainder = $remainder - int($remainder);
      
      print WRDATA "$key $knots{$key}{writhe} ".($knots{$key}{writhe} * (7/4))." $remainder \n";

    } elsif ($knots{$key}{comp} == 2 || $knots{$key}{comp} == 4) {

       my $remainder;
       $remainder = (7*($knots{$key}{writhe} - (2/7)))/4;
       $remainder = $remainder - int($remainder);
       
       print WRDATA "$key $knots{$key}{writhe} ".(($knots{$key}{writhe} - (2/7)) * (7/4))." $remainder \n";

     }

  }

 }

close(WRDATA);

open(WRDATA,">${cwd}/data/flatwrithe_all.dat");

foreach $key (@keyarray) {

  if (!defined($knots{$key}{writhe})) {

    print "Writhe not defined for $key.\n";

  } else {

    if ($knots{$key}{comp} == 3 || $knots{$key}{comp} == 1) {

      my $remainder;
      $remainder = (7*$knots{$key}{writhe})/4;
      $remainder = $remainder - int($remainder);
      
      print WRDATA "$key $knots{$key}{writhe} ".($knots{$key}{writhe} * (7/4))." $remainder \n";

    } elsif ($knots{$key}{comp} == 2 || $knots{$key}{comp} == 4) {

       my $remainder;
       $remainder = (7*($knots{$key}{writhe} - (2/7)))/4;
       $remainder = $remainder - int($remainder);
       
       print WRDATA "$key $knots{$key}{writhe} ".(($knots{$key}{writhe} - (2/7)) * (7/4))." $remainder \n";

     }

  }

 }

close(WRDATA);

open(WRDATA,">${cwd}/data/flatwrithe_alternating.dat");

foreach $key (@keyarray) {

  if (!defined($knots{$key}{writhe})) {

    print "Writhe not defined for $key.\n";

  } else {

    if ($knots{$key}{alternating}) {
      
      if ($knots{$key}{comp} == 3 || $knots{$key}{comp} == 1) {
	
	my $remainder;
	$remainder = (7*$knots{$key}{writhe})/4;
	$remainder = $remainder - int($remainder);
	
	print WRDATA "$key $knots{$key}{writhe} ".($knots{$key}{writhe} * (7/4))." $remainder \n";
	
      } elsif ($knots{$key}{comp} == 2 || $knots{$key}{comp} == 4) {
	
	my $remainder;
	$remainder = (7*($knots{$key}{writhe} - (2/7)))/4;
	$remainder = $remainder - int($remainder);
	
	print WRDATA "$key $knots{$key}{writhe} ".(($knots{$key}{writhe} - (2/7)) * (7/4))." $remainder \n";
	
      }
      
    }

  }

 }

close(WRDATA);

print "Now a run with no babar configurations allowed...\n";

open(WRDATA,">${cwd}/data/flatwrithe_alternating_no_babar.dat");

my $babarcount;
my $totalcount;

foreach $key (@keyarray) {

  if (!defined($knots{$key}{writhe})) {

    print "Writhe not defined for $key.\n";

  } else {

    if ($knots{$key}{alternating}) {

       my $file;
       do { $file = shift(@{$knots{$key}{allfiles}}); } until ($file !~ /babar/);

       print "file -> $file\n";
      
       if ($knots{$key}{comp} == 3 || $knots{$key}{comp} == 1) {
	
	 my $remainder;
	 $remainder = (7*$wknots{$file}{writhe})/4;
	 $remainder = $remainder - int($remainder);
	 
	 print WRDATA "$key $wknots{$file}{writhe} ".($wknots{$file}{writhe} * (7/4))." $remainder ";
	 
       } elsif ($knots{$key}{comp} == 2 || $knots{$key}{comp} == 4) {
	 
	 my $remainder;
	 $remainder = (7*($wknots{$file}{writhe} - (2/7)))/4;
	 $remainder = $remainder - int($remainder);
	 
	 print WRDATA "$key $wknots{$file}{writhe} ".(($wknots{$file}{writhe} - (2/7)) * (7/4))." $remainder ";
	 
       }

       if ($knots{$key}{filename} =~ /babar/) { print WRDATA "babar\n"; $babarcount++; } else {print WRDATA "nobabar\n";}
       $totalcount++;
       
     }
    
  }

 }

close(WRDATA);

print "$babarcount configurations of $totalcount had new local mins\n";

die();

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

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,">","${cwd}/data/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,">","${cwd}/data/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,">","${cwd}/data/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");

