#!/bin/bash

###########################################################
## Copyright (c) 2002-2024 Alexey Kuryakin daqgroup@mail.ru
###########################################################

###########################################################
## Find window by title [ and maybe class, pid, exe, host].
###########################################################

###########################################################
source $(crwkit which crwlib_base.sh); # Use base library #
source $(crwkit which crwlib_file.sh); # Use file library #
###########################################################

let fatal_notify_uses=0;

function do_help(){
 local name="$(basename ${BASH_SOURCE[0]})";
 echo "$name version 1.0";
 if [ $1 -eq 0 ]; then return 0; fi;
 echo "Copyright (c) 2002-2024 Alexey Kuryakin daqgroup@mail.ru";
 echo "$name - find window by title [ class, pid, exe, host ].";
 echo "Usage:";
 echo " $name [-options] [parameters]";
 echo "Options:";
 echo " --help           - print help.";
 echo " --version        - print version.";
 echo " -i,--ignore-case - ignore char case";
 echo " -c,--class c     - also match window class (c)";
 echo " -p,--pid p       - also match process PID  (p)";
 echo " -e,--exe e       - also match executable   (e)";
 echo " -h,--host h      - also match host name    (h)";
 echo " --               - end of options, followed params";
 echo "Parameters:";
 echo " title - target window title (mandatory)";
 echo " class - target window class (optional)";
 echo " exe   - target exe or pid   (optional)";
 echo "Notes:";
 echo " 1) -opt and --opt options are equivalent.";
 echo "    for example: -pid and --pid are synonyms.";
 echo " 2) title,class,host may be a regexp like '.*'";
 echo " 3) exe must be a basename of executable";
 echo " 4) pid must be a number = process PID";
 echo "Output:";
 echo " On succeed (found) print table:";
 echo "  win desk pid class host title";
 echo "   win   - window   ID  like 0x0340000c";
 echo "   desk  - desktop  ID  like 1";
 echo "   pid   - process PID  like 9832";
 echo "   class - window class like xterm.XTerm";
 echo "   host  - host name    like $(hostname)";
 echo "   title - window title like Double Commander";
 echo "Examples:";
 echo " unix $name --help";
 echo " unix $name --version";
 echo " unix $name '*'";
 echo " unix $name 'KCalc'";
 echo " unix $name -p 9812 'KCalc'";
 echo " unix $name -e kcalc 'KCalc'";
 echo " unix $name -i -c 'kcalc.kcalc' 'kcalc'";
 echo " unix $name -i -e kcalc -c 'kcalc.kcalc' -h $(hostname) 'KCalc'";
};

declare opt_i="";
declare host=".*";
declare pids=".*";
declare class=".*";

function findwindow(){
 local title="$1"; 
 if [ -n "$title" ]; then
  local win="$(wmctrl -lpx | grep $opt_i " $title" | grep $opt_i " $class " | grep $opt_i " $host " | grep -P " $pids " | grep '0x')";
  if [ -n "$win" ]; then
   echo "$win";
  else
   fatal 1 "Error: not found window: \"$title\".";
  fi;
 else
  fatal 1 "Error: invalid arguments: $@.";
 fi;
};

function exe_pids(){
 if [ -n "$1" ]; then
  pgrep -lf $opt_i "$1" | awk '{print $1}' | xargs;
 fi;
};

function do_opt_i(){
 opt_i="-i";
};

function do_opt_c(){
 if [ -n "$1" ]; then
  class="$1";
 fi;
};

function do_opt_p(){
 local p="$1";
 if [ -n "$p" ]; then
  p="${p//,/ }"; p="${p//:/ }";
  p="$(echo "$p" | xargs)";
  pids="(${p// /|})";
 fi;
};

function do_opt_e(){
 if [ -n "$1" ]; then
  do_opt_p "$(exe_pids "$1")";
 fi;
};

function do_opt_h(){
 if [ -n "$1" ]; then
  host="$1";
 fi;
};

function handle_arguments(){
 if [ -n "$2" ]; then do_opt_c "$2"; fi;
 if [ -n "$3" ]; then if is_number "$3"; then do_opt_p "$3"; else do_opt_e "$3"; fi; fi;
 findwindow "$@";
};

function fail_on_empty(){
 if [ -z "$1" ]; then
  fatal 1 "Error: missed arguments.\nType unix $(basename ${BASH_SOURCE[0]}) --help for help.";
 fi;
};

function fail_on_missed(){
 while [ -n "$1" ]; do
  if which $1 >/dev/null 2>&1; then
   true;
  else
   fatal 1 "Error: $1 not found.\nPlease install it first.";
  fi;
  shift;
 done;
};

function main(){
 fail_on_empty "$@";
 fail_on_missed wmctrl grep pgrep xargs awk wc;
 while [ -n "$1" ]; do
  case $1 in
   -version|--version)              do_help 0; exit 0; ;;
   -help|--help)                    do_help 1; exit 0; ;;
   -i|-ignore-case|--ignore-case)   do_opt_i; ;;
   -c|-class|--class)               shift; do_opt_c "$1"; ;;
   -p|-pid|--pid)                   shift; do_opt_p "$1"; ;;
   -e|-exe|--exe)                   shift; do_opt_e "$1"; ;;
   -h|-host|--host)                 shift; do_opt_h "$1"; ;;
   --)                              shift; handle_arguments "$@"; break; ;;
   -*)                              fatal 1 "Error: unknown option $1."; ;;
   *)                               handle_arguments "$@"; break; ;;
  esac;
  shift;
  fail_on_empty "$@";
 done;
};

main "$@";

##############
## END OF FILE
##############
