#!/bin/bash -e

GoogleEarth_Package_VERSION="0.5.2"

GoogleEarth_bin_URL="http://dl.google.com/earth/client/current/GoogleEarthLinux.bin"
GoogleEarth_bin="GoogleEarthLinux.bin"

function usage() {
  echo "googleearth-package $GoogleEarth_Package_VERSION" >&2
  echo 'usage: make-googleearth-package [options]' >&2
  echo '  Creates a Debian package from the Google Earth GNU/Linux installer.' >&2
  echo '  By default, will look for the installer in the current directory.' >&2
  echo '  If not found it will be downloaded automatically.' >&2
  echo '' >&2
  echo '  --fullname <name> Use <name> as full name in Maintainer field' >&2
  echo '  --email <email>   Use <email> as email address in Maintainer field' >&2
  echo '  --file <file>     Use <file> instead of' $GoogleEarth_bin >&2
  echo '  --download        Always try to download a new version' >&2
  echo '  --cleanup         Delete the installer after building successfully' >&2
  echo '  --quiet           Suppress all intermediate build output' >&2
  echo '  --force           Attempt to build an unsupported version' >&2
  exit 1
}

function download() {
  local wget=`which wget`
  local curl=`which curl`
  local downloader

  if [ -x $wget ]; then
    downloader=$wget
  elif [ -x $curl ]; then
    downloader=$curl
  else
    echo 'Either wget or curl is required to download Google Earth!' >&2
    echo '(Or download it yourself and point to it with --file)' >&2
    return 1
  fi
  
  $downloader $GoogleEarth_bin_URL || \
    (echo 'Could not download Google Earth! (You may need to use --file)' >&2 && \
    false)
}

function check_version() {
  
  local version

  version=$(sh "$OPT_FILE" --info      | \
            grep -E '^Identification:' | \
            sed -e 's/Identification: //')

  echo $version >&2

  if grep -E 'GNU/Linux 4.[012]' <<<"$version" > /dev/null; then
    GoogleEarth_VERSION=$(sed -e 's/.*GNU\/Linux //' <<<"$version")
    echo 'Supported Google Earth version:' $GoogleEarth_VERSION >&2
  elif [ "$OPT_FORCE" ]; then
    echo 'Unrecognized Google Earth version; using anyway (because of --force).' >&2
    GoogleEarth_VERSION=$(sed -e 's/.*GNU\/Linux //' <<<"$version")
    echo 'Guessed Google Earth version:' $GoogleEarth_VERSION >&2
  else
    echo 'Unrecognized Google Earth version (use --force to build anyway)' >&2
    return 1
  fi

  if [ "$GoogleEarth_VERSION" == "" ]; then
    GoogleEarth_VERSION=unknown
  fi
}

function parse_args() {
  OPT_FULLNAME="$DEBFULLNAME"
  OPT_EMAIL="$DEBEMAIL"
  OPT_FILE="$GoogleEarth_bin"
  for ((;$#>0;)); do
    if [ "$1" == "--fullname" ]; then
      OPT_FULLNAME="$2"
      shift 2
    elif [ "$1" == "--email" ]; then
      OPT_EMAIL="$2"
      shift 2
    elif [ "$1" == "--file" ]; then
      OPT_FILE="$2"
      shift 2
    elif [ "$1" == "--download" ]; then
      OPT_DOWNLOAD=1
      shift 1
    elif [ "$1" == "--cleanup" ]; then
      OPT_CLEANUP=1
      shift 1
    elif [ "$1" == "--quiet" ]; then
      OPT_QUIET=1
      shift 1
    elif [ "$1" == "--noquiet" ]; then
      OPT_QUIET=0
      shift 1
    elif [ "$1" == "--force" ]; then
      OPT_FORCE=1
      shift 1
    else
      echo 'Unrecognized command-line argument: ' "$1" >&2
      return 1
    fi
  done
}

function verify_file_option() {
  if [ "$OPT_DOWNLOAD" == "1" ]; then
    exit 1
  elif [ "$OPT_FILE" == "$GoogleEarth_bin" ]; then
    [ -e "$OPT_FILE" ]
  elif [ "$OPT_FILE" ]; then
    if [ ! -e "$OPT_FILE" ]; then
      echo 'File not found:' "'$OPT_FILE'" >&2
      exit 1
    fi
  fi
}

function verify_architecture() {
  if [ "$(dpkg-architecture -qDEB_BUILD_ARCH)" != "i386" -a "$(dpkg-architecture -qDEB_BUILD_ARCH)" != "amd64" -a "$(dpkg-architecture -qDEB_BUILD_ARCH)" != "ia64" ]; then
    if [ "$OPT_FORCE" != "1" ]; then
      echo 'Not building on non-x86; use --force to override.'
      exit 1
    fi
  fi
}


function make_menu_entry() {
  cat <<EOF >googleearth
?package(googleearth): \
  needs="X11" \
  section="Applications/Science/Geoscience" \
  title="Google Earth" \
  command="/usr/bin/googleearth" \
  icon="/usr/share/pixmaps/googleearth.xpm"
EOF
}

function make_mime_entry() {
  cat <<EOF >googleearth
application/vnd.google-earth.kml+xml; /usr/bin/googleearth '%s'; edit=/usr/bin/googleearth '%s'; test=test "$DISPLAY" != "" ;description="Keyhole Markup Language data"; nametemplate=%s.kml
application/vnd.google-earth.kmz; /usr/bin/googleearth '%s'; edit=/usr/bin/googleearth '%s'; test=test "$DISPLAY" != "" ;description="Keyhole Markup Language archive"; nametemplate=%s.kmz
application/keyhole; /usr/bin/googleearth '%s'; edit=/usr/bin/googleearth '%s'; test=test "$DISPLAY" != "" ;description="Keyhole Markup Language data"
application/earthviewer; /usr/bin/googleearth '%s'; edit=/usr/bin/googleearth '%s'; test=test "$DISPLAY" != "" ;description="Keyhole Markup Language data"
EOF
}

# contents of desktop entry taken from postinstall.sh line 10
function make_fdo_desktop_entry() {
  cat <<EOF >googleearth.desktop
[Desktop Entry]
Name=Google Earth
GenericName=3D planet viewer
Comment=Explore, search and discover the planet
Exec=googleearth %f
Terminal=false
Type=Application
Icon=/usr/lib/googleearth/resources/googleearth-icon.png
Categories=Network;
MimeType=application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/earthviewer;application/keyhole;
EOF
}

# contents of shared mime info entry taken from postinstall.sh line 26
function make_fdo_shared_mime_info_entry() {
  cat <<EOF >googleearth-mimetypes.xml
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
  <mime-type type="application/vnd.google-earth.kml+xml">
    <comment>Keyhole Markup Language data</comment>
    <glob pattern="*.kml"/>
  </mime-type>

  <mime-type type="application/vnd.google-earth.kmz">
    <comment>Keyhole Markup Language archive</comment>
    <glob pattern="*.kmz"/>
  </mime-type>

  <mime-type type="application/keyhole">
    <comment>Keyhole Markup Language data</comment>
  </mime-type>

  <mime-type type="application/earthviewer">
    <comment>Keyhole Markup Language data</comment>
  </mime-type>
</mime-info>
EOF
}

function make_kde_mime_entry() {
  cat <<EOF >vnd.google-earth.kmz.desktop
[Desktop Entry]
Comment=Google Earth Placemarker
Hidden=false
Icon=/usr/share/pixmaps/googleearth.xpm
MimeType=application/vnd.google-earth.kmz
Patterns=*.kmz
Type=MimeType
X-KDE-AutoEmbed=false
EOF

  cat <<EOF >vnd.google-earth.kml+xml.desktop
[Desktop Entry]
Comment=Google Earth Placemarker
Hidden=false
Icon=/usr/share/pixmaps/googleearth.xpm
MimeType=application/vnd.google-earth.kml+xml
Patterns=*.kml
Type=MimeType
X-KDE-AutoEmbed=false
EOF

  cat <<EOF >keyhole.desktop
[Desktop Entry]
Comment=Keyhole Markup Language data
Hidden=false
Icon=/usr/share/pixmaps/googleearth.xpm
MimeType=application/keyhole
Patterns=
Type=MimeType
EOF

  cat <<EOF >earthviewer.desktop
[Desktop Entry]
Comment=Keyhole Markup Language data
Hidden=false
Icon=/usr/share/pixmaps/googleearth.xpm
MimeType=application/earthviewer
Patterns=
Type=MimeType
EOF
}

function make_maint_scripts() {
  cat <<EOF >postinst
#!/bin/bash
set -e
if [ -x /usr/bin/update-menus ]; then update-menus; fi
if [ -x /usr/sbin/update-mime ]; then update-mime; fi
if [ -x /usr/bin/update-desktop-database ]; then update-desktop-database -q; fi
if [ -x /usr/bin/update-mime-database ]; then update-mime-database /usr/share/mime; fi
EOF
  chmod a+x postinst
  cp postinst postrm
}

function make_wrapper_script {
  cat <<EOF >googleearth
#!/bin/sh
cd /usr/lib/googleearth
exec /lib/ld-linux.so.2 --library-path /usr/lib/googleearth /usr/lib/googleearth/googleearth-bin "\$@"
EOF
  chmod a+x googleearth
}

function make_control() {
  local elfs=$(find .. -type f -print0 | xargs -0 file | awk '$2 ~ /^ELF/ {print $1}' | sed 's/:$//')

  local sonames=$(for elf in $elfs; do objdump -p "$elf" | awk '$1 == "SONAME" && $2 !~ /^\.\// {print $2}'; done)
  for soname in $sonames; do sed -e 's/\.so\./ /' <<< "$soname"; done > shlibs.local

  mkdir debian/
  cat <<EOF >debian/control
Source: googleearth-package

Package: googleeearth
Depends:
EOF

  local deps=$(for elf in $elfs; do dpkg-shlibdeps -O -Lshlibs.local "$elf" | sed -e 's/^shlibs:Depends=//' -e 's/, /\n/g'; done | sort -u)
  local depends=$(while read dep; do echo -n "$dep, "; done <<< "$deps" | sed 's/, $//')

  # clean up dpkg-shlibdeps helper files
  rm shlibs.local
  rm debian/control
  rmdir debian
  
  if [ "$(dpkg-architecture -qDEB_BUILD_ARCH)" != "i386" ]; then
    ia32libs=", ia32-libs"
  fi

  cat <<EOF >control
Package: googleearth
Version: ${GoogleEarth_VERSION}+${GoogleEarth_Package_VERSION}-1
Section: non-free/science
Priority: optional
Maintainer: $OPT_FULLNAME <${OPT_EMAIL}>
Architecture: $(dpkg-architecture -qDEB_BUILD_ARCH)
Depends: ttf-dejavu | ttf-bitstream-vera | msttcorefonts, $depends $ia32libs
Description: Google Earth, a 3D map/planet viewer
 Package built with googleearth-package.
EOF
}

function make_md5sums() {
  (cd .. && find usr -type f -print0 | xargs -0 md5sum) > md5sums
}

function build_package() {
  umask 0022

  local instdir="`pwd`/googleearth-deb"
  local tmpdir="`pwd`/googleearth-tmp"

  rm -rf "$instdir" "$tmpdir"
  mkdir "$instdir" "$tmpdir"

  ln "$OPT_FILE" "$tmpdir"
  sh "$OPT_FILE" --tar -xvf -C "$tmpdir" >&2

  cd "$instdir"
  mkdir -p usr/lib/googleearth
  cd usr/lib/googleearth
  tar -xf "$tmpdir"/googleearth-linux-x86.tar
  tar -xf "$tmpdir"/googleearth-data.tar

  # debian menu entry
  cd "$instdir"
  mkdir -p usr/share/menu
  cd usr/share/menu
  make_menu_entry

  # mime-support mime info
  cd "$instdir"
  mkdir -p usr/lib/mime/packages
  cd usr/lib/mime/packages
  make_mime_entry

  # freedesktop.org desktop entry
  cd "$instdir"
  mkdir -p usr/share/applications
  cd usr/share/applications
  make_fdo_desktop_entry

  # freedesktop.org shared mime info entry
  # works for GNOME, KDE, xfce(?), others?
  cd "$instdir"
  mkdir -p usr/share/mime/packages
  cd usr/share/mime/packages
  make_fdo_shared_mime_info_entry

  # KDE MIME database entry
  cd "$instdir"
  mkdir -p usr/share/mimelnk/application
  cd usr/share/mimelnk/application
  make_kde_mime_entry

  cd "$instdir"
  mkdir -p usr/share/pixmaps
  cp "$tmpdir"/googleearth.xpm usr/share/pixmaps
 
  cd "$instdir"
  mkdir -p usr/share/doc/googleearth
  cp "$tmpdir"/README* usr/share/doc/googleearth

  cd "$instdir"
  mkdir -p usr/bin
  cd usr/bin
  make_wrapper_script

  cd "$instdir"
  mkdir DEBIAN
  cd DEBIAN
  make_maint_scripts
  make_control
  make_md5sums
  cat control >&2

  cd "$instdir"
  find usr/lib -type f -print0 | xargs -0 chmod 644
  chmod 755 usr/lib/googleearth/googleearth-bin
  chmod 755 usr/lib/googleearth/linux/mailto-scripts/*

  cd ..
  find "$instdir" -type d -print0 | xargs -0 chmod 755
  fakeroot dpkg-deb -b "$instdir" .

  if [ "$?" == "0" ] && [ "$OPT_CLEANUP" == "1" ]; then
    rm -f "$OPT_FILE"
  fi

  rm -rf "$instdir" "$tmpdir"

}

parse_args "$@" || usage || exit $?
if [ "$OPT_QUIET" == "1" ]; then
  exec "$0" "$@" --noquiet 2> /dev/null
fi
verify_file_option || download || exit $?
verify_architecture
check_version || exit $?
build_package || exit $?
echo 'Success!'
