#!/bin/bash

CEFILETYPES="cr2|dng|tif|tiff|psd|jpg|gif|png"
CEFIELDS="-EXIF:DateTimeOriginal -EXIF:CreateDate -EXIF:ISO -EXIF:ExposureTime -EXIF:FNumber -EXIF:FocalLength"
CECOPY="-EXIF:Copyright=(c) %y, PUT YOUR NAME HERE"
CECONTACT="-EXIF:Artist=PUT YOR NAME HERE, PUT YOUR EMAIL HERE" 

cesplitname () {
   unset CERETURN
   local CEPREFIX
   if [[ "${1/\//}" == "$1" ]]; then
      CERETURN[0]=
      CERETURN[1]=$1
   else
      CERETURN[0]=${1%/*}
      CERETURN[1]=${1##*/}
   fi
   if [[ ${CERETURN[1]:0:1} == "." ]]; then
      CEPREFIX=.
      CERETURN[1]=${CERETURN[1]#.}
   fi
   if [[ "${CERETURN[1]/.//}" == "${CERETURN[1]}" ]]; then
      CERETURN[2]=
      CERETURN[1]=$CEPREFIX${CERETURN[1]}
   else
      CERETURN[2]=${CERETURN[1]##*.}
      CERETURN[1]=$CEPREFIX${CERETURN[1]%.*}
   fi
}

cefindmatch () {
   local CEFILELIST
   local CEFILE
   while read CEFILE; do
      cesplitname $CEFILE
      local CEF1=`echo $2 | tr [A-Z] [a-z]`
      local CEF2=`echo ${CERETURN[1]} | tr [A-Z] [a-z]`
      if [[ "$CEF1" == "$CEF2" ]] || [[ ! "${CEF1#$CEF2}" == "$CEF1" ]] || [[ ! "${CEF2#$CEF1}" == "$CEF2" ]]; then
         CEFILELIST[${#CEFILELIST[@]}]=$CEFILE
      fi
   done < <(
      find -E "$1" -type f -iregex ".*\.($CEFILETYPES)$" -maxdepth 1 -print
   )
   unset CERETURN
   CERETURN=( ${CEFILELIST[@]} )
}

cecopyexif () {
   local CESOURCE=$1
   local CEDEST=$2
   if [[ -d "$CESOURCE" ]]; then
      cesplitname "$CEDEST"
      cefindmatch "$CESOURCE" "${CERETURN[1]}"
      CESOURCE=${CERETURN[0]}
      CEDIRECTION="to $CEDEST"
   elif [[ -d "$CEDEST" ]]; then
      cesplitname "$CESOURCE"
      cefindmatch "$CEDEST" "${CERETURN[1]}"
      CEDEST=${CERETURN[0]}
      CEDIRECTION="from $CESOURCE"
   else
      CERETURN=( one )
   fi
   if [[ ${#CERETURN[@]} -eq 0 ]]; then
      echo "Unable to copy EXIF $CEDIRECTION"
      echo "  No matching file found."
   elif [[ ${#CERETURN[@]} -gt 1 ]] && [[ ! "$CEFORCE" == "Y" ]]; then
      echo "Unable to copy EXIF $CEDIRECTION"
      echo "  Multiple matching files found, enter names explicitly or use -f option to "
      echo "  match any file.  The following matches were found:"
      c=${#CERETURN[@]}
      for (( i=0; i < c; i++ )); do
         echo "    ${CERETURN[$i]}"
      done
   else
      [[ "$CESILENT" ]] || echo "Copying EXIF from $CESOURCE to $CEDEST..."
      exiftool -TagsFromFile "$CESOURCE" $CEFIELDS "$CECOPY" "$CECONTACT" -overwrite_original_in_place "$CEDEST" >/dev/null 2>/dev/null
   fi
}

CEFORCE=N
CESILENT=
CEYEAR=`date +"%Y"`

while getopts fhsy: CEARGS 2>/dev/null; do
   case "$CEARGS" in
      f)
         CEFORCE=Y
         ;;
      h)
         echo "Usage: cpexif [-yYEAR] [-f] [-s] SOURCE DESTINATION"
         exit
         ;;
      s)
         CESILENT=N
         ;;
      y)
         CEYEAR=$OPTARG
         ;;
   esac
done
[[ "$OPTIND" ]] && shift $(($OPTIND - 1))

CEDIRFLAG=N

CESOURCE=$1
if [[ -z "$CESOURCE" ]]; then
   echo "Error: You must provide a source and destination."
   exit
elif [[ -d "$CESOURCE" ]]; then
   [[ "${CESOURCE/\//}" == "$CESOURCE" ]] || CESOURCE=${CESOURCE%/}
   CEDIRFLAG=Y
elif [[ ! -f "$CESOURCE" ]]; then
   echo "Error: The source does not exist."
   exit
fi

shift
CEDEST=$1
if [[ -z "$CEDEST" ]]; then
   echo "Error: You must provide a destination."
   exit
elif [[ -d "$CEDEST" ]]; then
   [[ "${CEDEST/\//}" == "$CEDEST" ]] || CEDEST=${CEDEST%/}
   CEDIRFLAG=Y$CEDIRFLAG
elif [[ ! -f "$CEDEST" ]]; then
   echo "Error: The destination does not exist."
   exit
fi

CECOPY=${CECOPY//\\%y/$CEYEAR}
if [[ "$CEDIRFLAG" == "YY" ]]; then
   find -E "$CEDEST" -type f -iregex ".*\.($CEFILETYPES)$" -maxdepth 1 -print | while read CEFILE; do
      cecopyexif "$CESOURCE" "$CEFILE"
   done
else
   cecopyexif "$CESOURCE" "$CEDEST"
fi
