#!/usr/bin/perl

=head1 NAME

  WebAlbum v. pre-0.35 - Web (photo) Album generating script. 

=cut
# Simple Tags are those which do not require any special action, except noting their value. 
my %SIMPLE_TAGS = ( INDEX, TOPDIR, AUTHOR, EMAIL, HOME, TITLE, ABSTRACT, 
		    COL_NUMBER,  CONVERT, IMAGE_SIZE, IMAGE_LEGEND, IMAGE_TYPE,
		    TEXT_COLOR, BG_COLOR, BG_IMAGE, TAIL, 
		  );
# default values of some options, see the documentation 
# for explanation how to change them

my $DIR = qx/pwd/ ; $DIR =~ s/(.*)\n/$1/;
my $INDEX_FILE="index.txt";

my %album = ( 
     VERSION    => v. pre-0.35,
     INDEX      => "index.html", # The name of the html "index" files. I find index.shtml convenient...
     TOPDIR     => $DIR,          # Main album directory 
     CONVERT    => "convert -interlace line",   # name of the "convert" program 
     AUTHOR     => "Denis Havlik, 1998,1999", # It's me! 
     EMAIL      => "havlik\@ap.univie.ac.at", # my e-mail
     HOME       => "http://www.ap.univie.ac.at/users/havlik", # my home-page
     TITLE      => "WebAlbum v. pre-0.35",
     ABSTRACT   => "This script will help you to make a web-based photo album. Please read the html documentation for details. Newest version of the WebAlbum can be downloaded on my home-page. The script is a free software, published under GNU-licence.",
     TAIL       => '"<P><H1><A HREF=\"../$$hr{INDEX}\">UP</A>    <A HREF=\"$$hr{HOME}\">HOME</A></H1>\n<hr><address><a href=\"mailto:$$hr{EMAIL}\">$$hr{AUTHOR}</a></address><hr>\n</P>\n"', 
	     COL_NUMBER => 3,
	     IMAGE_SIZE => "150x150",
	     IMAGE_COLSPAN => 1,
	     TEXT_COLOR => "black",
	     BG_COLOR   => "silver",
	     BG_IMAGE   => undef,
	     IMAGE_TYPE	=> "jpg", 
	    );
#use CGI;

chdir $album{TOPDIR} || die "cannot change the dir to $album{TOPDIR}" ;

=head1 DESCRIPTION

WebAlbum is a html photo-album generator written in perl. The "Album"
is divided into "chapters". "Chapters" consist of a title,
introductory text and an array of thumbnails (i.e. scaled-down
photos). Thumbnails can have a "legend" below them.  Each chapter
lives in it's own sub-directory. When run, "WebAlbum" starts searching
the sub-directories of the main "album" directory for "index.txt"
templates. Based on the info found there, the script builds a main
"album" html - page and "chapters" pages in the
subdirectories. Furthermore, "Thumbnails" are produced "on the fly" if
they don't exist allready. If no "index-file" is found, a simple one
is produced on-the-fly, too.

WebAlbum does not care about the formate of your images. However, you are efectively limited to formates known to "convert" (many, see the man page) and your web-browser. Independent on the formate of your images, mini-images will all have the same formate (per default jpg), which can be handy if your image-files cannot be seen with web-browsers (postscript, dvi, pdf,...)

=head2 REQUIRES

This program is written in perl. Furthermore, it uses the "convert" program from ImageMagick package to produce thumbnails.  ImageMagick package can be found at: http://www.wizards.dupont.com/cristy/ImageMagick.html

=head2 FIRST STEPS

In order to produce an album, you mast have: photos (!), an idea on what you want to say about them, perl interpretor and a web browser. 
Find a directory where your photo-album will live. Divide the photos into "chapters", and make one sub-directory for each of the chapters. 
IMPORTANT: "Chapters" list in the main album will be sorted according to names of the sub-directories. 
In each subdirectory, make a template-file index.txt. This file is a standard ASCII text consisting of simple "TAG=value" pairs, separated with empty lines. Tags and possible values are described in the next chapter.

=head1 OPTIONS

At the moment, WebAlbum does not have any run-time options. Simply "cd" to the directory where your "album" lives and invoke the "WebAlbum". I will include some run-time options in the future (see TO DO section).

=head1 TAGS

Following tags are understood by the "WebAlbum" at the moment:

=head2 PREAMBLE TAGS

First group of the tags should be in the beginning of the index.txt file, i.e. before any photos:

=over 4

=item AUTHOR=your name, EMAIL=you@your.site, HOME=your home-page

Three optional tags with obvious function. Put them in the main index.txt file, or re-define them for each chapter as you please.

=for html <P></P>


=item TITLE=Title of the chapter/album : 

This tag should exist in every "index.txt". It sets the title for the chapter/album. It's value is usualy a plain ASCII text, although in principe you could add any HTML-tags to it. If not set, it defaults to name of the directory where the chapter lives.

=for html <P></P>

=item ABSTRACT=Abstract of the chapter/album : 

Use this tag to add some comments to the album/chapter. ASCII + HTML tags allowed. No default value.

=for html <P></P>

=item COL_NUMBER=number of columns in the chapter/album : 

Default number of columns in all the chapters is set to 3. If you want to change this value for all the chapters, add "WA_COLUMNS=N" to index.txt in the main album. the same entry in a chapter's "index.txt" changes the number of columns for the current chapter.

=for html <P></P>

=item IMAGE_SIZE=N x M :

This tag determines the size of the thumbnails to be produced. N and M are maximal sizes of thumbnails in x and y direction respectively. 
Although this tag usually sits in preamble section, you can also use it later, i.e. you can have differently-sized thumbnails in a single "chapter". In that case you will probably want to use the "IMAGE_COLSPAN" tag, too.
Thumbnails are produced by calling the "convert" program - one of the programs in the "ImageMagick" package. This package can be found at: http://www.wizards.dupont.com/cristy/ImageMagick.html

=for html <P></P>

=item IMAGE_TYPE=<TYPE>

This tag determines the image format of the mini_images. Default value is "jpg". I decided to implement this tag after reading the slashdot article about GIF-patents on Aug. 30. 1999. Another good reason for this tag is that many of the formats known to "convert" program (like postscript, dvi...) aren`t supported by standard web browsers .

=for html <P></P>

=item TEXT_COLOR=color :

Optional tag for setting the textcolor. It can be put just about anywhere, but in my opinion it only makes sense in the preamble of the index.txt. If all you want is change the color in one sentence, use html tags. Default value is "black"

=for html <P></P>

=item BG_COLOR=color :

Optional tag for setting the background color. Default value is "silver"

=for html <P></P>

=item BG_IMAGE=file name

Optional tag for setting the background image. No default value.

=for html <P></P>

=back

=head2 PHOTOS-RELATED TAGS

Following tags form the "body" of the photo albums: They determine which photos should be shown, how and where.

=over 4

=item BEGIN_IMAGES

This tag ends the PREAMBLE section. It must be present in the index.txt for every chapter. It has no meaning in the main index.txt file.

=for html <P></P>

=item IMAGE_FILE=file name

I strongly suspect this one to be rather obvious. Still: Every time you want an image to appear in a chapter of your album, you have to put a "IMAGE_FILE=file name" tag in index.txt. 

=for html <P></P>

=item IMAGE_LEGEND=text + html tags

If you put this tag before the "IMAGE_FILE" tag, the thumbnail will get a legend below it. Else, only a thumbnail is produced. 

=for html <P></P>

=item IMAGE_COLSPAN=integer

From time to time you might want to give more space to a particular thumbnail. Default value is 1, but it may be handy to change it to 2 or 3 for broader images. Also usefull if you temporary change size of thumbnails with "IMAGE_SIZE".

=for html <P></P>

=back

=head1 TO DO

  - add sub-albums and page-splitting
  - add following switches: 
  --thumbnails=force|no|standard  = to control thumbnails production
  --templates=(no|standard|rich) = to control authomatic templates production.
  -D --directory = to set the direstory where the album lives

  - do something about the frames structure of the album.

=cut
  
  #@dirstat = stat($album{TOPDIR});
  #@filestat= stat($FILE);
  #if ($filestat[10] >= $dirstat[10] ) { 
  #  print "files in directory $album{TOPDIR} are older than $FILE\n";
  #  die "no need for update!\n";
  #exit;
  #}

if ( open (M_IN,"<$INDEX_FILE") ) {
  warn "found \"$INDEX_FILE\" in main album directory. Reading new defaults...\n";
  while (<M_IN>){
    # simple tags only need to be saved.
    if (/([A-Z_]+)=(.*)/) {
      $album{$1} = $2;
    }
  }
} else {
  warn "No \"$INDEX_FILE\" in main album directory! Using default values.";
}
    
open (M_OUT,">$album{INDEX}") || die "cannot open $album{INDEX} for write!";
opendir (TOP,$album{TOPDIR}) || die "cannot read the directory $album{TOPDIR}";

&print_head(*M_OUT, \%album);
print M_OUT "<ul>\n";

# Parse the $album{TOPDIR} directory for subdirectories
# Every subdirectory is considered a chapter of the album, 
# Subdirectories must contain "$INDEX_FILE" file!!!
# Formate of the $INDEX_FILE is explained in the documentation.

foreach $CHAPTER ( sort (readdir(TOP)) ) {
    if ( (-d $CHAPTER) && !($CHAPTER =~ /\./)) {
      print "Scanning sub-directory: $CHAPTER... \n";
      if (! -f "$album{TOPDIR}/$CHAPTER/$INDEX_FILE") {
        warn "found no $album{TOPDIR}/$CHAPTER/$INDEX_FILE file!\n";
        warn "Creating a simple one...\n";
        make_indexfile("$album{TOPDIR}/$CHAPTER");
      }
      open(IN,"<$album{TOPDIR}/$CHAPTER/$INDEX_FILE")
        || die "cannot read $album{TOPDIR}/$CHAPTER/$INDEX_FILE";
      my %chapter = %album;
      my $i = $chapter{COL_NUMBER};
      $chapter{IMAGE_COLSPAN} = 1;
      $chapter{SUBDIR} = $CHAPTER;
      $chapter{TITLE} = $CHAPTER;
      $chapter{ABSTRACT} = "";

      while (<IN>){
        # This does it for the "simple" tags:
        /([A-Z_]+)=(.*)/ && ($chapter{$1} = $2);
        # BEGIN_IMAGES tag marks the end of the preamble. 
        # Now we can open the file for the new chapter, write it's header 
        # and make a link to it in the main album page.
        if (/BEGIN_IMAGES/) {
	  open(OUT,">$album{TOPDIR}/$CHAPTER/$chapter{INDEX}")
	  || die "cannot write to $album{TOPDIR}/$CHAPTER/$chapter{INDEX}";
	  &print_head(*OUT, \%chapter);
          print OUT "<TABLE ALIGN=CENTER BORDER=1 CELLSPACING=10 CELLPADDING=10>";
	  print M_OUT "<li><A HREF=$CHAPTER/$chapter{INDEX} TARGET=\"mainframe\">$chapter{TITLE} </A></li>\n";
	  $i = $chapter{COL_NUMBER};
        }
        s/IMAGE_COLSPAN=(.*)/$1/ && ($chapter{IMAGE_COLSPAN} = $1)  
                                 && ($i= $i- $chapter{IMAGE_COLSPAN}+1);
        if (s/IMAGE_FILE=(.*)/$1/) {
          ($i == $chapter{COL_NUMBER}) && print OUT "<TR>\n";
	  $chapter{IMAGE_FILE}  = $1;
	  $chapter{IMAGE_LEGEND} = ($chapter{IMAGE_LEGEND} || $1);
	  $i--;
	  &add_photo(*OUT,\%chapter);
	  $chapter{IMAGE_COLSPAN} = 1;
	  $chapter{IMAGE_LEGEND}  = undef;
          if ($i <= 0) { 
	    $i=$chapter{COL_NUMBER};
	    print OUT "</TR>\n";
          }
        }
      }
      close(IN);
      print OUT "\n</TABLE>\n";
      &print_tail(*OUT,\%chapter);
      close(OUT);
    }
  }
print M_OUT "</ul>\n<BR>\n";
&print_tail(*M_OUT,\%album);
######################################################################## 
#
#  Subroutines
#
######################################################################## 
#
#  header of the album/chapter
#
######################################################################## 
sub print_head {
  local *STDOUT = shift;
  my $hr = shift;
  print <<EOF;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD>
    <TITLE> $$hr{TITLE} </TITLE>
    <META NAME="GENERATOR" CONTENT="$0 $$hr{VERSION}">
    <META NAME="AUTHOR" CONTENT="$$hr{AUTHOR}">
    <META NAME="DESCRIPTION" CONTENT="Photo Album, $$hr{TITLE}">
    <META NAME="KEYWORDS" CONTENT="$$hr{AUTHOR} , Photo Album">
  </HEAD>
  <BODY TEXT="$$hr{TEXT_COLOR}" BGCOLOR="$$hr{BG_COLOR}" BACKGROUND="$$hr{BG_IMAGE}">
    <H1 ALIGN=CENTER>$$hr{TITLE}</FONT></H1>
    <HR WIDTH=75% ALIGN=CENTER SIZE=3>
    <P>$$hr{ABSTRACT}</P>
EOF
  return ; 
}
######################################################################## 
#
#  add a photo and legend to the "chapter"
#
######################################################################## 
sub add_photo {

  local *STDOUT = shift;
  my $hr = shift;

  my $DIR="$$hr{TOPDIR}/$$hr{SUBDIR}";
  my $IMAGE=$$hr{IMAGE_FILE};
  my $TYPE = $$hr{IMAGE_TYPE};
  my ($dev,$ino,$mode,$nlink,
      $uid,$gid,$rdev,$img_size,
      $atime,$mtime,$ctime,
      $blksize,$blocks)      =  stat("$DIR/$IMAGE");
  my $img_size= sprintf "%.1f", $img_size/1024;
  my $mini_image = $IMAGE ;
     $mini_image =~ s/(.*)\..*/mini_$1\.$TYPE/ ;
  #warn "$IMAGE size= $img_size kB\n";
  my $T1= -M "$DIR/$mini_image";
  my $T2= -M "$DIR/$IMAGE";
  #warn "$DIR/$mini_image: $T1\n $DIR/$IMAGE: $T2\n";

if ( ! (-f "$DIR/$mini_image") ) {
  warn "$$hr{CONVERT} -geometry $$hr{IMAGE_SIZE} $DIR/$IMAGE $DIR/$mini_image\n";
  system "$$hr{CONVERT} -geometry $$hr{IMAGE_SIZE} $DIR/$IMAGE $DIR/$mini_image";
  # this is a work-around for conversions of multi-page and animated pictures into non-animated formates
  if (-f "$DIR/$mini_image.0") {
    #warn "Ops. Here we had a multi-image=>single-image conversion. Clearing the garbage...\n";
    system "mv $DIR/$mini_image.0 $DIR/$mini_image; rm $DIR/$mini_image.*;";
  }
}
print <<EOF;
<td colspan="$$hr{IMAGE_COLSPAN}" align="center" valign="top"><A HREF="$IMAGE" TARGET="NEWFRAME" ><img src="$mini_image" align="top" ALT="Click on the image to enlarge ($img_size kB)"></A>
<P>$$hr{IMAGE_LEGEND}</P>
</TD>
EOF
    ;
}
######################################################################## 
#
#  tail of the album/chapter You can customize it by setting 
#  the "TAIL" tag! Use $$hr{TAG} in order to access previously defined tags
#  in the "TAIL"!
#
######################################################################## 
sub print_tail {
  local *STDOUT = shift;
  my $hr = shift;
  print eval $$hr{TAIL};
  print <<EOF;
</BODY>
</HTML>
EOF
;
}
######################################################################## 
#
# This procedure gets called whenever a subdirectory withouth "INDEX"
# file is found, to produce a simple one. It is a rather stupid
# procedure, but it may still be handy.
#
######################################################################## 
sub make_indexfile {
  my $DIR = shift;
  opendir (DIR,$DIR) || die "cannot read the $DIR directory";
  open (INDEX, ">$DIR/$INDEX_FILE");
  print INDEX "TITLE=NEW ENTRY!\n\n";
  print INDEX "ABSTRACT=This page has been authomatically produced by WebAlbum v. pre-0.35. If you want to change the appereance, please edit index.txt file.\n\n";
  print INDEX "BEGIN_IMAGES\n\n";

  foreach $FILE ( sort (readdir(DIR)) ) {
    #print "found $FILE!\n";
    if (-f "$DIR/$FILE") {
    #print "... adding $FILE!\n";
      print INDEX "IMAGE_LEGEND=$FILE\n";
      print INDEX "IMAGE_FILE=$FILE\n\n";
    }
  }
  close INDEX; close DIR;
}
__END__
 CHANGESLOG:
             v. 0.35  - BUG fixes...
             v. 0.34  - BUG-fix: conversion of multi-image formates into 
                        single image mini-pictures (such as ".ps" 
                        or animated gifs -> ".jpg" now (correctly) 
			produces a mini-image of a FIRST image found 
			in the starting file.
		      - NEW: simple index-file generation
Aug 30, 1999 v. 0.33  - NEW: starting with this version, mini_images are 
                        all of the same type, per default "jpg"
Aug 02, 1999 v. 0.32  - BUG-fixes: fixed the "TEXT_COLOR" attribute 
                        and documentation of IMAGE_LEGEND and IMAGE_FILE tags.
                        (by L.J. Casimir Prikockis <alaric@eclipse.net>)
Jul 09, 1999 v. 0.31  - BUG-fix: image-sizes calculation fixed.
Jul 06, 1999 v. 0.3   - First public release 
