#!/bin/bash
#       wrapper
#   Script to set up the Picasa environment and launch an executable
#   Invoke with WINEDEBUG set to enable debug messages.

# Compute a directory 
mydir=`dirname "$0"`
mydir=`readlink -f "$mydir"`
parentdir=`dirname $mydir`

GUIMSG=true
type xmessage > /dev/null 2>&1 && GUIMSG=xmessage
type gmessage > /dev/null 2>&1 && GUIMSG=gmessage
type kmessage > /dev/null 2>&1 && GUIMSG=kmessage

warn_user() {
    # First, send it to stdout for the power users who like looking at the console
    echo "$@"
    # Then send it to a GUI thingy for everyone else
    $GUIMSG -center -buttons "    Continue    ":7,"    Quit    ":8 -title "Warning" "$@"
    case $? in
      7)  ;;         # user picked 'Continue'
      8)  exit 1 ;;  # user picked 'Quit'
    esac
}

prompt_info() {
  echo "$@"
  $GUIMSG -center -buttons "    OK    " -title "Warning" "$@"
}

convert_path() {
  WINFILE_PAT="^[A-Za-z]:\\\\"

  echo "$1" | grep -qs "$WINFILE_PAT"
  if [ "$?" = "0" ] ; then
    echo $1
  else
    if [ -d "$1" ] ; then
      echo "$1" | grep -qs "/$" || BACKSLASH="/"
    fi
    winepath -w "${1}${BACKSLASH}"
  fi
}

check_dejavu_fonts() {
  local registry_export=`mktemp /tmp/picasa.dejavucheck.reg.XXXXXX`

  "${WINELOADER:-wine}" regedit /E $registry_export HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\External\ Fonts
  grep -q "DejaVu Sans" $registry_export
  has_dejavu=$?
  grep -q "DejaVu LGC Sans" $registry_export
  has_dejavulgc=$?

  if [ "$has_dejavu" -eq "0" ] ; then
    "${WINELOADER:-wine}" rundll32.exe setupapi.dll,InstallHinfSection UpdateTahomaFont 128 picasa.inf
  elif [ "$has_dejavulgc" -eq "0" ] ; then
    "${WINELOADER:-wine}" rundll32.exe setupapi.dll,InstallHinfSection UpdateTahomaFontLGC 128 picasa.inf
  fi

  rm -f $registry_export
}

run_picasa() {
  RESAMPLE="/resamplefile"
  RESERVED="locate print"
  PICASAURL_PAT="^picasa://"

  exe="$1"
  shift
  if [ "$1" = "/gate" ] ; then
    gate="$1"
    prog="$2"
    shift 2
  fi

  while [ "$*" != "" ]
  do
    IS_RESERVED=0
    if [ "$1" = "$RESAMPLE" ] ; then
        if [ $# -ge 3 ] ; then
          ARG[${#ARG[@]}]="$1"
          ITEM=`convert_path "$2"`
          ARG[${#ARG[@]}]="$ITEM"
          ITEM=`convert_path "$3"`
          ARG[${#ARG[@]}]="$ITEM"
          shift 3
        else
          ARG[${#ARG[@]}]="$1"
          shift
        fi
        continue
    fi
    for f in $RESERVED ; do
      if [ "$f" = "$1" ] ; then
        IS_RESERVED=1
        break
      fi
    done
    if [ "$IS_RESERVED" = "0" ] ; then
      echo "$1" | grep -qs "$PICASAURL_PAT" && IS_RESERVED=1
    fi
    test "$IS_RESERVED" = "0" -a ! -e "$1" && IS_RESERVED=1
    if [ "$IS_RESERVED" = "1" ] ; then
      ITEM="$1"
    else
      ITEM=`convert_path $1`
    fi
    ARG[${#ARG[@]}]="$ITEM"
    shift
  done

  # Redirect picasa output to ~/.picasa/picasa.log if we're not debugging
  if test "z$WINEDEBUG" = z ; then
    exec > "$WINEPREFIX/picasa.log" 2>&1
  fi

  if [ -z "$gate" ] ; then
    exec "${WINELOADER:-wine}" "$exe" "${ARG[@]}"
  else
    exec "${WINELOADER:-wine}" "$exe" "$gate" "$prog" "${ARG[@]}"
  fi
}

# This test is to work around a problem with libGL provided by NVidia.
HAVE_NVIDIA_HARDWARE=0
LSMOD=`which lsmod 2>/dev/null`
if [ ! "$LSMOD" ] ; then
    if [ -x /sbin/lsmod ] ; then
        LSMOD=/sbin/lsmod
    fi
fi

if [ "$LSMOD" ] ; then
    "$LSMOD" | grep -q nvidia
    if [ $? -eq 0 ] ; then
        HAVE_NVIDIA_HARDWARE=1
    fi
fi

if test "$HAVE_NVIDIA_HARDWARE" = "1" -a -e /dev/nvidia0; then
    if test ! -w /dev/nvidia0 -o ! -r /dev/nvidia0 -o \
           ! -w /dev/nvidiactl -o ! -r /dev/nvidiactl; then
        warn_user "
/dev/nvidia0 or /dev/nvidiactl are not accessable.  Picasa will crash
if these files are not accessable. To fix this, as root, please run:

chmod 666 /dev/nvidia0 /dev/nvidiactl

and then restart this program."
        exit 1
    fi
fi

# Make sure we can run 32-bit programs on a 64-bit system
if [ "`uname -m`" = "x86_64" ] ; then
    ldd "$parentdir/wine/bin/wine" > /dev/null
    if [ $? -gt 0 ] ; then
        prompt_info "Your 64-bit machine does not have the libraries to run 32-bit applications.
Please visit http://wiki.winehq.org/UsingWineOn64bit for information
regarding running 32-bit applications on 64-bit machines."
        exit 1
    fi
fi

# Set the environment up
export PATH=$parentdir/wine/bin:$mydir:"$mydir/xdg-utils-1.0.2/scripts":"$mydir/xdg-user-dirs-0.8/bin":$PATH
export LD_LIBRARY_PATH=$parentdir/wine/lib:$parentdir/lib:$LD_LIBRARY_PATH
export WINEDLLPATH=$parentdir/wine/lib/wine
export WINELOADER=$parentdir/wine/bin/wine
export WINESERVER=$parentdir/wine/bin/wineserver
export WINEPREFIX=$HOME/.picasa

if [ -n "$PICASA_WINEPREFIX" ] ; then
     # User specified a prefix in the environment, use it
     export WINEPREFIX="$PICASA_WINEPREFIX"
elif [ ! -d "$WINEPREFIX" ] ; then
    fstype=`stat --filesystem --format %T --dereference $HOME 2>/dev/null`
    if [ "$fstype" = "nfs" ] ; then
        # Home directory is on a remote volume; that can be very slow.
        # The user can set PICASA_WINEPREFIX to point to a local dir to avoid this.
        # Alternately, since environment variables like that are not easy to set sitewide,
        # sysadmins can create a direct subdirectory of /usr/local with permissions 1777.
        LOCALDIR=/var/opt/picasa

        # Super special exception - if we find a directory under /usr/local that is set
        #   up with 1777 permissions, let's presume that it was set up for this purpose, and use it
        if [ ! -d "$LOCALDIR" ] ; then
            LOCALDIR=`find /usr/local -maxdepth 1 -type d -perm 1777 2>/dev/null | head -1`
        fi

        ALTPREFIX="$LOCALDIR/$LOGNAME/.picasa"
        [ -d "$ALTPREFIX" ] || ( [ -d "$LOCALDIR" ] && mkdir -p "$ALTPREFIX" 2>/dev/null && touch "$ALTPREFIX/.here")
        if [ -f "$ALTPREFIX/.here" ] ; then
            # Leave a symlink behind.  
            ln -sf "$ALTPREFIX" "$WINEPREFIX"
            # but don't use it for this run, go straight to the symlink's target
            WINEPREFIX=$ALTPREFIX
        else
            warn_user "Performance may be poor if ~/.picasa is not on a local drive. 
You can work around this in several ways:
- by making ~/.picasa a symlink to a directory on a local drive,
- by setting the environment variable PICASA_WINEPREFIX, or 
- by creating a directory /var/opt/picasa/$LOGNAME/ which you have rights to
  (in which case Picasa will use /var/opt/picasa/$LOGNAME/.picasa).
- by creating a directory /usr/local/data with mode 1777
  (in which case Picasa will use /usr/local/data/$LOGNAME/.picasa).
If you make this change, be sure to remove the ~/.picasa directory we're about to create.
See also http://wiki.winehq.org/HomeDirectoryOnNFS."
        fi
    fi
fi


# Test to see if they are trying to run two versions of Picasa side by side
#   the indication is that ~/.picasa would be in use by another version of Picasa
sfile="drive_c/Program Files/Picasa2/Picasa2.exe"
if [ -f "$WINEPREFIX/$sfile" ] ; then
    if [ "`stat --dereference --format %i "$WINEPREFIX/$sfile"`" != "`stat --dereference --format %i "$parentdir/wine/$sfile"`" ] ; then
        warn_user "You appear to be running Picasa from two different directories.  
That will cause problems because both versions are trying to use $WINEPREFIX.
We recommend installing this version in the same directory and upgrading it in place.
You can cause this version of Picasa to use a completely different user configuration
directory by setting the environment variable PICASA_WINEPREFIX to a different directory before running.
Alternately, if you completely delete the $WINEPREFIX directory, then you can switch
to using this version.  However, then you will not be able to go back to the previous version."
        exit 1
    fi
fi

# Test for broken or incorrect WINEPREFIX and fix it up
[ -d "$WINEPREFIX" ] || mkdir -p "$WINEPREFIX"
[ -d "$WINEPREFIX/drive_c" ] || mkdir -p "$WINEPREFIX/drive_c"
[ -d "$WINEPREFIX/drive_c/Program Files" ] || mkdir -p "$WINEPREFIX/drive_c/Program Files"
[ -d "$WINEPREFIX/drive_c/windows" ] || mkdir -p "$WINEPREFIX/drive_c/windows"
[ -d "$WINEPREFIX/drive_c/windows/temp" ] || mkdir -p "$WINEPREFIX/drive_c/windows/temp"
[ -d "$WINEPREFIX/drive_c/windows/inf.done" ] || mkdir -p "$WINEPREFIX/drive_c/windows/inf.done"
[ -d "$WINEPREFIX/drive_c/windows/profiles" ] || mkdir -p "$WINEPREFIX/drive_c/windows/profiles"
[ -d "$WINEPREFIX/drive_c/windows/profiles/All Users/Start Menu/Programs" ] || mkdir -p "$WINEPREFIX/drive_c/windows/profiles/All Users/Start Menu/Programs"
[ -d "$WINEPREFIX/dosdevices" ] || mkdir -p "$WINEPREFIX/dosdevices"

# Repair/establish symlink dirs
for sdir in \
           "drive_c/Program Files/wine_gecko" \
	   drive_c/windows/command  \
	   drive_c/windows/fonts \
	   drive_c/windows/inf \
	   "drive_c/windows/profiles/All Users/Start Menu/Programs/Picasa2" \
	   drive_c/windows/system \
	   drive_c/windows/system32  \
  ; do 
  # Remove broken links first, in case they moved Picasa somewhere
  if [ -h "$WINEPREFIX/$sdir" ] ; then
    if [ "`stat --dereference --format %i "$WINEPREFIX/$sdir"`" = "`stat --dereference --format %i "$parentdir/wine/$sdir"`" ] ; then
    	continue;
    fi
    rm -f "$WINEPREFIX/$sdir"
  fi

  # Now link it
  [ -d "$WINEPREFIX/$sdir" ] || ln -s "$parentdir/wine/$sdir" "$WINEPREFIX/$sdir"

done

# Special case:  the .inf creation process (below) needs to populate system32, which
#  we can't do if the symlink is read only (e.g. Debian or RPM installs)
#  We have similar concerns about command/start.exe, and we're just being safe by adding system/ too
for sdir in \
	   drive_c/windows/command  \
	   drive_c/windows/system \
	   drive_c/windows/system32  \
  ; do 
  if [ -h "$WINEPREFIX/$sdir" -a ! -w "$WINEPREFIX/$sdir/" ] ; then
    rm -f "$WINEPREFIX/$sdir"
    sdirloc=`dirname "$WINEPREFIX/$sdir"`
    cp -prd "$parentdir/wine/$sdir" "$sdirloc"
  fi
done

# Upgrade alert - we're no longer symlinking all of Program Files/Picasa2, just individual dirs
[ -h "$WINEPREFIX/drive_c/Program Files/Picasa2" ] && rm -f "$WINEPREFIX/drive_c/Program Files/Picasa2"  

# Make the Program Files/Picasa2 directory, mostly full of symlinks
[ -d "$WINEPREFIX/drive_c/Program Files/Picasa2" ] || mkdir -p "$WINEPREFIX/drive_c/Program Files/Picasa2"  
(cd "$parentdir/wine/drive_c/Program Files/Picasa2";
    for x in * ; do 
      # Remove broken links first, in case they moved Picasa somewhere
      oldlink="`pwd`/$x"
      newlink="$WINEPREFIX/drive_c/Program Files/Picasa2/$x"
      if [ -h "$newlink" ] ; then
	    if [ "`stat --dereference --format %i "$oldlink"`" = "`stat --dereference --format %i "$newlink"`" ] ; then
		continue;
	    fi
            rm -f "$newlink"
      fi

      # Now link it
      [ -d "$newlink" ] || ln -s "$oldlink" "$newlink"

    done 
)

# The whole point of this exercise is to make temp be writable, make dang sure it's
#	not symlinked (should only be a problem during upgrades from 2.2.2820-3)
[ -h "$WINEPREFIX/drive_c/Program Files/Picasa2/temp" ] && rm -f "$WINEPREFIX/drive_c/Program Files/Picasa2/temp"  


# Repair/establish symlink files
for sfile in generic.ppd ; do 

  # Remove broken links first, in case they moved Picasa somewhere
  if [ -h "$WINEPREFIX/$sfile" ] ; then
    if [ "`stat --dereference --format %i "$WINEPREFIX/$sfile"`" = "`stat --dereference --format %i "$parentdir/wine/$sfile"`" ] ; then
	continue;
    fi

    rm -f "$WINEPREFIX/$sfile"
  fi

  # Now link it
  [ -f "$WINEPREFIX/$sfile" ] || ln -s "$parentdir/wine/$sfile" "$WINEPREFIX/$sfile"

done

# Make sure the dosdevices are set up
if [ -h "$WINEPREFIX/dosdevices/c:" ] ; then
  [ -d "$WINEPREFIX/dosdevices/c:" ] || rm -f "$WINEPREFIX/dosdevices/c:"
fi
[ -d "$WINEPREFIX/dosdevices/c:" ] || ln -s "$WINEPREFIX/drive_c/" "$WINEPREFIX/dosdevices/c:"

if [ -h "$WINEPREFIX/dosdevices/z:" ] ; then
  [ -d "$WINEPREFIX/dosdevices/z:" ] || rm -f "$WINEPREFIX/dosdevices/z:"
fi
[ -d "$WINEPREFIX/dosdevices/z:" ] || ln -s / "$WINEPREFIX/dosdevices/z:"

# Clean up any removable drive symlinks that no longer point to attached
# devices. These are automatically created by Wine (in programs/explorer/hal.c)
# but don't appear to ever get removed.
for drivelink in "$WINEPREFIX/dosdevices/"* ; do
  # We should only be dealing with symlinks here.
  if [ ! -L "$drivelink" ] ; then
    continue
  fi

  # Removable drive links have an associated "drive::" link, with two colons,
  # which represents the device that is mounted on the "drive:".
  if [ ! -L "$drivelink:" ] ; then
    continue
  fi

  # If the "drive:" doesn't point to a mount point for the "device::", then get
  # rid of the symlink.
  mount | grep -q "^$(readlink -f "$drivelink:") on $(readlink -f "$drivelink")"
  if [ $? -ne 0 ] ; then
    rm -f "$drivelink"
  fi
done


# Work the argument to find the thing to run
if [ $# -gt 0 ] ; then
    if [ "$1" != "wineserver" ] ; then
      if [ -f "$1" -o "$1" = "PicasaMediaDetector" ] ; then
        exe="$1"
        shift
      else
        exe=`find "$WINEPREFIX/drive_c/Program Files/" -follow -iname "$1"`
        if [ ! -f "$exe" ] ; then
          exe=`find "$WINEPREFIX/drive_c/Program Files/" -follow -iname "$1.exe"`
          if [ ! -f "$exe" ] ; then
            exe=`find "$parentdir/wine/lib/" -iname "$1"`
            if [ ! -f "$exe" ] ; then
              exe=`find "$parentdir/wine/lib/" -iname "$1.so"`
              if [ ! -f "$exe" ] ; then
                exe=`find "$parentdir/wine/lib/" -iname "$1.exe.so"`
              fi
            fi
          fi
        fi
        if [ -z "$exe" ] ; then
          exe="$1"
        fi
        shift
      fi
    fi
fi

# Redirect output to /dev/null if we're not debugging
if test "z$WINEDEBUG" = z ; then
    exec >/dev/null 2>&1
fi

new_install=0
upgrade=0

if [[ ! -f "$WINEPREFIX/user.reg" || ! -f "$WINEPREFIX/userdef.reg" || \
    ! -f "$WINEPREFIX/system.reg" ]] ; then
    new_install=1
fi

# Apply the .inf files (reapply if they've changed)
for infcmd in wine.inf/DefaultInstall mozctl.inf/Mozctl picasa.inf/DefaultInstall ; do
    inffile=`echo $infcmd | cut -d '/' -f 1`
    inftype=`echo $infcmd | cut -d '/' -f 2`

    runreg=0
    if [ -f "$WINEPREFIX/drive_c/windows/inf.done/$inffile" ] ; then
        diff -q "$WINEPREFIX/drive_c/windows/inf/$inffile" "$WINEPREFIX/drive_c/windows/inf.done/$inffile"  >/dev/null 2>&1
        if [ $? -ne 0 ] ; then
            runreg=1
            upgrade=1
        fi
    else
        runreg=1
    fi

    if [ $runreg -gt 0 ] ; then
        "${WINELOADER:-wine}" rundll32.exe setupapi.dll,InstallHinfSection $inftype 128 $inffile
        cp "$WINEPREFIX/drive_c/windows/inf/$inffile" "$WINEPREFIX/drive_c/windows/inf.done/$inffile" 
    fi
done

if [ $new_install -gt 0 ] ; then
    # save XDG environment variables
    XDG_CONFIG_DIRS_SAVE="$XDG_CONFIG_DIRS"
    XDG_DATA_DIRS_SAVE="$XDG_DATA_DIRS"

    # run xdg-user-dirs-update if needed
    if [ ! -f "${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs" ] ; then
        # set env vars if we using our copy of xdg-user-dirs-update
        if [ "`stat --format %i --dereference "$(which xdg-user-dirs-update)"`" = "`stat --format %i --dereference "$mydir/xdg-user-dirs-0.8/bin/xdg-user-dirs-update"`" ] ; then
            XDG_CONFIG_DIRS="$mydir/xdg-user-dirs-0.8/etc/xdg"
            XDG_DATA_DIRS="$mydir/xdg-user-dirs-0.8/share"
            export XDG_CONFIG_DIRS XDG_DATA_DIRS
        fi
        xdg-user-dirs-update
    fi

    # restore XDG environment variables
    XDG_CONFIG_DIRS="$XDG_CONFIG_DIRS_SAVE"
    XDG_DATA_DIRS="$XDG_DATA_DIRS_SAVE"
    export XDG_CONFIG_DIRS XDG_DATA_DIRS

    check_dejavu_fonts
    rm -f $registry_export
fi

if [ $upgrade -gt 0 ] ; then
    registry_export=`mktemp /tmp/picasa.upgradecheck.reg.XXXXXX`

    "${WINELOADER:-wine}" regedit /E $registry_export HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Hardware\ Profiles\\Current\\Software\\Fonts\\
    grep -q "FIXED.FON" $registry_export
    if [ $? -eq 0 ] ; then
        "${WINELOADER:-wine}" rundll32.exe setupapi.dll,InstallHinfSection UpdateFixedFont 128 picasa.inf
    fi
    check_dejavu_fonts
    rm -f $registry_export
fi

# Go
if [ "$1" = "wineserver" ] ; then
    shift
    exec "${WINESERVER:-wineserver}" "$@" 
else
    if [ "$exe" = "$WINEDLLPATH/license.exe.so" ] ; then
	run_picasa "$exe" "$@"
    fi
    exec "${WINELOADER:-wine}" "$exe" "$@" 
fi
