#!/usr/bin/perl

############################################################################
# This is GALREY version 1.0.1, an image gallery generator.
#   Copyright (C) 2000 Claudio Cicali
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Claudio Cicali
# Email: flexer@flexer.it
############################################################################
# 2004-01-11: Added patches from Martin Schulze, Debian 213875, 213933     #
#             Added patches from Laurent Fousse  Debian 208230             #
# 2003-04-25: Added patches from Michael Beendict, Marcel van Dorp,        #
#             Tapio Lehtonen and some suggestion from others               #
# 2002-02-05: Better thumbnails generation (me and Roberto Butti)          #
############################################################################

use Getopt::Long;
use File::Basename;

main();

sub main()
{
    print "GALREY version 1.0.1, Copyright (C) 2004 Claudio Cicali\n";
    print "Galrey comes with ABSOLUTELY NO WARRANTY;\n";
    print "This is free software, and you are welcome to redistribute it under certain conditions;\nread COPYING for details.\n\n";

    # Default settings
    $c_title        = 'My Galrey pictures collection';
    $c_thumbsize    = '80x60';
    $c_thumbprefix  = 't_';
    $c_thumbsperrow = 5;
    $c_index        = 'index.html';
    $c_pattern      = '*.jpg';
    $c_extension    = '';
    $c_imagespath   = '';
    $c_outputpath   = '';
    $c_generatedext = 'html';
    $c_config       = 'galrey.rc';
    $c_template     = '';
    $c_showinfo     = 'YES';
    $c_memofile     = '';

    # Command line paramaeters (if any)
    $result = GetOptions('images-path:s' => \$c_imagespath, 
                         'output-path:s' => \$c_outputpath,
                         'config:s'      => \$c_config,
                         'memofile:s'    => \$c_memofile,
                         'template:s'    => \$c_template);

    # Well, let's find that config file...

    $config_open = 1;
    open (CONFIG, "<$c_config") or $config_open = 0;

    if ($config_open eq 0)
    {
        $config_open = 2;
        open (CONFIG, "<~/$c_config") or $config_open = 0;
    }

    if ($config_open eq 0)
    {
        $config_open = 3;
        open (CONFIG, "</etc/$c_config") or $config_open = 0;
    }

    if ($config_open eq 0)
    {
        die "Cannot open config file $c_config";
    }

    if ($config_open eq 3)
    {
        print "Uhmmm... the config file was found in /etc; are you sure this the right place ? (read README or INSTALL, for details).\n";
    }

    # Configuration from config file
    while (<CONFIG>)
    {
        chomp; 
        s/^[#].*$//; # Kill comments
        next if /^\s*$/; # ignore empty lines
           
        @config =  /(\S+)\s*=\s*(.*)/g;

        $var = $config[0];
        $val = $config[1];
           
        #while ( ($var, $val) = each %config )
        {
            $var=uc($var);
            $c_title        = $val if $var eq 'TITLE';
            $c_thumbsize    = $val if $var eq 'THUMBSIZE';
            $c_thumbprefix  = $val if $var eq 'THUMBPREFIX';
            $c_thumbsperrow = $val if $var eq 'THUMBSPERROW';
            $c_index        = $val if $var eq 'INDEX';
            $c_pattern      = $val if $var eq 'PATTERN';
            $c_generatedext = $val if $var eq 'GENERATEDEXT';
            $c_showinfo     = uc($val) if $var eq 'SHOWINFO';
            if ($c_memofile eq '')
            { $c_memofile     = $val if $var eq 'MEMOFILE';   }
            if ($c_imagespath eq '')
            { $c_imagespath   = $val if $var eq 'IMAGESPATH'; }	
            if ($c_outputpath eq '')
            { $c_outputpath   = $val if $var eq 'OUTPUTPATH'; }
            if ($c_template eq '')
            { $c_template     = $val if $var eq 'TEMPLATE';   }
        }
    }

    close (CONFIG);

    # Final configuration refining. Be sure to have the paths and a valid generated ext
    if ($c_imagespath eq '')
    { $c_imagespath = '.'; }	
    if ($c_outputpath eq '')
    { $c_outputpath  = '.';}
    if ($c_template eq '')
    { $c_template  = 'galrey.tpl';}
        
    if (substr($c_generatedext,0,1) ne '.')
    {
        $c_generatedext = '.'.$c_generatedext;
    }

    print "Analyzing...\n";
    
    @files = glob($c_imagespath."/".$c_pattern);

    # Let's check: all the files must have the same extension (same type)
    $error = 0;
    foreach $file(@files)
    {
        $c_extension = '';
        ($filename,$path) = fileparse($file);
        if ($filename =~ m/\.(.*)/)
        {
            $c_extension = $&;
        }

        if ( defined($prev_ext) && ($c_extension ne $prev_ext))
        {
            $error = 1;
            last;
        }
	next if ($filename =~ /^$c_thumbprefix/); # Martin Schulze, debian bug 213875
        $prev_ext = $c_extension;
        push(@filenames, $filename);
    }

   if ($error == 1)
   {
       # Error: the specified pattern is wrong
       print "The specified pattern is not selective.\n";
       exit;
   }

   sort(@filenames);

   $i = @filenames;

   if ($i == 0)
   {
      print "No images to process...\n";
      exit;
   }

   if ($c_memofile ne '')
   {
     my @orderedfiles; # Ordered file patch, by Michael Benedict

     open(MEMOFILE, "<$c_memofile") or print "Memofile does not exist.\n" and exit;

     while (<MEMOFILE>)
     {
        chomp;
        s/[#].*$//; # Kill comments
        next if /^\s*$/; # ignore empty lines

# Patch by Tapio Lehtonen
#<        @memo =  /(\S+)\s* \s*(.*)/g;
#<        $memos{$memo[0]} = $memo[1];
 	@memo = split();
 	@memotext=@memo;
	push(@orderedfiles, $memo[0]) if (-f "$c_imagespath/$memo[0]"); # Martin Schulze, debian bug 213933
 	shift(@memotext);
        $memos{$memo[0]} = join(" ", @memotext);
# end patch

     }
     close (MEMOFILE);
     # Next foreach, Martin Schulze, debian bug 213933
     foreach my $ent (@filenames)
     {
        if (!exist_in_list ($ent, \@orderedfiles))
        {
          push(@orderedfiles, $ent);
        }
     }
     @filenames = @orderedfiles;
   }

   print "Creating HTML...\n";

   $first = $filenames[0];
   $first =~ s/$c_extension/$c_generatedext/;
   $last  = $filenames[$i-1];
   $last  =~ s/$c_extension/$c_generatedext/;

   $k=0;
   while ($k < $i)
   {
       $filehtml = $filenames[$k];
       $filehtml =~ s/$c_extension/$c_generatedext/;
       $current  = $filenames[$k];
       $previous = '';
       $next     = '';

       print "	$current\n";

       if ($k > 0)
       {
           $previous = $filenames[$k - 1];
           $previous =~ s/$c_extension/$c_generatedext/;
       }

       if (defined $filenames[$k + 1])
       {
           $next = $filenames[$k + 1];
           $next =~ s/$c_extension/$c_generatedext/;
       }

       $identify = `identify -format "%wx%h" "$c_imagespath/$filenames[$k]"`;
       chomp($identify);

       @dimension = split(/x/, $identify);

       $width      = $dimension[0];
       $height     = $dimension[1];

       createHtml($c_title,
                  $c_outputpath.'/'.$filehtml,
                  $current,
                  $next,
                  $previous,
                  $k+1,
                  $i,
                  $c_index,
                  $width,
                  $height);

       $k++;
   }

   print "Creating index.html...\n";

   $indexfile = $c_outputpath.'/'.$c_index;

   open(INDEX, ">$indexfile") or die "Can't open outfile.";

   print INDEX "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
   print INDEX "<html>\n<head>\n";
   print INDEX "<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n";
   print INDEX "<title></title>\n";
   print INDEX "</head>\n<body>\n<br>\n";
   print INDEX "<b><I>Click on a picture to see it enlarged</I></b><br>\n";
   print INDEX "\n<!-- ====================== [CUT HERE] ====================== -->\n";
   print INDEX "<table cellpadding=\"3\" cellspacing=\"3\">\n";

   $k=0;
   $r=0;
   while ($k < $i)
   {
       $filehtml = $filenames[$k];
       $filehtml =~ s/$c_extension/$c_generatedext/;
       $thumb = $c_thumbprefix.$filenames[$k];

       print "	$filenames[$k]\n";

       if ($r == 0)
       {
           print INDEX "\n<tr>";
       }

       $identify = `identify -format "%wx%hx%b" "$c_imagespath/$filenames[$k]"`;
       chomp($identify);

       @dimension  = split(/x/, $identify);

       $width      = $dimension[0];
       $height     = $dimension[1];
       $size       = $dimension[2];

       @t_dimension  = split(/x/, $c_thumbsize);

       $t_width      = $t_dimension[0];
       $t_height     = $t_dimension[1];

       if ($c_showinfo eq 'YES')
       {
           $x = 'x';
           print INDEX "\n<td><a href=\"$filehtml\"><img src=\"$thumb\" width=\"$t_width\" height=\"$t_height\" border=\"0\" alt=\"$filenames[$k]\"></a><br><div align=\"center\">[$width$x$height] $size</div></td>";
       }
       else
       {
           print INDEX "\n<td><a href=\"$filehtml\"><img src=\"$thumb\" width=\"$t_width\" height=\"$t_height\" border=\"0\" alt=\"$filenames[$k]\"></a></td>";
       }

       $r++;

       if ($r == $c_thumbsperrow)
       {
           $r = 0;
           print INDEX "\n</tr>";
       }
       $k++;
   }

   if (($r != $c_thumbsperrow) && ($r != 0)) # Laurent Fousse, debian bug 208230
   {
       print INDEX "\n</tr>";
   }

   print INDEX "</table>\n\n<!-- ====================== [CUT HERE] ====================== -->\n</body>\n</html>\n";
   close(INDEX);

   print "Creating thumbnails ($c_thumbsize) for ...\n";

   $ti=0;
   foreach $filename(@filenames)
   {
       $fullname  = $c_imagespath.'/'.$filename;
       $thumbname = $c_outputpath.'/'.$c_thumbprefix.$filename;
#       system "convert -sample $c_thumbsize $fullname $thumbname  2>/dev/null";

       # Patch by Marcel van Dorp, WiWo Support, April 2003

#<       system "convert +profile '*' -filter Lanczos -geometry $c_thumbsize $fullname $thumbname 2>/dev/null";
       $genthumb = FALSE;

       if (-e $thumbname)
       {
        # thumb exists, check it's format
        $cursize = `identify -format "%wx%h" "$thumbname"`;
        chomp($cursize);
        $genthumb = !($cursize==$c_thumbsize);
       }
       else
       {
        # thumb doesn't exist, so generate it.
        $genthumb = TRUE;
       }

       # This patch is... "suspended"... thumbnails generated on cropped photos, are
       # always re-generated (the test simply fails)
       $genthumb = TRUE;

       if ($genthumb)
       {
        print "	$filename (" . $c_thumbprefix.$filename . ")\n";
        system "convert +profile '*' -filter Lanczos -geometry $c_thumbsize '$fullname' '$thumbname' 2>/dev/null";
        $ti++;	#thumbnail counter, just FYI in print statement below
       } 
       else 
       {
        print "Skipping existing $thumbname\n";
       }
       # End patch

   }

   print "I've generated $ti thumbnails, $i html files and 1 $c_index.\n";
   print "Done.\n";
}

sub createHtml
{
 my $t = shift;
 my $f = shift;
 my $c = shift;
 my $n = shift;
 my $p = shift;
 my $id = shift;
 my $total = shift;
 my $index = shift;
 my $w = shift;
 my $h = shift;

 open(TEMPLATE, "<$c_template") or print "Template file doesn't exist.\n" and exit;
 open(OUTFILE, ">$f") or print "Can't open outfile.\n" and exit;

 while (<TEMPLATE>)
 {
  $line = $_;

  if (/<\/body>/)
  {
      print OUTFILE "<br><br><div align=\"center\" style=\"font-family: Verdana, Arial; color: yellow; font-size: 8pt;\">Created with <a style=\"font-family: Verdana, Arial; color: #33ffff; font-size: 8pt;\" href=\"http://www.flexer.it/galrey\">Galrey</a></div>\n";
  }

  if ($line =~ m/\$NEXT\$/)
  {
   if ($n eq "")
   {
    $line =~ s/\$NEXT\$/$first/g;
    #undef $line;
   }
   else
   {
    $line =~ s/\$NEXT\$/$n/g;
   }
  }

  if ($line =~ m/\$PREVIOUS\$/)
  {
   if ($p eq "")
   {
    $line =~ s/\$PREVIOUS\$/$last/g;
    #undef $line;
   }
   else
   {
    $line =~ s/\$PREVIOUS\$/$p/g;
   }
  }

  if ($line =~ m/\$DESCRIPTION\$/)
  {
   if ($c_memofile ne '')
   {
    if (exists($memos{$c}))
    {
      $line =~ s/\$DESCRIPTION\$/$memos{$c}/g;
    }
    else
    {
      $line =~ s/\$DESCRIPTION\$/$c/g;
    }
   }
   else
   {
    $line =~ s/\$DESCRIPTION\$/$c/g;
   }
  }
  if (defined $line)
  {
   $line =~ s/\$FIRST\$/$first/g;
   $line =~ s/\$LAST\$/$last/g;
   $line =~ s/\$TITLE\$/$t/g;
   $line =~ s/\$CURRENT\$/$c/g;
   $line =~ s/\$ID\$/$id/g;
   $line =~ s/\$TOTAL\$/$total/g;
   $line =~ s/\$INDEX\$/$index/g;
   $line =~ s/\$WIDTH\$/$w/g;
   $line =~ s/\$HEIGHT\$/$h/g;
   print OUTFILE $line;
  }
 }

 close(TEMPLATE);
 close(OUTFILE);
}

# Martin Schulze, debian bug 213933
sub exist_in_list
{
    my $key = shift;
    my $list = shift;
    my @list = @$list;

    foreach my $ent (@list) {
	return true if ($ent eq $key);
    }
    return false;
}
