#! perl

# Copyright (C) 2010 by Dirk Krause
# All rights reserved.
# 
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
# 
# * Redistributions of source code must retain the above
#   copyright notice, this list of conditions and the
#   following disclaimer.
# * Redistributions in binary form must reproduce the above 
#   opyright notice, this list of conditions and the following
#   disclaimer in the documentation and/or other materials
#   provided with the distribution.
# * Neither the name of the Dirk Krause nor the names of
#   contributors may be used to endorse or promote
#   products derived from this software without specific
#   prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.

my $controlfile = undef;
my $outputfile = undef;
my $texfile = undef;
my $beamertheme = undef;
my $background = "black";
my $presentationmaker = 0;
my $title = "";
my $author = "Holiday photographer";
my $makemode = 1;
my $inputenc = "latin1";
my $babelopt = undef;
my $useexif = 0;

my @filenames;
my $nfilenames = 0;


sub modification_time($) {
  my $filename = shift;
  my $back = undef;
  my $i1; my $i2; my $i3; my $i4; my $i5;
  my $i6; my $i7; my $i8; my $i9; my $ia;
  my $ib; my $ic; my $id;
  if(($i1,$i2,$i3,$i4,$i5,$i6,$i7,$i8,$i9,$ia,$ib,$ic,$id)=stat("$filename"))
  {
    $back = $i9;
  }
  return $back;
}

sub must_rebuild($$) {
  my $srcname = shift;
  my $dstname = shift;
  my $back = 1;
  my $srctime;
  my $dsttime;
  if($makemode) {
    $dsttime = modification_time($dstname);
    if(defined($dsttime)) {
      $srctime = modification_time($srcname);
      if(defined($srctime)) {
        if($dsttime > $srctime) {
	  $back = 0;
	}
      }
    }
  }
  return $back;
}



sub read_control_file() {
  my $back = 0;		# Function result
  my $line;		# Input line
  my $state = 0;	# 0=files, 1=options
  my $lineno = 0;	# Current line number
  my $mmtext;		# Text contents of makemode
  if(open(INPUT, "<$controlfile")) {
    $back = 1;
    while(<INPUT>) {
      $line = $_; chomp $line; $lineno++;
      if($line !~ /^\s*\#/o) {
        if($line =~ /^\s*\[/o) {
	  if($line =~ /^\s*\[\s*options\s*\]\s*/o) {
	    $state = 1;
	  } else {
	    if($line =~ /^\s*\[\s*files\s*\]\s*/o) {
	      $state = 0;
	    } else {
	      $back = 0;
	      print "$controlfile:$lineno: ERROR: Unknown section title \"$line\"\n";
	    }
	  }
	} else {
	  if($state == 0) {
	    if($line =~ /^\s*(\S.*\S)\s*=\s*(\S.*\S)\s*/o) {
	      $filenames[$nfilenames++] = "$1" . "=" . "$2";
	    } else {
	      if($line =~ /^\s*(\S.*\S)\s*/o) {
	        $filenames[$nfilenames++] = "$1";
	      }
	    }
	  } else {
	    if($state == 1) {
	      if($line =~ /^\s*presentation\s+maker\s*=\s*(\S.*\S)\s*/o) {
	        $line = $1;
		if($line eq "plain") {
		  $presentationmaker = 0;
		} else {
		  if($line eq "pdftk") {
		    $presentationmaker = 1;
		  } else {
		    if($line eq "beamer") {
		      $presentationmaker = 2;
		    } else {
		      print "$controlfile:$lineno: ERROR: Unknown presentation maker \"$line\"!\n";
		      print "Must be \"plain\", \"beamer\" or \"pdftk\"!\n";
		      $back = 0;
		    }
		  }
		}
	      } else {
	        if($line =~ /^\s*theme\s*=\s*(\S.*\S)\s*/o) {
		  $beamertheme = $1;
		} else {
		  if($line =~ /^\s*background\s*=\s*(\S.*\S)\s*/o) {
		    $background = $1;
		  } else {
	 	    if($line =~ /^\s*title\s*=\s*(\S.*\S)\s*/o) {
		      $title = $1;
		    } else {
		      if($line =~ /^\s*author\s*=\s*(\S.*\S)\s*/o) {
		        $author = $1;
		      } else {
		        if($line =~ /^\s*make\s+mode\s*=\s*(\S.*\S)\s*/o) {
			  $makemode = $1;
			  if($makemode !~ /^\d+$/o) {
			    $mmtext = $makemode; $makemode = 0;
			    if("$mmtext" eq "yes") { $makemode = 1; }
			    if("$mmtext" eq "on") { $makemode = 1; }
			    if("$mmtext" eq "true") { $makemode = 1; }
			    if("$mmtext" eq "enable") { $makemode = 1; }
			    if("$mmtext" eq "enabled") { $makemode = 1; }
			  }
			} else {
			  if($line =~ /^\s*input\s+encoding\s*=\s*(\S.*\S)\s*/o) {
			    $inputenc = $1;
			  } else {
			    if($line =~ /^\s*babel\s+options\s*=\s*(\S.*\S)\s*/o) {
			      $babelopt = $1;
			    } else {
			      if($line =~ /^\s*use\s+exif\s*=\s*(\S.*\S)\s*/o) {
			        $mmtext = $1;
			        if("$mmtext" eq "yes") { $useexif = 1; }
			        if("$mmtext" eq "on") { $useexif = 1; }
			        if("$mmtext" eq "true") { $useexif = 1; }
			        if("$mmtext" eq "enable") { $useexif = 1; }
			        if("$mmtext" eq "enabled") { $useexif = 1; }
			      } else {


		    if($line !~ /^\s*$/o) {
		      print "$controlfile:$lineno: ERROR: Syntax error!\n";
		      $back = 0;
		    }


		              }
			    }
			  }
			}
		      }
		    }
		  }
		}
	      }
	    }
	  }
	}
      }
    }
    close(INPUT);
  } else {
    print "$controlfile:1: ERROR: Can not open this file!\n";
  }
  if($back) {
    if($nfilenames == 0) {
      $back = 0;
      print "$controlfile:$lineno: ERROR: No files specified!\n";
    }
  }
  return $back;
}



sub run_plain() {
  my $back = 0;
  my $cmd;
  my $res;
  my $i;
  my $filename;
  my $pdfname;
  if(open(OUTPUT, ">$texfile")) {
    $back = 1;
    print OUTPUT "\\documentclass{scrartcl}\n";
    print OUTPUT "\\setcounter{secnumdepth}{0}\n";
    print OUTPUT "\\usepackage[$inputenc]{inputenc}\n";
    print OUTPUT "\\usepackage[T1]{fontenc}\n";
    print OUTPUT "\\usepackage{textcomp}\n";
    print OUTPUT "\\usepackage{mathptmx}\n";
    print OUTPUT "\\usepackage[scaled=.92]{helvet}\n";
    print OUTPUT "\\usepackage{courier}\n";
    print OUTPUT "\\renewcommand*{\\sectfont}{\\bfseries}\n";
    print OUTPUT "\\usepackage{graphicx}\n";
    print OUTPUT "\\usepackage{color}\n";
    print OUTPUT "\\usepackage[\n";
    print OUTPUT "  pdftex,\n";
    print OUTPUT "  colorlinks=true,\n";
    print OUTPUT "  pdfpagelayout=SinglePage,\n";
    print OUTPUT "  pdftitle={$title},\n";
    print OUTPUT "  pdfsubject={$title},\n";
    print OUTPUT "  pdfstartview={FitBH},\n";
    print OUTPUT "  pdfpagemode={FullScreen}\n";
    print OUTPUT "]{hyperref}\n";
    print OUTPUT "\\pagecolor{black}\n";
    print OUTPUT "\\setlength{\\paperwidth}{5.2075in}\n";
    print OUTPUT "\\setlength{\\paperheight}{3.75in}\n";
    print OUTPUT "\\setlength{\\pdfpagewidth}{\\paperwidth}\n";
    print OUTPUT "\\setlength{\\pdfpageheight}{\\paperheight}\n";
    print OUTPUT "\\setlength{\\textwidth}{\\paperwidth}\n";
    print OUTPUT "\\setlength{\\textheight}{\\paperheight}\n";
    print OUTPUT "\\setlength{\\voffset}{-1in}\n";
    print OUTPUT "\\setlength{\\topmargin}{0mm}\n";
    print OUTPUT "\\setlength{\\headheight}{0mm}\n";
    print OUTPUT "\\setlength{\\headsep}{0mm}\n";
    print OUTPUT "\\setlength{\\topskip}{0mm}\n";
    print OUTPUT "\\setlength{\\hoffset}{-1in}\n";
    print OUTPUT "\\setlength{\\oddsidemargin}{0mm}\n";
    print OUTPUT "\\setlength{\\evensidemargin}{0mm}\n";
    print OUTPUT "\\setlength{\\marginparwidth}{0mm}\n";
    print OUTPUT "\\setlength{\\marginparsep}{0mm}\n";
    print OUTPUT "\\setlength{\\parskip}{0mm}\n";
    print OUTPUT "\\setlength{\\parindent}{0.0cm}\n";
    print OUTPUT "\\pagestyle{empty}\n";
    print OUTPUT "\\begin{document}\n";
    for($i = 0; $i < $nfilenames; $i++) {
      $filename = $filenames[$i];
      if($filename =~ /(.*)=.*/o) {
        $filename = $1;
      }
      if($filename =~ /(.*)\.[^\.\/]+/o) {
        $pdfname = $1 . ".pdf";
      } else {
        $pdfname = $filename . ".pdf";
      }
      print OUTPUT "\\resizebox{!}{0.98\\textheight}{\\includegraphics{$pdfname}}\\clearpage\n";
      if(must_rebuild($filename,$pdfname)) {
        $cmd = "bmeps -lpdf \"$filename\" \"$pdfname\"";
	print "Execute command >>$cmd<<\n";
	$res = system("$cmd");
	if($res != 0) {
	  $back = 0;
	  print "ERROR: Command >>$cmd<< failed!\n";
	}
      }
    }
    print OUTPUT "\\end{document}\n";
    close(OUTPUT);
    if($back) {
      if($texfile =~ /(.*)\.[Tt][Ee][Xx]/o) {
        $texfile = $1;
      }
      $cmd = "pdflatex \"$texfile\"";
      print "Execute command >>$cmd<<\n";
      $res = system("$cmd");
      if($res == 0) {
        $cmd = "pdflatex -interaction=batchmode \"$texfile\"";
	system("$cmd");
	system("$cmd");
      } else {
        print "ERROR: Command >>$cmd<< failed!\n";
      }
    }
  } else {
    print "ERROR: Failed to write pdfLaTeX source \"$texfile\"!\n";
  }
}



sub run_pdftk() {
  my $i;		# Current index
  my $filename;		# Current input file name
  my $pdfname;		# Name of PDF file
  my $cmd;		# Bmeps command
  my $pdftkcmd;		# Command for pdftk
  my $ok = 1;		# Can continue
  my $res;		# Command result
  $pdftkcmd = "pdftk";
  for($i = 0; $i < $nfilenames; $i++) {
    $filename = $filenames[$i];
    if($filename =~ /(.*)=.*/o) {
      $filename = $1;
    }
    if($filename =~ /(.*)\.[^\.\/]+/o) {
      $pdfname = $1 . ".pdf";
    } else {
      $pdfname = $filename . ".pdf";
    }
    $cmd = "bmeps -lpdf \"$filename\" \"$pdfname\"";
    $res = 0;
    if(must_rebuild($filename,$pdfname)) {
      print "Execute command >>$cmd<<\n";
      $res = system("$cmd");
      if($res != 0) {
        $ok = 0;
        print "ERROR: Command >>$cmd<< failed!\n";
      }
    }
    $pdftkcmd = "$pdftkcmd \"$pdfname\"";
  }
  if($ok) {
    $pdftkcmd = "$pdftkcmd cat output \"$outputfile\"";
    print "Execute command >>$pdftkcmd<<\n";
    $res = system("$pdftkcmd");
    if($res != 0) {
      print "ERROR: Command >>$pdftkcmd<< failed!\n";
    }
  }
}


sub run_beamer() {
  my $back = 0;
  my $i;
  my $filename;
  my $pdfname;
  my $comment;
  my $lte = undef;
  if($useexif) {
    use Image::ExifTool;
    use DKrause::LaTeXEncoder;
    $lte = DKrause::LaTeXEncoder::new("${prefix}/share/uc2lat-t");
  }
  if(open(OUTPUT,">$texfile")) {
    $back = 1;
    print OUTPUT "\\documentclass{beamer}\n";
    print OUTPUT "\\mode<presentation>{\\usetheme{$beamertheme}\\setbeamercovered{transparent}}\n";
    if(defined($babelopt)) {
      print OUTPUT "\\usepackage[$babelopt]{babel}\n";
    }
    print OUTPUT "\\usepackage[$inputenc]{inputenc}\n";
    print OUTPUT "\\usepackage[T1]{fontenc}\n";
    print OUTPUT "\\usepackage{ifpdf}\n";
    print OUTPUT "\\usepackage{graphicx}\n";
    print OUTPUT "\\usepackage{color}\n";
    print OUTPUT "\\hypersetup{pdfpagemode=FullScreen}\n";
    print OUTPUT "\\title{$title}\n";
    print OUTPUT "\\author{$author}\n";
    print OUTPUT "\\subject{$title}\n";
    print OUTPUT "\\beamertemplateshadingbackground{$background}{$background}\n";
    print OUTPUT "\\begin{document}\n";
    for($i = 0; $i < $nfilenames; $i++) {
      $filename = $filenames[$i];
      $comment = undef;
      if($filename =~ /(.*)=(.*)/o) {
        $filename = $1; $comment = $2;
      } else {
	if($useexif) {
          my $exiftool = new Image::ExifTool;
	  my $info = $exiftool->ImageInfo($filename);
	  if(exists($info->{'Comment'})) {
	    $comment = $info->{'Comment'};
	    $comment =~ s/\000//g;
	    $comment = $lte->convert($comment);
	  }
	}
      }
      if($filename =~ /(.*)\.[^\.\/]+/o) {
        $pdfname = $1 . ".pdf";
      } else {
        $pdfname = $filename . ".pdf";
      }
      if(must_rebuild($filename,$pdfname)) {
        $cmd = "bmeps -lpdf \"$filename\" \"$pdfname\"";
	print "Execute command >>$cmd<<\n";
	$res = system("$cmd");
	if($res != 0) {
	  $back = 0;
	  print "ERROR: Command >>$cmd<< failed!\n";
	}
      }
      print OUTPUT "\\begin{frame}\n";
      print OUTPUT "\\frametitle{";
      if(defined($comment)) {
        print OUTPUT "$comment";
      } else {
        print OUTPUT "Photo " . ($i + 1);
      }
      print OUTPUT "}";
      print OUTPUT "\\includegraphics[height=0.8\\textheight]{$pdfname}";
      print OUTPUT "\\end{frame}\n";
    }
    print OUTPUT "\\end{document}\n";
    close(OUTPUT);
    if($back) {
      if($texfile =~ /(.*)\.[Tt][Ee][Xx]/o) {
        $texfile = $1;
      }
      $cmd = "pdflatex \"$texfile\"";
      print "Execute command >>$cmd<<\n";
      $res = system("$cmd");
      if($res == 0) {
        $cmd = "pdflatex -interaction=batchmode \"$texfile\"";
	system("$cmd");
	system("$cmd");
      } else {
        print "ERROR: Command >>$cmd<< failed!\n";
      }
    }
  } else {
    print "ERROR: Failed to write LaTeX source \"$texfile\"!\n";
  }
}



if(exists($ENV{"LANG"})) {
  my $lang = $ENV{"LANG"};
  if($lang =~ /.*\.[Uu][Tt][Ff]\-8/o) {
    $inputenc = "utf8";
  }
}


if($#ARGV > -1) {
  $controlfile = shift @ARGV;
  if($controlfile =~ /(.*)\.[^\.\/]+/o) {
    $outputfile = $1;
    $texfile = $outputfile . ".tex";
    $outputfile = $outputfile . ".pdf";
  } else {
    $texfile = $controlfile . ".tex";
    $outputfile = $controlfile . ".pdf";
  }
  if(read_control_file()) {
    if($presentationmaker == 0) {
      run_plain();
    } else {
      if($presentationmaker == 1) {
        run_pdftk();
      } else {
        if($presentationmaker == 2) {
	  run_beamer();
	}
      }
    }
  }
} else {
  print "ERROR: Must specify project file!\n";
}

