#! /bin/sh

# This is Dom's script for generating a photo gallery.
# Run it with no arguments in a directory with lots of photos.
# Last updated June 25, 2009
# Contact dom@cmu.edu for the latest version
#
# Before running, make sure your pictures are rotated properly.
# Use "jhead -autorot *" or manually rotate as appropriate.
#
# This script will NOT alter your existing images.
# It will generate IMG-large.jpg and IMG-small.jpg for each jpg.
# It will also accept FILE.mov if FILE.jpg is the thumbnail for it.
# By default, the large versions will be up to 1024, the small up to 200.
# These thumbnails will be made with convert if they do not exist.
#
# After all the image processing, lots of html files will be made.
# You may want to tweak this portion of the script, for example:
#  - add a footer with your contact information
#  - adjust the color scheme (default is lemon-chiffon, that's an inside joke)
#
# You will then be left with a lot of files, a gallery.html and 4 files
# for each photo (the original FILE.jpg, plus three generated files:
# FILE-small.jpg, FILE-large.html FILE.html)
#
# You may add captions/comments/tags to the comments.txt file.
# Each line in the file should start with an image file name, 
# any text following that is a comment.  The text may include html markup.
# Multiple lines for the same file can be included, ie for long comments.

### configurable options
#name of the gallery file
#index.html is a good name if you want to hide the directory listing
html="gallery.html";

#set this to yes if you want the image to automatically fit the screen
#(this should be enabled if thumbnails are shown while loading
# so that the large image is not confined to the tiny thumbnail size)
useJavascriptResizing="yes";

#using a little bit of javascript, the thumbnail can be displayed 
#while loading the photo... this is a very nice feature that requires
#browser support (almost universal) and javascript resizing (above)
#by default I'll set this to no just in case javascript is disabled,
#this means you will see an empty page during loading
thumbnailWhileLoading="no";

#when viewing an individual image you can click on it
#should that take you to the original or the large version?
#if you enable linking to the original,
#then you need to also upload the original image
#disabling this greatly reduces the overall gallery size
linkToOriginal="no";

#specify the maximum height and width of the large images
maxDim=800;
#maxDim=1024;
largeSize="${maxDim}x${maxDim}";

#specify the maximum height and width of the thumbnails
smallSize=200x200

### end of configuration options

#try to decide if we should look for JPG or jpg files
suffix="$1"
if [ "" == "$suffix" ]
then
 #count how many .jpg and .JPG files there are
 numJPG=`find . | grep -c .JPG`
 numjpg=`find . | grep -c .jpg`
else
 #the suffix was specified on the command line, disable this search
 numJPG=0;
 numjpg=0;
fi

#if there is 0 of one kind and some of the other, then use that suffix
if [ 0 -eq $numJPG ]
then
 if [ $numjpg -gt 0 ]
 then
#  echo "Definitely dealing with jpgs"
  suffix=".jpg"
 fi
fi
if [ 0 -eq $numjpg ]
then
 if [ $numJPG -gt 0 ]
 then
#  echo "Definitely dealing with JPGs"
  suffix=".JPG"
 fi
fi

# looks like there was a mix of .JPG and .jpg files, ask the user...
if [ "$suffix" == "" ]
then
 echo "I'm confused about the suffix, please specify one on the command line, eg \".JPG\""
 exit
fi

#pick the moviesuffix
moviesuffix=".mov"
if [ `find . | grep -c .MOV` -gt 0 ]
then
 moviesuffix=".MOV"
fi

#define these helpers
addSmall=" sed s/$suffix/\-small$suffix/";
addLarge=" sed s/$suffix/\-large$suffix/";
addMovie=" sed s/$suffix/$moviesuffix/";

#check for the comments file
commentsFile="comments.txt";
addedComments="no";
if [ -f "$commentsFile" ]
then
  haveComments="yes";
else
  haveComments="no";
fi

# date this script was run, inserted into the footer and meta data
genDate=`date "+%A %B %e, %Y %l:%M %P"`;

# meta date inserted into each html file
metaHTML="<meta generator=\"Script by Dominic Jonak (dom@cmu.edu)\"><meta date=\"$genDate\">";

# ok, now we're ready to get started
# get our list of files
files=`find . | grep $suffix | grep -v small | sed "s/\-large//g" | cut -b3- | sort | uniq`;
numfiles=`echo $files | tr ' ' '\n' | wc -l`;
counter=0;

# start making the gallery
echo "<html><head>"                                         > $html
echo "$metaHTML"                                           >> $html
echo "<title>My Gallery</title><style>"                    >> $html
echo "body{ background: #ffb; margin: 3px}"                >> $html
echo ".b{ background: #bbf; padding: 3px; margin: 6px 6px 3px 3px; float: left}" >> $html
echo ".c {border: thin solid #bbf; margin: -6px 0 0 -6px; padding: 0px}" >> $html
echo "</style></head><body>"                               >> $html

#this first loop creates all the large and small versions
#it also creates the gallery html file
for img in $files
#for img in ""
 do

  counter=`echo 1+$counter | bc`;
  printf "%d of %d: " $counter $numfiles

  curimg=`echo $img | sed "s/$suffix//"`
  imgbase=`basename $curimg`
  smallimg=`echo $img | $addSmall`
  largeimg=`echo $img | $addLarge`
  outhtml=`basename $img | sed "s/$suffix/.html/"`
  movie=`echo $img | $addMovie`;

  echo "<div class=b><div class=c><a href=$outhtml border=0>"      >> $html
  if [ -f $movie ]
  then 
   echo "<img border=10 src=$smallimg height=130></a></div></div>" >> $html

   echo "$img is a movie clip"

   if [ -f $smallimg ]
   then
    noop=1;
#    touch $smallimg
#    echo "Thumbnail for $img already exists"
   else
    convert -quality 75 -geometry $smallSize $img $smallimg
   fi


  else
#not a movie... create a large and small version
   if [ -f $largeimg ]
   then
    echo "Large version of $img already exists"
   else
    echo "Processing $img"
    convert -quality 75 -geometry $largeSize $img $largeimg
   fi

   if [ -f $smallimg ]
   then
    noop=1;
#    touch $smallimg
#    echo "Thumbnail for $img already exists"
   else
    convert -quality 75 -geometry $smallSize $largeimg $smallimg
   fi

   altText="$curimg";
   if [ "$haveComments" == "yes" ]
   then
     #altText="`grep ^$curimg $commentsFile | sed \"s/$curimg //\"`";
     altText="`grep ^$imgbase $commentsFile | cut -f 2- -d \" \"`";
     if [ "$altText" == "" ]
     then
       altText="$curimg";
     else
       #clean up the alt text, remove any line breaks and html code
       altText="`echo $altText|tr \"\\n\" \" \"`";
       altText="`echo $altText|sed \"s/<[^>]*>//g\"`";
       addedComments="yes";
     fi
   fi
   echo "<img border=0  src=$smallimg height=150 alt=\"$altText\" title=\"$altText\"></a></div></div>" >> $html

  fi
#done with $img

 done;

echo "<hr style=\"{clear:both}\">Dom@cmu.edu<br>" >> $html
echo "$genDate" >> $html
echo "</body></html>" >> $html
echo "Made $html"
#done making thumbnails and the gallery


###make individual htmls

#add the first and last
files="noprev
$files
nonext";

counter=0;

for img in $files
 do

  prevfile=$curfile;
  curfile=$nextfile;
  nextfile=$img;

  if [ "$nextfile" == "noprev" ]
  then
   noop=1;
  elif [ "$curfile" == "noprev" ]
  then
   noop=1;
  else

    counter=`echo 1+$counter | bc`;
    printf "%d of %d: " $counter $numfiles

    curimg=`echo $curfile | sed "s/$suffix//"`
    imgbase=`basename $curimg`
    outhtml=`basename $curfile | sed "s/$suffix/.html/"`
    cursmall=`echo $curfile | $addSmall`
    curlarge=`echo $curfile | $addLarge`
    movie=`echo $curfile | $addMovie`;
    if [ "$prevfile" == "noprev" ]
    then
      prevhtml="$html"
      prevsmall="";
    else
      prevhtml=`basename $prevfile | sed "s/$suffix/.html/"`
      prevsmall=`echo $prevfile | $addSmall`
    fi
    if [ "$nextfile" == "nonext" ]
    then
      nexthtml="$html"
      nextsmall="";
    else
      nexthtml=`basename $nextfile | sed "s/$suffix/.html/"`
      nextsmall=`echo $nextfile | $addSmall`
    fi

    echo "Generating $outhtml (prev $prevhtml next $nexthtml)"

    echo "<html><head>"                                         > $outhtml

    titleText="";
    if [ "$haveComments" == "yes" ]
    then
     #titleText="`grep ^$curimg $commentsFile | sed \"s/$curimg //\"`";
     titleText="`grep ^$imgbase $commentsFile | cut -f 2- -d \" \"`";
     if [ "$titleText" == "" ]
     then
       titleText="";
     else
       #clean up the title text, remove any line breaks and html code
       titleText="`echo $titleText|tr \"\\n\" \" \"`";
       titleText="`echo $titleText|sed \"s/<[^>]*>//g\"`";
     fi
   fi
   titleText="$curimg ($counter of $numfiles) $titleText";

    echo "$metaHTML"                                           >> $outhtml
    echo "<title>$titleText</title>"                           >> $outhtml

    # define resizeImage()
    echo "<script>"                                            >> $outhtml
    echo "function resizeImage(){"                             >> $outhtml
    echo "  var img=document.getElementById(\"curimage\");"    >> $outhtml
    echo "  if(!img)return;"                                   >> $outhtml
    echo "  var naturalRatio = img.height/img.width;"          >> $outhtml
    echo "  /* subtract 85 for the 50px images, 1px margin, text height, and buffer */" >> $outhtml
    echo "  var insideHeight = (document.body.clientHeight - 85);" >> $outhtml
    echo "  /* subtract 2 for the 1px margin on either side */">> $outhtml
    echo "  var insideWidth = (document.body.clientWidth-2);"  >> $outhtml
    echo "  var bodyRatio = insideHeight/insideWidth;"         >> $outhtml

    # limit the maximum size to the browser window
    # but don't exceed the maximum size either
    echo "  var maxDim = $maxDim;"                             >> $outhtml
    echo "  var maxH = maxDim;"                                >> $outhtml
    echo "  var maxW = maxDim;"                                >> $outhtml
    echo "  if(naturalRatio>=1){"                              >> $outhtml
    echo "    maxW = maxDim/naturalRatio;"                     >> $outhtml
    echo "  }else{"                                            >> $outhtml
    echo "    maxH = maxDim*naturalRatio;"                     >> $outhtml
    echo "  }"                                                 >> $outhtml

    echo "  if((naturalRatio>bodyRatio)&&(insideHeight<maxH)){">> $outhtml
    echo "    img.height = insideHeight;"                      >> $outhtml
    echo "    img.width = insideHeight/naturalRatio;"          >> $outhtml
    echo "  }else if((naturalRatio<=bodyRatio)&&(insideWidth<maxW)){">>$outhtml
    echo "    img.width = insideWidth;"                        >> $outhtml
    echo "    img.height = insideWidth*naturalRatio;"          >> $outhtml
    echo "  }else{"                                            >> $outhtml
    echo "    img.height = maxH;"                              >> $outhtml
    echo "    img.width = maxW;"                               >> $outhtml
    echo "  }"                                                 >> $outhtml
    echo "}"                                                   >> $outhtml

    echo "function swapImage(){"                               >> $outhtml
    # start preloading the neighboring images
    echo "  var nextimg=new Image(1,1);"                       >> $outhtml
    echo "  var previmg=new Image(1,1);"                       >> $outhtml
    echo "  nextimg.src=\"$nextfile\";"                        >> $outhtml
    echo "  previmg.src=\"$prevfile\";"                        >> $outhtml
    # swap in the high-res image
    echo "  var img=document.getElementById(\"curimage\");"    >> $outhtml
    echo "  if(!img)return;"                                   >> $outhtml
    echo "  img.src=\"$curlarge\";"                            >> $outhtml
    echo "  resizeImage()"                                     >> $outhtml
    echo "}"                                                   >> $outhtml
    echo "</script>"                                           >> $outhtml

    # style information
    echo "<style>"                                             >> $outhtml
    echo "a { text-decoration: none }"                         >> $outhtml
    echo "img { display: block; border: 0}"                    >> $outhtml
    echo ".nav { width: 75px; }"                               >> $outhtml
    echo ".navText { padding-top: 15px; padding-left: 0.5em}"  >> $outhtml
    echo "body { background: #ffb; margin: 1}"                 >> $outhtml
    echo "</style>"                                            >> $outhtml

#set whether or not we do fancy javascript
    if [ "yes" == "$useJavascriptResizing" ]
    then
     echo "</head><body onResize=\"resizeImage()\" onLoad=\"swapImage()\">" >> $outhtml
    else
     echo "</head><body>" >> $outhtml
    fi

    echo "<table border=0 cellpadding=0 cellspacing=0><tr>"    >> $outhtml
    echo "<td class=nav valign=top><center>"                   >> $outhtml
    echo "<a href=\"$prevhtml\">"                              >> $outhtml
    haveGalleryLink="no";
    if [ "$prevsmall" == "" ]
    then
      echo "<hr>Gallery<hr>"                                   >> $outhtml
      haveGalleryLink="yes";
    else
      echo "<img alt=\"Previous\" height=50 src=\"$prevsmall\">" >> $outhtml
      echo "Prev"                                              >> $outhtml
    fi
    echo "</a></center></td>"                                  >> $outhtml

    echo "<td class=nav valign=top><center>"                   >> $outhtml
    echo "<a href=\"$nexthtml\">"                              >> $outhtml
    if [ "$nextsmall" == "" ]
    then
      echo "<hr>(Gallery)<hr>"                                 >> $outhtml
      haveGalleryLink="yes";
    else
      echo "<img alt=\"Next\" height=50 src=\"$nextsmall\">"   >> $outhtml
      echo "Next"                                              >> $outhtml
    fi
    echo "</a></center></td>"                                  >> $outhtml

    if [ "$haveGalleryLink" == "no" ]
    then
      echo "<td valign=top><center>"                           >> $outhtml
      echo "<a href=\"$html\">"                                >> $outhtml
      echo "<hr>(Gallery)<hr>"                                 >> $outhtml
      echo "</a></center></td>"                                >> $outhtml
    fi

    echo "<td class=navText id=counter valign=top>"            >> $outhtml
    echo "$curimg<br>($counter&nbsp;of&nbsp;$numfiles)"        >> $outhtml
    echo "</td>"                                               >> $outhtml

    if [ "$haveComments" == "yes" ]
    then
      echo "<td class=navText id=comments valign=top>"         >> $outhtml
      #grep ^$curimg $commentsFile | sed "s/$curimg //"         >> $outhtml
      grep ^$imgbase $commentsFile | cut -f 2- -d ' '          >> $outhtml

      echo "</td>"                                             >> $outhtml
    fi

    echo "</tr></table>"                                       >> $outhtml

    echo "<div style=\"clear: both\" width=100%><center>"      >> $outhtml
    if [ -f $movie ]
    then
      # movie
      echo "<a href=\"$movie\">"                               >> $outhtml
      echo "<img border=1 src=\"$curfile\"></a>"               >> $outhtml
      echo "(click to play movie)"                             >> $outhtml
    else
      # thumbnail image
#set where the link goes, either the original or large version
      if [ "yes" == "$linkToOriginal" ]
      then
       echo "<a href=\"$curfile\">"                            >> $outhtml
      else
       echo "<a href=\"$curlarge\">"                           >> $outhtml
      fi

#set which image to display initially, either the thumbnail or load the large version
      if [ "yes" == "$thumbnailWhileLoading" ]
      then
       echo "<img id=\"curimage\" src=\"$cursmall\" "          >> $outhtml
      else
       echo "<img id=\"curimage\" src=\"$curlarge\" "          >> $outhtml
      fi

      if [ "yes" == "$useJavascriptResizing" ]
      then
       echo "onLoad=\"resizeImage()\">"                        >> $outhtml
      else
       echo ">"                                                >> $outhtml
      fi
    fi

    echo "</a></center></div>"                                 >> $outhtml

    #inline preloader, delays body.onLoad
    echo "<img width=0 height=0 src=\"$curlarge\">"            >> $outhtml
    echo "</body></html>"                                      >> $outhtml

  fi
  
 done;

if [ "$addedComments" == "no" ]
then
  echo "Warning, no comments were added"
  echo "You can enter comments/captions to $commentsFile"
fi

