#!/bin/bash

## Copyright (C) 2012 - 2023 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## This file gets sourced by msgdispatcher and msgprogressbar.
## Therefore the error_handler function has been already load.

fallbacks() {
   trap "error_handler" ERR

   if [ "$DISPLAY" = "" ]; then
      no_x="1"
   fi

   ## Check if zenity is installed.
   ## - This is not the case for cli users,
   ##   who removed zenity or custom builds which never had zenity installed.
   if [ "$(command -v "zenity")" = "" ] || [ "$DISPLAY" = "" ]; then
      ## zenity is not installed or no X server running.
      zenity() {
         ## dummy
         true
      }
   fi

   if [ "$(command -v "wmctrl")" = "" ] || [ "$DISPLAY" = "" ]; then
      ## wmctrl is not installed or no X server running.
      wmctrl_dummy=true
      wmctrl() {
         ## dummy
         true
      }
   else
      wmctrl_dummy=false
   fi

   if [ "$(command -v "xwininfo")" = "" ] || [ "$DISPLAY" = "" ]; then
      ## xwininfo (package x11-utils) is not installed or no X server running.
      xwininfo() {
         ## dummy
         true
      }
   fi

   if [ "$(command -v "kdialog")" = "" ] || [ "$DISPLAY" = "" ]; then
      ## kdialog is not installed or no X server running.
      kdialog() {
         ## dummy
         true
      }
   fi

   if [ "$(command -v "notify-send")" = "" ] || [ "$DISPLAY" = "" ]; then
      ## notify-send is not installed or no X server running.
      notify-send() {
         ## dummy
         true
      }
   fi

   if [ "$display" = "" ]; then
      display="$DISPLAY"
   fi
}

get_own_window_title() {
   trap "error_handler" ERR

   sleep .5 &
   wait "$!" || true

   ## TODO
   if [ "$autostart" = "1" ]; then
      ## Runs in background anyway, waiting a bit longer does not hurt.
      local max_wait="120"
   else
      local max_wait="60"
   fi

   if [ "$wmctrl_dummy" = "true" ]; then
      local max_wait="0"
   fi

   local counter
   counter="0"

   local xwininfo_output xwininfo_first_useful_line

   while true; do
      if [ ! "$WINDOWID" = "" ]; then
         true "WINDOWID: $WINDOWID Success."
         break
      fi

      counter="$(( $counter + 1 ))"

      if [ "$counter" -ge "$max_wait" ]; then
         true "Giving up on \$WINDOWID. Not found after $max_wait seconds."
         own_window_title="false"
         return 0
      else
         true "Waiting for \$WINDOWID up to $max_wait seconds. This might take a while. Please do not abort this! $counter / $max_wait"
         sleep "1" &
         wait "$!" || true
      fi
   done

   xwininfo_output="$(xwininfo -id "$WINDOWID" 2>&1)"
   ## contains:
   ## xwininfo: Window id: 0x2600012 "~/Whonix/packages/msgcollector : bash"

   own_window_title="$(echo "$xwininfo_output" | awk -F'"' '/Window id/ {print $2}')"
   ## Example own_window_title:
   ## ~/Whonix/packages/msgcollector : bash

   true "own_window_title: $own_window_title"
}

output_wait_for_window() {
   trap "error_handler" ERR

   local title="$@"

   sleep .5 &
   wait "$!" || true

   ## TODO
   if [ "$autostart" = "1" ]; then
      ## Runs in background anyway, waiting a bit longer does not hurt.
      local max_wait="120"
   else
      local max_wait="60"
   fi

   local counter
   counter="0"

   while true; do
      ## "2>/dev/null" to hide output "Can not open display.", when not yet available.
      local wmctrl_list
      ## Getting a list of all existing windows.
      wmctrl_list="$(wmctrl -l 2>/dev/null)" || true

      local grep_exit_code
      grep_exit_code="0"
      echo "$wmctrl_list" | grep --quiet --fixed-strings -- "$title" || { grep_exit_code="$?" ; true; };

      if [ "$grep_exit_code" = "0" ]; then
         true "Found window title \"$title\"."
         window_title_found="true"
         break
      fi

      counter="$(( $counter + 1 ))"

      if [ "$counter" -ge "$max_wait" ]; then
         true "Giving up on wmctrl. Window title \"$title\" not found after $max_wait seconds."
         window_title_found="false"
         break
      else
         true "Waiting for window title \"$title\" up to $max_wait seconds. This might take a while. Please do not abort this! $counter / $max_wait"
         sleep "1" &
         wait "$!" || true
      fi
   done
}

output_wmctrl_move_window_to_left_top() {
   ## Move windows to the left top, so they do not overlap.
   ## Thanks to: http://user.cavenet.com/rolandl/timer.txt

   trap "error_handler" ERR

   if [ "$no_x" = "1" ]; then
      true "no_x is set to 1, do not try wmctrl, return 0 from output_wmctrl."
      return 0
   fi

   local title="$@"

   output_wait_for_window "$title"

   ## Wait a bit longer. Otherwise it might still fail in some cases.
   sleep "1" &
   wait "$!" || true

   ## Move windows to the left top.
   wmctrl -r "$title" -e 0,0,0,-1,-1 >/dev/null 2>/dev/null || true
}

output_wmctrl_maximize_window() {
   trap "error_handler" ERR

   if [ "$no_x" = "1" ]; then
      true "no_x is set to 1, do not try wmctrl, return 0 from output_wmctrl."
      return 0
   fi

   local title="$@"

   output_wait_for_window "$title"

   if [ "$progressbar" = "1" ]; then
      true "Not maximizing progress bar."
   else
      ## Wait a bit longer. Otherwise it might still fail in some cases.
      sleep "1" &
      wait "$!" || true

      ## Maximize window.
      wmctrl -r "$title" -b add,maximized_vert,maximized_horz >/dev/null 2>/dev/null || true
   fi
}
