#!/usr/local/bin/perl
echo "Gallery ios currently unavailable";
exit;
#$dotimer=1 if $ENV{REMOTE_ADDR} eq "136.200.128.154" || $ENV{HTTP_X_FORWARDED_FOR} eq "136.200.128.154";
open(LOAD,"/usr/bin/uptime|");
$load=<LOAD>;
$load=~/load average: ([\d.]+),/;
close LOAD;
if($1 > 10.0){
	print <<EOF;
Content-type: text/html

<html><head><title>Photo Gallery</title></head>
<body>
Sorry, the Gallery has been temporarily shut down due to system load.
<p>
<a href="http://$ENV{SERVER_NAME}$ENV{REQUEST_URI}">Try again</a>
</body></html>
EOF
exit;
}
use POSIX "strftime";
################################################################
# Explicit paths initialized here
%SITE=(
	"trconnection.com","/home/todd:www::/home/roger/lib/weblib.lib:/trc/pictures",
	"www.trconnection.com","/home/todd:www::/home/roger/lib/weblib.lib:/trc/pictures",
	"toddfestwest.com","/home/todd:www::/home/roger/lib/weblib.lib:/trc/pictures",
	"www.toddfestwest.com","/home/todd:www::/home/roger/lib/weblib.lib:/trc/pictures",
	"rocemabra.com","/home/todd:www::/home/roger/lib/weblib.lib:http://rocemabra.com/trc/pictures",
	"www.rocemabra.com","/home/todd:www::/home/roger/lib/weblib.lib:http://rocemabra.com/trc/pictures",
	"classof1971.com","/home/todd:www::/home/roger/lib/weblib.lib:http://rocemabra.com/trc/pictures",
	"riolinda.classof1971.com","/home/todd:www::/home/roger/lib/weblib.lib:http://rocemabra.com/trc/pictures",
	"webhost5.water.ca.gov","/export/home/roger:www:::/~roger/pictures",
	"webhost1.water.ca.gov","/export/home/roger:www:::/~roger/pictures",
	"webhost2.water.ca.gov","/export/home/roger:www:::/~roger/pictures",
	"webhost6.water.ca.gov","/export/home/roger:www:::/~roger/pictures");
$SITENAME="\L$ENV{SERVER_NAME}";
if(defined($SITE=$SITE{$SITENAME})){
	($SITEDIR,$WWWDIR,$DBFORMAT,$WEBLIBLOC,$DEFURL)=split(/:/,$SITE,5);
	if($DBFORMAT eq ""){$DBFORMAT="NDBM";}
	if($WEBLIBLOC eq ""){$WEBLIBLOC="weblib.lib";}
	$NEWDB=$DBFORMAT eq "NEWDB";
}
else{
	print <<EOF;
Content-type: text/html

<html><head><title>The Gallery</title></head>
<body bgcolor=#ffffff>
<h1>This site ($SITENAME) is not configured to use the Gallery</h1>
</body></html>
EOF
	exit;
}
$style=<<EOF;
body {font: 8pt verdana,helvetica;}
EOF
$mcvert="$SITEDIR/bin/mcvert";
$identify="$SITEDIR/bin/identify";
$thumbnailbin="$SITEDIR/bin/thumbnail";
open(CFG,"$SITEDIR/gallery.cfg");
################################################################
if($NEWDB){
	require DB_File;
	import DB_File;
}
# Determine which Environment file to initialize with
while(<CFG>){
	chop;
	($scriptname,$envfile)=split(/\t/);
	last if $ENV{SCRIPT_NAME} eq $scriptname;
}
close(CFG);
# Set up any defaults and read in initialization variables
&initialize_defaults;
require $envfile;
$bordersize=$BORDERSIZE?$BORDERSIZE:20;
$slideshowmaxwidth=$SLIDESHOWMAXWIDTH||285;
$slideshowmaxheight=$SLIDESHOWMAXHEIGHT||214;
require $WEBLIBLOC; # required here to protect weblib variables
$prevoff=$PREVOFF?$PREVOFF:"$DEFURL/prevoff.gif";
$prevon= $PREVON ?$PREVON :"$DEFURL/prev.gif";
$nextoff=$NEXTOFF?$NEXTOFF:"$DEFURL/nextoff.gif";
$nexton= $NEXTON ?$NEXTON :"$DEFURL/next.gif";
($TABLECOLOR,$TABLELIGHT,$TABLEDARK)=split(/;/,$TABLECOLOR);
&getparams;
$param{preview}=$PREVIEWLOCK unless $param{preview};
if($UPLOAD && $ENV{CONTENT_TYPE} =~ m#^multipart/form-data#){&upload;}
elsif($UPLOAD && $param{"upload"}){
	&ReadParse(*in);
	&display_upload;
}
else{
	&ReadParse(*in);
	$indexdb=$INDEXDB;
	$indexdb.=".db" if $NEWDB;
	$galleryurldir=$GALLERYURLDIR;
	$gallerydir="$WWWDIR/$galleryurldir";
	dbmopen(%INDEX,"$PAGEHOMEDIR/$indexdb",0644);
}
&openweb;
&timer;
print $preface;
&load_gallery;
if($preview=$param{"preview"}){&display_preview;}
else {&select_and_display_picture;}
$HTMLCLOSETAG=$PAGETAIL unless $param{"slideshow"};
&timer;
&htmlclose;
################################################################
# Load Gallery
################################################################
sub load_gallery{
	local(%galleryindex)=%INDEX;
	&timer;
	foreach $key(keys %galleryindex){delete $galleryindex{$key} if $key =~ /%%/;}
	if($param{"set"} && $param{"set"} ne "-1"){ # Restrict to specified set
		$setid=$param{"set"};
		foreach $key(keys %galleryindex){
			($caption,$parameters)=split(/%%/,$galleryindex{$key});
			%parameters=split(/[=;]/,$parameters);
			if(",$parameters{SetID}," =~ /,$setid,/){push(@gallery,$key);}
		}
	}
	else{ 
		@gallery=();
		if($ALLOWUNINDEXED){
			chdir("$PAGEHOMEDIR/$gallerydir");
			opendir(DIR,"$PAGEHOMEDIR/$gallerydir");
			@gallery=grep(-f,readdir(DIR)); # Select all local pictures for display
			foreach $picture(@gallery){
				delete $galleryindex{$picture};
			}
			closedir(DIR);
		}
		push(@gallery,keys %galleryindex); # Add non-local pictures
	}
	@gallerylist=@gallery;
	@presentationorder=@order=sort {"\U$a" cmp "\U$b"} @gallery;
	$order=0;
	%order=map {$_,$order++} @order;
	%presentationorder=%order;
	if($RANDOMPREVIEW){
		srand($RANDOMPREVIEW);
		&shuffle(\@presentationorder);
		$order=0;
		%presentationorder=map{$_,$order++} @presentationorder;
	}
	elsif($param{"newest"}){
		foreach $picture(@gallerylist){
			($thumbnail=$picture)=~s/\.([^.]+)$/_$1/g;
			$thumbnail="$PAGEHOMEDIR/$WWWDIR/$THUMBNAILDIR/tn_$thumbnail.jpg";
			@stat=stat($thumbnail);
			$mod{$picture}=$stat[9];
		}
		@presentationorder=sort {$mod{$b} <=> $mod{$a}} @presentationorder;
		$order=0;
		%presentationorder=map{$_,$order++} @presentationorder;
	}
}
################################################################
# Print Set List
################################################################
sub printsetlist{
	foreach $key(keys %INDEX){
		next if $key =~ /%%/;
		($caption,$parameters)=split(/%%/,$INDEX{$key});
		%parameters=split(/[=;]/,$parameters);
		next unless $parameters{SetID};
		@setid=split(/,/,$parameters{SetID});
		foreach $setid(@setid){$setid{$setid}=1;}
	}
	foreach $setid (sort byset keys %setid){
		$set="<a href=$weblib::URL/set=$setid$upload>";
		$SetID=$INDEX{"SetID%%$setid"};
		$SetHeader="Unclassified";
		if($SetID =~ /%%/){($SetHeader,$SetID)=split(/%%/,$SetID);}
		$SetID=~s/^of |^from |^by //;
		$SetID="Set $setid" unless $SetID;
		$set.=$SetID;
		$set.="</a><br>\n";
		$set=~s/_/ /g;
		if($SetHeader ne $oldSetHeader){
			$#set+=3;
			push(@set,
				"<hr><center><font size=+1>$SetHeader</font></center><hr>".
				"\n");
		}
		$oldSetHeader=$SetHeader;
		push(@set,$set);
	}
	$#set=int(($#set+$setcolumns)/$setcolumns)*$setcolumns;
	$rows=$#set/$setcolumns;
	for($row=0;$row<$rows;$row++){
		for($col=0;$col<$setcolumns;$col++){
			$index=$row+$col*$rows;
			$set=$set[$index];
			next unless $set;
			$col[$col].=$set;
		}
	}
	if(@col){
		print "<center>\n";
		print "<table><caption>Select By Set Identifier</caption><tr>\n";
		for($col=0;$col<=$#col;$col++){
			print "<td valign=top><font size=-2>$col[$col]</font></td>\n";
		}
		print "</tr></table>\n";
		print "</center>\n";
		@col=();
	}
}
################################################################
# Select and Display Picture
################################################################
sub select_and_display_picture{
	&timer;
	if(($picture=$param{"picture"}) && $picture ne "-1"){
		@pictures=split(/,/,$picture); # Allow random selection from list
		@gallery=();
		foreach $picture(@pictures){
			@picture=split(m#/#,$picture);
			$picture=$picture[$#picture];
			if(-f "$PAGEHOMEDIR/$gallerydir/$picture"){
				push(@gallery,$picture);
			}
			elsif($INDEX{$picture}){
				push(@gallery,$picture);
			}
			else{
				print "Sorry, there is no picture by that name<p>\n";
			}
		}
	}
	if($#gallery>=0){
		&select_from_gallery;
		&display_picture;
	}
	if(!$param{"slideshow"}){
		&prepare_navigation;
		&setup_scale if $parameters{Width};
		&category_select;
		unless ($PRIVATE){
			print <<EOF;
<hr>
If you've got pictures to share, I'd be happy to display them here. Contact me
at <a href=mailto:$PAGEADMIN>$PAGEADMIN</a> for details
EOF
			if($UPLOAD){
				print " or submit them individually here:\n";
				&submitform;
			}
		}
	}
}
################################################################
# Select From Gallery
################################################################
sub select_from_gallery{
	srand(time);
	$picture=$gallery[int(rand($#gallery+1))];
}
################################################################
# Display Picture
################################################################
sub display_picture{
	local($URL);
	$bordersize=$BORDERSIZE?$BORDERSIZE:20;
	$innertablecolor=$INNERTABLECOLOR?$INNERTABLECOLOR:$TABLECOLOR;
	print "<center>\n";
	($caption,$parameters)=split(/%%/,$INDEX{$picture});
	$caption=~s/\\#/%23/gm;
	@caption=split(/#/,$caption);
	%parameters=split(/[=;]/,$parameters);
	&prepare_caption;
	$wh=&scale_picture;
	%savecaption=%caption;
	@SetID=split(/,/,$parameters{SetID});
	if(-f "$PAGEHOMEDIR/$gallerydir/$picture"){
		$URL="/$HTMLPATH/$galleryurldir/$picture";
		&print_picture($URL,$picture);
	}
	else{
		$URL=delete $caption{URL};
		&print_picture($URL,$URL);
	}
	unless($param{"slideshow"}){
		$twidth=500;
		$twidth=$width if $width>500;
		print(&enclose($caption{Caption})),delete $caption{Caption}
			if $caption{Caption};
		foreach $key(Source,Photographer,Artist,"Artist/Photographer",Compiler,
			Manipulator,Venue,Date,Commentary){
			print(&enclose("$key: $caption{$key}")),delete $caption{$key}
				if $caption{$key};
		}
		foreach $key (sort keys %caption){
			print(&enclose("$key: $caption{$key}"));
			delete $caption{$key};
		}
	}
	%caption=%savecaption;
	print "</center>\n";
}
################################################################
# Prepare Caption
################################################################
sub prepare_caption{
	local($caption,$caplabel,$captext);
	%caption=();
	foreach $caption(@caption){
		$caption=~s/%23/#/gm;
		if($caption!~/:\s/){
			if($caption=~m#^http://|^/#){$caption="URL: $caption";}
			else{$caption="Caption: $caption";}
		}
		($caplabel,$captext)=split(/:\s+/,$caption,2);
		chomp($captext);
		$caplabel=~s/\n//;
		$caption{$caplabel}=$captext;
	}
}
################################################################
# Scale Picture
################################################################
sub scale_picture{
	local($wh,$scalew,$scaleh,$width,$height);
	if($param{"slideshow"}){
		$scalew=$slideshowmaxwidth/$parameters{Width}; #570
		$scaleh=$slideshowmaxheight/$parameters{Height}; #345
		$scale=$scalew>$scaleh?$scaleh:$scalew;
		$scale=1 if $scale>1;
	}
	else{
		$scale=&getcookie(StickyScale);
		$scale=$parameters{Scale} unless $scale;
		$scale=1 unless $scale;
		$scale=$in{Scale} if $in{Scale};
	}
	$width=int($parameters{Width}*$scale+.5);
	$height=int($parameters{Height}*$scale+.5);
	$wh="width=$width " if $width;
	$wh.="height=$height " if $height;
	return $wh;
}
################################################################
# Print Picture
################################################################
sub print_picture{
	$bordercolor="bordercolor=$TABLECOLOR";
	if($TABLELIGHT){$bordercolor.=" bordercolorlight=$TABLELIGHT";}
	if($TABLEDARK){$bordercolor.=" bordercolordark=$TABLEDARK";}
	print <<EOF;
<table border=0 cellpadding=0 cellspacing=0>
<tr><td>
<table style='border: $TABLECOLOR ridge ${bordersize}px'
 cellpadding=0 cellspacing=0 align=center>
<tr><td bgcolor=$innertablecolor>
EOF
	if($VOTE && $caption{Vote}){&vote;}
	print "<a href=$weblib::URL/picture=$picture>" if $param{"slideshow"};
	print "<img border=0 ${wh}src=$_[0]>";
	print "</a>" if $param{"slideshow"};
	print "</td></tr>\n";
	print "</table></td></tr></table>\n";
	print &prevarrow if $NAVIGATION && !($param{"slideshow"} || $VOTE);
	print "$_[1]\n" unless $SUPPRESSPICTURENAME && !$SUPPRESSONLYONPREVIEW;;
	print &nextarrow if $NAVIGATION && !($param{"slideshow"} || $VOTE);
	print "<br>\n";
}
################################################################
# Prepare navigation
################################################################
sub prepare_navigation{
	$action=$weblib::URL;
	$action.="/vote" if $param{vote};
	print "[<a href=$action$upload>random</a>]\n";
	print "[<a href=$action/preview$upload>thumbnail preview</a>]\n"
		if $THUMBNAILDIR;
	print "Show me another from the Gallery<br>\n";
	if(@SetID && not $upload){
		foreach $SetID(@SetID){
			$action="$weblib::URL/set=$SetID";
			if($INDEX{"SetID%%$SetID"}){
				$SetID=$INDEX{"SetID%%$SetID"};
				$SetHeader="Unclassified";
				if($SetID =~ /%%/){($SetHeader,$SetID)=split(/%%/,$SetID);}
				$SetID="by $SetID"
					if $SetHeader eq "Photographers" || $SetHeader eq "Artists";
				$SetID=~s/_/ /g;
			}
			else{
				$SetID=" from set $SetID";
			}
			print "[<a href=$action$upload>random</a>]\n";
			print "[<a href=$action/preview$upload>thumbnail preview</a>]\n"
				if $THUMBNAILDIR;
			print "$SetID<br>\n";
		}
	}
}
################################################################
# Set up Scale
################################################################
sub setup_scale{
	$scalepercent=($scale*100)."%";
	$action=$weblib::URL;
	$action.="/picture=$picture" if $picture;
	$action.="/set=$setid" if $setid;
	print <<EOF;
<form method=post action=$action$upload>
This image is scalable, for viewing on smaller monitors. It is currently shown
at $scalepercent.<br>
<select name=Scale>
EOF
	for($i=1;$i<=20;$i++){
		$optionscale=$i/10;$optionpercent=($optionscale*100)."%";
		if($scale == $optionscale){
			print "<option value=$optionscale selected>$optionpercent\n";
		}
		else{
			print "<option value=$optionscale>$optionpercent\n";
		}
	}
	$label=$STICKYSCALE?"All Pictures":"Picture";
	print <<EOF;
</select>
<input type=submit value="Scale $label">
</form>
EOF
}
################################################################
# Category Select
################################################################
sub category_select{
	$savepicture=$picture;
	$setcolumns=$SETCOLUMNS?$SETCOLUMNS:4;
	print "<hr width=75%>\n" if $setid;
	#&printsetlist unless $setid;
	#&printsetlist if $setid eq "full";
	&printsetlist if $param{"full"} || !$SUPPRESSFULLSETLIST;
	@gallerylist=sort {"\U$a" cmp "\U$b"} @gallerylist;
	$#gallerylist=int(($#gallerylist+$setcolumns)/$setcolumns)*$setcolumns;
	$rows=$#gallerylist/$setcolumns;
	for($row=0;$row<$rows;$row++){
		for($col=0;$col<$setcolumns;$col++){
			$index=$row+$col*$rows;
			$picture=$gallerylist[$index];
			next unless $picture;
			$col[$col].="*",$starred=1 unless 
				-f "$PAGEHOMEDIR/$gallerydir/$picture"||$INDEX{$picture}=~m#^/#;
			$url="$weblib::URL$upload/picture=$picture";
			$url.="/set=$setid" if $setid;
			$col[$col].="<a href=$url>$picture</a><br>\n";
		}
	}
	$SetID=$INDEX{"SetID%%$setid"};
	$SetHeader="Unclassified";
	if($SetID =~ /%%/){($SetHeader,$SetID)=split(/%%/,$SetID);}
	if($SetID){$SetID=" in this set ".$SetID;}
	else{$SetID=" from set $setid";}
	$SetID=~s/_/ /g;
	$inthisset=$setid?$SetID:"";
	if(0&&$setid){
		print "<center>\n";
		print "Select by Picture$inthisset<br>\n<table><tr>\n";
		for($col=0;$col<=$#col;$col++){
			print "<td valign=top>";
			print "$col[$col]</td>\n";
		}
		print "</tr></table>\n";
		print "<a href=$weblib::URL$upload>Full Gallery listing</a>\n" if $setid;
		print "</center>\n";
		print "'*' indicates that the picture is not local to $PAGENAME and may ",
			"not be available at all times" if $starred;
	}
}
################################################################
# Display Preview
################################################################
sub display_preview{
	local($picture,$thumbnail,@stat,%mod,$previewlink);
	&timer;
	if($in{PreviewNo}){$previewgroup=$in{PreviewNo};}
	else{$previewgroup=$preview;}
	$previewgroup=1 if $previewgroup == -1;
	$previewprev=$previewgroup-1;
	$previewnext=$previewgroup+1;	
	@gallerylist=sort {"\U$a" cmp "\U$b"} @gallerylist;
	if($RANDOMPREVIEW){
		srand($RANDOMPREVIEW);
		&shuffle(\@gallerylist);
	}
	else{
		if($param{"newest"}){
			foreach $picture(@gallerylist){
				($thumbnail=$picture)=~s/\.([^.]+)$/_$1/g;
				$thumbnail="$PAGEHOMEDIR/$WWWDIR/$THUMBNAILDIR/tn_$thumbnail.jpg";
				@stat=stat($thumbnail);
				$mod{$picture}=$stat[9];
			}
			@gallerylist=sort {$mod{$b} <=> $mod{$a}} @gallerylist;
			if($PREVIEWNEWEST){
				$url="$weblib::URL/preview";
				$url.="/set=$setid" if $setid;
				$previewlink="<a href=$url>Show preview in alphabetical order</a><br>\n";
			}
		}
		elsif($PREVIEWNEWEST){
			$url="$weblib::URL/preview/newest";
			$url.="/set=$setid" if $setid;
			$previewlink="<a href=$url>Show preview in newest first order</a><br>\n";
		}
	}
	$gallerycount=$#gallerylist+1;
	$previewnext=0 if ($previewnext-1)*12>$#gallerylist;
	$previewprev=int($gallerycount/12)+1 if $previewprev>int($gallerycount/12)+1;
	$gbegin=($previewgroup-1)*12;
	$gend=($previewgroup*12)-1;
	@gallerylist=@gallerylist[$gbegin..$gend];
	$#gallerylist=int(($#gallerylist+4)/4)*4;
	$rows=$#gallerylist/4;
	$SetID=$INDEX{"SetID%%$setid"};
	$SetHeader="Unclassified";
	if($SetID =~ /%%/){($SetHeader,$SetID)=split(/%%/,$SetID);}
	if($SetID){$SetID=" in this set ".$SetID;}
	else{$SetID=" from set $setid";}
	$SetID=~s/_/ /g;
	$inthisset=$setid?$SetID:"";
	print "<center>\n";
	$PREVIEWMESSAGE="Select by Picture$inthisset<br>\n"
		unless $PREVIEWMESSAGE;
	print "$PREVIEWMESSAGE<br>$previewlink" unless $PREVIEWLOCK;
	&print_preview_table;
	$gend=$gend+1>$gallerycount?$gallerycount-1:$gend;
	$url="$weblib::URL/preview";
	$url.="/set=$setid" if $setid;
	$url.="/newest" if $param{"newest"};
	&print_preview_navigation;
	print "<br>There are a total of $gallerycount pictures ";
	if($setid){print "in this set\n";}
	else{print "in the gallery\n";}
	print "<br>'*' indicates that the picture is not local to $PAGENAME",
		" and may not be available at all times" if $starred;
	print "</center>\n";
}
################################################################
# Print Preview Table
################################################################
sub print_preview_table{
	print "<table border=0>\n";
	$index=0;
	for($row=0;$row<$rows;$row++){
		print "<tr>\n";
		for($col=0;$col<4;$col++){
			$picture=$gallerylist[$index];
			$index++;
			next unless $picture;
			$star="";
			$star="*",$starred=1
				unless -f "$PAGEHOMEDIR/$gallerydir/$picture"||$INDEX{$picture}=~m#^/#;
			$url="$weblib::URL$upload/picture=$picture";
			$url.="/set=$setid" if $setid;
			$url.="/newest" if $param{"newest"};
			$thumbnailimg="";
			if($THUMBNAILDIR){
				($thumbnail=$picture)=~s/\.([^.]+)$/_$1/g;
				$thumbnail="$THUMBNAILDIR/tn_$thumbnail.jpg";
				$thumbnail="temp/$thumbnail" if $upload;
				$tbs=$THUMBNAILBORDERSIZE?$THUMBNAILBORDERSIZE:0;
				if(-f "$PAGEHOMEDIR/$WWWDIR/$thumbnail"){
					$thumbnailimg="<img src=/$HTMLPATH/$thumbnail border=$tbs><br>";
				}
			}
			print "<td valign=center align=center>";
			print "<a href=$url$upload>" unless $PREVIEWLOCK;
			print $thumbnailimg;
			print "$star$picture" unless $SUPPRESSPICTURENAME;
			print "</a>" unless $PREVIEWLOCK;
			if($param{"newest"}){
				$mod=POSIX::strftime("%m/%d/%Y",localtime($mod{$picture}));
				print "<br><font size=-2>Added: $mod</font>\n";
			}
			print "</td>\n";
		}
		print "</tr>\n";
	}
	print "</table>\n";
}
################################################################
# Print Preview Navigation
################################################################
sub print_preview_navigation{
	print "<table><tr><td>\n";
	if($previewprev){
		$url="$weblib::URL/preview=$previewprev$upload";
		$url.="/set=$setid" if $setid;
		$url.="/newest" if $param{"newest"};
		print "<a href=$url>";
		print "<img src=\"$prevon\" border=0></a>";
	}
	else{
		print "<img src=\"$prevoff\">";
	}
	print "</td><td>\n";
	print "<form action=$url method=post>";
	print "<select name=PreviewNo onChange='submit();'>\n";
	$previewno=0;
	while($previewno*12<$gallerycount){
		local($begin,$end);
		$previewno++;
		$begin=($previewno-1)*12+1;
		$end=$previewno*12;
		$end=$gallerycount if $end>$gallerycount;
		$selected=$begin==$gbegin+1?" selected":"";
		print "<option value=$previewno$selected>Pictures $begin through $end\n";
	}
	print "</select></form>\n";
	print "</td><td>\n";
	if($previewnext){
		$url="$weblib::URL/preview=$previewnext";
		$url.="/set=$setid" if $setid;
		$url.="/newest" if $param{"newest"};
		print "<a href=$url$upload>";
		print "<img src=\"$nexton\" border=0></a>";
	}
	else{
		print "<img src=\"$nextoff\">";
	}
	print "</td></tr></table>\n";
}
################################################################
# Submit Form
################################################################
sub submitform{
	&setfeatures;
	if($VIEWER_FEATURE{MULTIPARTFORMS}){
		%caption=(),$savepicture="" unless $upload;
		$for=$savepicture?" for $savepicture ":"";
		$URL=$caption{URL}?$caption{URL}:"http://";
		($captionvalue=$caption{Caption})=~s/"/%22/g;
		print <<EOF;
<form enctype="multipart/form-data" ACTION=$weblib::URL/upload METHOD=POST>
Send this file: <input name=UserFile type=file>
<input type=submit value="Send my picture"><br>
or Send this URL: <input name=URL size=70 value="$URL"><br>
<input name=UserFileName value="$savepicture" type=hidden>
<table>
<caption>Additional Information$for (where applicable)</caption>
<tr><td>Short Caption</td>
<td><input name=Caption size=40 value="$captionvalue"></td></tr>
EOF
		foreach $key(Photographer,Artist,Date,Venue){
			($captionvalue=$caption{$key})=~s/"/%22/g;
			print "<tr><td>$key</td><td>",
				"<input name=$key size=30 value=\"$captionvalue\"></td></tr>\n";
		}
		$Email=$setid if $upload;
		$galleryID=$Email unless $galleryID;
		print <<EOF;
<tr><td>Your E-mail address</td>
<td><input name=Email size=30 value="$galleryID">
<input type=checkbox name=Cookie>Save in a cookie</td></tr>
<tr><td colspan=2>Including your E-mail address will allow you to submit
corrections, if necessary, and to view all your previous submissions.</tr></td>
<tr><td>Commentary</td>
<td><textarea name=Commentary
 wrap=soft cols=40 rows=5>$caption{Commentary}</textarea></td>
</tr>
</table>
</form>
EOF
	}
}
################################################################
# Upload
################################################################
sub upload{
local($size,$junk,$width,$height);
	&set_temp_gallery;
	$cgi_lib'maxdata=562144;
	&ReadParse(*in,*incfn,*inct);
	if($in{Cookie}){
		$cookiedate=&cookiedate(time+365*86400);
		$cookie="galleryID=$in{Email}; expires=$cookiedate";
		delete $in{Cookie};
	}
	if($in{URL} eq "http://"){delete $in{URL};}
	$filename=delete $incfn{"UserFile"};
	$filetype=delete $inct{"UserFile"};
	if($filetype eq "application/x-macbinary"){
		$filename=~s/%\d\d/_/g;
		delete $in{URL};
		chdir("$PAGEHOMEDIR/$gallerydir");
		open(FILE,">$filename");
		print FILE delete $in{UserFile};
		close FILE;
		($filetype)=$filename=~/\.([^.])$/;
		$filetype=~tr/A-Z/a-z/;
		$filetype="jpeg" if $filetype="jpg";
		$filetype="image/$filetype";
		print "system(\"$mcvert -UdS $filename\");<br>";
		system($mcvert,"-UdS",$filename);
		rename("$filename.data",$filename);
		chop($info=`$identify $filename`);
		($junk,$size)=split(/\s+/,$info);
		($width,$height)=split(/x/,$size);
	}
	elsif($filetype eq "image/gif" || $filetype eq "image/jpeg" ||
		$filetype eq "image/png"){
		chdir("$PAGEHOMEDIR/$gallerydir");
		$filename=~s/%\d\d/_/g;
		delete $in{URL};
		open(FILE,">$filename");
		print FILE delete $in{UserFile};
		close FILE;
		chop($info=`$identify $filename`);
		($junk,$size)=split(/\s+/,$info);
		($width,$height)=split(/x/,$size);
		$|=1;
		system($thumbnailbin,$filename,"$PAGEHOMEDIR/$thumbnaildir");
	}
	elsif($in{URL}){
		@URL=split(m#/#,$in{URL});
		$filename=$URL[$#URL];
		if($filename!~/\.gif$|\.jpg$|\.jpeg?$/){
			$filename="";
		}
	}
	elsif($in{UserFileName}){$filename=$in{UserFileName};}
	delete $in{UserFile};
	delete $in{UserFileName};
	if($filename){
		$param{"picture"}=$picture=$filename;
		$Email=delete $in{Email};
		@indexentry=();
		foreach $key(keys %in){
			$in{$key} =~ s/%(\d\d)/pack("c",hex($1))/ge;
			push(@indexentry,"$key: $in{$key}") if $in{$key};
		}
		dbmopen(%INDEX,"$PAGEHOMEDIR/$indexdb",0644);
		if(@indexentry){
			$size="";
			$size="Width=$width;Height=$height" if $width;
			$INDEX{$filename}=join("#",@indexentry);
			$INDEX{$filename}.="%%" if $size || $Email;
			$INDEX{$filename}.=$size;
			$INDEX{$filename}.=";" if $size && $Email;
			$INDEX{$filename}.="SetID=$Email" if $Email;
		}
		$upload="/upload";
		$SetID="/set=$Email" if $Email;
		$SetID="/set=anon\@$ENV{REMOTE_HOST}" unless $SetID;
		$ENV{PATH_INFO}="$upload$SetID/picture=$filename";
	}
}
################################################################
# Display Upload
################################################################
sub display_upload{
	$preface=<<EOF;
Any pictures listed below represent those you have recently submitted, but not
formally accepted for the Photo Gallery. You may update information for any
of them by selecting the link for that photo, and updating the submission
form.
<p>
EOF
	$galleryID=getcookie("galleryID");
	$param{set}=$galleryID if $param{"set"} == -1 || !$param{set};
	$ENV{PATH_INFO}.="/set=anon\@$ENV{REMOTE_HOST}" unless $param{"set"};
	&set_temp_gallery;
	dbmopen(%INDEX,"$PAGEHOMEDIR/$indexdb",0644);
	$upload="/upload";
}
################################################################
# Set Temp Gallery
################################################################
sub set_temp_gallery{
	$indexdb="temp/$INDEXDB";
	$indexdb.=".db" if $NEWDB;
	$galleryurldir="$GALLERYURLDIR/temp";
	$gallerydir="$WWWDIR/$galleryurldir";
	$thumbnaildir="$gallerydir/thumbnails";
}
################################################################
# Sort by Set
################################################################
sub byset {
	local($setida,$setidb)=($INDEX{"SetID%%$a"},$INDEX{"SetID%%$b"});
	local(@a,@b,$setaheader,$setbheader);
	local($cat)=
		"^Classmates%%|^Artists%%|^Personalities%%|^Photographers%%|^of |^by ";
	if($setida=~/$cat/o){
		@a=split(/%%|\s/,$setida);
		$setida=join(" ",$a[0],$a[$#a],@a[1..($#a-1)]);
	}
	if($setidb=~/$cat/o){
		@b=split(/%%|\s/,$setidb);
		$setidb=join(" ",$b[0],$b[$#b],@b[1..($#b-1)]);
	}
	"\L$setida" cmp "\L$setidb";
}
################################################################
# Enclose
################################################################
sub enclose{
	local($line)=shift;
	if(length($line) > 100){
		$line="<table width=$twidth><tr><td>\n$line</td></tr></table>\n";
	}
	else{$line="$line<br>\n";}
	return $line;
}
################################################################
# Open Web
################################################################
sub openweb{
	$refresh=$param{"slideshow"}?"refresh=10":"";
	if($STICKYSCALE && $in{Scale}){
		print "Set-Cookie: StickyScale=$in{Scale}\n";
	}
	if($refresh){
		print "Window-target: gallery\n";
		$script=<<EOF;
self.innerWidth=$slideshowmaxwidth+(2*$bordersize)+40
self.innerHeight=$slideshowmaxheight+(2*$bordersize)+60
EOF
		&htmlopen($PAGENAME,"",$refresh,"script=$script","style=$style");
	}
	else{
		$robots="nofollow";
		if($ENV{PATH_INFO}){$robots="noindex,nofollow";}
		if($cookie){&htmlopen("$PAGENAME|","cookie=$cookie","robots=$robots","style=$style");}
		else{&htmlopen("$PAGENAME|","robots=$robots","style=$style");}
	}
}
################################################################
# Vote
################################################################
sub vote{
	local($vote,$name,$question,$answer,@answers,$printanswer,$w,$h,$position);
	local($checked,@votepercent,@numvotes,$mastervote,@mastervote);
	local($nexturl,$prevurl,$prevpicture,$nextpicture,$prev,$next);
	local($db,$key)=split(/:/,$VOTE);
	$db.=".db" if $NEWDB;
	$key=$param{"ip"} if $param{"ip"} && $ADMIN;
	$vote=&initialize_vote;
	($name,@vote)=split(/:/,$vote);
	($question,@answers)=split(/;\s*/,$caption{Vote});
	delete $caption{Vote};
	$w=$parameters{Width};
	$h=$parameters{Height};
	if($w>300 || $w>$h){$position="width=100%";}
	else{$position="align=left";}
	print "<table bgcolor=white border=5 bordercolor=red $position><tr><td>\n";
	&print_vote_choices;
	if($VOTECLOSED){&postvote_navigation;}
	print "</td></tr></table>\n";
}
################################################################
# Initialize Vote
################################################################
sub initialize_vote{
	local($vkey,$vote,@vote,$master,$mastername,$name,$item);
	local($order,$prefix,$postfix,@master,$id);
	dbmopen(%VOTE,"$PAGEHOMEDIR/$db",0644);
	($prefix,$postfix,$master)=split(/:/,$VOTE{master},3);
	@master=split(/:/,$master);
	$master="";
	foreach $id(@master){
		$master.="$prefix$id$postfix:";
	}
	chop $master;
	@order=split(/:/,$master);
	$order=0;
	%order=map {$_,$order++} @order;
	%presentationorder=%order;
	@presentationorder=@order;
	if($RANDOMPREVIEW){
		srand($RANDOMPREVIEW);
		&shuffle(\@presentationorder);
		$order=0;
		%presentationorder=map{$_,$order++} @presentationorder;
	}
	$mastervote=$VOTE{$ANSWERKEY};
	($mastername,@mastervote)=split(/:/,$mastervote);
	if($REVEALANSWER){
		foreach $vkey(keys %VOTE){
			next if $vkey eq "master" || $ADMIN{$vkey};
			($name,@vote)=split(/:/,$VOTE{$vkey});
			$item=0;
			foreach $vote(@vote){
				if($vote){
					$votepercent[$vote-1][$item]++;
					$numvotes[$item]++;
				}
				$item++;
			}
		}
	}
	$vote=$VOTE{$key};
	$VOTECLOSED="" if $vote=~/::/ && !$REVEALANSWER;
	$VOTECLOSED="The voting period is closed" if $REVEALANSWER && !$VOTECLOSED;
	dbmclose(%VOTE);
	return $vote;
}
################################################################
# Print Vote Choices
################################################################
sub print_vote_choices{
	local($answer,$printanswer,$vote,$word);
	unless($VOTECLOSED){
		print "<form action=$VOTEURL method=POST>\n";
		print "<input type=hidden name=picture value=\"$picture\">\n";
		print "<hr><input type=submit value=\"Vote!\">\n";
	}
	print "Voter: $name\n" if $name;
	if($REVEALANSWER){
		print "<br>Correct answer in <font color=green>Green</font>.";
		print "<br>Your answer is <font color=red>Red</font> if not correct.";
	}
	elsif($VOTECLOSED){
		print $VOTECLOSED;
	}
	print "<hr>\n";
	foreach $word(keys %WORDSUBSTITUTION){
		$question=~s/ $word / <font color=$WORDSUBSTITUTION{$word}>$word<\/font> /;
	}
	print "<font size=+2><b>$question</b></font><br>\n";
	$vote=0;
	if($VOTECLOSED){
		print "<table border=0 cellpadding=0 cellspacing=0 width=100%>\n";
	}
	foreach $answer(@answers){
		$vote++;
		$printanswer=$answer;
		if($VOTECLOSED){
			print "<tr><td>";
			$printanswer="<font color=red>$answer</font>"
				if $vote[$order{$picture}] == $vote;
		}
		else{
			$checked=$vote[$order{$picture}] == $vote?" checked":"";
		}
		$printanswer="<font size=+2><b><font color=green>$answer</font></b></font>"
			if $REVEALANSWER && $mastervote[$order{$picture}] == $vote;
		print "<input type=radio name=vote value=$vote$checked>"
			unless $VOTECLOSED;
		print " $printanswer \n";
		printf "</td><td align=right>%d</td>".
				"<td align=right>&nbsp; %5.2f%%</td></tr>\n",
				$votepercent[$vote-1][$order{$picture}],
				$votepercent[$vote-1][$order{$picture}]*100/$numvotes[$order{$picture}]
			if $REVEALANSWER;
		print "<br>"if $w<$h && !$REVEALANSWER;
		print "\n" unless $REVEALANSWER;
	}
	if($VOTECLOSED){print "</table>\n";}
	print "</form>\n" unless $VOTECLOSED;
}
################################################################
# Postvote Navigation
################################################################
sub postvote_navigation{
	$prevpicture=$presentationorder[$presentationorder{$picture}-1];
	$nextpicture=$presentationorder[$presentationorder{$picture}+1];
	$prev=$presentationorder{$picture} == 0?$prevoff:$prevon;
	$prevurl="<img src=$prev border=0>";
	$next=$presentationorder{$picture} == @mastervote-1?$nextoff:$nexton;
	$nexturl="<img src=$next border=0>";
	$prevurl="<a href=$weblib::URL/picture=$prevpicture>$prevurl</a>"
		if $prev eq $prevon;
	$nexturl="<a href=$weblib::URL/picture=$nextpicture>$nexturl</a>"
		if $next eq $nexton;
	print "<table width=100%><tr><td>$prevurl</td>";
	print "<td align=right>$nexturl</td></tr></table>";
}
################################################################
# Shuffle
################################################################
sub shuffle{
	my $array=shift;
	my $i;
	for($i = @$array; --$i; ){
		my $j=int rand($i+1);
		next if $i == $j;
		@$array[$i,$j] = @$array[$j,$i];
	}
}
################################################################
# Prev Arrow
################################################################
sub prevarrow{
		local($newest)="/newest" if $param{"newest"};
		local($prevpicture,$prevurl,$prev);
		local($set)=$setid?"/set=$setid":"";
		$prevpicture=$presentationorder[$presentationorder{$picture}-1];
		$prev=$presentationorder{$picture} == 0?$prevoff:$prevon;
		$prevurl="<img src=$prev border=0 align=absmiddle>";
		$prevurl="<a href=$weblib::URL/picture=$prevpicture$set$upload$newest>$prevurl</a>"
			if $prev eq $prevon;
		return $prevurl;
}
################################################################
# Next Arrow
################################################################
sub nextarrow{
		local($newest)="/newest" if $param{"newest"};
		local($set)=$setid?"/set=$setid":"";
		$nextpicture=$presentationorder[$presentationorder{$picture}+1];
		$next=$presentationorder{$picture} == @gallerylist-1?$nextoff:$nexton;
		$nexturl="<img src=$next border=0 align=absmiddle>";
		$nexturl="<a href=$weblib::URL/picture=$nextpicture$set$upload$newest>$nexturl</a>"
			if $next eq $nexton;
		return $nexturl;
}
################################################################
# Initialize Defaults
################################################################
sub initialize_defaults{
# This routine serves to document and initialize configuration parameters
# Full or partial URLs for previous and next arrow icons
	$PREVOFF="";
	$PREVON="";
	$NEXTOFF="";
	$NEXTON="";
# Randomizizes the preview if set to a seed value. If 0, no randomn preview
	$RANDOMPREVIEW=0;
# GALLERYURLDIR is set to the partial URL to access gallery images
	$GALLERYURLDIR="";
# PAGEHOMEDIR is the directory which contains the gallery directory
	$PAGEHOMEDIR="";
# If UPLOAD is set, uploads will be enabled
	$UPLOAD=0;
# INDEXDB is set to the partial path within $PAGEHOMEDIR in which the gallery 
# index database is found
	$INDEXDB="";
# PREVIEWMESSAGE is set to an alternate text for the preview page
	$PREVIEWMESSAGE="";
# PREVIEWLOCK is set if the display is locked to a preview only
	$PREVIEWLOCK=0;
# PREVIEWNEWEST is set to offer display of preview in "newest first" order
	$PREVIEWNEWEST=0;
# ALLOWUNINDEXED is set if all pictures in the gallery directory are to be
#  displayed, even if they are not found in the index
	$ALLOWUNINDEXED=0;
# THUMBNAILDIR is set to the subdirectory within the "WWWDIR" in which
# thumbnails are stored
	$THUMBNAILDIR="";
# THUMBNAILBORDERSIZE is set to the width of the border around thumbnail images
	$THUMBNAILBORDERSIZE=0;
# HTMLPATH is set to partial path to HTML directory
	$HTMLPATH="";
# SUPPRESSPICTURENAME is set when the picture name is to be suppressed
	$SUPPRESPICTURENAME=0;
# SUPPRESSONLYONPREVIEW is set when the picture name is suppressed, but not on picture display
	$SUPPRESSONLYONPREVIEW=0;
# PAGENAME set to a string naming the page/gallery
	$PAGENAME="";
# BORDERSIZE set to the width of the table border surrounding pictures
	$BORDERSIZE=20;
# TABLECOLOR set to color name of hex string for outer table
	$TABLECOLOR="";
# INNERTABLECOLOR set to color name of hex string for inner table
	$INNERTABLECOLOR="";
# VOTE is set to a structure indicating type of voting and vote tally db
	$VOTE="";
# NAVIGATION is set if additional navigation arrows are added
	$NAVIGATION=1;
# STICKYSCALE is set if the selected scale to the be kept for all images
	$STICKYSCALE=1;
# PRIVATE is set if viewers are not invited to submit images
	$PRIVATE=0;
# REVEALANSWER is set when a Vote is to be revealed
	$REVEALANSWER=0;
# ADMIN hash contains the IP addresses of administrators' machines as keys,
# with 1 as value
	%ADMIN={};
# VOTECLOSED is set to a closed message no more votes are to be accepted
	$VOTECLOSED="";
# PRINTFULLSETLIST overrides default to not print set list
	$PRINTFULLSETLIST=0;
}
sub timer{
	@times=times;
	print "Time: $times[0]; Delta: ",$times[0]-$oldtime,"<br>\n" if $dotimer;
	$oldtime=$times[0];
}
