: magical incantation finds Perl as long as it's in the user's path
eval 'exec perl -wS $0 ${1+"$@"}'
	if 0;

############################################################################
# Please change this accordingly if you change the DESTDIR in the tarball 
# distribution Makefile or the --prefix of the RPM installation
$LIBDIR = "/usr/local/share/igal2";
# for example if you make DESTDIR=/usr then $LIBDIR="/usr/lib/igal2"
############################################################################
#
# A short note from Eric Pop the developer of the "old" igal version:
# Note to do-it-yourselvers and Computer Science types:  the IGAL code is
# UGLY.  I'm am amateur programmer, not a CS type.  If my scrappy code runs
# and gives the right results, I'm happy.  If others find it useful, that's
# wonderful.  I hope my comments can help decipher the mess below a bit.  I
# wrote IGAL partly because I wanted another excuse to learn Perl (it's
# useful for my research too) and because other image gallery generators
# had hairy dependencies and didn't do what I needed.  So... my apologies
# if the spaghetti below makes you cringe.  It works for me, so I don't
# really have plans (or time) to clean it up.
#
############################################################################
# If you KNOW you have the ImageMagick package installed (e.g commands like
# identify and convert) then setting this equal to 1 may speed up the code a
# bit (igal will stop checking for these commands every time it runs)
#
$HAVEIM = 0;
############################################################################
# If you KNOW you have the libjpeg stuff installed (e.g commands like cjpeg,
# djpeg and pnmscale) then setting this equal to 1 may speed up the code a
# bit (igal will stop checking for these commands every time it runs)
#
$HAVELJ = 0;
############################################################################
# If you KNOW you have Jhead installed then setting this equal to 1 may speed
# up the code a bit (igal will stop checking for these commands every time it
# runs)
#
$HAVEJH = 0;
############################################################################

# This is IGAL version 2.0, an online Image GALlery generator.
#   Copyright (C) 2000 Eric Pop, 2003 Wolfgang Trexler
#   This version was enhanced by Wolfgang Trexler (wt) Apr. 2003 - Nov. 2008
#
#   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: Eric Pop, Dept. of Electrical Engineering, Stanford University
# Email: epop@stanford.edu
# Enhancements were done by: Wolfgang Trexler, Austria
# EMail: wt-igal@trexler.at

use FileHandle;
use Getopt::Long;
use POSIX qw(ceil floor);


# some constants
$VERSION = "2.0";
$Getopt::Long::ignorecase = 0;
$itile = "tile.png";
$slidetemplate = "slidetemplate2.html";
$indextemplate = "indextemplate2.html";
$csstemplate = "igal2.css";
$directorylinefile = "directoryline2.html";
$captionfile = ".captions";
$userigaldir = "$ENV{'HOME'}/.igal2";
$thumbprefix = ".thumb_";
$slideprefix = ".slide_";
$destback = "";
STDOUT->autoflush("1");

# default command-line argument values
$opt_a = "0";          # to write image size under thumbnails in index page
$opt_c = "0";          # -c to use user-supplied captions
$opt_C = "0";          # same as -c, but preserve image names as captions
$opt_d = ".";          # look in current directory "."
$opt_f = "0";          # -f to force thumbnail regeneration
$opt_h = "0";
$opt_i = "index.html"; # name of the main thumbnail index file
$opt_j = "0";          # -j uses jhead to extract EXIF metadata
$opt_k = "0";          # -k for the captions to also be used as slide titles
$opt_m = "";           # -m Apply a watermark to each image
$opt_n = "0";          # -n to use image file names for the .html files
$opt_o = "";           # -o dir specifies alternate prefix for target links
$opt_p = "3";          # cellpadding value for the thumbnail index tables
$opt_r = "0";          # -r to omit the film reel effect altogether
$opt_s = "0";          # -s to make no slides, just thumbnail links to images
$opt_t = "21";         # height of the .tile.png tiled image
$opt_u = "0";          # write captions under thumbnails on index page
$opt_w = "5";          # index rows are 5 images wide by default
$opt_x = "0";          # -x to omit the image count from the caption
$opt_y = "0";          # max height of a thumbnail (defaults to 75 below)
$opt_ad = "0";         # write out only dimensions
$opt_as = "0";         # write out only file size
$opt_bigy = "0";       # max height of the slides.  use if images are huge.
$opt_con = "";         # options to be passed to convert or cjpeg
$opt_help = "0";       # displays brief usage message; same as -h
$opt_www = "0";        # makes everything world-readable
$opt_xy = "0";         # scale thumbs to n pixels in their longer dimension
$opt_dest = "";        # Destination directory of helper files
$opt_AddSubdir = "0";  # Add subdirectories to index.html file
$opt_pagination = "0"; # maximum number of images on one page, zero means no pagination

$usage = <<"END_OF_USAGE";
This is iGal2 $VERSION an HTML image slide show generator.
Syntax:  igal [-option -option ...]
Options:     -a           write image sizes under thumbnails on index page
             -c           first generate and then use captions
             -C           like -c, but preserve file names as captions
             -d <dir>     operate on files in directory <dir> (.)
             -f           force thumbnail regeneration
             -h           displays this brief help; same as --help
             -i <file>    name of the main thumbnail index file (index.html)
             -j           add EXIF metadata to the slide pages
             -k           use the image captions for the HTML slide titles
             -m <file>    Automatically add watermark to each image
             -n           use image file names for the HTML slide files
             -p <n>       cellpadding value of thumbnail index tables (3)
             -r           omit the film reel effect altogether
             -s           make no HTML slides, link thumbnails to images
             -t <n>       height of the film reel tiled image (21)
             -u           write captions under thumbnails on index page
             -w <n>       rows in thumbnail index are <n> images wide (5)
             -x           omit the image count from the captions
             -y <n>       scale all thumbnails to the same height <n> (75)
             --ad         like -a, but write only the image dimensions
             --as         like -a, but write only the file size (in kbytes)
             --bigy <n>   like -y, use it if you have very large image files
             --con <>     options to pass to convert or cjpeg (e.g. -quality N)
             --help       displays this brief help; same as -h
             --www        make all iGal files world-readable
             --xy <n>     scale thumbs to <n> pixels in their longer dimension
             ------------- N E W   F U N C T I O N S --------------------------
	     --dest <dir> Destination directory for the helper files 
			  (thumbnails, slides, etc.) igal generates. This is
			  relative to the operative directory -d and has to be
			  one level below (.)
	     --AddSubdir  If igal finds further directories beneath your image
	     	          directory -d, it will generate HTML Links in the 
			  index file (index.html) to this directories. 
		 	  Default is (off). Directories given with --dest or 
			  starting with a "." will be ignored.
			  Note: igal will not work recursively, it just adds
                          HTML links to the directories below.
             -m <file>    Automatically add watermark to each image - this
                          works well with a transparent .gif, but anything
                          can be used - edit the "composite" line later on
                          to adjust visibility/position of mark if required
                          Originals will be left with a .unmarked extension
             -o <dir>     Root URL of alternate location for the links to full
                          size images. Use this if your indexes will be in
                          a different location/server from the back end images
             --pagination <n> Maximum number of images on one page.
                          If the given number of images is reached a new page 
                          is started. Pagination number <n> should be a multiple 
                          of parameter -w (default 5).
                          Default 0 - means no pagination at all.
Note:         default values are given in parentheses (where applicable).
Authors:      Wolfgang Trexler <wt-igal\@trexler.at>
              Eric Pop <epop\@stanford.edu> (original igal)
	      contributions: 
              Stewart Addison <contactsxa\@gmail.com>, Riku Kalinen
URL:          http://igal.trexler.at/
END_OF_USAGE

# store command-line options upfront to write in the index <HEAD>
@igal_options = @ARGV;

# process command-line arguments (overriding defaults above)
GetOptions('a','c','C','d=s','f','h','i=s','j','k','m=s','n','o=s',
           'p=i','r','s','t=i','u','w=i','x','y=i','ad','as',
           'bigy=i', 'con=s','help','im','www','xy=i', 'dest=s', 
	   'AddSubdir', 'pagination=s') or die "$usage";

die $usage if ($opt_help or $opt_h);
# deal with the competing -y and --xy options
if (($opt_y == 0) and ($opt_xy == 0)) {
	$opt_y = 75;    # default, if neither -y nor --xy is specified
} else {
	$opt_f = "1";   # if either is specified, force thumbnail regeneration
}
die "Please only specify one of the -y and --xy options\n" if ($opt_y and $opt_xy);
# other error (sanity) checks
die "Please enter nonnegative thumbnail dimensions\n" if (($opt_y < 0) or ($opt_xy < 0));
die "Please enter a nonnegative cellpadding value\n" if ($opt_p < 0);
die "Please choose at least one image per index row\n" if ($opt_w <= 0);
die "Please enter a nonnegative tiled image height\n" if ($opt_t < 0);
die "Please enter a nonnegative pagination value\n" if ($opt_pagination < 0);
$opt_o = "$opt_o/" if ( $opt_o );

# strip any unnecessary slashes from the end of the given $opt_d directory
$opt_d =~ s/\/$//;

# let users store their templates in a $HOME/.igal directory, if it exists,
# instead of the site-wide /usr/local/share/igal (from line 8 up top)
$LIBDIR = $userigaldir if ((-r $userigaldir) && (-d $userigaldir));

# load up image files from $opt_d into array @imgfiles
opendir DIR, $opt_d or die "Can't open directory $opt_d\n";

# find and read all jp(e)g, gif and png files
@jpgfiles = grep((!/^\./ and /\.jpe?g$/i), readdir DIR);
rewinddir DIR;   # this is CRUCIAL here!!!
@giffiles = grep((!/^\./ and /\.gif$/i), readdir DIR);
rewinddir DIR;   # this is CRUCIAL here!!!
@pngfiles = grep((!/^\./ and /\.png$/i), readdir DIR);
@imgfiles = @jpgfiles;
push(@imgfiles, @giffiles);
push(@imgfiles, @pngfiles);

@imgfiles = sort @imgfiles;      # sort alphabetically, by file name
$njpg = @jpgfiles;
$nfiles = @imgfiles;             # how many total image files i've loaded

die "Can't find any image files in directory $opt_d\n" if ($nfiles == 0);

# find and read all directories (except beginning with . and igal destination) for later use
if ($opt_AddSubdir) {
	rewinddir DIR;
	foreach $file (readdir DIR) {
		if (-d "$opt_d/$file" && !($file =~ /^\./) && !($file =~ /$opt_dest/)) {
			push(@directories, $file);
		}
	}
	if (defined(@directories)) {
		@directories = sort @directories;      # sort alphabetically, by name
	} else {
		print "Information: Option --AddSubdir is set, but can't find any matching subdiretories!\n";
	}


}

closedir DIR;

# Store image extensions
@imgext = (); @captions = ();

foreach $file (@imgfiles) {
	# store image captions & extensions in separate arrays along the way
	$file =~ m/(^.*)\.(\w{3,4})$/;
	push(@captions, $1);
	push(@imgext, $2);
}


# wt 08.04.03: check for destination directory of igal files, and create it if necessary
$opt_dest =~ s/\/$//;     # strip any unnecessary slashes from the end of the given $opt_dest directory
if (length $opt_dest > 0) {
	if ($opt_dest =~ m/(\/|\\|\#|<|>|%|\"|\s)/) {
		die "\nYour destination directory ($opt_dest) contains a character ($1) which\nis not allowed inside an URL.  URIs may not contain delimiters such as \\, <, >, #, %, \" or \nwhite space.\n\n";
	}
	if (! -d "$opt_d/$opt_dest") {
		mkdir "$opt_d/$opt_dest" or die "Can't create directory for igal files ($opt_d/$opt_dest) [$!]";
	}
	print "Using directory $opt_d/$opt_dest for igal files (except for index.html)\n";
	$opt_dest = "$opt_dest/";	# Append / to directory for further use
	$destback = "../";		# will be used in html later on to find the directory where images reside
}


# if the -c (or -C) option was supplied let user specify captions, else see below
if ($opt_c or $opt_C) {
	if (! -r "$opt_d/$opt_dest$captionfile") {
		# create $captionfile file if it doesn't exist
		print "Found $nfiles image files in directory $opt_d\n";
#		die "Please select more files for your slide show!\n" if ($nfiles <= 1);
		open(CAP,">$opt_d/$opt_dest$captionfile") or die "Can't create $opt_d/$opt_dest$captionfile file\n";
		print "Creating the $opt_dest$captionfile file...\n";
		print CAP "# This is igal's $captionfile file, first generated ", scalar localtime, ".\n";
		print CAP "# To the left of the separator are the image file names.  Enter your captions\n# on the right side, one per line.  The captions may include HTML tags.\n# To add any comments to this file or to exclude any images from the slide \n# show, add a # sign at the beginning of their respective lines.  You may\n# also change the order of images in your slide show at this time.\n\n";
			for ($i = 0; $i < $nfiles; $i++) {
				print CAP "$imgfiles[$i] ---- ";
				print CAP "$captions[$i]" if $opt_C;
				print CAP "\n";
			}
		close(CAP);
		die "Now edit the $opt_dest$captionfile file to your liking and rerun igal -c\n";
	} else {
		# read in files specified in the .captions file
		open(CAP,"$opt_d/$opt_dest$captionfile") or die "Can't open $opt_d/$opt_dest$captionfile file\n";
		@imgfiles = ();     # reset arrays b/c we're rereading them
		@captions = (); @imgext = (); $njpg = 0;
		print "Reading the $captionfile file ... ";
		while (defined($line = <CAP>)) {
			chomp($line); $line =~ s/^\s*//; $line =~ s/\s*$//;
			# only read lines with the ---- delimiter that don't start with #
			if (($line =~ m/\w\s*----\s*/) && !($line =~ m/^\#/)) {
				@arr = split(/\s*----\s*/,$line);
				# first check image extensions
				$temp = $arr[0]; $temp =~ s/^.*\.//;
				push(@imgfiles,$arr[0]);
				push(@imgext, $temp);
				push(@arr,"") if (scalar @arr == 1);
				push(@captions,$arr[1]);
				$njpg++ if ($arr[0] =~ m/jpe?g/i);
			}
		}
		close(CAP);
		$nfiles = @imgfiles;
		print "found $nfiles image files.\n";
		die "Please select more files for your slide show!\n" if ($nfiles < 1);
	}
} else {
	print "Found $nfiles image files in directory $opt_d\n";
}

# find out if the imagemagick commands exist
$HAVEIM = (&exist("identify") and &exist("convert")) unless ($HAVEIM);
print "\nWARNING:  The ImageMagick package (imagemagick.org) doesn't seem to be\ninstalled.  Image dimensions will not be available in the generated HTML.\nOnly JPG images are supported... falling back onto cjpeg/djpeg/pnmscale.\n\n" unless ($HAVEIM);

# find out if the libjpeg commands exist
$HAVELJ = (&exist("cjpeg") and &exist("djpeg") &exist("pnmscale")) unless ($HAVELJ or ($njpg == 0) or $HAVEIM);
print "\nWARNING:  at least one of the commands \"cjpeg\", \"djpeg\" and \"pnmscale\" is not\ninstalled.  You can find these at rpmfind.net (inside libjpeg and libgr-progs)\nor you can download the source code from:\n    http://www.ijg.org/ and\n    http://netpbm.sourceforge.net/\n\n" unless ($HAVELJ or ($njpg == 0) or $HAVEIM);

# find out if the jhead exists
$HAVEJH = (&exist("jhead")) unless ($HAVEJH);
print "\nWARNING: The Jhead package is not installed; without it you won't get information about the camera used to take the photo.\n" unless ($HAVEJH);

# give up if no image processing commands can be found
die "ERROR:  the necessary image processing tools aren't installed on your system.\nPlease obtain them as specified above.\n\n" unless ($HAVEIM or $HAVELJ);

# initialize the arrays that will hold image file sizes
@xdim=(); @ydim=(); @isiz=();

# Jan 13, 2003:  i played around w/the various ways in which convert can
# resize images, i.e with -scale, -sample, -geometry (equivalent to -resize)
# and lo and behold, i realized that igal will run MUCH faster when resizing
# is done with -scale while quality is about same as with -geometry (in igal
# 1.3 and earlier).  using -sample gives me a bit more speed advantage but
# is not worth using as the scaled-down output seems to be pretty poor.
# here are some timed-runs on a directory w/some images:
# 	* w/convert -sample (poor quality) 7.24 sec
#	* w/convert -scale (ok quality) 9.14 sec
#	* w/convert -resize (ok quality) 23.8 sec
#	* w/cjpeg/djpeg (ok quality) 20.1 sec
# so from now on all convert -scale is used everywhere below because it seems
# to be the clear winner for quality vs speed.

# generate .thumbnails in the same directory with the original image files (or in the given --dest directory)
# if they don't exist already or if the -f switch is given

print "Creating thumbnails:  ";
for ($i = 0; $i < $nfiles; $i++) {
	$file = $imgfiles[$i];
	$fullfile = "$opt_d/$file";
	die "Can't open $fullfile\n" unless (-r $fullfile);
	$fullthumb = "$opt_d/$opt_dest$thumbprefix$file";
	if ((! -e $fullthumb) or $opt_f) {
		if ($HAVEIM) {
			$command = "convert $opt_con -scale x$opt_y \"$fullfile\" \"$fullthumb\"";
			# opt_xy handling: determine dimensions and scale the bigger dimension
			# Bug fixing code new since version 1.4.7
			if ($opt_xy) {
			        $temp = `identify -ping -format \"\%wx\%h %b\" \"$fullfile\"`;
				$temp =~ m/(\d+)x(\d+)\s([\d\.]+[mkb]*)/i;
				$width = $1; $height = $2; $temp = $3;
				if ($width > $height) {
				    $dimension = "$opt_xy" . "x";
				} else {
				    $dimension = "x" . "$opt_xy";
				}
				$command = "convert $opt_con -scale $dimension \"$fullfile\" \"$fullthumb\"";
			}
		} else {
			if ($imgext[$i] =~ m/(gif|png)/i) {
				print "\nIgnoring $file:  get ImageMagick (imagemagick.org) to process GIF and PNG files.\n";
				$command = 0;
			} else {
				$com1 = "djpeg \"$fullfile\"";
				$com3 = "cjpeg $opt_con -outfile \"$fullthumb\"";
				$scale = "pnmscale -ysize $opt_y";
				$scale = "pnmscale -xysize $opt_xy $opt_xy" if ($opt_xy);
				$command = $com1 . " | " . $scale . " | " . $com3;
			}
		}
		system("$command") if ($command);
		print "$thumbprefix$file " if ($command);
	}
}
print "... done!\n";

# determine image file sizes
if ($HAVEIM && !($opt_bigy)) {
	print "Determining image sizes ";
	foreach $file (@imgfiles) {
		$fullfile = "$opt_d/$file";
		$temp = `identify -ping -format \"\%wx\%h %b\" \"$fullfile\"`;
		$temp =~ m/(\d+)x(\d+)\s([\d\.]+[mkb]*)/i;
		push(@xdim,$1);  push(@ydim,$2);  $temp = $3;
		# round nicely in kb if identify returned the size in bytes
		$temp = sprintf ("%.1fk", $temp/1024) if ($temp =~ s/([\d\.]+)b*$/$1/i);
		push(@isiz,$temp);
		print ".";
	}
	print " done!\n";
}

# scale down slides if the --bigy <n> option was given
if ($opt_bigy and !($opt_s)) {
	if ($HAVEIM) {
		print "Scaling down big slides and determining new slide sizes:  ";
		@xdim=(); @ydim=(); @isiz=();    # reset image size arrays
	} else {
		print "Scaling down big slides:  ";
	}
	for ($i = 0; $i < $nfiles; $i++) {
		$file = $imgfiles[$i];
		$fullfile = "$opt_d/$file";
		die "Can't open $fullfile\n" unless (-r $fullfile);
		$fullslide = "$opt_d/$opt_dest$slideprefix$file";
		if ((! -e $fullslide) or $opt_f) {
			if ($HAVEIM) {
				$command = "convert $opt_con -scale x$opt_bigy \"$fullfile\" \"$fullslide\"";
			} else {
				if ($imgext[$i] =~ m/(gif|png)/i) {
					print "\nIgnoring $file:  get ImageMagick (imagemagick.org) to process GIF and PNG files.\n";
					$command = 0;
				} else {
					$com1 = "djpeg \"$fullfile\"";
					$com3 = "cjpeg $opt_con -outfile \"$fullslide\"";
					$scale = "pnmscale -ysize $opt_bigy";
					$command = $com1 . " | " . $scale . " | " . $com3;
				}
			}
			system("$command") if ($command);
			print "$slideprefix$file " if ($command);
		}
		if ($HAVEIM) {
			$temp = `identify -ping -format \"\%wx\%h %b\" \"$fullslide\"`;
			$temp =~ m/(\d+)x(\d+)\s([\d\.]+[mkb]*)/i;
			push(@xdim,$1);  push(@ydim,$2);  $temp = $3;
			# round nicely in kb if identify returned the size in bytes
			$temp = sprintf ("%.1fk", $temp/1024) if ($temp =~ s/([\d\.]+)b*$/$1/i);
			push(@isiz,$temp);
		}
	}
	print "... done!\n";
}

if ( $opt_m ) {
        # This is a fairly simple watermarking method - this could be made
        # more complex ...
        die "ImageMagick required for watermarking\n" if (! &exist("composite"));
        die "Cannot open watermark file $opt_m" if ( ! -r $opt_m );
        print "Adding watermarks:";
	for ($i = 0; $i < $nfiles; $i++) {
		$file = $imgfiles[$i];
		$original = "$file.unmarked";
		# If original exists, user has re-run the script - don't
		# add a second watermark
                if ( -r $original ) {
                        print " [$file already marked]";
                } else {
                        die "Can't open $file\n" unless (-r $file);
		        rename $file, $original || die "Failed to rename $file to $original";
		        print " $file";
                        # Could add '&& unlink $original' but wouldn't protect against reruns
		        system "composite -dissolve 33 -geometry +20+20 $opt_m $original $file";
		        die "Failed to add watermark to $file" if ( ! -r $file );
		}
        }
        print "\nPre-watermarked files have been left with a .unmarked extension\n";
        print "You may wish to remove those before publishing the gallery\n";
}

# create the individual slide show files
if ($opt_s) {
	print "Linking thumbnails directly to image files...  Making no html slides.\n";
	if (! -e "$opt_d/$opt_dest$csstemplate") {
		print "No CSS template file ... getting $LIBDIR/$csstemplate\n";
		die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
		die "$LIBDIR/$csstemplate cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$csstemplate");
		system("cp -f $LIBDIR/$csstemplate \"$opt_d/$opt_dest\"");
        }
} else {
	$nfiles = @imgfiles;      # total number of files (same as # of captions)
	@slides = ();
	if ($opt_n) {                       # decide on the slide html file names
		for ($i = 0; $i < $nfiles; $i++) {
			$temp = $imgfiles[$i];
			$temp =~ s/\.\w+?$/\.html/; # strip suffix, bug fixing (1.4.5)
			push(@slides,$temp);
		}
	} else {
		for ($i = 0; $i < $nfiles; $i++) {
			push(@slides, $i+1 . ".html");
		}
	}
	system("rm -f \"$opt_d/$opt_dest*.html\"");
	if (! -e "$opt_d/$opt_dest$csstemplate") {
		print "No CSS template file ... getting $LIBDIR/$csstemplate\n";
		die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
		die "$LIBDIR/$csstemplate cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$csstemplate");
		system("cp -f $LIBDIR/$csstemplate \"$opt_d/$opt_dest\"");
	} else {
		print "Found CSS template file $opt_dest$csstemplate ... using it.\n";
	}
	if (! -e "$opt_d/$opt_dest.$slidetemplate") {
		print "No $opt_dest.$slidetemplate file ... getting a copy from $LIBDIR/\n";
		die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
		die "$LIBDIR/$slidetemplate cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$slidetemplate");
		system("cp -f $LIBDIR/$slidetemplate \"$opt_d/$opt_dest.$slidetemplate\"");
	} else {
		print "Found $opt_dest.$slidetemplate file ... using it.\n";
	}
	print "Creating individual slides:  ";
	# read slidetemplate from filesystem once
	$slidetemplate_string = read_file_in_string("$opt_d/$opt_dest.$slidetemplate");
	for ($i = 0; $i < $nfiles; $i++) {
		$workarea = $slidetemplate_string;	# fill work area with slidetemplate
		open(SW,">$opt_d/$opt_dest$slides[$i]") or die "Can't create slide file\n";
		print "$slides[$i] ";
		if ($opt_k) {    # use image caption for the HTML slide title
			$title = $captions[$i];
		} else {         # otherwise use the image name (strip suffix)
			$title = $imgfiles[$i];
			$title =~ s/\.\w+?$//;
		}
		$workarea =~ s/<!--SLIDE-TITLE-->/$title/g;
		$imgfile_i_encoded = URLencode($imgfiles[$i]);
		if ($opt_bigy) {
			$slide = URLencode($slideprefix . $imgfiles[$i]);
			if ($HAVEIM) {
				$workarea =~ s/(<.*)<!--THIS-IMAGE-->(.)(.*>)/<A href=\"$destback$imgfile_i_encoded\">$1$slide$2 width=$xdim[$i] height=$ydim[$i] alt=\"$title\" title=\"click to see full-size\"$3<\/a>/;
			} else {
				$workarea =~ s/(<.*)<!--THIS-IMAGE-->(.)(.*>)/<A href=\"$destback$imgfile_i_encoded\">$1$slide$2 alt=\"$title\" title=\"click to see full-size\"$3<\/a>/;
			}
		} else {
			if ($HAVEIM) {
				$workarea =~ s/<!--THIS-IMAGE-->(.)/$destback$imgfile_i_encoded$1 width=$xdim[$i] height=$ydim[$i] alt=\"$title\"/g;
			} else {
				$workarea =~ s/<!--THIS-IMAGE-->/$destback$imgfile_i_encoded/g;
			}
		}
		# exif metadata
		if ($opt_j && $HAVEJH) {
			local $f = $imgfiles[$i];
			local $exif = `jhead "$f" | egrep -v '^File|Camera make' | grep : | sed 's/\$/<br>/'`;
			$workarea =~ s/<!--IMAGE-EXIF-->/$exif/;
		}
		# add in the image counter unless -x is specified
		if ($opt_x) {
			$imagecaption = $captions[$i];
		} else{
			$imagecaption = $captions[$i] . "&nbsp;&nbsp;&nbsp;(" . ($i+1) ."/$nfiles)" if (! $opt_x);
		}
		$workarea =~ s/<!--IMAGE-CAPTION-->/$imagecaption/g;

		# find out if pagination is used and which number the index file has...
		$index_file_number = ($opt_pagination) ? int ($i / $opt_pagination) : 0;
		$index_filename = ($index_file_number == 0) ? $opt_i : "$index_file_number$opt_i";
		$workarea =~ s/<!--INDEX-FILE-->/$destback$index_filename/g;

		if ($opt_bigy) {
			$pref = $slideprefix;
		} else {
			$pref = $destback;
		}
		if ($i == 0 && $nfiles == 1) {	# special treatment if there is exactly one file!
			$temp = URLencode("$pref$imgfiles[0]");
			$workarea =~ s/<!--NEXT-IMAGE-->/$temp/g;
			$temp = URLencode("$slides[0]");
			$workarea =~ s/<!--PREV-SLIDE-->/\"$temp\" title=\"$captions[0]\"/g;
			$temp = URLencode("$slides[0]");
			$workarea =~ s/<!--NEXT-SLIDE-->/\"$temp\" title=\"$captions[0]\"/g;
		} elsif ($i == 0) {			# first image, previous points to last image
			$temp = URLencode("$pref$imgfiles[$i+1]");
			$workarea =~ s/<!--NEXT-IMAGE-->/$temp/g;
			$temp = URLencode("$slides[$nfiles-1]");
			$workarea =~ s/<!--PREV-SLIDE-->/\"$temp\" title=\"$captions[$nfiles-1]\"/g;
			$temp = URLencode("$slides[$i+1]");
			$workarea =~ s/<!--NEXT-SLIDE-->/\"$temp\" title=\"$captions[$i+1]\"/g;
		} elsif ($i == $nfiles-1) {	# last image, next points to first image
			$temp = URLencode("$pref$imgfiles[0]");
			$workarea =~ s/<!--NEXT-IMAGE-->/$temp/g;
			$temp = URLencode("$slides[$i-1]");
			$workarea =~ s/<!--PREV-SLIDE-->/\"$temp\" title=\"$captions[$i-1]\"/g;
			$temp = URLencode("$slides[0]");
			$workarea =~ s/<!--NEXT-SLIDE-->/\"$temp\" title=\"$captions[0]\"/g;
		} else {
			$temp = URLencode("$pref$imgfiles[$i+1]");
			$workarea =~ s/<!--NEXT-IMAGE-->/$temp/g;
			$temp = URLencode("$slides[$i-1]");
			$workarea =~ s/<!--PREV-SLIDE-->/\"$temp\" title=\"$captions[$i-1]\"/g;
			$temp = URLencode("$slides[$i+1]");
			$workarea =~ s/<!--NEXT-SLIDE-->/\"$temp\" title=\"$captions[$i+1]\"/g;
		}
		print SW "$workarea";
		close(SW);
	}
	
	print "... done!\n";
}


#############################################################################
# create the main index file with all the thumbnails
if ($opt_r) {
	print "Got option -r... omitting film reel effect.\n";
} elsif (! -e "$opt_d/$opt_dest.$itile") {
	print "No $opt_dest.$itile file... getting a copy from $LIBDIR/\n";
	die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
	die "$LIBDIR/$itile cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$itile");
	system("cp -f $LIBDIR/$itile \"$opt_d/$opt_dest.$itile\"");
} else {
	print "Found $opt_dest.$itile file ... using it.\n";
}
# rescale the tiled image if the -t switch was called but -r wasn't
if (($HAVEIM) and (! $opt_r)) {
	$tileh = `identify -ping -format \"\%wx\%h %b\" \"$opt_d\/$opt_dest.$itile\"`;
	$tileh =~ s/\d+x(\d+)\s[\d\.]+./$1/;
	system("mogrify -scale x$opt_t $opt_d/$opt_dest.$itile") if ($opt_t != $tileh);
}

if (! -e "$opt_d/$opt_dest.$indextemplate") {
	print "No $opt_dest.$indextemplate file... getting a copy from $LIBDIR/\n";
	die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
	die "$LIBDIR/$indextemplate cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$indextemplate");
	system("cp -f $LIBDIR/$indextemplate \"$opt_d/$opt_dest.$indextemplate\"");
} else {
	print "Found $opt_dest.$indextemplate ... using it.\n";
}

print "Creating the index file(s) ";
$indexfile = read_file_in_string("$opt_d/$opt_dest.$indextemplate"); # read indexfile in string to parse it
$indexfile =~ s/<!--#IGAL-OPTIONS#-->/@igal_options/g;     # set comment about igal options in index file
$indexfile =~ s/<!--#IGAL-CSS#-->/$opt_dest$csstemplate/g; # set the name (and path) of css template file

# Generate the links for directories
if ($opt_AddSubdir && defined(@directories)) {

	if (! -e "$opt_d/$opt_dest.$directorylinefile") {
		print "No $opt_dest.$directorylinefile file ... getting a copy from $LIBDIR/\n";
		die "$LIBDIR cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r $LIBDIR);
		die "$LIBDIR/$directorylinefile cannot be read or does not exist.\nPlease install igal properly.\n" unless (-r "$LIBDIR/$directorylinefile");
		system("cp -f $LIBDIR/$directorylinefile \"$opt_d/$opt_dest.$directorylinefile\"");
	} else {
		print "Found $opt_dest.$directorylinefile file ... using it.\n";
	}

	$output = "";
	$directoryline = read_file_in_string("$opt_d/$opt_dest.$directorylinefile");
	foreach $directory (@directories) {
		$temp = $directoryline;
		$temp =~ s/#DIRECTORY#/$directory/g;
		$directoryURLencoded = URLencode($directory);
		$temp =~ s/#DIRECTORY-URLENCODED#/$directoryURLencoded/g;
		$output .= $temp;
	}
	$indexfile =~ s/<!--#DIRECTORYLINE#-->/$output/;
} else {
	$indexfile =~ s/<!--#DIRECTORIES-START#-->.*<!--#DIRECTORIES-END#-->/<!-- no directories -->/s;
}
$indexfile =~ s/<!--#IGAL-VERSION#-->/$VERSION/g;	#add version information

#generate the table rows
$indexfile_copy = $indexfile;
if ($opt_pagination && $nfiles > $opt_pagination) { # pagination necessary!
	$paginate = $opt_pagination;
} else { 			# no pagination necessary
	$paginate = $nfiles;
}

for ($page = 0; $page * $paginate < $nfiles; $page++) {
	$output = "";
	$indexfile = $indexfile_copy;

	$on_this_page = int (($page+1) * $paginate <= $nfiles) ? $paginate : ($nfiles - $page*$paginate); # number of pictures on page
	$rows = int $on_this_page/$opt_w;     # number of film rows
	$rem = $on_this_page % $opt_w;        # number of thumbnails on last (incomplete) row
#	print "rows=$rows - rem=$rem - on_this_page=$on_this_page\n";

	if ($rem > 0) { $rows++; }	# is there a last incomplete row? if yes, we need one more circle for this one
	for ($i = 1; $i <= $rows; $i++) {
		# 
		$columns = ($i == $rows && $rem > 0) ? $rem : $opt_w; # last row needs less columns

		$output .= "  <TABLE border=0 cellspacing=0 cellpadding=$opt_p>\n";
		$output .= "    <TR><TD class=\"tiled\" height=$opt_t colspan=" . ($columns + 2) . ">&nbsp;</TD></TR>\n" unless ($opt_r);
		$output .= "    <TR>\n      <TD class=\"thumb\">&nbsp;</TD>\n";
		for ($j = 1; $j <= $columns; $j++) {
			$fileindex = ($page * $paginate) + (($i-1)*$opt_w+$j-1);	# calculate which file is in use
#			print "i=$i - j=$j (columns=$columns)- fileindex=$fileindex\n";
			$output .=  "      <TD class=\"thumb\">\n      ";
			if ($opt_s) {
				$output .= "<A href=\"$opt_o" . URLencode($imgfiles[$fileindex]) . "\">";
			} else {
				$output .= "<A href=\"$opt_o$opt_dest" . URLencode($slides[$fileindex]) . "\">";
			}
			print ".";
			$altname = $captions[$fileindex];
			$thumb = $opt_dest . $thumbprefix . $imgfiles[$fileindex];
			$thumbEncoded = $opt_dest . URLencode($thumbprefix . $imgfiles[$fileindex]);
			if ($HAVEIM) {
				$temp = `identify -ping -format \"\%wx\%h\" \"$opt_d/$thumb\"`;
				$temp =~ m/(\d+)x(\d+)/;  $x=$1;  $y=$2;
				$output .= "<IMG src=\"" . $thumbEncoded . "\" width=$x height=$y alt=\"$altname\" title=\"$altname\" border=0>";
			} else {
				$output .= "<IMG src=\"" . $thumbEncoded . "\" alt=\"$altname\" title=\"$altname\" border=0>";
			}
			$output .= "</A></TD>\n";
		}
		$output .= "        <TD class=\"thumb\">&nbsp;</TD>\n    </TR>\n";
		$output .= "    <TR><TD class=\"tiled\" height=$opt_t colspan=" . ($columns+2) . ">&nbsp;</TD></TR>\n" unless ($opt_r);
		if (($opt_a or $opt_ad or $opt_as) and $HAVEIM) {
			$output .= "    <TR>\n      <TD>&nbsp;</TD>\n";
			for ($j = 1; $j <= $columns; $j++) {
				$fileindex = ($page * $paginate) + (($i-1)*$opt_w+$j-1);	# calculate which file is in use
#				print $fileindex;
				$output .= "      <TD>";
				$printdim = "$isiz[$fileindex]" if $opt_as;
				$printdim = "$xdim[$fileindex]x$ydim[$fileindex]" if $opt_ad;
				$printdim = "$xdim[$fileindex]x$ydim[$fileindex] ($isiz[$fileindex])" if $opt_a;
				$output .= $printdim;
				$output .= "</TD>\n";
			}
			$output .= "    </TR>\n";
		}
	#	write image captions under images if option -u is given
		if ($opt_u) {
			$output .= "    <TR>\n      <TD>&nbsp;</TD>\n";
			for ($j = 1; $j <= $columns; $j++) {
				$fileindex = ($page * $paginate) + (($i-1)*$opt_w+$j-1);	# calculate which file is in use
#				print $fileindex;
				$output .= "      <TD>" . $captions[$fileindex] . "</TD>\n";
			}
			$output .= "    </TR>\n";
		}
		$output .= "  </TABLE>\n    <BR>\n";

	}

	# now replace placeholder in index-file with generated html code
	$indexfile =~ s/<!-- contents with thumbnails will be inserted here by igal -->/$output/;
	# insert pageination
	if ($opt_pagination && $nfiles > $opt_pagination) { # pagination necessary!
		$numberpages = ceil($nfiles / $opt_pagination);
		$nextpage = $page+1;
		$tmptext = "Page $nextpage of $numberpages";
		# forward navigation
		if (($page+1) * $paginate < $nfiles) {
			$nextpagename = "$nextpage$opt_i";
			$lastpage = $numberpages -1;
			$tmptext .= "<a href=\"$nextpagename\">&nbsp;&gt;&gt;</a>&nbsp;&nbsp;<a href=\"$lastpage$opt_i\">&gt;|</a>";
		}		
		# backward navigation
		if ($page > 0) {
			$prevpage = $page-1;
			$prevpagename = ($prevpage == 0) ? $opt_i : "$prevpage$opt_i";
			$tmptext = "<a href=\"$opt_i\">|&lt;&nbsp;&nbsp;</a><a href=\"$prevpagename\">&lt;&lt;</a> $tmptext";
		}
		$indexfile =~ s/<!--#IGAL-PAGINATION#-->/$tmptext/g;
	}
	$indexfile =~ s/<!-- \*{4}.*\*{4} -->//g;	#clean up
	$indexfile =~ s/<!--#.*#-->//g;			#clean up

	$index_filename = ($page == 0) ? $opt_i : "$page$opt_i";
	print "$index_filename ";
	open(IXW,">$opt_d/$index_filename") or die "Can't create main $index_filename file\n";
	print IXW $indexfile;
	close(IXW);
}

print " done!\n";

# if --www was invoked make all images world-readable at the END
if ($opt_www) {
	$dir = ($opt_d eq ".") ? $opt_dest : "$opt_d/$opt_dest";
	$dir =~ s/\ /\\ /g;	# escape blanks in directory/filenames for system call
	print "\nMaking all igal files world-readable for WWW publishing...\n";
	print "chmod a+r $dir$csstemplate\n";
	system("chmod a+r $dir$csstemplate");
	print "chmod a+r $dir*.html\n";
	system("chmod a+r $dir*.html");
	print "chmod a+r $dir$thumbprefix*.*\n";
	system("chmod a+r $dir$thumbprefix*.*");
	print "chmod a+r $dir$slideprefix*.*\n";
	system("chmod a+r $dir$slideprefix*.*");
	print "chmod a+r $dir.$itile\n" unless($opt_r);
	system("chmod a+r $dir.$itile") unless($opt_r);
	print "chmod a+r ";
	# imagefiles are in same directory, therefore $dir has to be set different
	$dir = ($opt_d eq ".") ? "" : "$opt_d/";
	foreach $file (@imgfiles) {
		print "$dir$file ";
		system("chmod a+r \"$dir$file\"");
	}
	print "\nDone!\n";
}

##############################################################################

# subroutine that checks if a certain program is in the user's path
# usage &exist("identify") --> 1 (or 0 if it doesn't exist)
sub exist {
    local($program) = @_;
    foreach $dir (split(/:/,$ENV{'PATH'})) {
		return 1 if (-f "$dir/$program");
    }
	return 0;
}


# subroutine that reads a file in a string...
# called with $string = read_file_in_string("datei.txt");
sub read_file_in_string {
	local($filename) = @_;

	open(FILE,$filename) or die "Can't open file $filename [$!]\n";
	local $/; 
	$string = <FILE>;
	close(FILE);

	return $string;
}

# subroutine that URL encodes a string...
# called with $string = URLencode("text to encode");
sub URLencode {
	local($string) = @_;
	$string =~ s/([^a-zA-Z0-9\.\_])/sprintf "%%%02X",ord($1)/eg;

	return $string
}
