#!/usr/bin/perl

# Photo Browser code
#
# Put this in the top of a directory tree where you've stored lots of photos.
# The file should be named photos.cgi, and changed to be -rwx------. You
# may need to change the value of $style_file, and the reference to
# ../dot.jpg. This is an image one pixel large which I stretch to ensure
# widths and heights are respected; omitting the XHTML which refers
# to it shouldn't do any harm.
#
# You will also need to include a file .htaccess in the top directory,
# whose contents should be the single line:
#
#	DirectoryIndex photos.cgi
#
# This script makes thumbnails and medium-sized images dynamically,
# and produces valid XHTML as output.
#
# All comments and bug reports are welcome.
#
# Robert Craven, rac101@doc.ic.ac.uk

use strict;
use Image::Magick;

my $style_file;
my $cgi_base;
my $top_dir;

my $input_string;
my $dir;		my $dir_slash;
my $count;
my $size;
my $parent;
my @dirfiles;
my $cgi_base_dir;

my @images;
my $num;
my $imager;
my $index;
my $height;	my $newheight;
my $width;	my $newwidth;

	# set some urls

$style_file="photos.css";
$top_dir  = "./";
$cgi_base = "${top_dir}photos.cgi?";

	# get the query string find the variables

$input_string = $ENV{'QUERY_STRING'};
while ($input_string =~ s/^([^&]*)=([^&]*)(&|$)//) {
    if ($1 eq "dir") {
        $dir = "$2";
	$dir_slash = "$dir/";
    } elsif ($1 eq "count") {
        $count = $2;
    } elsif ($1 eq "size") {
        $size = $2;
    }
}

	# change to the directory we want and get some data

if($dir) {
    chdir $dir;
    if ($dir =~ /\//) {
        $parent = $dir;
	$parent =~ s/\/[^\/]+$//;
	$parent = "${cgi_base}dir=$parent";
    } else {
        $parent = $top_dir;
    }
    $cgi_base_dir = "${cgi_base}dir=$dir";
} else {
    $parent = "../";
    $cgi_base_dir = "$cgi_base";
}
@dirfiles = glob "*";

	# image files

foreach (@dirfiles) {
    if ((/\.jpg$/ || /\.JPG$/) && (!/^med_/) && (!/^thumb_/)) {
        push @images, $_;
    }
}
@images = sort @images;
$num = @images;
$imager = Image::Magick->new;

print <<END;
Content-Type: text/html

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<head>
  <title>Photos</title>
  <link rel="stylesheet" type="text/css" href="$style_file" />
</head>

<body>

<p>
  Current album: <b>/$dir</b>
  <br /><br />
</p>

<table>
  <tr>
    <td>
      [ <a href="$parent">UP</a> ]
      <br /><br />
END

	# print any directories in the contained in the current

foreach (@dirfiles) {
    if (-d) {
        print "      <a href=\"${cgi_base}dir=${dir_slash}$_\">";
	print "$_</a><br />\n";
    }
}

print <<END;
      <img src="../dot.jpg" height="1px" width="50px" alt="dot" />
    </td>
    <td class="photos">
END

if (defined $count) {
    
    	# we're showing an individual image
    
    $index = $count + 1;
    print <<END;
      <table cellspacing="0px" cellpadding="0px" border="0px" width="300px">
        <tr>
	  <td colspan="3" align="left">
	    <a href="$cgi_base_dir">thumbnails</a>  |
END
    if ($size eq "med") {
        print "            medium |\n            <a href=\"$cgi_base_dir&amp;count=$count&amp;size=full\">full</a>\n";
    } else {
        print "            <a href=\"$cgi_base_dir&amp;count=$count&amp;size=med\">medium</a> |\n            full\n";
    }
    print <<END;
            <br /><br /><br />
          </td>
	</tr>
	<tr>
	  <td align="left" width="80px">
END
    if ($index > 1) {
	print "            &lt;- <a href=\"$cgi_base_dir&amp;count=".($count-1)."&amp;size=$size\">prev</a>\n";
    }
    else {
	print "            &lt;- <a href=\"$cgi_base_dir&amp;count=".($num-1)."&amp;size=$size\">last</a>\n";
    }
    print <<END;
      	  </td>
	  <td align="center">
	    Image $index of $num
	  </td>
	  <td align="right" width="80px">
END
    if ($index < $num) {
	print "            <a href=\"$cgi_base_dir&amp;count=".($count+1)."&amp;size=$size\">next</a> -&gt;\n";
    } else {
        print "            <a href=\"$cgi_base_dir&amp;count=0&amp;size=$size\">first</a> -&gt;\n";
    }
    print <<END;
    	  </td>
	</tr>
      </table>
      <br />
END
    if ($size eq "med") {
        
	# test to see if a medium size image exists;
	# if it doesn't exist, then create it
	
        if (! -e "med_$images[$count]") {
	    $imager->Read("$images[$count]");
	    $height = $imager->Get('height');
	    $width = $imager->Get('width');
	    if ($width > $height) {
	        $newwidth = 600;
		$newheight = int($newwidth*$height/$width);
	    } else {
	        $newheight = 600;
		$newwidth = int($newheight*$width/$height);
	    }
	    $imager->Resize(width=>$newwidth,height=>$newheight);	    
	    $imager->Write("med_$images[$count]");
	    @$imager = ();
	}    
	print "      <img src=\"${dir_slash}med_$images[$count]\" alt=\"$images[$count]\" />\n";
    } else {
    	print "      <img src=\"${dir_slash}$images[$count]\" alt=\"$images[$count]\" />\n";
    } 
} else {

	# we're showing thumbnails

    for (my $i = 0; $i < $num; $i++) {
        if (! -e "thumb_$images[$i]") {
	    $imager->Read("$images[$i]");
	    $height = $imager->Get('height');
	    $width = $imager->Get('width');
	    if ($width > $height) {
	        $newwidth = 160;
		$newheight = int($newwidth*$height/$width);
	    } else {
	        $newheight = 160;
		$newwidth = int($newheight*$width/$height);
	    }
	    $imager->Resize(width=>$newwidth,height=>$newheight);
	    $imager->Write("thumb_$images[$i]");
	    @$imager = ();
	}
	print "      <a href=\"$cgi_base_dir&amp;count=$i&amp;size=med\">\n";
        print "        <img src=\"${dir_slash}thumb_$images[$i]\" border=\"0px\" alt=\"$images[$i]\" />\n      </a>\n";
    }
}

print <<END;
    </td>
  </tr>
</table>

</body>

</html>
END

