#!/usr/bin/perl -w
# ----------------------------------------------------------------------
# Copyright (C) 2001, 2002, 2003 by Bodo Bauer <bb@bb-zone.com>
#
# 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., 59 Temple Place - Suite 330, Boston, 
# MA 02111-1307, USA. 
#
# ----------------------------------------------------------------------
# Simple script to generate html based galleries
# ----------------------------------------------------------------------
# $Revision: 1.19 $
#
# $Log: mkgallery.pl,v $
# Revision 1.19  2004/06/27 13:52:00  bb42
# * Fixed meta index sorting (patch by Stefan Troeger)
#
# Revision 1.18  2004/06/27 11:41:57  bb42
# * use 'exifinfo' to extract timedate information
#   for image subtitle by default
# * Made ImageMagick default for scaling images
#   (didn't find gimp.pm for Gip 2.0?!)
# * Print warning message if no 'jpg' files are found
#   (no more crashes in this case)
#
# Revision 1.17  2004/06/20 21:20:25  bb42
#
#
# * Fixed minor bug in 'jhead' code
# * added submissions by Daniel Schreibl:
#   - new template variabes
#   - allow custom sorting of meta index
#   - fixed default sorting of meta index
# * added submission by Kyle Maxwell
#   - Allow change of extension for HTML files
#
# Revision 1.16  2004/06/20 15:34:16  bb42
# Fixed jet another bug in 'jhead' code
#
# Revision 1.15  2004/06/20 15:16:32  bb42
# Fixed minor bug in 'jhead' code
#
# ----------------------------------------------------------------------
use strict;
use HTML::Entities;
use HTML::Template;
use URI::Escape;

#
# Default parameters
#
my $P = {
    sc_size      => 800,          # Size of scaled images
    th_size      => 100,          # size of thumb nails
    scale        => 1,            # scale images?
    cols         => 5,            # columns on index pages
    th_max       => 25,           # max thumb nails per index page
    title        => 'Gallery',    # title for index pages
    img_dir      => '.',          # directory with originals
    verbose      => 0,            # be verbose?
    force        => 0,            # force thumbnail and scales creation
    slide_delay  => 15,           # delay between two slides (sec)
    meta         => 0,            # create meta index
    metalink     => 1,            # create link to meta index in galleries
    gimp         => 0,            # use Gimp (1) or ImageMagick (0) to scale?
    quality      => 100,          # JPEG quality for scaled images
    raw_captions => 0,            # omit underscore replacement for image captions?
    short_dsc    => 1,            # enable short descriptions?
    no_save      => 0,            # dont save config if set to 1
    template     => 'default',    # templates to use
    metalinkurl  => 'index.html', # meta link destination
    order        => 'order.txt',  # file containing ordered image list
    jhead        => 'exifinfo -t 0x0132 ', # path to program to generate title (date/time)
    extension    => 'html',  	  # extension for HTML files
    template_dir  => '/usr/lib/bbgallery/template' # where template files are kept
};

my %P = %{$P};
my $version      = "1.2.3";    # Version Number
my $instprefix   = "/usr";
# my $P{template_dir} = "$instprefix/lib/bbgallery/template";
# ----------------------------------------------------------------------
#                     S U B R O U T I N E S
# ----------------------------------------------------------------------

sub strip_ws ( $ ) {
    my $string = shift;
    if ( defined ( $string ) ) {
        for ($string) { s/^\s+//; s/\s+$//; }
	return ( $string );
    }
    return ( undef );
}

sub load_config ( $$ ) {
    my $cnf  = shift;
    my $file = shift;
    if ( open ( CNF, $file ) ) {
	print "Reading config from $file\n" if ( $P{verbose} );
	while ( <CNF> ) {
	    next if ( /^\s*$/ || /^\s*\#/ );
	    my ( $token, $value ) = split ( /=/, $_, 2 );
	    $token = strip_ws ( $token );
	    $value = strip_ws ( $value );
	    
	    for ( $token ) {
		if ( defined ( $P{$token} ) ) {
		    $cnf->{$token} = $value;
		} else {
		    print "Warning: Unknown token '$token' in config file: $file\n";
		}
	    }
	}
	close ( CNF );
    } else {
	print "Warning: Can not read config file: $file ($!)"  if ( $P{verbose} );
    }
}

sub write_config ( $ ) {
    my $file = shift;
    return ( 1 ) if ( $P{no_save} );

    if ( open ( CNF, ">$file" ) ) {
	print CNF "#-----------------------------------------------------------------------\n";
        print CNF "# BBGallery settings - v$version\n";
	print CNF "#-----------------------------------------------------------------------\n";

	foreach my $var ( keys  ( %P ) ) {
	    next if ( $var eq 'force' );
	    next if ( $var eq 'no_save' );
	    next if ( $var eq 'img_dir' );
	    next if ( $var eq 'meta' );
	    next if ( $var eq 'verbose' );
	    print CNF "$var = $P{$var}\n";
	}
	print CNF "# END\n";
	close ( CNF );
	return ( 1 );
    } else {
	print "Warning: Could not save configuration to $file ($!)\n" if ( $P{verbose} );
	return ( 0 );
    }
}

sub im_scale ( $$$$$$$ ) {
    my $in_dir  = shift;
    my $out_dir = shift;
    my $prefix  = shift;
    my $size    = shift;
    my $verbose = shift;
    my $force   = shift;
    my $quality = shift;

    my $cwd;
    chomp($cwd = `pwd`);

    $P{img_dir} = "$cwd/$P{img_dir}" if (  $P{img_dir} !~ /^\// );
    $out_dir = "$cwd/$out_dir" if ( $out_dir  !~ /^\// );

    $|=1;

    print "Reading images in $P{img_dir}\n" if ( $verbose );
    if ( opendir ( IN, $P{img_dir} ) ) {
	my @images = sort ( readdir ( IN ) );
	close ( IN );
	
	for ( my $i=0; $i<=$#images; $i++ ) {
	    if ( $images[$i] =~ /.*\.jpg$/ ) {
		print "  $images[$i] " if ( $verbose );

		my $infile = "$P{img_dir}/$images[$i]";
		my $outfile = "$out_dir/$prefix$images[$i]";
		
		my $skip=0;
		if ( -f $infile && ( my $inmtime = (stat(_))[9] ) ) {
		    if ( -f $outfile && ( my $outmtime = (stat(_))[9] ) ) {
			$skip = 1 if ( $inmtime < $outmtime );
		    }
		}

		if ( $skip && !$force ) {
		    print "skipping\n" if ( $verbose );
		} else {
		    print "loading " if ( $verbose );
		    
		    open ( ID, "identify -ping -format \"%w %h\" \"$P{img_dir}/$images[$i]\"|" ) || die ( "identify not found ($!)\n" );
		    my ($w, $h ) = split ( /\s+/, <ID> , 2 );
		    close ( ID );
		    $h = strip_ws ( $h );
		    $w = strip_ws ( $w );
		    print "$h x $w " if ( $verbose );

		    my $nh;
		    my $nw;
		    
		    if ( $h && $w ) {
			if ( $h>$w ) {
			    $nh = $size;
			    $nw = int ( ( $size/$h ) * $w );
			} else {
			    $nw = $size;
			    $nh = int ( ( $size/$w ) * $h );
			}
			print "scaling to $nh x $nw " if ( $verbose ); 
			system ( "convert \"$P{img_dir}/$images[$i]\" -ping -quality $quality -sample $nw" . "x" . "$nh JPEG:\"$out_dir/$prefix$images[$i]\"" );
			print "done\n" if ( $verbose );
		    } else {
			print "Corrupt image file ($images[$i]) skipping ...";
		    }
		}
	    }
	}
    }
}

sub scale_images () {
    mkdir ( "$P{img_dir}/scaled", 0777 ) if ( ! -d "$P{img_dir}/scaled" );
    
    if ( $P{gimp} ) {
	system ( "$instprefix/lib/bbgallery/gimp_scale.pl -img_dir $P{img_dir} -out_dir $P{img_dir}/scaled " .
		 "-prefix sc_ -size $P{sc_size} -verbose $P{verbose} -force $P{force} -quality $P{quality}"  );
    } else {
	im_scale ( $P{img_dir}, "$P{img_dir}/scaled", "sc_", $P{sc_size}, $P{verbose}, $P{force}, $P{quality} );
    }
}

sub create_thumbs () {
    mkdir ( "$P{img_dir}/thumbs", 0777 ) if ( ! -d "$P{img_dir}/thumbs" );
    if ( $P{gimp} ) {
	system ( "$instprefix/lib/bbgallery/gimp_scale.pl -img_dir $P{img_dir} -out_dir $P{img_dir}/thumbs " .
		 "-prefix th_ -size $P{th_size} -verbose $P{verbose} -force $P{force} -quality $P{quality}"  );
    } else {
	im_scale ( $P{img_dir},  "$P{img_dir}/thumbs", "th_", $P{th_size}, $P{verbose}, $P{force}, $P{quality} );
    }
}

sub meta_index_entry ( $ ) {
    my $img = shift;
    my $nr_img = $#{$img} + 1;
    if ( open ( MI, ">$P{img_dir}/.bbmeta" ) ) {
	my @d = split ( /\//, $P{img_dir} );
	my $subdir = $d[$#d];
	my $subdir_html = encode_entities($subdir);
 	my $subdir_uri  = encode_entities(uri_escape($subdir));

 	my $thumb_uri   = encode_entities(uri_escape($img->[0]->{THUMB}));
	print MI<<END;
## BBGallery Metaindex entry
GAL_TITLE:   $P{title}	
GAL_INDEX:   $subdir_uri/html/index_0.$P{extension}
GAL_THUMB:   $subdir_uri/thumbs/$thumb_uri
GAL_COUNT:   $nr_img
END
	close ( MI );
    }
}

sub create_meta_index () {
    print "Creating meta index\n" if ( $P{verbose} );
    my @galleries;
    my $total=0;
    my $index = undef;
    my $thumb = undef;
    if ( opendir ( DIR, $P{img_dir} ) ) {
    	my @dir;
	if ( -f "$P{img_dir}/$P{order}" ) {
	    print "Reading alternative sorting list\n" if ( $P{verbose} );    	
	    if ( open ( SRT, "$P{img_dir}/$P{order}" ) ) {
		@dir = <SRT>;
		chomp(@dir);
                s/^\s*(.*)\s*$/$1/ foreach @dir;
		close( SRT );
	    }
	}
	else {
	    @dir = sort ( readdir ( DIR ) );
	}
   	close ( DIR );
	
	foreach my $d ( @dir ) {
	    next if ( $d =~ /^\./ );
	    if ( open M, "$d/.bbmeta" ) {
		print "  - adding gallery in: $d\n" if ( $P{verbose} );
		my %gallery;
		while ( <M> ) {
		    chop;
		    next if /^\s*\#/;
		    my ( $token, $value ) = split /:/, $_, 2;
		    $gallery{strip_ws ($token) } = strip_ws  $value ;		    
		    $total += $value if ( $token eq 'GAL_COUNT' );
		    $index = strip_ws $value if ( ! defined $index && $token eq 'GAL_INDEX' );
		    $thumb = strip_ws $value if ( ! defined $thumb && $token eq 'GAL_THUMB' );
		}
		close M;		
		push @galleries, \%gallery;
	    }
	}
    }
    my @rows;
    my @row;
    my $i=1;
    foreach my $g ( @galleries ) {
	push @row, $g;
	if ( $i >= $P{cols} ) {
	    my @r = @row;
	    push @rows, { COLUMNS => \@r };
	    @row = ();
	    $i=0;
	}
	$i++;	
    }
    push @rows, { COLUMNS => \@row };

    my $param;
    $param->{ROWS}       = \@rows;    
    $param->{TITLE}      = $P{title};
    $param->{COLUMNS_NR} = $P{cols};
    $param->{META_URL}   = $P{metalink} ? "../index.$P{extension}" : 0;
    $param->{GAL_TOTAL}  = scalar@galleries;

    if ( -f "$P{template_dir}/$P{template}/meta.tmpl" && open IMG, ">$P{img_dir}/index.$P{extension}" ) {
	my $tmpl = HTML::Template->new(filename          => "$P{template_dir}/$P{template}/meta.tmpl",
				       die_on_bad_params => 0,
				       cache             => 1);
	$tmpl->param ( $param );	    
	
	print "writing $P{img_dir}/index.$P{extension}\n" if ( $P{verbose} );	    
	print IMG $tmpl->output();	    
	close IMG;
    }

    # copy icon files, stylesheets, etc to html dir
    if ( opendir ( D, "$P{template_dir}/$P{template}" ) ) {
	my @files = readdir D;
	closedir D;
	foreach my $file ( @files ) {
	    next if ( $file =~ /\~$/ );
	    next if ( $file =~ /tmpl$/ );
	    next if ( $file =~ /^\./ );
	    system "cp $P{template_dir}/$P{template}/$file \"$P{img_dir}/$file\"";
	} 
    }

    # write .bbmeta for super meta galleries... :)
    if ( open M, ">$P{img_dir}/.bbmeta" ) {

	if ( $thumb =~ /^\.\/(.*)/ ) {
	    $thumb = $1;
	}
	if ( $index =~ /^\.\/(.*)/ ) {
	    $index = $1;
	}

	my @pwd = split '/', `pwd`;
	my $pwd = strip_ws $pwd[$#pwd];

	print M <<END;
## BBGallery Super-Metaindex entry
GAL_TITLE: $P{title}	
GAL_INDEX: $pwd/index.$P{extension}
GAL_THUMB: $pwd/$thumb
GAL_COUNT: $total
END
        close M;
    }
}

sub image_page ( $$$ ) {
    my $img        = shift;
    my $img_idx    = shift;
    my $index      = shift;
    my $image      = $img->[$img_idx]->{THUMB};
       $image      =~ s/^th_(.*)\.jpg/$1/;
    my $image_cap  = $image;
    my $param;

    if ( $P{jhead} ) {
	my $datetime = `$P{jhead} $P{img_dir}/$image.jpg`;
	$param->{IMG_DATETIME} = encode_entities($datetime);
    }

    if ( ! $P{raw_captions} ) {
	$image_cap  =~ s/_/ /g;
	$image_cap  =~ s/-/ /g;
    } else {
	$image_cap  = $image_cap . '.jpg';
    }
    $param->{IMG_CAPTION} = encode_entities($image_cap);
    my $image_uri  = encode_entities(uri_escape("$image"));
    mkdir ( "$P{img_dir}/html", 0777 ) if ( ! -d "$P{img_dir}/html" );
    my $filename    = "$P{img_dir}/html/$image.$P{extension}";
    my $filename_sl = "$P{img_dir}/html/sl_$image.$P{extension}";
    if ( open ( IMG, ">$filename" ) ) {
	print "writing $filename\n" if ( $P{verbose} );

	my $dsc   = 0;
	my $short = 0;
	if ( -f "$P{img_dir}/$image.txt" ) {
	    if ( open ( DSC, "$P{img_dir}/$image.txt" ) ) {
		print "Reading image description\n" if ( $P{verbose} );
		$short = <DSC>;
		$dsc = $short;
		chomp($short);
		while ( <DSC> ) {
		    $dsc .= $_;
		}
		close ( DSC );
	    }
	    $short =~ s/\<[^\>]*\>//g;
	    $dsc   = 0 if ( $dsc   eq '' );
	    $short = 0 if ( $short eq '' );
	}

	$param->{IMG_DSC_SHORT}  = $short;
	$param->{IMG_DSC}        = $dsc;

	my $next_idx = ( $img_idx == $#{$img} ) ? -1 : $img_idx + 1;	
	my $prev_idx = ( $img_idx ) ? $img_idx-1 : -1;
	my $d = $img->[$next_idx]->{THUMB};
	$d =~ s/^th_(.*)\.jpg/$1/;
	my $d_html   = encode_entities($d);
	$param->{NEXT_CAPTION} = $d_html;
 	my $d_uri    = encode_entities(uri_escape($d));
	$param->{NEXT_URL}        = ( $next_idx < 0 ) ? 0 : "$d_uri.$P{extension}";
	$param->{NEXT_THUMB_PATH} = ( $next_idx < 0 ) ? 0 : "../thumbs/th_$d_uri.jpg";

	if ( $next_idx < 0 ) {
	    $d = $img->[0]->{THUMB};
	    $d =~ s/^th_(.*)\.jpg/$1/;
	    $d_html  = encode_entities($d);
	    $d_uri   = encode_entities(uri_escape($d));
	}
	
	$param->{SLIDESHOW_NEXT}    = "sl_$d_uri.$P{extension}";
	$param->{SLIDESHOW_URL}     = "sl_$image.$P{extension}";
	$param->{SLIDESHOW_TIMEOUT} = $P{slide_delay};
	$param->{TITLE}             = "$P{title}: $image_cap";
	$param->{TITLE_SHORT}       = "$P{title}";

	$d             = $img->[$prev_idx]->{THUMB};
	$d             =~ s/^th_(.*)\.jpg/$1/;
	$d_html        = encode_entities($d);
	$param->{PREV_CAPTION} = $d_html;
	$d_uri         = encode_entities(uri_escape($d));

	my $jp         = encode_entities(uri_escape($img->[$img_idx]->{THUMB}));

	$param->{PREV_URL}          = ( $prev_idx < 0 ) ? 0 : "$d_uri.$P{extension}";
	$param->{PREV_THUMB_PATH}   = ( $prev_idx < 0 ) ? 0 : "../thumbs/th_$d_uri.jpg";
	$param->{INDEX_URL}         = "index_$index.$P{extension}";
	$param->{IMG_URL}           = "$image.$P{extension}";

	my $ml_hdr     = ( $P{metalink} ) ? "<link rel=\"start\" type=\"text/html\" HREF=\"../index.$P{extension}\">" : '';

	my $tmpl       = HTML::Template->new( filename          => "$P{template_dir}/$P{template}/image.tmpl",
					      die_on_bad_params => 0,
					      cache             => 1);

	$param->{IMG_NR}            = $img_idx+1;
	$param->{IMG_TOTAL}         = $#{$img}+1;
	$param->{IMG_PATH}          = "../$image_uri.jpg";
	$param->{IMG_SCALED_PATH}   =  $P{sc_size} ? "../scaled/sc_$image_uri.jpg" : $param->{IMG_PATH} ;
	$param->{META_URL}          = ( $P{metalink} ) ? "../../index.$P{extension}" : 0;

	if ( $img_idx > 0 ) {
	    $d       = $img->[0]->{THUMB};
	    $d       =~ s/^th_(.*)\.jpg/$1/;
	    $d_html  = encode_entities($d);
	    $d_uri   = encode_entities(uri_escape($d));
	    $param->{FIRST_URL} = "$d_uri.$P{extension}";
	} else {
	    $param->{FIRST_URL} = 0;
	}
	if ( $img_idx < $#{$img} ) {
	    $d       = $img->[$#{$img}]->{THUMB};
	    $d       =~ s/^th_(.*)\.jpg/$1/;
	    $d_html  = encode_entities($d);
	    $d_uri   = encode_entities(uri_escape($d));
	    $param->{LAST_URL}  = "$d_uri.$P{extension}";
	} else {
	    $param->{LAST_URL}  = 0;	
	}
 	
	$tmpl->param ( $param );

	print IMG $tmpl->output();
	close ( IMG );
	
	if ( -f "$P{template_dir}/$P{template}/slideshow.tmpl" && open IMG, ">$filename_sl" ) {
	    my $tmpl = HTML::Template->new(filename          => "$P{template_dir}/$P{template}/slideshow.tmpl",
					   die_on_bad_params => 0,
					   cache             => 1);
	    $tmpl->param ( $param );	    
	    
	    print "writing $filename_sl\n" if ( $P{verbose} );	    
	    print IMG $tmpl->output();	    
	    close IMG;
	}
    }
}

sub index_page ( $$$$$$ ) {
    my $range = shift;
    my $img   = shift;
    my $prev  = shift;
    my $this  = shift;
    my $next  = shift;
    my $total = shift;
    my $param;

    mkdir ( "$P{img_dir}/html", 0777 ) if ( ! -d "$P{img_dir}/html" );

    print "Writing index for $range->{FIRST} -> $range->{LAST}\n" if ( $P{verbose} );

    my $dsc = '';
    if ( -f "$P{img_dir}/index.txt" ) {
	if ( open ( DSC, "$P{img_dir}/index.txt" ) ) {
	    print "Reading gallery description\n" if ( $P{verbose} );
	    while ( <DSC> ) {
		$dsc .= $_;
	    }
	    close ( DSC );
	}
	$dsc = 0 if ( $dsc eq '' );	
    }

    $param->{NEXT_URL} = $next != -1 ? "index_$next.$P{extension}" : 0;
    $param->{PREV_URL} = $prev != -1 ? "index_$prev.$P{extension}" : 0;
    $param->{META_URL} = ( $P{metalink} ) ? ( '../../' . $P{metalinkurl} ) : 0;
    $param->{INDEX_NR} = $this+1;
    $param->{INDEX_TOTAL} = $total+1;
    $param->{DESCRIPTION} = $dsc;
    unless ( $this || $total ) {
	$param->{INDEX_NR}    = 0;
	$param->{INDEX_TOTAL} = 0;
    }
    $param->{COLUMNS_NR} = $P{cols};
    $param->{TITLE}      = $P{title};

    my @rows;
    my @row;

    for ( my $i=$range->{FIRST}; $i<=$range->{LAST}; $i++ ) {
	my %row;

	my $image     = $img->[$i]->{THUMB};
	$image     =~ s/^th_(.*)\.jpg/$1/;
	my $image_cap = $image;
	if ( ! $P{raw_captions} ) {
	    $image_cap =~ s/_/ /g;
	    $image_cap =~ s/-/ /g;
	} else {
	    $image_cap = $image_cap . '.jpg';
	}

	image_page ( $img, $i, $this );
	
	$row{IMG_URL}        = encode_entities(uri_escape($image)) . ".$P{extension}";
	$row{IMG_THUMB_PATH} = '../thumbs/' . encode_entities(uri_escape($img->[$i]->{THUMB}));
	$row{IMG_CAPTION}    = encode_entities($image_cap);


	if ( $i - $range->{FIRST} && ($i - $range->{FIRST}) % $P{cols} == 0 ) {
	    my @r = @row;
	    push @rows, { COLUMNS => \@r };
	    @row = ();
	}

	my $short = ''; 
	if ( $P{short_dsc} ) {
	    if ( -f "$P{img_dir}/$image.txt" ) {
		if ( open ( DSC, "$P{img_dir}/$image.txt" ) ) {
		    print "Reading image description\n" if ( $P{verbose} );
		    $short = <DSC>;
		    chomp($short);
		    close ( DSC );
		}
	    }
	    $short=~s/\<[^\>]*\>//g;
	    $row{IMG_CAPTION}    = encode_entities($short) if ( $short ne '' );
	}       
	push @row, \%row;
    }
    push @rows, { COLUMNS => \@row };
    $param->{ROWS} = \@rows;

    $param->{FIRST_URL} = ( $this == 0 )      ? 0 : "index_0.$P{extension}";
    $param->{LAST_URL}  = ( $this == $total ) ? 0 : "index_$total.$P{extension}"; 

    if ( -f "$P{template_dir}/$P{template}/index.tmpl" && open IND, ">$P{img_dir}/html/index_$this.$P{extension}" ) {
	my $tmpl = HTML::Template->new(filename          => "$P{template_dir}/$P{template}/index.tmpl",
				       die_on_bad_params => 0,
				       cache             => 1);
	$tmpl->param ( $param );	    
	    
	print "writing $P{img_dir}/html/index_$this.$P{extension}\n" if ( $P{verbose} );	    
	print IND $tmpl->output();	    
	close IND;
    }   
}

sub parse_commandline () {
    my %c;

    # check for global config file
    if ( -f "$ENV{HOME}/.bbgallery" ) {
	load_config (  \%P, "$ENV{HOME}/.bbgallery" );
    }

    # config file in CWD?
    if ( -f ".bbgallery" ) {
	load_config (  \%P, ".bbgallery" );
    }

    return if ( $#ARGV < 0 );

    for ( my $i=0; $i<=$#ARGV; $i++ ) {
	for ( $ARGV[$i] ) {
	    ( /^-v$/ || /^--verbose$/ ) && do {
		$c{verbose} = ( defined ( $c{verbose} ) ) ? $c{verbose}++ : 1;
		last;
	    };
	    ( /^-f$/ || /^--force$/ )&& do {
		$c{force} = 1;
		last;
	    };
	    ( /^-s$/ || /^--scale$/ )&& do {
		$c{sc_size} = $ARGV[++$i];
		$c{scale} = ( $c{sc_size} == 0 ) ? 0 : 1;
		last;
	    };
	    /^--thumb$/ && do {
		$c{th_size} = $ARGV[++$i];
		last;
	    };
	    ( /^-c$/ || /^--cols$/ ) && do {
		$c{cols} = $ARGV[++$i];
		last;
	    };
	    ( /^-m$/ || /^--max$/ ) && do {
		$c{th_max} = $ARGV[++$i];
		last;
	    };
	    ( /^-t$/ || /^--title$/ ) && do {
		$c{title} =  encode_entities($ARGV[++$i]);
		last;
	    };
	    ( /^-d$/ || /^--directory$/ ) && do {
		$c{img_dir} = $ARGV[++$i];
		# config file in image dir?
		if ( -f "$c{img_dir}/.bbgallery" ) {
		    load_config ( \%P, "$c{img_dir}/.bbgallery" );
		}
		last;
	    };
	    ( /^-w$/ || /^--wait$/ ) && do {
		$c{slide_delay} = $ARGV[++$i];
		last;
	    };
	    ( /^-h$/ || /^--help$/ ) && do {
		usage();
		exit ( 1 );
		last;
	    };
	    ( /^-M$/ || /^--meta$/ ) && do {
		$c{meta} = 1;
		last;
	    };
	    ( /^-L$/ || /^--metalink$/ ) && do {
		$c{metalink} = 0;
		last;
	    };
	    ( /^-I$/ || /^--imagemagick$/ ) && do {
		$c{gimp} = 0;
		last;
	    };
	    ( /^-G$/ || /^--gimp$/ ) && do {
		$c{gimp} = 1;
		last;
	    };

	    ( /^-q$/ || /^--quality$/ ) && do {
		$c{quality} = $ARGV[++$i];
		last;
	    };
	    ( /^-V$/ || /^--version$/ ) && do {
		print STDERR "$0 Version $version\n";
		exit ( 1 );
	    };
	    ( /^--raw-caption$/ ) && do {
		$c{raw_captions} = 1;
		last;
	    };
	    ( /^-o$/ || /^--order$/ ) && do {
		$c{order} = $ARGV[++$i];
		last;
	    };
	    ( /^--no-short-dsc/ )&& do {
		$c{short_dsc} = 0;
		last;
	    };
	    ( /^--template-dir/ ) && do {
		$c{template_dir} =  $ARGV[++$i];
		last;
	    };
	    ( /^--template/ || /^-T$/ ) && do {
		$c{template} =  $ARGV[++$i];
		if ( ! -d "$P{template_dir}/$c{template}" ) {
		    print "Sorry but a template '$c{template}' doesn't exist.\n\nTerminating...\n";
		    exit 1;
		}
		last;
	    };
	    ( /^--metalinkurl$/ ) && do {
                $c{metalinkurl} = $ARGV[++$i];
                last;
            };
	    ( /^--exifinfo$/ ) && do {
                $c{jhead} = $ARGV[++$i];
                last;
            };

	    ( /^--no-save$/ ) && do {
		$c{no_save} = 1;
		last;
	    };
	    print "Ignoring unknown parameter: $ARGV[$i]\n";
	}
    }
    # title defaults to directory name (if one given)
    if (!$c{title}) {
	my @d = split ( /\//, $c{img_dir} );
	$c{title} = $d[$#d];
    }

    # internally we remember not to use jhead if it has no value
    if ( exists ( $c{jhead} ) ) {
	if ( $c{jhead} eq 'none' ) {
	    $c{jhead} = '';
	} 
    }
    # make sure cmdline options take precedense over config files 
    # and builtin defaults
    map { $P{$_} = $c{$_} } keys ( %c );

}

sub usage () {
    print STDERR<<END;
$0 [options]
  Options:
    -v  --verbose         Be verbose [no]
    -f  --force           Force the (re)creation of thumb nails and
                          scaled images [no]
    -s  --scale <n>       Scale images to <n> pixels 
	                  (n=0 disables scaling) [800]
        --thumb <n>       Make thumbnails <n> pixels big [100]
        --no-short-dsc    Disable short descriptions. By default the
                          first line of the description (if present)
                          is used as caption. With this option the
                          filename will always be used.
    -c  --cols  <n>       Create index pages with <n> columns [5]
    -m  --max   <n>       Maximal <n> thumb nails on one index
	                  page [25]
    -t  --title <s>       Use <s> as title [Gallery]
    -d  --directory <s>   Create gallery for images in directory <s> [.]
    -T  --template <s>    Name of templates to use [default]
        --template-dir <s> Directory where template exists
    -w  --wait <n>        Delay between slides in slide show is set to
                          <n> seconds [15]
    -M  --meta            Create meta index instead of image and index 
                          pages
    -h  --help            Show this help screen
    -L  --metalink        Disable link to meta index in gallery index [yes]
    -V  --version         Print version number and exit
    -I  --ImageMagick     Use ImageMagick to scale images (default)
    -G  --gimp            Use Gimp to scale images 
    -q  --quality <1-100> JPEG quality of scaled images [100]
    -o  --order <s>       Use file <s> to order images in index pages
        --raw-caption     Use filename as is for image captions. By default 
                          underscores and dashes are replaced with spaces 
                          and the extension is stripped
        --metalinkurl <s> Link target for metaindex [index.html]
        --exifinfo <s>    jhead program (if not in path), or "none" [exifinfo -t 0x0132 ]
        --no-save         Do not save configuration in image direcorty	
     -e  --extension <s>  Use <s> as extension for HTML files [html]

    For more detailed instructions point your browser to
    $instprefix/lib/bbgallery/doc/usage.html

END
}

# ----------------------------------------------------------------------
#                            M A I N
# ----------------------------------------------------------------------

# get parameters
parse_commandline ();

# see if there are images
if ( opendir D, $P{img_dir} ) {
    my @d = readdir D;
    closedir D;
    
    my $i =0;
    foreach my $f ( @d ) {
	$i++ if ( $f =~ /\.jpg/ );
    }
    if ( !$i ) {
	print "WARNING:\n";
	print "  No images found\n\n";
	print "  Make sure your image files have the extension '.jpg'\n";
	print "  and try again.\n";
	exit 1;
    }
    print "Found $i images in $P{img_dir}...\n" if ( $P{verbose} );
} else {
    print "Can't read image directory $P{img_dir} ($!)\n";
    exit;
}


# report on jhead (used for jpeg date/time info)
print "Using '$P{jhead} <imagefile>' to get image title\n" if ( $P{jhead} && $P{verbose} );

# check if we have templates
unless ( -d "$P{template_dir}/$P{template}" ) {
    print "ERROR: Templates not found: $P{template}\n";
    exit 1;
}

# normalize the inout directory to absolute
my $cwd;
chomp($cwd = `pwd`);
$P{img_dir} = "$cwd/$P{img_dir}" if (  $P{img_dir} !~ /^\// );

# save settings 
write_config ( "$P{img_dir}/.bbgallery" );

# meta index mode?
if ( $P{meta} ) {
    create_meta_index ();
    exit ( 0 );
}

# create thumbs and scale images 
scale_images() if ( $P{scale} );
create_thumbs();

my @order = ();
if ( open ( ORD, "<$P{img_dir}/$P{order}" ) ) {
    while (<ORD>) { 
	chomp;
        s/^\s*(.*)\s*$/$1/;
	push @order, $_;
    }
}


# read in all the thumbs
if ( opendir ( TH, "$P{img_dir}/thumbs" ) ) {
    my @thumbs_tmp = sort ( readdir ( TH ) );
    closedir ( TH );
    my @thumbs;

    if (@order) {
	foreach my $n (@order) {
	    push @thumbs,"th_$n"  if grep (/th_$n/, @thumbs_tmp);
	}
    } else {
	@thumbs = sort @thumbs_tmp;
    }
    
    my @img;
    my @idx;
    my $img_cnt = 0;
    my $idx_cnt = 0;
    my $first   = 0;

    # filter out all unwanted files and break the list down into index pages
    for ( my $i=0; $i<=$#thumbs; $i++ ) {	
	if ( $thumbs[$i] =~ /^th_.*\.jpg$/ ) {
	    if ( $img_cnt && ( $img_cnt % $P{th_max} == 0 ) ) {
		my $last = $img_cnt - 1;
		$idx[$idx_cnt++] = {
		    FIRST => $first,
		    LAST  => $img_cnt-1,
		};
		$first = $img_cnt;
	    }
	    $img[$img_cnt++] = {
		THUMB => $thumbs[$i],
		INDEX => $idx_cnt,
	    };
	}
    }
    $idx[$idx_cnt] = {
	FIRST => $first,
	LAST  => $img_cnt-1,
    };

    # create index pages
    for ( my $i=0; $i<=$#idx; $i++ ) {	
	index_page ( $idx[$i], \@img, 
		     ( $i ) ? $i-1: -1 ,                    # prev
		     $i,                                    # this
		     ( defined ( $idx[$i+1] ) ) ? $i+1: -1, # next
	             $#idx );                               # total
    }

    # copy image files etc to html dir
    if ( opendir ( D, "$P{template_dir}/$P{template}" ) ) {
	my @files = readdir D;
	closedir D;
	foreach my $file ( @files ) {
	    next if ( $file =~ /\~$/ );
	    next if ( $file =~ /tmpl$/ );
	    next if ( $file =~ /^\./ );
	    system "cp $P{template_dir}/$P{template}/$file \"$P{img_dir}/html/$file\"";
	} 
    }

    # write meta index entry
    meta_index_entry ( \@img );
}
exit ( 0 );



