#!/usr/bin/perl -w
# $Header: /home/cb/lib/cvs/df7cb.de/lib/Bilder.pm,v 1.8 2004/02/27 12:16:02 cb Exp $
# cb 000716
# cb 030318 Einbettung in .shtml, generisches Layout
# cb 030511 Kommentare wieder eingebaut
# cb 031122 Switched to $PATH_INFO for parameters

package Bilder;

use strict;
use lib '/home/cb/lib/perl';
use cb::html;
#use cb::template;
use Template;
#use db;
use Bilder::Pic;

# global variables
my $template_config = {
	INCLUDE_PATH => '/home/cb/public_html/bilder.template',
};
my $template = Template->new($template_config);


sub parse_options
{
	my $args = {};
	$args->{path} = $ENV{PATH_INFO} || "";
	$args->{path} = "/" if $args->{path} =~ m!^//!; # Apache 1 insanity

	if($ENV{REDIRECT_URL}) { # mod_rewrite mode
		$args->{jpg_url} = $ENV{REDIRECT_URL}; # root URL = REDIRECT_URL minus PATH_INFO
		my $p = $args->{path};
		$args->{jpg_url} =~ s/$p[^\/]*$//;
		$args->{jpg_dir} = $ENV{DOCUMENT_ROOT}.$args->{jpg_url};
		$args->{template_dir} = "$args->{jpg_dir}.template";
	} else { # separate bilder.jpg dir
		$args->{jpg_dir}="$ENV{SCRIPT_FILENAME}.jpg";
		$args->{jpg_url} = "$ENV{SCRIPT_NAME}.jpg";
		$args->{template_dir} = "$ENV{SCRIPT_FILENAME}.template";
	}
	# debug
	#print_contenttype();
	#print "jpg_dir=$jpg_dir<p>\n";
	#print "jpg_url=$jpg_url<p>\n";
	#print "PWD=".`/bin/pwd`."<p>\n";
	#printenv();
	#exit(0);
	# /debug

	$args->{options} = "";
	if($ENV{"QUERY_STRING"}) {
		my ($dir, $pic) = ("", ""); # old-style options
		foreach(split(/\&/, $ENV{"QUERY_STRING"})) {
			$args->{size} = $1 if /^size=(\d+)/;
			$dir = $1 if /^dir=([\wäöüßÄÖÜ\%_-]+)/;
			$pic = $1 if /^pic=([\dabc-]+)/;
		}
		if($dir) { # redirect from old-style URL (mod_rewrite mode)
			print "Status: 301 Moved\nLocation: http://$ENV{HTTP_HOST}$args->{jpg_url}/$dir/$pic\n\n";
			exit 0;
		}
		$args->{options} = $args->{size} ? "?size=$args->{size}" : "";
	}
	#$args->{admin} = 1 if $ENV{REDIRECT_ADMIN_USER} or $ENV{REMOTE_USER} || "" eq "cb";

	$args->{path} =~ s/\.(html|admin|comment)$//;

	if($args->{path} eq "") {
		# add trailing / if missing
	#	print "Status: 301 Moved\nLocation: http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}/$options\n\n";
		die "PATH_INFO is empty, fix your RewriteRules!";
		exit 0;
	} elsif($args->{path} eq "/") {
		# default
	} elsif($args->{path} =~ m!^/([^/]+$)!) {
	#	print "Status: 301 Moved\nLocation: http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}$path/$options\n\n";
		die "trailing / is missing, fix your RewriteRules!";
		exit 0;
	} elsif($args->{path} =~ m!^/(.+)/($)!) {
		$args->{dir} = decode_special($1);
	} elsif($args->{path} =~ m!^/(.+)/([^/]*$)!) {
		($args->{dir}, $args->{pic}) = (decode_special($1), decode_special($2));
		$args->{specpic} = encode_special($args->{pic});
	} else {
		print "Content-Type: text/html\nStatus: 404 Not found\n\n";
		exit 0;
	}

	if($args->{dir}) {
		$args->{specdir} = encode_special($args->{dir});
		my $d = $args->{dir};
		$d =~ s!.*/!!;
		($args->{dirdate}, $args->{dirtitle}) = splitname($d);
		$args->{date} = yymmdd2txt($args->{dirdate});
	}

	$args->{page_suffix} = ".html";
	if($args->{admin}) {
		$args->{page_suffix} = ".admin";
	}

	$args->{mode} = "bilder"; # TODO

	return $args;
}

sub handler
{
	my $args = parse_options;

	die "no dir: $args->{jpg_dir}" unless -d $args->{jpg_dir};

	#my $imgsize_bin = "/home/cb/public_html/lib/imgsize";
	#die "no executable: $imgsize_bin" unless -x $imgsize_bin;

	#my ($dir, $pic, $mode, $size, $options, $admin) = ("", "", "bilder", 0, "", 0);

	#printenv();

	#$script_url =~ s/(bilder|index).shtml//; # auto-index

	#############################################################################
	unless(defined $args->{dir}) {
		bilder_root($args) unless $args->{dir};
		return;
	}
	unless(defined $args->{pic}) {
		bilder_index($args) unless $args->{pic};
		return;
	}
	bilder_show($args);
	return;
}

sub bilder_root
{
	my $args = shift;
	print_contenttype();
	die "kein dir angegeben" if $args->{mode} eq "kommentar";

	#template_file($args->{admin} && "$args->{template_dir}/admin-root.html", "$args->{template_dir}/bilder-root.html");
	chdir $args->{jpg_dir} or die "$args->{jpg_dir}: $!";

	my $vars = {
		TITLE => "Bilder",
	};

	my ($oy, $om, $od);
	foreach(sort sort_by_date glob "$args->{jpg_dir}/*") {
		next unless -d $_;
		s!.*/!!;
		my ($date, $t) = splitname($_);
		my ($y, $m, $d) = yymmdd2ymd($date);
		push @{$vars->{FILES}}, {
			NAME => $_,
			LINK => encode_special($_) . "/" . $args->{options},
			DATE => yymmdd2txt($date),
			YEAR => $y,
			MONTH => $m,
			DAY => $d,
			OLDYEAR => $oy,
			OLDMONTH => $om,
			OLDDAY => $od,
			TITLE => $t
		};
		($oy, $om, $od) = ($y, $m, $d);
	}

	$template->process("bilder-root.html", $vars);
	#template_sub "__COMMENTLIST__", "get_recent_comments" if $use_comments;

} # if($dir eq "")


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

#$script_url = "./" if $mode eq "kommentar"; # auf Normalansicht verlinken

sub bilder_index
{
	my $args = shift;

	print_contenttype();

	#template_file $args->{admin} && "$args->{template_dir}/admin-index.html", "$args->{template_dir}/$args->{mode}-index.html";

	my $vars = {};
	#$vars->{FILES} = [];
	foreach(sort sort_by_date glob "$args->{jpg_dir}/$args->{dir}/*") {
		my $isdir = -d $_;
		s!.*/!!;
		next if /^index/;
		my ($d, $t) = splitname($_);
		my $n = $_;
		s/\.jpg$//i;
		unshift @{$vars->{FILES}}, {
			NAME => $n,
			SPECNAME => encode_special($n),
			LINK => encode_special($_) . ($isdir ? "/" : $args->{page_suffix}) . $args->{options},
			ISDIR => $isdir,
			YYDATE => $d,
			DATE => yymmdd2txt($d),
			TITLE => $t
		};
	}

	# Vorgänger/Nachfolger raussuchen, Namen finden
	chdir $args->{jpg_dir} or die "$args->{jpg_dir}: $!";
	my ($prevdir, $nextdir) = getprevnextname($args->{dir});
	if($prevdir) {
		my ($prevdate, $prevtitle) = splitname($prevdir);
		$vars->{PREVDIR}{LINK} = encode_special("../$prevdir/") . $args->{options};
		$vars->{PREVDIR}{TITLE} = $prevtitle;
		$vars->{PREVDIR}{DATE} = yymmdd2txt($prevdate);
	}
	if($nextdir) {
		my ($nextdate, $nexttitle) = splitname($nextdir);
		$vars->{NEXTDIR}{LINK} = encode_special("../$nextdir/") . $args->{options};
		$vars->{NEXTDIR}{TITLE} = $nexttitle;
		$vars->{NEXTDIR}{DATE} = yymmdd2txt($nextdate);
	}

	chdir "$args->{jpg_dir}/$args->{dir}" or die "$args->{jpg_dir}/$args->{dir}: $!";

	$vars->{UPDIR}{LINK} = "../$args->{options}";
	$vars->{UPDIR}{TITLE} = "parent directory";

	$vars->{DIRTITLE} = $args->{dirtitle};
	$vars->{DIR} = $args->{dir};
	$vars->{SPECDIR} = $args->{specdir};
	$vars->{DIRDATE} = $args->{date};
	$vars->{MAP} = index_map($args);
	#template_sub "__INFO__", \&index_info; TODO

	#s/__COMMENTS__/$comments/g;
	#template_sub "__COMMENTLIST__", "get_recent_comments" if $use_comments;

	#template_output;
	$template->process("$args->{mode}-index.html", $vars);

	exit(0);
}

sub index_map {
	my $args = shift;
	return "" unless -f "index-map.html";
	local $_;

	my $return;
	open M, "index-map.html" or die "index-map.html: $!";
	while(<M>) {
		# <img src="index.jpg">, $reload für admin.cgi
		s/src="([^"]+)"/src="$args->{jpg_url}\/$args->{specdir}\/$1"/; #$reload"/;
		# <area shape= coords= href="21-Arndt.jpg" alt="21-Arndt.jpg">
		if(/href="([^"]+)"/) {
			my $pic = $1;
			$pic =~ s/\.jpg$//i;
			my ($nr, $title) = splitname($pic);
			s/href="[^"]+"/href="$pic$args->{page_suffix}$args->{options}"/;
			s/alt="[^"]+"/alt="$title"/;
			s/title="[^"]+"/title="$title"/;
		}
		$return .= $_;
	}
	close M;

	return $return;
}

sub index_info {
	return unless -f "info.html";

	open M, "info.html";
	while(my $l = <M>) {
		print $l;
	}
	close M;

	return "";
}


#############################################################################
# Bild ausgeben

sub bilder_show
{
	my $args = shift;
	($args->{nr}, $args->{title}) = splitname($args->{pic});

	#template_file $args->{admin} && "$args->{template_dir}/admin-show.html", "$args->{template_dir}/$args->{mode}-show.html";
	chdir "$args->{jpg_dir}/$args->{dir}" or die "$args->{jpg_dir}/$args->{dir}: $!";

	$args->{pic_suffix} = ".jpg" if -f "$args->{pic}.jpg";
	$args->{pic_suffix} = ".JPG" if -f "$args->{pic}.JPG";

	unless($args->{pic_suffix}) {
		my @files = glob "$args->{pic}.*";
		if(@files == 1) {
			$args->{pic} = $files[0];
			$args->{pic_suffix} = $1 if $args->{pic} =~ s/(\.\w+)$//;
			warn "using glob $args->{pic}*";
		}
		die "more than one picture found $args->{pic}*" if @files > 1;
	}
	unless($args->{pic_suffix}) {
		my @files = glob "$args->{nr}*";
		if(@files == 0) {
			die "$args->{dir}/$args->{pic}* was not found.";
		}
		die "more than one picture with number $args->{nr}" if @files > 1;

		my $newtitle = encode_special($files[0]);
		$newtitle =~ s/\.jpg$//i or die "s///";
		warn "redirecting to $newtitle";
		sleep 1; # sleep to prevent redirect loop DoS

		print "Status: 302 Renamed\nLocation: http://$ENV{HTTP_HOST}$args->{jpg_url}/$args->{specdir}/$newtitle$args->{page_suffix}$args->{options}\n\n";
		exit 0;
	}

	#$comments = "";
	#$comments = return_comments($dir, $pic) if $use_comments;

	#$script_url = "./" if $mode eq "kommentar"; # auf Normalansicht verlinken

	print_contenttype();

	my $vars = {};
	$vars->{DIR}{NAME} = $args->{dir};
	$vars->{DIR}{DATE} = $args->{date};
	$vars->{DIR}{TITLE} = $args->{dirtitle};
	$vars->{DIR}{LINK} = "./$args->{options}";

	# ?reload=123 durchreichen
	#s#__PICTURE__#$specdir/$spec_fname$reload#g;

	$vars->{PIC} = Bilder::Pic::new($args);

	# Vorgänger/Nachfolger raussuchen, Namen finden
	my ($prev, $next) = getprevnextname($args->{pic});
	my ($prevnr, $prevtitle) = $prev ? splitname($prev) : ("", "");
	my ($nextnr, $nexttitle) = $next ? splitname($next) : ("", "");
	if($prev) {
		$vars->{PREVPIC}{LINK} = encode_special($prev) . $args->{page_suffix} . $args->{options};
		$vars->{PREVPIC}{TITLE} = $prevtitle;
	}
	$vars->{THISLINK} = $args->{specpic} . $args->{page_suffix};
	if($next) {
		$vars->{NEXTPIC}{LINK} = encode_special($next) . $args->{page_suffix} . $args->{options};
		$vars->{NEXTPIC}{TITLE} = $nexttitle;
	}

	$vars->{COMMENTS} = "";

	$template->process("$args->{mode}-show.html", $vars);

	exit(0);
}

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


sub sort_by_date {
	my ($aa, $bb) = ($a, $b);
	$aa = ($aa =~ /^[5-9]/ ? "19" : "20") . "$aa";
	$bb = ($bb =~ /^[5-9]/ ? "19" : "20") . "$bb";
	return $bb cmp $aa;	# r&uuml;ckw&auml;rts sortieren
}


sub splitname {
	my $b = shift;
	$b =~ s/\.jpg$//i;		# .jpg abschneiden
	$b =~ s/_/ /g;		# Leerzeichen für die Ausgabe
	return ($b, $b) if $b =~ /^[\dabc-]+$/;	# Bild-Nr vom Text trennen
	return ($1, $2) if $b =~ /([\dabc-]+)-(.*)/;	# Bild-Nr vom Text trennen
	return ($b, $b);
# Bild-Nummer ist der erste Teil bis zum letzten '-', das nur Zahlen oder
# ein a/b/c vornedran hat (letzteres für Sebastians Bilder)
}


sub getprevnextname {
	my $nr = shift;
	my @files = sort glob "*";
	my ($prev0, $prev, $found) = ("", "", "");

	foreach my $file (@files) {
		next if $file eq "template";
		next if $file =~ /^index/;
		$file =~ s/\.jpg$//i;
		return($prev, $file) if $found;
		$prev = $prev0;
		$prev0 = $file;
		$found = $file if($file =~ /^$nr/);
	}
	return($prev, "") if $found =~ /^$nr/;
	return("", "");
}

1;
