#!/bin/sh

# Script for splash screens on i.MX platforms
#
# This is needed because we write a single generic image into unit in the
# factory. When CPU card is placed into a assembled unit, it will detect the
# screen resolution and program the appropriate splash image.
#
# Custom splash screens are stored in /media/factorydata/splash-images.
# Production splash screens are stored in /usr/share/splash-images. The set of
# splash screens for each supported resolution are named
# <image_width>x<image_height>.<extension>. The splash screen for Polaris uses
# a legacy naming convention, Polaris<image_width>x<image_height>.<extension>.
# A cache of the sha1sums for all images is stored along with the set of images
# sorted in reverse numerical order by image width, by image height in a file
# called checksums.sha1. This allows the largest resolution, valid splash
# screen to be selected without complicated math. The checksums.sha1 file is
# created at install time, or before, using the following command:
#
# sha1sum * | sort -nr -tx -k2 | sort -s -nr -t' ' -k2 > checksums.sha1
#
# Possible improvements
#
# Use compression for the bmp files to save space
#
# HFP-36 The logo must be smaller than 500kB

# set -x

if grep -q "i.MX 6" /proc/cpuinfo; then
  ISMX6=true
else
  ISMX6=
fi
FAMILY_ID="$(cut -f2 /proc/navico_platform/family_id)"
factorydata_directory="/media/factorydata"

# The App writes a new splashscreen for Condor
if [ "$FAMILY_ID" != "Condor" ]; then

### Custom Splash Screen
# If there's no image stored in the custom image directory and the logo mtd
# partition has a custom splash screen then it needs to be cached, so it won't
# get blown away by the new updatesplashscreen script.
#
# Only BMP images, between 320x240 and 1280x800, and are splash screens, and
# then only if not recognised as a production splash screen.
CheckCustomSplash() {
if [ ! -d $factorydata_directory/splash-images -a -z "$ISMX6" ]; then
   logo_mtd="$(grep -i '"logo"' /proc/mtd|cut -d: -f1)"
   image_signature=$(dd if=/dev/$logo_mtd bs=26 count=1 2>/dev/null | \
      hexdump -v -n28 -e '/2 "%04x:" 5 "%d:" "%d\n"')
   # 4d42:614470:xx:xx:xx:640:480

   # Is it a BMP file?
   image_magic=${image_signature%%:*}
   if [ "$image_magic" = '4d42' ]; then
      image_signature=${image_signature#*:}
      image_size=${image_signature%%:*}

      image_signature=${image_signature#*:}
      image_signature=${image_signature#*:}
      image_signature=${image_signature#*:}
      image_signature=${image_signature#*:}
      image_width=${image_signature%%:*}
      image_height=${image_signature##*:}

      # Check these values are reasonable for a splash screen
      if [ $image_size -ge 50000 -a $image_size -le 2100000 \
         -a $image_width -ge 300 -a $image_width -le 2000 \
         -a $image_height -ge 200 -a $image_height -le 1000 ]
      then
         # Custom splash screens are not production ones
         mtd_sha1="$(dd if=/dev/$logo_mtd bs=1 count=40 skip=$image_size 2>/dev/null)"
         if [ -z "$mtd_sha1" ] || ! grep -q "$mtd_sha1" <<EOF
09af03ee86995d3feb65ab7df58935ab61be59de
10200d384bbd25d3f8b7933942c8eca18bfb1995
1a68f016f56c8cba603c24f401ad175501e52b80
1e202aeecb768478dfb6f4c21dc402b2bda5e3ab
248920e794b091e332edf28063c0d47d8ce720f3
41c5a26d1e472aa40664fec90a9493fee9f980a0
48b07bc157a08245ae5610c75ef2e491a058c2cd
49a4274320b90b81649541197ef73dbbadeafe4c
5b7bfde0c0a49e0194a04e6ffd74fcb6e3cba1f9
66d7d997816a750dab1692cdbfa83a5426b6520f
85ee3d82bff3ccbc185763fcaf75fcdf1207fc55
988447caefd33f0cca69cdb7fc19ea5190d662d2
98c1864b9f93ee3838e82d21183053ec95812a03
9ae14c8a20d87db895e8e9c777d8b8f016ba0032
a1dd232d4649eb0d9737a9fee0d002376ecb931e
a2a55b2641e325eaf98e62b364dff617a3d75025
aeed5218fc76dcd849df520637eb10fcbd2f72f2
b5612c24c418fc76ee058a84d8558e3506e94a78
b791452bddcaa70104e0780caeaf0d7c1f886cb0
c34cc2863628001eda8d851e2307eb8867f85957
e35a6221d1a493854cc825bdeef6c85394ee1e77
efeca7bf269989628017e591f32ba2057ff1def8
EOF
         then
            # Assume it's a valid custom screen and cache it
            mount -o remount,rw $factorydata_directory
            mkdir -p $factorydata_directory/splash-images
            (
               cd $factorydata_directory/splash-images
               dd if=/dev/$logo_mtd bs=$image_size count=1 of=${image_width}x${image_height}.bmp
               sha1sum ${image_width}x${image_height}.bmp > checksums.sha1
               sync
            )
            mount -o remount,ro $factorydata_directory
         fi
      fi
   fi
fi
}

CheckCustomSplash

# If the custom splash files directory exists then use it
for images_directory in \
  $factorydata_directory/splash-images \
  /usr/share/splash-images \
  ''
do
  if [ -z "${images_directory}" ]; then
    echo "Can't find images directory"
    exit 1
  elif [ -d "${images_directory}" ]; then
    break
  fi
done

logo_mtd="$(grep -i '"logo"' /proc/mtd|cut -d: -f1)"
if [ -z "${logo_mtd}" ]; then
  echo "Can't find logo partition"
  exit 1
fi

checksums_file="${images_directory}"/checksums.sha1
if [ ! -e "$checksums_file" ]; then
  echo "Can't find checksums file"
  exit 1
fi

# U:800x600p-51	Atlantis 8" v2.1 
#   ^^^x^^^ = display resolution
#
# Alternative method
# display_resolution="$(grep -o '[[:digit:]]\+x[[:digit:]]\+' /sys/class/graphics/fb0/mode)"
#
if grep -q "i.MX 6" /proc/cpuinfo; then
  display_resolution="$(sed -e 's/^[^0-9]*\([0-9]*x[0-9]*\).*$/\1/' < /sys/class/graphics/fb0/mode)"
else
  display_resolution="$(cut -f2 /proc/navico_platform/disp_mode|cut -d'_' -f1)"
fi
display_width="${display_resolution%x*}"
display_height="${display_resolution#*x}"

# Are we dealing with Polaris?
config_filename=/etc/NOS/Config.ini
filename_prefix=
if [ "$(cut -f2 /proc/navico_platform/family_id)" = 'Atlantis' -a -r "$config_filename" ] && \
   grep -iq '^ProductDataset=Polaris\>' "$config_filename"
then
  filename_prefix=Polaris
fi

# Search from largest to smallest available resolution, stopping at the first
# one that's less than or equal to the display resolution

checksums_fifo=/tmp/checksums_fifo
if rm -f $checksums_fifo && mkfifo $checksums_fifo; then
  grep " ${filename_prefix}[[:digit:]]" "$checksums_file" >$checksums_fifo &
  while read line_sha1sum line_filename; do
    image_resolution="${line_filename#$filename_prefix}"
    image_resolution="${image_resolution%.*}"
    image_width="${image_resolution%x*}"
    image_height="${image_resolution#*x}"
    if [ "$image_width" -le "$display_width" -a \
	 "$image_height" -le "$display_height" ]; then
      image_sha1="$line_sha1sum"
      image_filename="$line_filename"
      image_length=$(stat -c %s "${images_directory}/${image_filename}")
      break
    fi
  done <$checksums_fifo
  rm -f $checksums_fifo
else
  echo "Can't read checksums file"
  exit 1
fi

if [ "$(dd if=/dev/"${logo_mtd}" bs=1 count=40 skip=$image_length 2>/dev/null)" = "$image_sha1" ]; then
  echo "$logo_mtd is up-to-date with: $image_filename"
else
  echo "$logo_mtd is updating with: $image_filename"
  cp "${images_directory}/${image_filename}" /tmp

  # Flip the image if necessary
  if [ $(cat /proc/navico_platform/disp_intf | cut -f 4) = 180 ]; then
      mv /tmp/"${image_filename}" /tmp/unflipped-"${image_filename}"
      flip_bmp -i /tmp/unflipped-"${image_filename}" -o /tmp/"${image_filename}"
  fi

  echo -n "${image_sha1}" >> /tmp/"${image_filename}"
  flash_eraseall /dev/"${logo_mtd}" >/dev/null 2>&1
  nandwrite -p /dev/"${logo_mtd}" /tmp/${image_filename} >/dev/null 2>&1
  echo "done"
fi

fi # Condor if statement

exit 0
