#!/usr/bin/perl -w
# takes one argument - the input file name,
# which should be comma separated two column
# data with each input string enclosed in 
# quotes (").


use strict;

#constants to do with text stuff
my $width=600;
my $height=600;
my $page=sprintf("%sx%s",$width,$height); #set up the canvas size
my $leftoffset=20; # left margin in pixels
my $smallest_font_size=30; #lower bound on font size
my $baseline_down_offset; #font positioning variable
my @colours=('red','green'); # if you can't work out what this does, you 
                             # probably shouldn't be looking at source code
my $delay=500; # time between frames of animated gif, 100 ticks/second,
   # so 500 gives you 5 seconds per frame 
my $font_divisor=1.2; 
#approximately speaking,
#font_size/font_divisor * number_of_letters == width
#1.2 works for courier bold, work it out for yourself if you
#want to use a different font! 

my $q_string=''; # string to hold output quote
my $ostring=''; # string to hold the command for 
                # the output to the 'convert' programme

# variables to do with file input and output
my $filename=$ARGV[0];
my $buffer;
my $tmp_output_filename; # we output lots of temp files to /tmp
my $quote_counter=0;

#variable to hold type of opinion - 1= good, 0=bad 
#e.g. 1=best bit about computing, 0=worst bit about computing
my $type=0;

# now, on with the show...
open(FILE, $filename) or die "Can''t open $filename : $!";


# go through the file
while ($buffer=readline FILE) {
   #split it at "," into two statements - i include the quotes
   #in the split command, as we've got quotes around the statements.
   #and we want to discard them
   my @strings=split /","/,$buffer;
   $tmp_output_filename=sprintf('/tmp/fr%04d.gif',$quote_counter);
   for $type (0 .. 1) {
      $ostring='';
      $q_string=$strings[$type];
      
      # lose the newline if there is one
      chomp ($q_string);
      # lose the remaining quote marks 
      $q_string=~s/"//;
      # escape single quote marks for output 
      $q_string=~s/'/\\'/;
      if ($q_string eq '-') {
        # i have marked non entries with a hyphen, so let's just
        # replace that with a space (rather than have a huge hyphen
        # appear in the output).
        $q_string=' ';
      }
      # let's quickly look at what we're outputting as a quote, eh?
      print ("quote string: $q_string\n");

      # find out how long it is. 
      my $number_of_letters=length($q_string);

      my $font_size=$smallest_font_size;
      my $number_of_lines=0;
      my @output;
      my $chars_per_line=$width*$font_divisor/$font_size;

      if ($number_of_letters <= $chars_per_line) {
      # it fits on one line, let's scale up the font if there's room
          $font_size=($width*$font_divisor) / $number_of_letters;
          @output=($q_string);
      }  else  {
      # we have to slice the string into smaller chunks
      # may as well stick with smallest font size 
      # first let's split it into individual words
         my @words=split(/ /, $q_string);
         #now let's see how many chars per line we are allowed
         my $chars_so_far=0;
         foreach my $word (@words) {
            if ($chars_so_far+length($word) > $chars_per_line) {
            # if we are going to go over the maximum word length
            # increment the line counter, reset the char counter,
            # and stick the new word as a new array entry (using push)
               $chars_so_far=0;
               $number_of_lines++;
               push(@output,$word);
            } elsif ($number_of_lines==0 and $chars_so_far==0) {
            # first case, just make the first entry in output=word
            # need to treat this as a separate case or you end up with
            # a space at the start of the text
               $output[0]=$word;
            } else {
            # we're in the middle of a line, just add the word to the current line
            # of the output (with a space)
               $output[$number_of_lines]=$output[$number_of_lines].' '.$word;
            }
            $chars_so_far+=length($word);
         } 
      }
      #default is that the type is the worst thing (red, low on the page)
      $baseline_down_offset=400;
      if ($type==1) { # but if type ==1 is the best (green, high on the page)
         $baseline_down_offset=200;
      } 
      $baseline_down_offset=$baseline_down_offset-$number_of_lines*$font_size;
      $ostring=$ostring."-fill $colours[$type] -pointsize $font_size";
      for my $i (0 .. $number_of_lines)  {
         # get the place right
         my $geometry="$leftoffset,$baseline_down_offset";
         # get the text right
         my $textstring="-draw \"text $geometry \'$output[$i]\'\"";
         # add it to the output string
         $ostring=$ostring.' '.$textstring;
         # move to the next line
         $baseline_down_offset+=$font_size;
      } 
      # default: open existing image
      my $image_details=$tmp_output_filename; 
      if ($type==0) {
         #unless it is the first time for this frame, in which
         #case build it anew
         $image_details="-size $page xc:white";

      }
      print("Writing out to temporary file $tmp_output_filename now\n");
      system "convert $image_details -font Courier-bold $ostring $tmp_output_filename";
   }
   $quote_counter++;
}
close FILE;
# actually turn the pile of temp files into an animation
# loop 0 makes it loop forever
system "convert -delay $delay -loop 0 /tmp/f* animation.gif";
system "rm /tmp/f*.gif";
