#!/bin/bash

TV_script_dir=$(dirname $(readlink -f "$0"))
TV_base_dir=$(dirname $TV_script_dir)

if [ -d "$TV_base_dir/.tvscript" ] ; then
  TV_tar="yes"					# tar-Version
  TV_profile="$TV_base_dir/profile"
  TV_Wine_dir="$TV_base_dir/.wine"
else
  TV_profile="$HOME/.teamviewer/6"
  TV_Wine_dir="$TV_base_dir/wine"
fi

TV_Wine_bin="$TV_Wine_dir/bin"

# Wine from non-standard location
export PATH=$TV_Wine_bin:$TV_script_dir:$PATH:$TV_script_dir/xdg-utils-1.0.2/scripts
export LD_LIBRARY_PATH=$TV_Wine_dir/lib:$LD_LIBRARY_PATH
export WINEPREFIX="$TV_profile"
export WINEDLLPATH="$TV_Wine_dir/lib/wine"
export WINELOADER="$TV_Wine_bin/wine"
export WINESERVER="$TV_Wine_bin/wineserver"


function tv_Prepare()
{
  exec 2>&1				# redirect stderr

  setup_wine
  setup_wine_tweaks
  setup_tar_env
}

function tv_Run()
{
  exec 2>&1				# redirect stderr

  local binary="$1"
  shift					# Remove $0 "$@" contains all parameters except $0 (now: all after binary)

  "$TV_Wine_bin/$binary" "$@"
}

function tv_LogInfo()
{
  exec 2>&1					# redirect stderr

  echo "TeamViewer: 6.0.9380"
  echo "Profile: $HOME ($LOGNAME)"
  echo "Desktop: $DESKTOP_SESSION"

  if [ -x "$(type -p lsb_release)" ] ; then	# log information about the Linux distribution
    lsb_release -a
  else
    echo /etc/*-release
    for rfile in /etc/*-release ; do		# echo the head of the first valid *-release file
      if [ -e "$rfile" ] ; then
        cat $rfile | head -n 10
        break
      fi
    done
  fi

  validate_user				# die if root
  validate_binary "$1"

  echo " "
}

function setup_wine()
{
  # setup dosdevices and symlinks
  local c_sym="$WINEPREFIX/dosdevices/c:"
  local c_dir="$WINEPREFIX/drive_c/"
  local z_sym="$WINEPREFIX/dosdevices/z:"
  local z_dir="/"
  make_path "$WINEPREFIX/dosdevices"
  setup_drive_symlink "$c_sym" "$c_dir"
  setup_drive_symlink "$z_sym" "$z_dir"

  # setup program files and logfile symlinks
  setup_prog_dir
  setup_log_symlink
}

# ensure path exists
function make_path()
{
  local path="$1"
  [ -d "$path" ] || mkdir -p "$path" || die "Could not create $path"
}

# setup/validate drive symlinks
function setup_drive_symlink()
{
  local sym="$1"
  local dst="$2"

  if ! ( [ -h "$sym" ] && [ -d "$sym" ] ) ; then
    rm -f "$sym"
  fi
  [ -d "$sym" ] || ln -s "$dst" "$sym" || die "Could not create $sym (link to $dst)"
}

# setup logfile symlinks
function setup_log_symlink
{
  local cuser=$(id -un)
  local basepath="$WINEPREFIX/drive_c/users/$cuser"

  [ -d "$basepath" ] || return	# does not (yet) exist, probably first call of wrapper

  local nameLog="TeamViewer6_Logfile.log"
  local nameWinelog="winelog"
  local logs="logfiles"

  if ! [ -e "$WINEPREFIX/$logs" ] ; then
    local dst=$( find "$basepath" | grep -m 1 $nameLog )
    if [ -e "$dst" ] ; then
      local dstdir=$(dirname "$dst")
      ln -s "$dstdir" "$WINEPREFIX/$logs"				# Create a symlink to the TeamViewer logfiles
      ln -s "$WINEPREFIX/$nameWinelog" "$WINEPREFIX/$logs/$nameWinelog"	# Include a winelog-symlink in that folder
    fi
  fi
}

# setup/validate win symlinks
function setup_win_symlink()
{
  local sym="$WINEPREFIX/$1"
  local dst="$TV_Wine_dir/$1"

  if [ -h "$sym" ] ; then
    [ "$(stat --dereference --format %i "$sym" 2> /dev/null)" = "$(stat --dereference --format %i "$dst")" ] || rm -f "$sym"
  fi

  [ -d $(readlink -f "$sym") ] || ln -s "$dst" "$sym" || die "Could not create $sym (link to $dst)"
}

function setup_prog_dir()
{
  local progdir="$WINEPREFIX/drive_c/Program Files/TeamViewer/Version6"
  local progsrc="$TV_Wine_dir/drive_c/Program Files/TeamViewer/Version6"

  if ! [ -d "$progdir" ] ; then
    mkdir -p "$progdir" || die "Could not create $progdir"
  fi

  # always check all files (may change due to updates)
  for item in $(ls "$progsrc") ; do
    if ! [ -e "$progdir/$item" ] ; then
      ln -s "$progsrc/$item" "$progdir/$item" || die "Could not create $progdir/$item (link to $progsrc/$item)"
    fi
  done
}

function setup_wine_tweaks()
{
  # Enable Subpixel Hinting
  if ! [ -e "$WINEPREFIX/.set_fontsmooth" ] ; then
    touch "$WINEPREFIX/.set_fontsmooth"
    "$WINELOADER" regedit "$TV_script_dir/fontsmooth_rgb.reg"
  fi

  # Disable XVidExtension (causes problems with some drivers)
  if ! [ -e "$WINEPREFIX/.set_xvidmode" ] ; then
    touch "$WINEPREFIX/.set_xvidmode"
    "$WINELOADER" regedit "$TV_script_dir/no_xvidmodeext.reg"
  fi

  # Disable XRandR (causes problems with some drivers)
  if ! [ -e "$WINEPREFIX/.set_xrandr" ] ; then
    touch "$WINEPREFIX/.set_xrandr"
    "$WINELOADER" regedit "$TV_script_dir/no_xrandr.reg"
  fi

  # Disable synchronizing of file associations and menu entries
  if ! [ -e "$WINEPREFIX/.set_fileassoc" ] ; then
    touch "$WINEPREFIX/.set_fileassoc"
    "$WINELOADER" regedit "$TV_script_dir/no_fileassocs.reg"
  fi
}

function setup_tar_env()
{
  local dsrc="$TV_script_dir/teamviewer.desktop.template"
  local ddst="$TV_script_dir/teamviewer.desktop"
  local texec="$TV_script_dir/teamviewer"
  local ticon="$TV_script_dir/teamviewer.png"

  # Create a desktop shortcut
  if [ "$TV_tar" = "yes" ] && ( ! [ -e "$ddst" ] ) ; then
    # adapt desktop file
    sed -e "s|EXEC|$texec|g" \
        -e "s|ICON|$ticon|g" \
        "$dsrc" > "$ddst"

    # create symlink for the desktop-file
    ln -s ".tvscript/teamviewer.desktop" "$TV_base_dir/teamviewer.desktop"
  fi
}

function validate_user()
{
  local userid=$(id -u)

  if [ $userid = 0 ] ; then
    die "TeamViewer must not be executed as root!"
  fi
}

function validate_binary()
{
  local binary="$1"

  if ! ( [ "$binary" = "wine" ] || [ "$binary" = "wineserver" ] ) ; then
    die "unexpected parameter $binary"
  fi
}

function die()
{
  echo -e "\nError: $@\n"
  exit 1
}

# go!
make_path "$WINEPREFIX"		# path for winelog must exist
set -o pipefail			# exit if tv_LogInfo dies
tv_LogInfo "$1"	| tee $WINEPREFIX/winelog	|| exit 1
echo "Checking setup..."
tv_Prepare	>> $WINEPREFIX/winelog
echo "Launching $2..."
tv_Run "$@"	>> $WINEPREFIX/winelog

