#!/bin/bash
#
# generate_compare
#
# Assuming that old version of all generated examples were saved...
#   mved =.sfx _=.sfx
# instead of just deleting the old, compare the old files with the new.  If
# the new version of the file changed: report the change and delete the old.
# OR if unchanged replace it with the old version again.
#
# Options (see notes in generate_options)
#  -n    check for changes but do NOT recover old backups
#  -m    Only keep the major change images.
#  -c    Clear all backups after comparision finished
#  -s    We are skipping images (debug testing), so skip compare (for now)
#
# This is to attempt to reduce the amount of upload changes that occurs
# from IM Example rebuilds, to my archives, and to remote web sites.
#
# Source settings common to all examples
[ -f ./generate_options     ] && . ./generate_options
[ -f ../generate_options    ] && . ../generate_options
[ -f ../../generate_options ] && . ../../generate_options

if [ "`ls 2>/dev/null core*`" ]; then
  echo >&2 "Removing core files"
  ls >&2 core*
  rm -f core*
fi

if [ ! "`ls 2>/dev/null _*`" ]; then
  [ "$VERBOSE" ] && echo >&2 "No Old Example saves found!"
  exit 0;
fi

if [ "$SKIP" ]; then
  echo "Skipping comparision with backup images!"
  exit 0
fi

if [ "$NO_RECOVER" ]; then
  echo "Removing unchanged backups, (no recover)"
else
  echo  "Recovering unchanged backups..."
fi

not_regenerated=''
n='
'

escalation=0

for old in _*; do
  if [ -h "$old" ]; then
    rm -f "$old"
    continue
  fi
  if [ ! -f "$old" ]; then
    #case $old in    # ignore missing GIF text images of the plain text result
    #*.txt.gif|*.anim.gif|*.mvg.gif|*.svg.gif|*.utf8.gif)
    #   continue ;;
    #esac
    echo >&2 "generate_compare: Old Example \"$old\" disappeared"
    continue
  fi

  new=`echo -n "$old" | sed 's/^_//'`
  if [ ! -f "$new" ]; then
    not_regenerated="$not_regenerated$old$n"
    continue
  fi

  # Direct file comparision -- if unchanged, restore backup
  [ $VERBOSE ] && echo "$new.......";
  if cmp -s "$old" "$new"; then
    if [ "$NO_RECOVER" ]; then
      # junk the older image (same)
      rm $old
      #case $old in
      #*.txt|*.anim|*.mvg|*.svg|*.utf8)
      #  if [ -f "$old.gif" ]; then
      #    rm -f "$old.gif"
      #  fi ;;
      #esac
    else
      # replace new with old if unchanged
      rm "$new"; mv "$old" "$new"
      #case $old in
      #*.txt|*.anim|*.mvg|*.svg|*.utf8)
      #  if [ -f "$old.gif" ]; then
      #    rm -f "$new.gif"; mv "$old.gif" "$new.gif"
      #  fi ;;
      #esac
    fi
    continue
  fi

  # Handle any special file format comparisions.
  error='';
  case $new in
    *.txt|*.mvg|*.svg|*.utf8)  # text file changed
      #rm -f "$old.gif"        # delete the GIF text image too
      error='text changed'
      ;;
    *.anim)  # remove the line with the date and direct compare again
      if cmp -s <(grep -v '^. Extracted on ' "$new") \
                <(grep -v '^. Extracted on ' "$old"); then
         rm "$new"; mv "$old" "$new"  # replace new with old if unchanged
         if [ -f "$old.gif" ]; then   # replace the GIF text image
           rm -f "$new.gif"; mv "$old.gif" "$new.gif"
         fi
         continue
      fi
      error='anim changed'
      ;;
    *.gif) # multi-image formats
      o_count=`identify -format %n $old`
      n_count=`identify -format %n $new`
      # check if number of images in GIF chnaged
      if [ "$o_count" -a "$n_count" ] && [ "$o_count" -ne "$n_count" ]; then
        error="image count $n_count->$n_count" # major change
      elif [ "$n_count" -ne '1' ]; then
        error="multi-image"  # Can't compare at this time - future expandsion
      fi
      ;;
    *.png|*.jpg)  # handled using single image compare below
      ;;
    *) error="unknown format"  # future expandsion
      ;;
  esac

  # Compare single images to see if it is just a minor change
  if [ -z "$error" ]; then
    o_size=`identify -format %wx%h $old`
    n_size=`identify -format %wx%h $new`
    if [ "$o_size" != "$n_size" ]; then
      error="size $o_size->$n_size"   # major change
    fi
  fi
  # if [ -z "$error" ]; then
  #   case "$new" in
  #   *.gif)
  #     o_colors=`identify -format %k $old`
  #     n_colors=`identify -format %k $new`
  #     if [  "$o_colors" != "$n_colors" ]; then
  #       error="color $o_colors->$n_colors"  # major change"
  #     fi
  #     ;;
  #   esac
  # fi
  if [ -z "$error" ]; then
    # case $new in
    #   *.gif)  # Compare dithered images
    #           # -- blur it to remove the influence of the dither.
    #           # THIS DOES NOT WORK WELL
    #       error=`convert $new $old -virtual-pixel Gray -blur 0x2 miff:- |
    #                  compare -metric PAE - null: 2>&1`
    #       ;;
    #   *)  # normal images just directly compare
    error=`compare -dissimilarity-threshold 50% \
                   -metric PAE $new $old null: 2>&1`
    #       ;;
    # esac
    if [ -z "$error" ]; then
      echo >&2 "Image Compare produced no result for $new -- THIS IS BAD"
      continue
    fi
    if echo "$error" | grep -q 'opacity differs'; then
      error='opacity differs'  # MAJOR ERROR
    elif   echo "$error" | grep -iq '[a-df-z]';   then # not 'e'
      echo >&2 "Image Compare Failure for $new:"
      echo >&2 "    $error"
      continue
    else
      error=`echo "$error" | sed 's/ .*//'`
      if [ "$error" -eq 0 ]; then
        # new generated image matchs old image
        if [ "$NO_RECOVER" ]; then
          # junk the older image (same)
          rm $old
        else
        # replace new with old if unchanged
          rm "$new"; mv "$old" "$new"
        fi
        continue
      elif [ "$error" -lt 5000 ]; then
        if [ $escalation -lt 1 ]; then
          echo >&2 "Minor Changes Seen (PAE < 5000)"
          escalation=1
        fi
        if [ -z "$MAJOR" ]; then
          printf "   %-30s Changed (cmp $error minor)\n" "$new"
        else
          printf "   %-30s Changed (cmp $error minor) - delete backup\n" "$new"
          rm "$old";
        fi
        continue;
      fi
      error="cmp $error MAJOR"
    fi
  fi

  # Image must be really different!
  if [ $escalation -lt 10 ]; then
    echo >&2 "Some Examples Changed!"
    escalation=10
  fi
  printf "   %-30s Changed ($error)\n" $new
  #[ ! "$DEBUG" ] && rm "$old"

done

if [ "$not_regenerated" ]; then
  echo "Backups found that were not Re-Generated"
  echo -n "$not_regenerated" | column -t -c 70 | sed 's/^/   /'
fi

if [ "$CLEAR" ]; then
  echo "Clearing any Backup Images that changed"
  rm -f _*
fi

