#!/bin/sh

# determine the installation directory of stic_std_variables and execute inline
if test -n "$STIC_MAIN_DIR"
then
  stic_init_dir=$STIC_MAIN_DIR
elif test -r $HOME/.stic_main_dir
then
  stic_init_dir=$(cat $HOME/.stic_main_dir)
fi
if test "$stic_init_dir" = ""
then
  stic_init_dir=$(dirname "$0")/
else
  stic_init_dir="$stic_init_dir"/scripts/
fi
if test -r "$stic_init_dir"stic_std_variables
then
  . "$stic_init_dir"stic_std_variables
elif test  -z "$STIC_NO_BASH" -a -n "$(type -p stic_std_variables)"
then
  . stic_std_variables
fi


if test $# -lt 2
then
  echo usage : $0 'listname_template file [more files]'
  echo 'This script sorts the given files into seven different categories'
  echo 'which are represented by listfiles. Their names are derived from the'
  echo 'given listname_template by appending the following texts :'
  echo ' unique      = files not already known which are no trash.'
  echo ' interesting = possibly superior doubles (>101% of best double)'
  echo '               and internal doubles in the list of input files.'
  echo ' equivalent  = probably quite equivalent doubles (101% to 83.33%).'
  echo ' inferior    = probably inferior doubles (smaller than 83.33%).'
  echo ' problem     = unreadable but probably pictures (try netscape).' 
  echo ' trash       = probably trashy files with no doubles.' 
  echo ' unreadble   = similar cannot convert this file into a readable JPEG.'
  echo 'other arguments are filenames to examine.'
  exit 1
fi


# adjustable parameters

# how much better than all doubles has an interesting image to be ?
export interesting_threshold=101
# how much better has a double to be to make an image inferior ?
export inferior_threshold=120
# how many pixels needs a unique non-trash image to have
export trash_threshold=256

# be sure to choose a unique mapname. ${mapname}_* will get removed !
export mapname=/tmp/similar_adhoc_$$
export map_initialized="no"

# if set to yes , this variable prevents the time consuming search for inner
# doubles.
export simple_check="no"

# The length of a line of pacifier characters
export pacl=50


# targets

listname="$1"
shift 1

export unique_list="$listname"unique
export interesting_list="$listname"interesting
export equivalent_list="$listname"equivalent
export inferior_list="$listname"inferior
export problem_list="$listname"problem
export trash_list="$listname"trash
export unreadable_list="$listname"unreadable

# the replies of similar are globally accessible. 
# this is to avoid redundant calls
export s1 x1 y1 s2 x2 y2

# counting the pacifier characters
export pacifier_counter=0


# functions

zero_list() {
# make list file empty without removing the inode (test -n x has no output)
  if test "$1" = "-" -o "$1" = ""
  then
    return 0
  fi
  test -n x >"$1"
  return 0
}


append_list() {
# append $1 to list $2
# echo "$1" "$2"
  if test "$2" = "-" 
  then
    echo "$1"
  elif test "$2" = ""
  then
    dummy=dummy
  else 
    echo "$1" >>"$2"
  fi
  return 0
}


write_pacifier() {
# write $1 without a newline to stdout
# append newline each $pacl calls

 echo -n "$1"
 pacifier_counter=$(expr $pacifier_counter + 1)
 mod=$(expr $pacifier_counter - '(' $pacifier_counter / $pacl ')' '*' $pacl)
 if test $mod = 0
 then
   echo "  $pacifier_counter"
 fi
 return 0
}


set_x1_y1() {
 x1=$1
 y1=$2
 return 0
}

set_x2_y2() {
 x2=$1
 y2=$2
 return 0
}


larger_size() {
# file names to compare in $1 and $2
# percentage threshold in $3 (e.g. 105 )

  s1=$("$stic_bin_dir"similar -no_rc -imagesize:xy:"$1" 2>/dev/null)
  s2=$("$stic_bin_dir"similar -no_rc -imagesize:xy:"$2" 2>/dev/null)
# ? how to scanf ?
  set_x1_y1 $s1
  set_x2_y2 $s2

  if test -z "$x1" -o -z "$y1" -o -z "$x2" -o -z "$y2"
  then
    return 1
  fi
  if test $x1 -gt $(expr '(' $x2 '*' $3 ')' / 100)
  then
    if test $y1 -gt $(expr '(' $y2 '*' $3 ')' / 100)
    then
      return 0
    fi
  fi
  return 1
}


evaluate_double() {
# $1 file to evaluate
# $2 list of files to compare with

  for j in $2
  do
    if larger_size "$j" "$1" $inferior_threshold
    then
      write_pacifier -
      append_list "$1" "$inferior_list"
      return 0
    fi
  done
  for j in $2
  do
    if larger_size "$1" "$j" $interesting_threshold
    then
      dummy=dummy
    else
      write_pacifier =
      append_list "$1" "$equivalent_list"
      return 0
    fi
  done
  write_pacifier +
  append_list "$1" "$interesting_list"
  return 0
}


trash_size() {
# test file $1 wether image is within $trash_threshold x $trash_threshold

  s1=$("$stic_bin_dir"similar -no_rc -imagesize:xy:"$1" 2>/dev/null)
  set_x1_y1 $s1
  if test -z "$x1" -o -z "$y1"
  then
    return 0
  fi
  if test $x1 -le $trash_threshold -a $y1 -le $trash_threshold
  then
    return 0
  fi
  return 1 
}


evaluate_unique() {
# evaluate image $1  which found no double in the database
# parameter $2 possibly contains the current similar options which are empty
# in case of the main database.
 
  if trash_size "$1"
  then
    if test -z "$s1"
    then
      if test $("$stic_bin_dir"similar -no_rc -imagoid:"$1") = "1"
      then
        write_pacifier '?'
        append_list "$1" "$problem_list"
      else
        write_pacifier -
        append_list "$1" "$unreadable_list"
      fi
    else
      write_pacifier -
      append_list "$1" "$trash_list"
    fi
    return 0
  fi
  unique="yes"

  # the internal double check of the unique file may be ommitted
  if test "$simple_check" = "yes"
  then
    write_pacifier +
    append_list "$1" "$unique_list"
    return 0
  fi

  if test -z "$2"
  then
    # check against the adhoc database for internal doubles
    if test "$map_initialized" = "yes"
    then
      evaluate_image "$1" "-no_rc -mapname:$mapname"
    else
      write_pacifier +
      append_list "$1" "$unique_list"
    fi
    "$stic_bin_dir"similar -no_rc -mapname:"$mapname" -append:"$1" 2>/dev/null
    map_initialized="yes"
  else
    write_pacifier + 
    append_list "$1" "$unique_list"
  fi
  return 0
}


init_lists () {
# make list files empty 
  zero_list "$unique_list"
  zero_list "$interesting_list"
  zero_list "$equivalent_list"
  zero_list "$inferior_list"
  zero_list "$problem_list"
  zero_list "$trash_list"
  zero_list "$unreadable_list"
  return 0
}


evaluate_image () {
# evaluate the class of a single image $1 with similar options $2

# echo ; echo $1 + $2

# avoid categorizing own list files and snntpbatch .tee files
 if echo "$1" | grep '^'"$listname.*" >/dev/null
 then
   return 0
 fi
 if echo "$1" | grep '.*\.tee$' >/dev/null
 then
   return 0
 fi

 found=$("$stic_bin_dir"similar $2 -search:"$1" 2>/dev/null)
 if test -n "$found"
 then
   evaluate_double "$1" "$found"
 else
   evaluate_unique "$1" "$2"
 fi 
}


file_exists() {
# tests wether the first argument is a valid file address
  if test -e "$1"
  then
    return 0
  fi
  return 1
}


remove_map() {
  if file_exists ${mapname}_*
  then
    rm ${mapname}_*
  fi
}


final_procedure() {
  echo
  remove_map
}


# --- main


trap final_procedure EXIT

init_lists

for i in "$@"
do
  evaluate_image "$i" ""
done 


