#!/bin/perl

# This program searches the KnotDB database for knot types without a mugshot
# then generates corresponding povray views of them in the /mugshots directory.

use strict;
use warnings;
use File::Slurp;
use File::Path;
use Data::Dumper;
use File::Copy;

print "mkMugshots 1.0: Now updated to new directory structure!\n";

# We start by loading the database.

my $DBFILE = read_file('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/) {

	delete $wknots{$key};

    } elsif (defined($wknots{$key}{mugshot})) {

	delete $wknots{$key};

    }

    my @mugglob;
    my $mugname;

    $mugname = $key =~ s/vect/a*.jpg/;

    @mugglob = <./mugshots/$mugname>;

    if (scalar @mugglob == 3) {

      @{$knots{$key}{mugshots}} = @mugglob;

      print "Restored link to files @mugglob.\n";
      delete $wknots{$key}

    }

}

$numkeys = keys ( %wknots );
print "There seem to be $numkeys knot types in the database without mugshots. Generating mugshots now.\n";

my $tubename;
my $pngname;
my $imgname;
my $throttle;
my $axis;
my $dirname;
my $thickness;
my $cvtoutput;
my $borderW;
my $borderH;
my $jpgname;
my $filename;
my $cream   = "--red=0.9647  --green=0.9098 --blue=0.7647";
my $dkbrown = "--red=0.00392 --green=0.4    --blue=0.3686";
my $dkgreen = "--red=0.5490  --green=0.3176 --blue=0.0392";
my $ltbrown = "--red=0.8470  --green=0.7019 --blue=0.3960";
my $ltgreen = "--red=0.78039 --green=0.9176 --blue=0.8980";

$throttle = 0;

chdir "./vects" or die "Couldn't change to ./vects: $_";

foreach $key ( keys %wknots ) {

    $filename = $wknots{$key}{filename};
    print "Processing knot type $key, represented by filename $filename.\n";
    print "Computed thickness ...";

    open(ROPELENGTH,"ropelength $filename |");
    while (<ROPELENGTH>) {
	if (/Thickness:\s*(\S+)/) { 
	    $thickness = $1;
	}
    }
    close ROPELENGTH;

    $thickness /= 2.0; # ropelength returns diameter thickness.

    print "$thickness\n";

    # We check to see if the knot has color information. If so, we'll leave that info alone when we tube.

    my $headstuff = `head $filename`;
    my @headlines;

    @headlines = split('\n',$headstuff);
    $headlines[1] =~ m/(\d+) (\d+) (\d+) .+/;
    
    if ($3 > 0) { # The third entry should be the colors

      $tubename = `tube -q -r $thickness $filename 2> /dev/null`;

    } else {
 
      $tubename = `tube $cream $ltbrown $ltgreen $dkbrown $dkgreen -q -r $thickness $filename 2> /dev/null`;

    }

    chomp($tubename);

    if ($tubename !~ /.tube.off/) {

	die("Tube run seems to have failed with command line\n tube $cream $ltbrown $ltgreen $dkbrown $dkgreen -q -r $thickness $filename 2> /dev/null ");

    }

    print "Generated tube $tubename. Now generating views.\n";

    for ($axis=0;$axis<3;$axis++) {

	print "Orienting to axis $axis.\n";
	$imgname = $filename;
	$imgname =~ s/.vect//;
	$imgname = $imgname.".a".$axis.".png";
	print "Will output image file $imgname.\n";
	
	`orient -a $axis $tubename`;

	print "Now running povsnap.\n";
    
	$pngname = `povsnap -qp --NoDisplay $tubename`;
	chomp($pngname);

	print "Povsnap generated file $pngname.\n";

	#`convert -trim $pngname $imgname`;
	#`convert -resize 768x768 $imgname $imgname`;
	`convert -contrast -trim $pngname $imgname`;
	$cvtoutput = `convert -resize 768x768 -verbose $imgname $imgname`;

	#print "Convert output is: $cvtoutput";
	$cvtoutput =~ /\=\>(\d+)x(\d+)/;
	print "Read new image dimensions as $1 x $2\n";
	
	$borderW = (768 - $1)/2.0;
	$borderH = (768 - $2)/2.0;

	$cvtoutput = `convert -border ${borderW}x${borderH} -bordercolor white -verbose $imgname $imgname`;

	#print "Convert output is: $cvtoutput";
	$cvtoutput =~ /\=\>(\d+)x(\d+)/;
	print "After adding border, image is $1 x $2\n";

	$jpgname = $imgname;
	$jpgname =~ s/png/jpg/;
	$cvtoutput = `convert $imgname $jpgname`;

	unless (-f $jpgname) { die("convert doesn't seem to have created $jpgname. Here's the output: $cvtoutput.\n"); }

	print "Converted $imgname to $jpgname.\n"; 

	move($jpgname, "../mugshots/$jpgname") or die("Couldn't move $jpgname to ../mugshots/$jpgname");
    
	$dirname = $tubename;
	$dirname =~ s/.off//;

	print "Will now attempt to remove povsnap directory $dirname.\n";

	unlink($imgname) or die("Couldn't remove $imgname: $_");
	unlink($pngname) or die("Couldn't remove $pngname: $_");
	rmtree($dirname) or die("Couldn't remove $dirname: $_");

	print "Now adding information to database.\n";

	$knots{$key}{mugshot}[$axis] = $jpgname;

	print "Now adding $jpgname to svn.\n";
	`svn add ../mugshots/$jpgname`;

    }

    print "Updated knots{key}. Writing proposed knot database.\n\n";

    open(KNOTDB,'>../ProposedKnotDB.pl') or die "Unable to create Knot database.";
    print KNOTDB Data::Dumper->Dump([\%knots],['*knots']),"\n";
    close KNOTDB;

    # Also unlink all the crap produced by povsnap. What's it called?

    $throttle++;

    if ($throttle > 400) { die ("Throttle killed it.\n"); }
}

print "Done mugshots. Updating main knot database.\n\n";

chdir("..");
open(KNOTDB,'>KnotDB.pl') or die "Unable to create Knot database.";
print KNOTDB Data::Dumper->Dump([\%knots],['*knots']),"\n";
close KNOTDB;    

# now we want to montage everything
# `montage -tile `echo $rowcount`x3 -geometry +80+20 arrayimage-*.png tubes.png`;      	
