#!/usr/bin/perl -w # -*- cperl -*-

# Makesite v1.5 (january 2004)
# MakeSite v1.4 (october 2003)
# par :
#  Julien « Éole » Avarre (julien@croot.net)
#  Guillaume « Guitou »THIBAUX (guitou@guitou.com)

# CE LOGICIEL EST DISTRIBUÉ SELON LES TERMES DE LA LICENCE PUBLIQUE GÉNÉRALE (GPL)
# <http://www.gnu.org/licenses/gpl.txt>

# TODO -=> `-' ; + -=> DONE.

# + Utiliser un CSS par défaut ;
# + ne pas mettre de lien vers un toto.avi.html suivant inéxistant
# + ne plus faire ces 3 boucles pour convert ;
# + ne plus faire des system de convert, mais passer par la lib ImagaMagick ;
# + rotater les images en fonction de EXIF ;
# + faire un « retour au répertoire précédant » optionel;
# + spécifier un fichier CSS en option ;
# + inclure un fichier CSS en option et le copier vers le rép. cible ;
# + ne plus se servir de la commande date(1) mais d'une classe interne Perl ;
# + implémenter Getopt::Long pour les options ;
# + utilisation des POD pour la documentation
# + gérer les balises LINK
# + gérer les balises LINK prefetch
# + remplacer la commande basename par du Perl
# - faire pointer le next de la dernière image sur un HTML de AVI ? ;
# - monter un CVS sur savanah ;
# - faire en sorte que si les gens n'ont pas jhead, le script continue son execution ;
# - passer le script en anglais ;
# - faire un script d'installation (Makefile.PL) ;
# - faire des images pour suivant, précédant ;
# - trouver un moyen moins porc que mplayer pour les vidéos (MJPEGTools) ;
# - trouver un meilleur moyen que `jhead' pour récupérer EXIF v2.2 ;
# - se servir des champs EXIF pour classer les photos par date;
# - si un répertoire web existe déjà, ne pas écraser, mais récupérer toutes les images
#    (anciennes + nouvelle), classer le tout. ;
# - passer à un système de template pour la v2, stockés dans /usr/local/share/makesite ;
# - générer un page HTML pour les vidéos avec plusieures frames de la vidéo.
# - faire un mode `force' qui ecrase le répertoire de sortie www ;

use strict;
use Image::Magick;
use Getopt::Long;
use Pod::Usage;
use Date::Manip;
use File::Basename;

# support des accents windows
my %accent_print = ("\x82" => "é",
                    "\x83" => "â",
                    "\x85" => "à",
                    "\x87" => "ç",
                    "\x88" => "ê",
                    "\x8a" => "è",
                    "\x8c" => "î");

my %accent_url   = ("\x82" => "%82",
                    "\x83" => "%83",
                    "\x85" => "%85",
                    "\x87" => "%87",
                    "\x88" => "%88",
                    "\x8a" => "%8a",
                    "\x8c" => "%8c");


#
# quelques parametres du script
#

$0  =~ qr|.*/(.*)(\.pl)?$| ;
my $me = $1;
my $version = "1.5";
my $date = UnixDate (ParseDateString("today"), "%C");
my $average_size = "800";
my $bg_color = "white";
my $css_file = "makesite.css";
my $current_dir = $ENV{PWD};
my $email = 'eole@croot.net';
my $parent_dir = 1;
my $photos_dir;
my $prev_url = "..";
my $result;
my $menu_width = "50";
my $thumb_size = "120";
my $verbose;
my $man;
my $force;
my $help;
my $web_dir;
my $url_help = "http://eole.megarezo.org/about";
my $url_home = $url_help;
my $favicon = "/about/camera.png";
my %jpeg_files;
my $mode = 0755;
my $jhead_bin = "/usr/bin/jhead";
my $copyright = "http://artlibre.org/licence.php/lal.html";
my @orig_files;
my $flag_named;
my $title;
my $first_pic;
my $last_pic;
my $want_html = 1;
my $want_picz = 1;
my $want_exif = 1;
my $total_img = 0;
my $total_mvi = 0;
my $total =0;

&make_options;
&make_checks;
&make_data;

if ($want_picz) {
    &make_picz;
} else {
    print "[!] Asked not to generate pictures.\n"
}

if ($want_html) {
    &make_welcome;
    &make_html_image;
    &make_menu;
    &make_index;
} else {
    print "[!] Asked not to generate HTML Files.\n"
}

&make_css;
&make_mod;
print "[/] done! (Thank you for using Makesite [contact/suggestions: eole\@croot.net)\n";

#
# Gestion des options
#
sub make_options {
    my $html_only;
    my $picz_only;

    if ($#ARGV == 1) {
	# check no dash
	$photos_dir = $ARGV[0];
	$web_dir = $ARGV[1];
    } else {
	$result = GetOptions ("average_size=i" => \$average_size,
			      "background-color|bg_color=s" => \$bg_color,
			      "copyright=s"  => \$copyright,
			      "css-file=s" => \$css_file,
			      "current-dir=s" => \$current_dir,
			      "email=s" => \$email,
			      "favicon-url=s" => \$favicon,
			      "force|f" => \$force,
			      "help" => \$help,
			      "help-url=s" => \$url_help,
			      "html-only" => \$html_only,
			      "picz-only" => \$picz_only,
			      "input-dir|i=s" => \$photos_dir,
			      "jhead-bin=s"  => \$jhead_bin,
			      "man"  => \$man,
			      "menu-width=i" => \$menu_width,
			      "mode|=i" => \$mode,
			      "output-dir|o=s" => \$web_dir,
			      "parent-url!" => \$parent_dir,
			      "prev-url=s" => \$prev_url,
			      "thumbnail-size=i" => \$thumb_size,
			      "verbose!" => \$verbose,
			      "version|v" => sub { version_msg() }
			     ) or pod2usage(0);
	if ($picz_only) {
	    $want_html = 0;
	}
	if ($html_only) {
	    $want_picz = 0;
	}
    }
    pod2usage(-exitstatus => 0, -verbose => 2) if $man;
    pod2usage(-msg => "$me version $version", -exitstatus => 0, -verbose => 1) if $help;
}

sub version_msg {
    pod2usage(-msg =>  "$me version $version (january 2004)\nBy Guitou (guitou\@guitou.com) and Eole (eole\@croot.net)\n",  -exitval => 0, -verbose => 1);
}


sub make_checks {
    #
    # test si le rep de photos source est accessible
    #

    if (not defined $photos_dir) {
	print "TATA";
	pod2usage ("$me: photos\' directory not defined.")
    }

    if (not defined $web_dir) {
	print "TOTO";
	pod2usage ("$me: web gallery\'s directory not defined.")
    }


    if (-x $photos_dir) {
	print "[+] \"$photos_dir\" accessible\n";
    } else {
	print "[-] \"$photos_dir\" unavailable!\n";
	exit 1;
    }

    #
    # creation du repertoire destination
    #
    if (mkdir $web_dir) {
	print "[+] \"$web_dir\" created.\n";
    } else {
	if ($force) {
	    print "[!] \"$web_dir\" already exists, but overwriting forced !\n";
	} else {
	    print "[-] \"$web_dir\" already exists!\n";
	    exit 1;
	}
    }
}

sub make_data {
    #
    # analyse du repertoire source
    #

    opendir (DIRH, $photos_dir) or die "Can't opendir $photos_dir : $!\n";
    @orig_files = grep { /^[^\.]+\.(avi|jpe?g)$/i && -f "$photos_dir/$_" } readdir(DIRH);
    @orig_files = sort @orig_files;
    closedir DIRH;

    #
    # Récupération des informations EXIF avec jhead
    #
    unless (-e $jhead_bin) {
	print STDERR "You need jhead for running Makesite (http://www.sentex.net/~mwandel/jhead)\n";
	exit 1;
    }

    foreach my $file (@orig_files) {
	$total++;		# count the files processed, ugly way, I know!
	if (isjpeg($file)) {
	    $total_img++;
	    open EXIF, "$jhead_bin $photos_dir/$file | " or die "Error jhead: $!";
	    my %data;
	    foreach my $line (<EXIF>) {
		#       print $line;
		chomp $line;
		if ($line) {

		    my @data = split /: /, $line, 2;
		    $data[0] =~ s/\s+$//;
		    $data{ $data[0] } = $data[1];
		}
		$jpeg_files{$file} = \%data;
	    }
	    close EXIF;
	}
    }

    #
    # test pour savoir si les photos sont nomméees
    #
    $flag_named = 0;
    foreach my $filename (@orig_files) {
	if ($filename =~ /^IMG_\d+[ _](.+)\.jpe?g$/i) {
	    $flag_named = 1;
	} else {
	    $flag_named = 0;
	    last;
	}
    }
    if ($flag_named) {
	print "[+] photos are named and the menu width sizes ", $menu_width + $thumb_size ," pixels\n"
    } else {
	print "[/] photos are unnamed and the menu width sizes ", $menu_width + $thumb_size ," pixels\n"
    }
    # Display the total images processed
    if ($total_img == 1 or  $total_img == 0) {
	print "[/] $total_img image and "
    } else {
	print "[/] $total_img images and "
    }
    # Display the total movies processed
    $total_mvi = $total - $total_img;
    if ($total_mvi == 1 or $total_mvi == 0) {
	print "$total_mvi video will be treated.\n"
    } else {
	print "$total_mvi videos will be treated.\n"
    }


}



#	Images Generation !
#
#  Copy, rotation, recompression to jpg format
#  max, average (800x600), thumb
#  For videos : thumb génération from first mplayer's frame [damn ugly]
#
sub make_picz {
    foreach my $filename (@orig_files) {
	if (isjpeg($filename)) {
	    my $test_ret = undef;
	    my $image = new Image::Magick->new;

	    $image->Read("$photos_dir/$filename");
	    print "[+] Processing $filename :";

	    if (defined ${ jpeg_files{$filename} }{Orientation}) {
		my $rotate =  ${ jpeg_files{$filename} }{Orientation};
		$rotate =~ /(\d+)/;
		my $angle = $1;
		chomp $rotate;
		$image->Rotate(degrees              => $angle);
		print " rotate $angle degs,";
	    }

	    $test_ret = $image->Write(filename      => "$web_dir/max_$filename",);

	    if ($test_ret) {
		print "ERROR $test_ret: max_$filename\n"; exit 1
	    } else {
		print " max";
	    }

	    $image->Resize (geometry                => $average_size . "x" . $average_size);
	    $test_ret = $image->Write(filename      => "$web_dir/average_$filename",);

	    if ($test_ret) {
		print "ERROR $test_ret: average_$filename\n"; exit 1
	    } else {
		print ", average";
	    }

	    $image->Resize (geometry                => $thumb_size . "x" . $thumb_size);
	    $test_ret = $image->Write(filename      => "$web_dir/thumb_$filename",);

	    if ($test_ret) {
		print "ERROR $test_ret: thumbs\n"; exit 1;
	    } else {
		print ", thumbnail generated.\n";
	    }
	}
	# `convert $rotation -quality 90 "$photos_dir/$filename" "$web_dir/max_$filename"`;
	# `convert -quality 80 -resize "$average_size x $average_size" "$web_dir/max_$filename" "$web_dir/average_$filename"`;
	# `convert -quality 75 -resize  "$thumb_size x $thumb_size" "$web_dir/average_$filename" "$web_dir/thumb_$filename"`;
	#

	# M-x Porcass-mode :-(
	elsif (isavi($filename)) {
	    (my $base_filename = $filename) =~ s/.avi$//i;
	    use File::Copy qw/mv cp/;
	    print "[copying] $photos_dir/$filename > $web_dir/$filename\n";
	    cp "$photos_dir/$filename", "$web_dir/$filename";
	    chdir $web_dir;
	    `mplayer -frames 1 -vo png $filename -ao null > /dev/null`;
	    chdir "$current_dir";
	    system "convert -resize $thumb_size" . "x" . "$thumb_size $web_dir/00000001.png $web_dir/thumb_$base_filename.jpg";
	    `rm $web_dir/00000001.png`;
	    `rm $web_dir/00000002.png`;
	    print "[+] file \"$web_dir/thumb_$filename\" created.\n";
	    $total_mvi++;
	}
    }
}

#
#  welcome.html file generation
#
sub make_welcome {
    $title = basename($photos_dir);
    chomp $title;

    foreach my $key (keys %accent_print) {
	$title =~ s/$key/$accent_print{$key}/g;
    }

    unless ($orig_files[0]) {
	print STDERR "$me: Input dir is empty.";
	exit 1;
    }

    ($first_pic = $orig_files[0])  =~ s/(.*).jpe?g/$1.html/;
    ($last_pic  = $orig_files[ $#orig_files ])=~ s/(.*).jpe?g/$1.html/;

    my $disp_total;

    # no video
    if (!$total_mvi) {
	if ($total_img == 1) {
	    $disp_total = "Il y a une image dans cette galerie."
	} elsif (!$total_img) {
	    $disp_total = "Il y a aucune image dans cette galerie."
	} else {
	    $disp_total = "Il y a $total_img images dans cette galerie."
	}
	#only one video
    } elsif ($total_mvi == 1) {
	if ($total_img == 1) {
	    $disp_total = "Il y a une image et une vidéo dans cette galerie"
	} elsif (!$total_img) {
	    $disp_total = "Il n'y a ni image, ni vidéo dans cette galerie. Ça ne sert pas à grand chose ..."
	} else {
	    $disp_total = "Il y a $total_img images et une vidéo dans cette galerie."
	}
	# more than one video
    } else {
	if ($total_img == 1) {
	    $disp_total = "Il y a une image et $total_mvi vidéos dans cette galerie"
	} elsif (!$total_img) {
	    $disp_total = "Il y a aucune image et $total_mvi vidéos dans cette galerie."
	} else {
	    $disp_total = "Il y a $total_img images et $total_mvi vidéos dans cette galerie."
	}
    }



    my $welcome_html_code = <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//FR">
<!-- WELCOME PAGE-->
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Photos : $title</title>

    <link rel="StyleSheet" href="$css_file" type="text/css" media="screen" title="Makesite's default">
    <link rel="alternate StyleSheet" href="$url_help/black-makesite.css" type="text/css" media="screen" title="Black Makesite">
    <link rel="alternate StyleSheet" href="$url_help/default.css" type="text/css" media="screen" title="Blue Power !">
    <link rel="alternate StyleSheet" href="$url_help/green.css" type="text/css" media="screen" title="Da BOo !">

    <link rel="top" href="$prev_url">
    <link rel="up" href="index.html">
    <link rel="contents" href="index.html">
    <link rel="home" href="$url_home">
    <link rel="next" href="$first_pic">
    <link rel="prev" href="$last_pic">
    <link rel="first" href="$first_pic">
    <link rel="last" href="$last_pic">
    <link rel="prefetch" href="$orig_files[0]">
    <link rel="prefetch" href="$orig_files[-1]">
    <link rel="author" href="mailto:$email">
    <link rel="copyright" href="$copyright">
    <link rel="help" href="$url_help">
    <link rel="icon" href="$favicon">
  </head>

  <body bgcolor="$bg_color">
    <div  id="main">
EOF
      ;

    if ($parent_dir) {
	print "[!] Using \`$prev_url\' as previous URL.\n";
	$welcome_html_code .= <<EOF
      <h1 class="main">
        <a href="$prev_url" target="_top" title="Répertoire précedent">$title</a>
      </h1>\n
EOF
	  ;
    } else {
	print "[!] Not Using any previous URL.\n";
	$welcome_html_code .= "      <h1>$title</h1>\n";
    }

    $welcome_html_code .= <<EOF
    <ul id="navbar">
      <li><a href="welcome.html" target="_top" title="Sans le  menu à gauche">Version non fenêtrée</a></li>
      <li><a href="index.html" target="_top" title="Avec le menu à gauche">Version Fenêtrée</a></li>
      <li><a href=".." target="_top" title="back to parent dir">Retour au menu général</a></li>
      <li><a href="http://eole.megarezo.org/about" target="_top" title="Infos">À propos de ces photos </a></li>
    </ul>
      <p class="title">
        $disp_total<br /><br />
       	Série Générée le $date
       	grâce à <a href="$url_home/makesite.html" title="Makesite's home page">$me</a> version $version.<br />
       	Développé par
       	<a href="mailto:eole\@croot.net?Subject='[Makesite roulaize !]" title="contact Eole">
       	  eole\@croot.net
       	</a> (2003-2004) sur une idée de
       	<a href="mailto:guitou\@guitou.com?Subject='[Makesite roulaize !]" title="contact Guitou">
       	  guitou\@guitou.com
       	</a> (2003)
        <br /><br />
      </p>
EOF
      ;
    if ($parent_dir) {
	$welcome_html_code .= <<EOF
    <div align="center">
	<a href="$first_pic" title="première image">Début</a> |
      <a href="$prev_url" target="_top" title="back to parent dir">Retour au menu général</a> |
	<a href="$last_pic" title="denière image">Fin</a>
    </div>
EOF
	  ;

    } else {
	$welcome_html_code .= "    <div align=\"center\">\n  <a href=\"$url_home\" title=\"infos\">À propos des photos</a>\n</div>\n"
    }


    $welcome_html_code .= <<EOF
    <br />
    <div align="center" class="copyright">
      Ce site web est compatible avec les standards en vigueur. <br/>Ici,
      <a href="http://validator.w3.org/check?uri=referer" target="_top" title="Site HTML valide">HTML</a> et
      <a href="http://jigsaw.w3.org/css-validator/" target="_top" title="Feuille de style CSS valide"/>CSS</a> sont conformes avec les normes du
      <a href="http://w3c.org/" target="_top" title="Word Wide Web Consortium">W3C</a>.
    </div>
    </div>
  </body>
</html>
EOF
      ;

    open FH, ">$web_dir/welcome.html" or die "Can't open : $!\n";
    print FH $welcome_html_code;
    close FH or die "Can't close: $!\n";
    print "[+] file \"$web_dir/welcome.html\" created.\n";
}


#
# generation du fichier index.html
#
sub make_index {
    my $frame_left_width = $thumb_size + $menu_width;
    my $index_html_code = <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
  <head>
    <title>photos : $title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="generator" content="$me v$version by Guitou and Éole">
    <meta name="author" content="Julien Avarre">
    <meta name="description" content="Eole's picture">

    <link rel="StyleSheet" href="$css_file" type="text/css" media="screen">
    <link rel="alternate StyleSheet" href="$url_help/black-makesite.css" type="text/css" media="screen" title="Black Makesite">
    <link rel="alternate StyleSheet" href="$url_help/default.css" type="text/css" media="screen" title="Blue Power !">
    <link rel="alternate StyleSheet" href="$url_help/green.css" type="text/css" media="screen" title="Da BOo !">

    <link rel="first" href="$first_pic">
    <link rel="last" href="$last_pic">
    <link rel="author" href="mailto:$email">
    <link rel="contents" href="index.html">
    <link rel="copyright" href="$copyright">
    <link rel="icon" href="$favicon">
    <link rel="home" href="$url_home">
  </head>
  <frameset cols="$frame_left_width,*">
    <frame src="menu.html" name="left" frameborder="0">
    <frame src="welcome.html" name="right" frameborder="0">
    <noframes>
       <h1><a href="welcome.html" title="Welcome page">welcome</a></h1>
    </noframes>
  </frameset>
</html>
EOF
      ;

    open FH, ">$web_dir/index.html" or die "Can't open : $!\n";
    print FH $index_html_code;
    close FH;
    print "[+] file \"$web_dir/index.html\" created.\n";
}

#
# generation du fichier menu.html
#
sub make_menu {
    my $table_left_width = $thumb_size + 10;
    my $menu_html_code_head = <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//FR">
<!-- MENU FRAME by $me -->
<html>
  <head>
    <title>Photos : $title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="generator" content="$me by Éole">

    <link rel="StyleSheet" href="$css_file" type="text/css" media="screen">
    <link rel="alternate StyleSheet" href="$url_home/black-makesite.css" type="text/css" media="screen" title="Black Makesite">
    <link rel="alternate StyleSheet" href="$url_home/blue-makesite.css" type="text/css" media="screen" title="Blue Power !">
    <link rel="alternate StyleSheet" href="$url_home/green-makesite.css" type="text/css" media="screen" title="Da BOo !">

    <link rel="home" href="$url_home">
    <link rel="contents" href="index.html">
    <link rel="first" href="$first_pic">
    <link rel="last" href="$last_pic">
    <link rel="author" href="mailto:$email">
    <link rel="copyright" href="$copyright">
    <link rel="icon" href="$favicon">
  </head>
  <body bgcolor="$bg_color" text="#000000" link="#000000" vlink="#000000">
    <div class="menu">
    <table cellspacing="4" border="0" width="$table_left_width"  class="menu">
EOF
      ;

    my $menu_html_code_tail = <<EOF
    </table>
    </div>
  </body>
</html>
EOF
      ;

    open (FH, ">$web_dir/menu.html") or die "Can't open : $!\n";
    print FH $menu_html_code_head;
    foreach my $filename (@orig_files) {
	if (isjpeg($filename)) {
	    (my $base_filename = $filename) =~ s/.jpe?g$//i;
	    my $base_filename_clean = $base_filename;
	    $base_filename_clean =~ s/^IMG_[0-9]+[ _]// if $flag_named;
	    $base_filename_clean =~ s/_/ /g;
	    foreach my $key (keys %accent_print) {
		$base_filename_clean =~ s/$key/$accent_print{$key}/g;
	    }
	    my $filename_url = $filename;
	    foreach my $key (keys %accent_url) {
		$filename_url =~ s/$key/$accent_url{$key}/g;
	    }
	    my $base_filename_url = $base_filename;
	    foreach my $key (keys %accent_url) {
		$base_filename_url =~ s/$key/$accent_url{$key}/g;
	    }
	    print FH <<EOT
      <tr>
        <td class="menu">
          <a href="$base_filename_url.html" target="right" title="Display $base_filename_clean">
            <img src="thumb_$filename_url" alt="Shows $base_filename_clean" /></a>
          <br />$base_filename_clean
        </td>
      </tr>
EOT
	      ;
	}
	if (isavi($filename)) {
	    (my $base_filename = $filename) =~ s/.avi$//i;
	    my $base_filename_clean = $base_filename;
	    $base_filename_clean =~ s/^MVI_\d+[ _]// if $flag_named;
	    $base_filename_clean =~ s/_/ /g;
	    foreach my $key (keys %accent_print) {
		$base_filename_clean =~ s/$key/$accent_print{$key}/g;
	    }
	    my $filename_url = $filename;
	    foreach my $key (keys %accent_url) {
		$filename_url =~ s/$key/$accent_url{$key}/g;
	    }
	    my $base_filename_url = $base_filename;
	    foreach my $key (keys %accent_url) {
		$base_filename_url =~ s/$key/$accent_url{$key}/g;
	    }
	    print FH<<EOT
      <tr>
        <td>
          <a href="$filename" target="right" title="Select this movie">
            <img src="thumb_$base_filename.jpg" alt="download video" />
          </a><br />
          $base_filename_clean<br />
        </td>
      </tr>
EOT
	      ;
	}
    }


    print FH $menu_html_code_tail;
    close FH or die "Can't close:$!";
    print "[+] file \"$web_dir/menu.html\" created.\n";
}


#
# Generate the appropriate HTML file for one picture
# Displays
#  - galerie's name
#  - links
#  - average picture
#  - EXIF headers descriptions
#

sub make_html_image {
    my $base_filename_left;
    my $base_filename_right;
    my $left_file;
    my $right_file;
    my $left_file_text;
    my $right_file_text;


    my $jpg_html_code_head = <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//FR">
<!-- PHOTO FRAME -->
<html>
  <head>
    <title>Photos : $title </title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="generator" content="$me by Guitou and Éole">
    <meta name="author" content="Julien Avarre">

    <link rel="StyleSheet" href="$css_file" type="text/css" media="screen">
    <link rel="alternate StyleSheet" href="$url_help/black-makesite.css" type="text/css" media="screen" title="Black Makesite">
    <link rel="alternate StyleSheet" href="$url_help/default.css" type="text/css" media="screen" title="Blue Power !">
    <link rel="alternate StyleSheet" href="$url_help/green.css" type="text/css" media="screen" title="Da BOo !">

    <link rel="home" href="$url_home">
    <link rel="up" href="index.html">
    <link rel="contents" href="index.html">
    <link rel="help" href="$url_help">
    <link rel="first" href="$first_pic">
    <link rel="last" href="$last_pic">
    <link rel="author" href="mailto:$email">
    <link rel="copyright" href="$copyright">
    <link rel="icon" href="$favicon">
EOF
      ;


    my $main_table = <<EOT
  <table border="0" cellspacing="4">
    <tr>
EOT
      ;


    my $jpg_html_code_tail = <<EOT
      <div class="copyright">
        Cette image est sous <a href="$copyright" title="license libre">Copyright</a>. 2003 2004 par Julien « Éole » Avarre.<br />
        Ce site web est compatible avec les standards en vigueur. <br/>Son
        <a href="http://validator.w3.org/check?uri=referer" target="_top" title="Site HTML valide">HTML</a> et son
        <a href="http://jigsaw.w3.org/css-validator/" target="_top" title="Feuille de style CSS valide"/>CSS</a> sont conformes avec les normes du
        <a href="http://w3c.org/" target="_top" title="Word Wide Web Consortium">W3C</a>.
      </div>
    </div>
  </body>
</html>
EOT
      ;


    my $left_file_nil = <<EOT
      <td width="60" valign="top" align="right">
      </td>
EOT
      ;


    my $right_file_nil = <<EOT
      <td width="60" valign="top" align="left">
      </td>
EOT
      ;


    for (my $i = 0; defined $orig_files[$i] ; $i++) {

	if (isjpeg($orig_files[$i])) {
	    (my $base_filename = $orig_files[$i]) =~ s/.jpe?g$//i;
	    my $base_filename_clean = $base_filename;
	    $base_filename_clean =~ s/^IMG_\d+[ _]// if $flag_named;
	    $base_filename_clean =~ s/_/ /g;

	    foreach my $key (keys %accent_print) {
		$base_filename_clean =~ s/$key/$accent_print{$key}/g;
	    }
	    open(FH, ">$web_dir/$base_filename.html") or die "Can't open : $!\n";

	    print FH $jpg_html_code_head;
	    print FH "    <link rel=\"up\" href=\"index.html\">\n";
	    print FH "    <link rel=\"top\" href=\"$prev_url\">\n" if ($parent_dir);

	    if ($i > 0 && defined($orig_files[$i-1])) {
		($base_filename_left = $orig_files[$i-1]) =~ s/\.jpe?g$//i;
		foreach my $key (keys %accent_url) {
		    $base_filename_left =~ s/$key/$accent_url{$key}/g;
		}

		print FH "    <link rel=\"prev\" href=\"$base_filename_left.html\">\n";
		print FH "    <link rel=\"prefetch\" href=\"", $orig_files[$i-1], "\">\n";
		$left_file_text =  <<EOT
      <td width="60" valign="top" align="right">
        <h1><a href="$base_filename_left.html" target="right" title="Previous picture">&lt</a></h1>
      </td>
EOT
		  ;

	    } else {
		print FH "    <link rel=\"prev\" href=\"welcome.html\">\n";
		$left_file_text = $left_file_nil;
	    }


	    if (defined $orig_files[$i+1] &&  $orig_files[$i+1] !~ /\.avi$/i) {
		($base_filename_right = $orig_files[$i+1]) =~ s/\.jpe?g$//i;
		# Avec les nouveaux header HTML 4.0, je pense que c'est obsolète.
		#foreach my $key (keys %accent_url) {
		# $base_filename_right =~ s/$key/$accent_url{$key}/g;
		# }

		print FH "    <link rel=\"next\" href=\"$base_filename_right.html\">\n";
		print FH "    <link rel=\"prefetch\" href=\"", $orig_files[$i+1], "\">\n";
		$right_file_text = <<EOT
      <td width="60" valign="top" align="left">
        <h1><a href="$base_filename_right.html" target="right" title="Next picture">&gt</a></h1>
      </td>
EOT
		  ;

	    } else {
		print FH "<link rel=\"next\" href=\"welcome.html\">\n";
		$right_file_text = $right_file_nil
	    }

	    print FH <<EOT
      </head>
    <body bgcolor="$bg_color" text="#000000" link="#000000" vlink="#000000">
      <div align="center" class="main">
EOT
	      ;

	    if ($parent_dir) {
		print FH "  <h2><a href=\"$prev_url\" target=\"_top\" title=\"Retour\">$base_filename_clean</a></h2>\n"
	    } else {
		print FH "  <h2>$base_filename_clean</h2>\n"
	    }

	    print FH $main_table;
	    print FH $left_file_text;

	    my $filename_url = $orig_files[$i];
	    foreach my $key (keys %accent_url) {
		$filename_url =~ s/$key/$accent_url{$key}/g;
	    }

	    print FH <<EOT
      <td width="$average_size" align="center">
        <a href="max_$filename_url" target="right" title="Cliquez sur la photo pour la voir dans sa taille originelle.">
          <img class="average" src="average_$filename_url" alt="average_$filename_url" /></a>
      </td>
EOT
	      ;

	    print FH $right_file_text;

	    print FH <<EOT
        </tr>
      </table>
      <table border="0" align="left" class="info">
	<tr>
	    <th>Informations</th>
        </tr>
EOT
	      ;

	    #
	    # EXIF Data
	    #
	    my $filename = $orig_files[$i];

	    if (isjpeg($filename)) {
		foreach my $file ( $jpeg_files{$filename}) {
		    foreach my $data (keys %{ $file }) {
			if ($data and ${ $file }{$data}) {
			    print FH <<EOT
        <tr>
          <td>$data</td>
          <td>${ $file }{$data}</td>
        </tr>
EOT
			}
		    }
		}
	    }

	    print FH "      </table>\n";

	    print FH $jpg_html_code_tail;
	    close(FH);
	    if ($parent_dir) {
		print "[+] file \"$web_dir/$base_filename.html\" created. [with parent dir]\n";
	    } else {
		print "[+] file \"$web_dir/$base_filename.html\" created.\n";
	    }
	}
    }
}


#
# Little usefull functions
#
sub isjpeg {
    my $file = shift;

    if ($file =~ /\.jpe?g$/i) {
        return 1;
    } else {
        return 0;
    }
}

sub isavi {
    my $file = shift;

    if ($file =~ /\.avi$/i) {
        return 1;
    } else {
        return 0;
    }
}

#
# Generate default's CSS
#
sub make_css {
    if ($css_file eq "makesite.css") {
	open  CSS, ">$web_dir/$css_file" or die "Error: $!";
	print CSS foreach (<DATA>);
	close CSS or die "Error: $!";
	print "[+] default cascading style sheet \`$css_file\' created\n";
    } else {
	print "[!] no default cascading style sheet created, use $css_file instead\n";
    }
}

#
# Setting rights if $mode given
#
sub make_mod {
    print "[/] setting proper file rights.\n";
    opendir (CHMOD, $web_dir) or die "[-] Can't opendir $web_dir : $!\n";
    my @files = grep { /(.*)/ && -f "$web_dir/$_"   } readdir(CHMOD);

    chmod $mode, $web_dir;
    foreach (@files) {
	s#(.*)#$web_dir/$1#;
	chmod $mode, $_ or die "[-] Proper file rights failled : $!\n";
    }
    closedir CHMOD;
}

=head1 NAME

Makesite - A Static Pictures Gallery Generator

=head1 SYNOPSYS

makesite [photos_directory] [web_directory]

makesite -i photo_dir -o web_dir --css-file mine.css --average-size=640

makesite -input-dir photo_dir --output-dir=www --noparentdir

=head1 OPTIONS

=over 8

=item B<--verbose>

Having information of current progression

=item B<--noverbose>

Disable infomation output.

=item B<--input-dir, -i>

Specify the pictures input directory.

=item B<--output-dir, -o>

Specify where the HTML gallery will be generated.

=item B<--email>

User's email written on main page (not implemented yet).

=item B<--prev-url [URL]>

Specify the URL where the actual generated page has to come back. `..' is given by default.

=item B<--parent-url>

Allows the use of a parent URL. Activated by default

=item B<--noparent-url>

Disable the parent URL.

=item B<--thumbnail-size [size]>

Specify a width size for the thumbnails. 120 pixels is the default value.

=item B<--average_size [size]>

Give a width for the averaged images. 800 is the default. That makes 800x600 pictures.

=item B<--css-file [file]>

Change the name of the CSS file used. By default a makesite.css is generated and used.

=item B<--background-color>

Change the background color, `white' is the default color.

=item B<--menu-width>

This the amount of pixel added to the thumbnails width that make the width of the menu frame.
By default it is 50 pixels. So the menu frame is 170 pixels long.

=item B<--force, -f>

Overwrite file and the output directory.

=item B<--mode>

Give octal right for generated files and the output dir. For more explanations see chmod(1).

=item B<--favicon-url>

Enter an favicon URL. [ by default : http://eole.megarezo.org/camera.png ]

=item B<--help-url>

Enter an favicon URL. [ default values : http://eole.megarezo.org/about ]
Get jhead at http://www.sentex.net/~mwandel/jhead

=item B<--jhead-bin>

Specify Jhead binary absolute path [ default = /usr/bin/jhead ].

=item B<--html-only>

Don't generate pictures, only HTML and CSS files.

=item B<--picz-only>

Don't generate HTML and CSS, only pictures and movies.

=back

=head1 DESCRIPTION

This program generates a static HTML pictures gallery .
It makes two frames, but you can navigate without frames if you prefer :

=over 2

=item *
The left one, called menu with the thumbnails in column ;

=item *
on the right panle, there's an average sized picture and it's meta-informations.

=back

Some nice makesite features :

=over 2

=item *
Videos are also thumbnailled (requires mplayer being installed).

=item *
EXIF fields are parsed and written (requires jhead).

=item *
Pictures are automaticly rotated if the camera handle the orientation (requires jhead and ImageMagick).

=item *
Use of <link rel="prefetch"> which allows pictures preloaded.

=item *
Use of other <link> tag for the standard navigation support.

=item *
Nice use of Cascading Style Sheets, an alternate CSS file support.

=item *
W3C HTML Transitional standard compliant. <http://validator.w3.org>
CSS2 compliant <http://jigsaw.w3.org/css-validator>.

=back

Needed softwares :

=over 2

=item *
ImageMagick - http://imagemagick.org

=item *
jhead - http://www.sentex.net/~mwandel/jhead

=item *
mplayer - http://mplayerhq.hu

=back

=head1 AUTHORS

This program is made  by Julien "Éole" Avarre <eole@croot.net>,
based on Guillaume Thibaux's  idea and primary code.

=head1 REPORTING BUGS

Please send  suggestions, ideas, comments and report bugs to <eole@croot.net>.

=head1 COPYRIGHT

Copyright © 2003 Free Software Foundation, Inc.  This is free
software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE see for more explanation : <http://www.gnu.org/licenses/gpl.txt>

=cut

#
# default CSS file :
#

__DATA__
/*
** makesite.css for makesite in
**
** Made by Julien « Éole » Avarre
** contact at <eole@croot.net>
*/

body {
  background-attachment: fixed;
  text-align:           left;
  background-color:	white;
}

#menu
{

}


h1
{
  color:                black;
}

h1.main
{
  color:                black;
  text-align:		left;
  margin-left:		2em;
}

h2
{
  color:                black
}

smaller.version
{
  color:                #EE5C42; /* tomato2; */
  font-weight:          bold
  }

a:link
{
  color:                black;
  text-decoration:      none
  }

a:visited
{
  color:                darkgray;
  text-decoration:      none
  }

a:hover
{
  color:                #3A5FCD; /* royalblue3; */
  text-decoration:      underline
}

a:active {
  color: red;
  background-color: #FDF6CB
}

b
{
  color:                #CD5555; /* IndianRed3; */
}

tt
{
  border-style:         dotted;
  border-color:         gray;
  background:           white;
  padding-left:         0.5cm;
  padding-right:        0.5cm ;
  padding-top:          0.1cm;
  padding-bottom:       0.1cm;
/*   font-family:          courier */
  }

pre
{
  border-style:         dotted;
  border-color:         gray;
  background:           white;
/*  margin-left:         1cm; */
  margin-right:         10%;
  padding-left:         1cm;
  padding-top:          1cm;
  padding-bottom:       1cm;
/*   font-family:          courier */
  }
p
{
  color:		gray;
  font-style:		italic;
  margin-top:		1em;
  margin-left:		2em;
}

table.menu
{
  text-align:           center;
}

table.info
{
  margin-left:          30%;
  color:                gray;
  padding-bottom:       0.2cm;
}

td.info
{
  color:                gray
}

td.menu
{
  text-align:           center;
  padding-bottom:       0.2cm;
}

div.copyright
{
  margin-top:     	5em;
  padding-top:    	.5em;
  font-size:      	xx-small;
  max-width:      	85ex;
  text-align:     	center;
  text-transform: 	uppercase;
  margin-left:    	auto;
  margin-right:   	auto;
  font-family:    	monospace;
  color:          	#888;
  line-height:    	120%;
}

div.copyright a {
  color:		#88f;
  text-decoration:	none;
}

div.copyright a:hover {
  color:		#88f;
  text-decoration:	none;
  background-color:	#eee;
}

#navbar  {
/*  min-width: 63em; */
  list-style-type: none;
  padding: 0;
  margin: 0;
  height: 1.5em;
  background-color: #eee;
  border-top: solid 1px black;
  border-bottom: solid 1px black;
}

#navbar li {
  display: inline;
  padding: 0;
  margin: 0;
}

#navbar li a:link, #navbar li a:visited {
  text-decoration: none;
  text-align: center;
  float: left;
  display: block;
  width: 15em;
  padding: 3px 0px;
  margin: 0;
  background-color: #eee;
  color: #053188;
  font-size: smaller;
  /* font-variant: small-caps; */
  border-right: solid 1px #bbb;
  border-bottom: solid 1px #ddd;
}

#navbar li a#selected:link, #navbar li a#selected:visited {
  text-decoration: underline;
  background-color: #fff;
  color: #053188;
}

#navbar li a:hover {
  text-decoration: underline;
  background-color: #fff;
  color: #053188;
}

#navbar li a:active {
  background-color: #fff;
  color: #053188;
  border-right: solid 1px #ddd;
}
