#! /usr/bin/perl -w
###############################################################################
# aqgen.pl - ani quote generator, reads a file of ani quotes and randomally   #
#            chooses one of them                                              #
#            copies the quote source and then uses that until empty (so as    #
#            not to reuse quotes)                                             #
#                                                                             #
# Author: Steven Hanley <sjh@svana.org>                                       #
# Date: 2004-04-27                                                            #
# Last Modified: 2005-05-03                                                   #
#                                                                             #
# cachefile and quotefile may be passed as arguments, otherwise they default  #
# to the variables defined below.                                             #
# if you wish to get a unique quote (once per iteration of reading in the     #
# file use the --unique argument, otherwise it simply selects one at random   #
# from the quotefile every time                                               #
#                                                                             #
# 2005-05-03: lca is over so I can mess around with my signature again, time  #
#             to finish this code                                             #
###############################################################################

use strict;
use Data::Dumper;
use Getopt::Long;

my $cachefile = "/home/sjh/.used_ani_quotes";
my $quotefile = "/home/sjh/asd/ani_quotes.text";
my $staticfile = "/home/sjh/.signature_static";

my ($help, $unique) = (0, 0);

GetOptions ('quotefile=s' => \$quotefile,
            'cachefile=s' => \$cachefile,
            'staticfile=s' => \$staticfile,
            'unique' => \$unique,
            'help' => \$help);

die "Usage: $0 [--quotefile=file] [--cachefile=file] [--unique] [--help]\n"
   if ($help);


# reads a quote file (filename is the argument)
# format is
# "# album (.*)$
# catching the album name
# anything after that until the next album name is either blank lines or quotes
# quotes are
#
# nonblank
# [nonblank]
# -> track name$
#
# there are blank lines seperating quotes
#
# the hash returned is album -> track -> quote
# this is a nice format to store in a hash and to read and write
# however it is more difficult to select an item of or remove items
# from or reference individual items easily
sub read_quote_file ($) {
   my $filename = shift;

   open (FH, "<$filename") or die "could not open $filename $!\n";
   my @file = <FH>;
   close (FH);

   my $quotes;

   my ($quote,$album);
   foreach (@file) {
	   if (/^$/) {
         $quote = "";
      } elsif (/^\#\salbum\s(.*)$/) {
         chomp; $album = $1;
      } elsif (/^->\s(.*)$/) {
         chomp; $quotes->{$album}->{$1} = $quote;
      } else {
         # dont chomp quotes as the line endings are part of the quote
         $quote .= $_;
      }
   }

   return $quotes;
}

# pretty way to dump the data as it was originally read
#   foreach my $album (keys %{$quotes}) {
#      $text .= "# album $album\n\n";
#      foreach my $track (keys %{$quotes->{$album}}) {
#         $text .= $quotes->{$album}->{$track};
#         $text .= "-> $track\n\n";
#      }
#	}

# rather then storing the left over quotes on disk in a similar
# manner to the original format, simply dump an easy to use structure
sub dump_quote_cache ($$) {
   my ($filename, $quotecache) = @_;

   open (FH, ">$filename") or die "could not open $filename $!\n";
   print FH Dumper ($quotecache);
   close (FH);
}

sub read_quote_cache ($) {
   my $filename = shift;

   my $quotes = undef;

   if (open (FH, "<$filename")) {
      my $text = join ("", <FH>);
      close (FH);

      my $VAR1; eval ($text); $quotes = $VAR1;
   }

   return $quotes;
}

# turn the quotes into an array of references to quotes ready to print
# this array can have items removed at random and be dumped and read
sub serialise_quotes ($) {
   my $quotes = shift;

   my @qlist;
   foreach my $album (keys %{$quotes}) {
      foreach my $track (keys %{$quotes->{$album}}) {
         my $q = $quotes->{$album}->{$track};
         # upper case the first letter of the words in track and album names
         my $a = join (" ", map { ucfirst; } split / /, $album);
         my $t = join (" ", map { ucfirst; } split / /, $track);
         push @qlist, "$q   $t - $a - Ani";
      }
	}
   return \@qlist;
}

# removes a random element from the array and returns it
# contents $qarr changed
sub remove_random_quote ($) {
   my $qarr = shift;

   # return in a seperate statement to ensure scalar context
   my $ret = splice (@{$qarr}, rand @{$qarr}, 1);
   return $ret;
}

my $qarr = undef;
if ($unique) {
   $qarr = read_quote_cache ($cachefile);

   # if the quote cache is empty read it form the original again
   if (not defined $qarr or not scalar (@{$qarr})) {
      my $quotes = read_quote_file ($quotefile);
      $qarr = serialise_quotes ($quotes);
   }
} else {
   # read the original list from disk and serialise
   my $quotes = read_quote_file ($quotefile);
   $qarr = serialise_quotes ($quotes);
}

my $quote = remove_random_quote ($qarr);

my $static = "";
if ($staticfile ne "") {
   open (FH, "<$staticfile") or warn "could not open $staticfile $!\n";
   $static = join ("", <FH>);
   close (FH);
}

# to store remaining unused quotes if necessary
dump_quote_cache ($cachefile, $qarr) if $unique;

print $static, $quote, "\n";
