#!/bin/sh
set -euf

###### USAGE #####
#run in new directory(will be polluted with images
#just run ./make-realwallpaper

main() {
  # fetch source images in parallel
  #fetch nightmap-old-raw.jpg \
  #  http://awka.sourceforge.net/Night_le_huge.jpg &
  fetch nightmap-raw.jpg \
     http://www.zeitnews.org/sites/default/files/users/20/article_slideshow_images/nasa-noaa-satellite-reveals-new-views-earth-night-1354814354_0.jpg &
  fetch daymap-raw.png \
    http://www.nnvl.noaa.gov/images/globaldata/SnowIceCover_Daily.png &
  fetch clouds-raw.jpg \
    http://user.chol.com/~winxplanet/cloud_data/clouds_2048.jpg &
  fetch krebs.sat.tle \
     http://www.celestrak.com/NORAD/elements/stations.txt &
  wait

  #check_type nightmap-old-raw.jpg image
  check_type nightmap-raw.jpg image
  check_type daymap-raw.png image
  check_type clouds-raw.jpg image

  in_size=2048x1024
  xplanet_out_size=1466x1200
  out_geometry=1366x768+100+160

  nightsnow_color='#0c1a49'  # nightmap
  #nightsnow_color='#0a3b5c'  # nightmap-old

  # normalize *-raw.* to *.png
  #nightmap-old-raw.jpg
  for raw in \
      nightmap-raw.jpg \
      daymap-raw.png \
      clouds-raw.jpg \
      ;
  do
    normal=${raw%-raw.*}.png
    if needs_rebuild $normal $raw; then
      echo "make $normal; normalize $raw" >&2
      convert $raw -scale $in_size $normal
    fi
  done

  # create nightmap-fullsnow
  if needs_rebuild nightmap-fullsnow.png; then
    convert -size $in_size xc:$nightsnow_color nightmap-fullsnow.png
  fi

  # extract daymap-snowmask from daymap-final
  if needs_rebuild daymap-snowmask.png daymap.png; then
    convert daymap.png -threshold 95% daymap-snowmask.png
  fi

  # extract nightmap-lightmask from nightmap
  if needs_rebuild nightmap-lightmask.png nightmap.png; then
    convert nightmap.png -threshold 25% nightmap-lightmask.png
  fi

  # create layers
  make_layer nightmap-snowlayer.png nightmap-fullsnow.png daymap-snowmask.png
  make_layer nightmap-lightlayer.png nightmap.png nightmap-lightmask.png

  # apply layers
  flatten nightmap-lightsnowlayer.png \
    nightmap-lightlayer.png \
    nightmap-snowlayer.png

  flatten nightmap-final.png \
    nightmap-lightsnowlayer.png \
    nightmap.png
    # nightmap-old.png

  # make all unmodified files as final
  for normal in \
      daymap.png \
      clouds.png \
      ;
  do
    final=${normal%.png}-final.png
    needs_rebuild $final &&
      ln $normal $final
  done

  # make_gcloud_cloudmask

  map=daymap-final.png
  night_map=nightmap-final.png
  cloud_map=clouds-final.png
  gcloud_map=gcloud-cloudmask.png
  satellite_file=krebs.sat

  # create xplanet output
  cat >xplanet.config <<EOF
[earth]
"Earth"
map=$map
night_map=$night_map
cloud_map=$cloud_map
cloud_threshold=10
shade=15
EOF

  # create xplanet output satellite version
  cat >xplanet-sat.config <<EOF
[earth]
"Earth"
map=$map
night_map=$night_map
cloud_map=$cloud_map
cloud_threshold=10
satellite_file=$satellite_file
shade=15
EOF

#  # create xplanet output gcloud version
#  cat >xplanet-gcloud.config <<EOF
#[earth]
#"Earth"
#map=$map
#night_map=$night_map
#cloud_map=$gcloud_map
#cloud_threshold=10
#shade=15
#EOF
#
#  # create xplanet output gcloud-satellite version
#  cat >xplanet-gcloud-sat.config <<EOF
#[earth]
#"Earth"
#map=$map
#night_map=$night_map
#cloud_map=$gcloud_map
#cloud_threshold=10
#satellite_file=$satellite_file
#shade=15
#EOF

  cat >krebs.sat <<EOF
25544 "ISS" Image=none trail={orbit,-2,2,1} color=grey thickness=1 fontsize=10
37820 "T1" Image=none trail={orbit,-2,2,1} color=grey thickness=1 fontsize=10
EOF

  cat >krebs.mar <<EOF
EOF

  # rebuild every time to update shadow
  xplanet --num_times 1 --geometry $xplanet_out_size \
    --output xplanet-output.png --projection merc \
    -config xplanet.config

  # rebuild everytime satellite version
  xplanet --num_times 1 --geometry $xplanet_out_size \
    --output xplanet-sat-output.png --projection merc \
    -config xplanet-sat.config

#  # rebuild every time to update shadow gcloud
#  xplanet --num_times 1 --geometry $xplanet_out_size \
#    --output xplanet-gcloud-output.png --projection merc \
#    -config xplanet-gcloud.config
#
#  # rebuild everytime satellite gcloud version
#  xplanet --num_times 1 --geometry $xplanet_out_size \
#    --output xplanet-gcloud-sat-output.png --projection merc \
#    -config xplanet-gcloud-sat.config

  # trim xplanet output
  if needs_rebuild realwallpaper.png xplanet-output.png; then
    convert xplanet-output.png -crop $out_geometry \
      realwallpaper.png
  fi

  # trim xplanet-sat output
  if needs_rebuild realwallpaper-sat.png xplanet-sat-output.png; then
    convert xplanet-sat-output.png -crop $out_geometry \
      realwallpaper-sat.png
  fi

#  # trim xplanet output
#  if needs_rebuild realwallpaper-gcloud.png xplanet-gcloud-output.png; then
#    convert xplanet-gcloud-output.png -crop $out_geometry \
#      realwallpaper-gcloud.png
#  fi
#
#  # trim xplanet-sat output
#  if needs_rebuild realwallpaper-gcloud-sat.png xplanet-gcloud-sat-output.png; then
#    convert xplanet-gcloud-sat-output.png -crop $out_geometry \
#      realwallpaper-gcloud-sat.png
#  fi
}

# generate clouds from google maps
make_gcloud_cloudmask() {
  echo 'fetch gcloud-*.png tiles' >&2
  for y in $(seq -w 0 15); do
    for x in $(seq -w 0 15); do
      echo "curl -sS -o gcloud-$y-$x.png -z gcloud-$y-$x.png \\\"https://mts0.google.com/vt/lyrs=h@239000000,weather_nolabels,weather_0cloud&hl=en&src=app&x=$x&y=$y&z=4&s=Galil\\\""
    done
  done | xargs --max-args=1 -P 10 -I @ sh -c @
  gcloud_tiles=$(find -name 'gcloud-[0-9][0-9]-[0-9][0-9].png'|sort)
  if needs_rebuild gcloud-raw.png $gcloud_tiles; then
    echo 'make gcloud-raw.png' &&
    montage -mode Concatenate -background None \
      $gcloud_tiles -tile x16 gcloud-raw.png
  fi

  check_type gcloud-raw.png image

  gcloud_in_size=2048x2048
  gcloud_out_size=2048x1024
  gcloud_out_geometry=2048x1024+0+512
  gcloud_base_color='#ffffff'

  if needs_rebuild gcloud-normal.png gcloud-raw.png; then
    echo "make gcloud-normal.png; normalize gcloud-raw.png" >&2
    convert -flatten gcloud-raw.png \
      -scale $gcloud_in_size gcloud-normal.png
  fi

  if needs_rebuild gcloud-distmap.png; then
    convert -size 2048x2048 gradient: -rotate 180 \
      -fx "p{i, (asinh(tan((j/h+0.5)*pi))/2.6+0.5) * h }" \
      gcloud-distmap.png
  fi

  if needs_rebuild gcloud-cloudmask.png gcloud-normal.png; then
    echo 'make gcloud-cloudmask.png' &&
    convert gcloud-normal.png gcloud-distmap.png \
      -fx 'p{i,v*h}' \
      -crop $gcloud_out_geometry \
      gcloud-cloudmask.png
  fi

  if needs_rebuild gcloud-fullcloud.png; then
    echo 'make gcloud-fullcloud.png' &&
    convert -size $gcloud_out_size xc:$gcloud_base_color gcloud-fullcloud.png
  fi
}

# usage: getimg FILENAME URL
fetch() {
  echo "fetch $1"
  curl -sS -z "$1" -o "$1" "$2"
}

# usage: check_type FILENAME TYPE
check_type() {
  if ! file -ib "$1" | grep -q "^$2/"; then
    echo "$1 is not of type $2" >&2
    rm "$1"
    return 1
  fi
}

# usage: image_size FILENAME
image_size() {
  identify "$1" | awk '{print$3}'
}

# usage: make_mask DST SRC MASK 
make_layer() {
  if needs_rebuild "$@"; then
    echo "make $1 (apply mask)" >&2
    convert "$2" "$3" -alpha off -compose copy_opacity -composite "$1"
  fi
}

# usage: flatten DST HILAYER LOLAYER
flatten() {
  if needs_rebuild "$@"; then
    echo "make $1 (flatten)" >&2
    composite "$2" "$3" "$1"
  fi
}

# usage: needs_rebuild DST SRC...
needs_rebuild() {
  a="$1"
  shift
  if ! test -e "$a"; then
    #echo "  $a does not exist" >&2
    result=0
  else
    result=1
    for b; do
      if test "$b" -nt "$a"; then
        #echo "  $b is newer than $a" >&2
        result=0
      fi
    done
  fi
  #case $result in
  #  0) echo "$a needs rebuild" >&2;;
  #esac
  return $result
}

main "$@"