#!/bin/bash

error() { #red text and exit 1
  echo -e "\e[91m$1\e[0m" 1>&2
  exit 1
}

if ! command -v yad &>/dev/null; then
  error "YAD needs to be installed to run Artian-Apps."
fi

if [[ $(id -u) == 0 ]]; then
  echo "Artian-Apps is not designed to be run as root! Please try again as a regular user." | yad --center --window-icon="${DIRECTORY}/icons/logo.png" \
  --width=700 --height=300 --text-info --title="Error" \
  --image="${DIRECTORY}/icons/error.png" --image-on-top --fontname=12 \
  --button='OK'
  error "Artian-Apps is not designed to be run as root! Please try again as a regular user."
fi

# set GUI format versioning
export GUI_FORMAT_VERSION=2

#display first 4 arguments this script receives (for debugging)
if false;then
  echo "1 $1" 1>&2
  echo "2 $2" 1>&2
  echo "3 $3" 1>&2
  echo "4 $4" 1>&2
fi

#if this script runs itself with a 3rd argument, then yad used it.
if [ ! -z "$3" ];then
  input="$3" #the 3rd argument is the "sysname" column - invisible and used internally for scripts.
  
  echo "Selection: $input" 1>&2
  
  refresh_list() { #Refresh the current list of apps in the event of a change
    if [ ! -z "$pipe" ];then
      echo -e "\f" > "$pipe"
      "${DIRECTORY}/preload" yad "$prefix" > "$pipe" 2>/dev/null
    fi
  }
  
  if [[ "$input" == *'Updates/' ]];then
    #updater window
    get_positions
    
    "${DIRECTORY}/updater" gui fast $geometry2 --skip-taskbar --close-on-unfocus
    exitcode=$? #0 if update successful, 1 if list of updates was closed
    
    #figure out which prefix we are on and refresh the app list
    prefix="$(echo "$input" | sed 's+Updates/$++g')"
    
    if [ $exitcode == 0 ];then
      refresh_list
    fi
  elif [ "$input" == 'Search/' ];then
    #search window
    get_positions
    
    source "${DIRECTORY}/api" #to set the yadflags array variable
    
    app="$(yadflags+=("$geometry2") ; app_search_gui)"
    
    if [ ! -z "$app" ];then
      "${DIRECTORY}/gui" '' "$app" "/$app" "$app"
    fi
    
  elif [[ "$input" == */ ]];then
    #app folder selected
    echo -e '\f' > $pipe #clear the yad list
    "${DIRECTORY}/preload" yad "${input::-1}" >> $pipe #send yad the app-list - derived from folder name but dropping the final slash character
    
  else #app details window
    
    # make sure terminal_manage function is available
    # the old updater did not source the new api script
    typeset -f terminal_manage &>/dev/null || { set -a; source "${DIRECTORY}/api"; }
    
    #app is in format $prefix/$app, so split them out
    app="$(basename "$input")"
    prefix="$(dirname "$input")"
    
    #add status heading
    app_status="$(app_status "${app}")"
    
    #text to the right of the app icon
    abovetext="<b>$app</b> ($(sed 's/corrupted/corrupted - installation failed/g' <<<"$app_status" | sed 's/disabled/disabled - installation is prevented on your system/g'))"
    
    #If package-app, show what packages it installs
    if [ -f "${DIRECTORY}/apps/${app}/packages" ];then
      packages="$(cat "${DIRECTORY}/apps/${app}/packages")"
      if [ "$(wc -w <<<"$packages")" == 1 ];then
        #if package-app uses only 1 package, use singular case
        abovetext+=$'\n'"- This app installs the <b>${packages}</b> package."
      else
        #if package-app uses multiple packages, use plural case
        abovetext+=$'\n'"- This app installs these packages: <b>$(sed 's/ /, /g' <<<"$packages")</b>"
      fi
    fi
    
    #show app's website if available
    if [ -f "${DIRECTORY}/apps/${app}/website" ];then
      website="$(head -n1 "${DIRECTORY}/apps/${app}/website")"
      abovetext+=$'\n'"- Website: <a href="\""$website"\"">$website</a>"
      
      #show credits link if available - on same line as website link
      if [ -f "${DIRECTORY}/apps/${app}/credits" ];then
        abovetext+=" | <a href="\""file://${DIRECTORY}/apps/${app}/credits"\"">Credits</a>"
      fi
      
    else #website unavailable
      #show credits link standalone, if available
      if [ -f "${DIRECTORY}/apps/${app}/credits" ];then
        abovetext+=$'\n'"- <a href="\""file://${DIRECTORY}/apps/${app}/credits"\"">Credits</a>"
      fi
    fi
    
    num_users="$(usercount "$app")"
    if [ ! -z "$num_users" ] && [ "$num_users" -gt 20 ];then
      #list the number of users, using this printf command to add commas (,) for every thousand number
      abovetext+=$'\n'"- <b>$(printf "%'d" "$num_users")</b> users"
      
      if [ "$num_users" -ge 10000 ];then
        #if this app has over 10,000 users, add two exclamation points!!
        abovetext+="!!"
      elif [ "$num_users" -ge 1500 ];then
        #if this app has over 1500 users, add an exclamation point!
        abovetext+="!"
      fi
    fi
    
    #array holding various buttons that may be passed to yad
    whichbutton=()
    
    if [ -f "${DIRECTORY}/apps/$app/uninstall" ] || [ -f "${DIRECTORY}/apps/$app/install" ] || [ -f "${DIRECTORY}/apps/$app/install-$arch" ];then
      whichbutton+=("--button=Scripts!${DIRECTORY}/icons/shellscript.png!Feel free to see how an app is installed!"$'\n'"Perfect for learning or troubleshooting.:6")
    fi
    if [ "$(cat "${DIRECTORY}/data/settings/Show Edit button")" == 'Yes' ];then
      #if edit button enabled, show it
      whichbutton+=("--button=Edit!${DIRECTORY}/icons/edit.png!Make changes to the app:8")
    fi
    
    #display buttons based on app's installation status
    if [ "$app_status" == 'installed' ];then
      #if installed, display uninstall button
      whichbutton+=("--button=Uninstall!${DIRECTORY}/icons/uninstall.png:2")
    elif [ "$app_status" == 'uninstalled' ];then
      #if uninstalled, display install button
      whichbutton+=("--button=Install!${DIRECTORY}/icons/install.png:4")
    elif [ "$app_status" == 'disabled' ];then
      #if disabled, display only an 'enable' button
      whichbutton+=("--button=<b>Enable</b>!!Force this app to install on your system."$'\n'"This app was disabled for a reason so if you enable it..."$'\n'"YOU HAVE BEEN WARNED.:12")
    else
      #if app status is 'corrupted', and a log file exists for this app, then display a button to view the log file
      if [ "$app_status" == 'corrupted' ];then
        logfile="$(ls "$DIRECTORY/logs"/* -t | grep "fail-${app}" | head -n1)"
        if [ ! -z "$logfile" ];then
          whichbutton+=("--button=Errors!${DIRECTORY}/icons/log-file.png!$app failed to $(echo "$(basename "$logfile")" | awk -F'-' '{print $1}'). Click this button to view the error output saved in the log file.:14")
        fi
      fi
      #if status is corrupted or unknown, then show both buttons
      whichbutton+=("--button=Uninstall!${DIRECTORY}/icons/uninstall.png:2" "--button=Install!${DIRECTORY}/icons/install.png:4")
    fi
    
    #only display app icon if it exists
    if [ -f "${DIRECTORY}/apps/${app}/icon-64.png" ];then
      imageline=(--image="${DIRECTORY}/apps/${app}/icon-64.png" --image-on-top)
    fi
    
    #Make sure app details window is focused (necessary for openbox window manager)
    (i=0
      while [ "$(xdotool getactivewindow getwindowname)" != "Details of ${app}" ] && [ $i -lt 20 ]; do
        wmctrl -a "Details of ${app}" #Raise the window named "Details of ${app}"
        sleep 0.2
        i=$((i+1))
      done) &
    
    #display app details window
    get_positions
    (cat "${DIRECTORY}/apps/$app/description" || echo "Description unavailable") | yad --class Artian-Apps --name "Artian-Apps" --text-info --fontname=12 --wrap --show-uri \
      --text="$(sed 's/&/&amp;/g' <<<"$abovetext")" \
      "${imageline[@]}" \
      --title="Details of ${app}" --window-icon="${DIRECTORY}/icons/logo.png" \
      $geometry2 --close-on-unfocus --skip-taskbar \
      "${whichbutton[@]}"
    button=$?
    
    case $button in
    4)
      #install
      terminal_manage install "$app" &
      ;;
    2)
      #uninstall
      terminal_manage uninstall "$app" &
      ;;
    6)
      #scripts
      install_script="${DIRECTORY}/apps/${app}/$(script_name_cpu "$app")"
      uninstall_script="${DIRECTORY}/apps/${app}/uninstall"
      
      text_editor "$uninstall_script" &
      sleep 0.1
      text_editor "$install_script" &
      
      "${DIRECTORY}/gui" "$@" #open details window again
      ;;
    8)
      #edit
      "${DIRECTORY}/createapp" "$app"
      refresh_list
      ;;
    12)
      #enable
      
      #remove status file containing 'disabled'
      rm -f "${DIRECTORY}/data/status/${app}"
      refresh_list &
      "${DIRECTORY}/gui" "$@" #open details window again
      ;;
    14)
      #viewlog
      echo "Viewing error log of $app..."
      echo "Log filepath: $logfile"
      "${DIRECTORY}/etc/viewlog" "$logfile"
      
      "${DIRECTORY}/gui" "$@" #open details window again
      ;;
    *)
      #unknown button
      exit 0
      ;;
    esac
    
  fi
  exit 0
fi

DIRECTORY="$(readlink -f "$(dirname "$0")")"

#check mission-critical scripts and re-download them if they contain a syntax error
(
  sleep 10
  command -v shellcheck >/dev/null || exit 0
  
  if shellcheck "${DIRECTORY}/updater" --color=always | grep '\[31m' --before 1 ;then
    echo "Downloading updater script to repair syntax error"
    errors="$(wget -O "${DIRECTORY}/updater" 'https://git.fdc.abrish.ir/a.kamyar/PublicFiles/Artian-Apps/updater' 2>&1)" || echo "$errors"
  fi | sed 's/]31m//g'
  
  if shellcheck "${DIRECTORY}/api" --color=always | grep '\[31m' --before 1 ;then
    echo "Downloading api script to repair syntax error"
    errors="$(wget -O "${DIRECTORY}/api" 'https://git.fdc.abrish.ir/a.kamyar/PublicFiles/Artian-Apps/api' 2>&1)" || echo "$errors"
  fi | sed 's/]31m//g'
) &

set -a #make all functions in the api available to subprocesses
source "${DIRECTORY}/api" || error "failed to source ${DIRECTORY}/api"

#For systems with older versions of yad, the text color column cannot be left blank. This python script determines the default text color from GTK bindings.
if [ -z "${text_color+x}" ];then
  #0400 is the latest version
  yad_version="$(zcat /usr/share/doc/yad/NEWS.gz | head -n 1 | tr -cd '0123456789\n')"
  if [ $yad_version -lt 0400 ]; then
    if command -v python3 &>/dev/null; then
      python_version="python3"
    else
      python_version="python2"
    fi
    export text_color=$(echo "import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
tv = Gtk.TextView()
style = tv.get_style_context()
textcolor = style.get_color(Gtk.StateType.NORMAL)
print(Gdk.RGBA.to_string(textcolor))
" | $python_version -)
  else
    export text_color=""
  fi
fi

#display the Artian-Apps logo in the terminal
generate_logo &

#install dependencies
runonce <<"EOF"
  dependencies='yad curl wget aria2 lsb-release software-properties-common apt-utils apt-transport-https gnupg imagemagick bc librsvg2-bin locales shellcheck git wmctrl xdotool x11-utils rsync'
  # Install dependencies if necessary
  if ! dpkg -s $dependencies >/dev/null 2>&1; then
    sudo_popup apt install $dependencies -y -f --no-install-recommends
  fi
EOF

#Various stuff to run in background (enclosed in brackets so Geany IDE can collapse the code)
{
mkdir -p "${DIRECTORY}/data/status" "${DIRECTORY}/data/update-status" \
  "${DIRECTORY}/data/preload" "${DIRECTORY}/data/settings" \
  "${DIRECTORY}/data/status" "${DIRECTORY}/data/update-status" \
  "${DIRECTORY}/data/categories"

#check for updates
"${DIRECTORY}/updater" set-status &
trap "kill $! &>/dev/null" EXIT #kill the above subprocess on exit

#Click Artian-Apps usage link every time the GUI is run only if the 'Enable Analytics' setting is enabled
if [ "$(cat "${DIRECTORY}/data/settings/Enable analytics")" == 'Yes' ];then
  #click it
  curl -s -X 'GET' "https://git.fdc.abrish.ir/a.kamyar/PublicFiles/Artian-Apps" -H 'accept: image/gif' -A "Artian-Apps software manager for Artian company" >/dev/null &
fi
}

#Determine the app list mode. Allowed values: 'yad-*', 'xlunch-*'
guimode="$(cat "${DIRECTORY}/data/settings/App List Style")"
[ -z "$guimode" ] && guimode=yad-default

#In YAD mode, two windows are handled in a side-by-side configuration. As a group, they must be centered on the the screen.
#In Xlunch mode, the window must be centered, but xlunch only handles absolute offsets.
get_positions() {
  #determine screen_width and screen_height
  screen_dimensions="$(xrandr --nograb --current | awk -F 'connected |\\+|\\('  '/ connected.*[0-9]+x[0-9]+\+/ && $2 {printf $2 ", "}' | sed -n -e 's/^.*primary //p' | tr 'x+' ' ' | tr ',+' ' ')"
  if [ -z "$screen_dimensions" ];then
    # if screen_dimensions is empty, this could be a single monitor wayland display which does not have the word "primary" in the output
    # workaround is to get the first output returned for the connected display
    screen_dimensions="$(xrandr --nograb --current | awk -F 'connected |\\+|\\('  '/ connected.*[0-9]+x[0-9]+\+/ && $2 {printf $2 ", "}' | tr 'x+' ' ' | tr ',+' ' ')"
  fi
  screen_width="$(awk '{print $1}' <<<"$screen_dimensions")"
  screen_height="$(awk '{print $2}' <<<"$screen_dimensions")"
  unset screen_dimensions
  
  if [[ "$guimode" == yad* ]];then

    # if this is being run by yad, there should be a yad window id
    # store in arrary of x and y
    # this allows for windows to be moved by the user and the second window to still show up where expected
    main_yad_window=$YAD_XID
    if [ -n "${main_yad_window}" ]; then
      window_info=$(xwininfo -id $main_yad_window)
      # for speed of execution, we are assuming the order of matches from xwininfo
      # this is safe as the output order has been standardized for over a decade
      # this is the location of where the window content starts inside the title bar and window borders (pos x then pos y)
      main_yad_window_pos=($(echo "$window_info" | sed -n 's/Absolute upper-left.*://p'))
      # these are the dimensions of where the window content starts inside the title bar and window borders (dim x then dim y)
      main_yad_window_dim=($(echo "$window_info" | sed -n 's/Width://p;s/Height://p'))
      # again, for speed, all border widths are saved to one array
      # left, right, title, bottom [0, 1, 2, 3]
      # this is the size of the window borders (including title bar)
      border_widths=($(xprop _NET_FRAME_EXTENTS -id "$main_yad_window" | sed -n  's/_NET_FRAME_EXTENTS.*=//p' | tr ',' '\n'))
      #total dimensions for both yad windows side by side
      if [ $screen_width -le 1000 ] || [ $screen_height -le 600 ];then
        #gui size for small screens
        height=${main_yad_window_dim[1]}
        width=600
        
        #width of first window
        width1=${main_yad_window_dim[0]}
        #width of second window
        width2=350
      else
        #gui size for large screens
        height=${main_yad_window_dim[1]}
        width=800
        
        #width of first window
        width1=${main_yad_window_dim[0]}
        #width of second window
        width2=480
      fi
      #how far down the top of the title bar of yad window is from the top of the screen
      yoffset=$((main_yad_window_pos[1]-border_widths[2]))
      
      #screen offsets for window 1
      #use current position of the left side of the main window border
      xoffset1=$((main_yad_window_pos[0]-border_widths[0]))
      #screen offsets for window 2
      #use current position of the right side of the main window border
      xoffset2=$((xoffset1+border_widths[0]+width1+border_widths[1]))
      
      #set completed location arguments for both yad windows
      geometry1="--geometry=${width1}x${height}+${xoffset1}+${yoffset}"
      geometry2="--geometry=${width2}x${height}+${xoffset2}+${yoffset}"
    else
      # default positions when the main window does not exist yet
      #total dimensions for both yad windows side by side
      if [ $screen_width -le 1000 ] || [ $screen_height -le 600 ];then
        #gui size for small screens
        height=400
        width=600
        
        #width of first window
        width1=250
        #width of second window
        width2=$((width - width1))
      else
        #gui size for large screens
        height=600
        width=800
        
        #width of first window
        width1=320
        #width of second window
        width2=$((width - width1))
      fi
      #how far down the top of the title bar of yad window is from the top of the screen
      yoffset=$(((screen_height/2)-(height/2)))
      
      #screen offsets for window 1
      xoffset1=$(((screen_width/2)-(width/2)))
      #screen offsets for window 2
      xoffset2=$(((screen_width/2)-(width/2)+width1))
      
      #set completed location arguments for both yad windows
      geometry1="--geometry=${width1}x${height}+${xoffset1}+${yoffset}"
      geometry2="--geometry=${width2}x${height}+${xoffset2}+${yoffset}"
    fi
    
  elif [[ "$guimode" == xlunch* ]];then
    #desired dimensions for xlunch window
    height=700
    width=800
    #determine 
    xoffset=$(((screen_width/2)-(width/2)))
    yoffset=$(((screen_height/2)-(height/2)))
  else
    error "Unrecognized app list style '$guimode'!"
  fi
}
# run get_positions once incase sometime requires the position value immediatly
get_positions

#Compile xlunch if required
if [[ "$guimode" == xlunch* ]] && ([ ! -d "${DIRECTORY}/xlunch" ] || [ ! -f /usr/bin/xlunch ]);then
  #signal files
  rm -f /tmp/xlunchfailed /tmp/xlunchfinished /tmp/terminalexit
  echo '' > /tmp/terminalexit
  "${DIRECTORY}/etc/terminal-run" "
    function error {
      echo -e "\""\e[91m$1\e[39m"\""
      echo 'Close this terminal to exit.'
      echo '' > /tmp/xlunchfailed
      sleep infinity
    }
    trap 'echo "\"""\"" > /tmp/terminalexit' EXIT
    
    #uninstall xlunch first
    sudo rm -rf /etc/xlunch /usr/share/xlunch /usr/bin/xlunch /usr/bin/genentries /usr/bin/updateentries /usr/bin/genentries.desktop.sh /usr/share/icons/hicolor/48x48/apps/xlunch_ghost.png /usr/share/icons/hicolor/48x48/apps/xlunch.png /usr/share/applications/genentries.desktop
    
    rm -f /tmp/terminalexit
    sudo rm -rf /usr/bin/xlunch "\""$DIRECTORY/xlunch"\"" 2>/dev/null
    sudo apt install -y libimlib2-dev libx11-dev || error 'APT failed to install libimlib2-dev and libx11-dev packages!'
    cd "\""$DIRECTORY"\""
    git clone https://github.com/Tomas-M/xlunch.git || error 'Failed to clone xlunch repository!'
    cd "\""$DIRECTORY/xlunch"\""
    echo 'Running make...'
    echo "\"""\$"(cat '${DIRECTORY}/xlunch/Makefile' | grep -v 'genentries \|cp -r svgicons/')"\"" > '${DIRECTORY}/xlunch/Makefile'
    make -j8 || error 'make command failed!'
    echo 'Running sudo make install...'
    sudo make install || error 'sudo make install failed!'
    sudo rm -f /usr/share/applications/genentries.desktop
    cd $HOME
    if [ ! -f /usr/bin/xlunch ];then
      error 'xlunch should be installed now, but /usr/bin/xlunch does not exist!'
    fi
    echo '' > /tmp/xlunchfinished
  " 'Compiling xlunch...'
  
  #if terminal doesn't start in 3 seconds, then /tmp/terminalexit will exist.
  sleep 3
  
  #check for an exit status code from the running terminal
  while true; do
    if [ -f /tmp/xlunchfinished ];then
      echo "xlunch finished installing."
      break
    elif [ -f /tmp/xlunchfailed ];then
      #revert back to yad
      echo 'yad-default' > "{DIRECTORY}/data/settings/App List Style"
      error "xlunch failed to compile!"
    elif [ -f /tmp/terminalexit ];then #if terminal doesn't start in 3 seconds, then /tmp/terminalexit will exist.
      #revert back to yad
      echo 'yad-default' > "{DIRECTORY}/data/settings/App List Style"
      error "The xlunch compilation terminal exited prematurely."
    else
      sleep 1
    fi
  done
fi

#Determine message of the day. If announcements file missing or over a day old, download it.
if [ ! -f "${DIRECTORY}/data/announcements" ] || [ ! -z "$(find "${DIRECTORY}/data/announcements" -mtime +1 -print)" ]; then
  announcements="$(wget -qO- https://git.fdc.abrish.ir/a.kamyar/PublicFiles/Artian-Apps)"
  echo "$announcements" > "${DIRECTORY}/data/announcements"
fi & #use $announcements and & here to avoid delaying launch or emptying the file before download completes

if [[ "$guimode" == yad* ]];then
  
  #create a named pipe to send app list through to yad
  pipe="$(mktemp -u)" #get a random filename to work with
  mkfifo $pipe #make the named pipe
  trap "rm -f $pipe" EXIT #remove this named pipe on exit
  echo pipe is $pipe
  
  while true;do #main operating loop for yad window
    #in background process, send initial app list to yad; first echo line waits until yad is accepting input, then use small delay to prevent items from being missed
    (echo -e '\f' > $pipe
    sleep 0.5
    "${DIRECTORY}/preload" yad '' >> $pipe) &
    
    #retrieve a random line from the announcements file for this session
    motd="$(shuf -n 1 "${DIRECTORY}/data/announcements")"
    
    #constantly read from the pipe and send all output to yad
    #if an item is selected, this script will be run with the row's contents
    { yad --class Artian-Apps --name "Artian-Apps" --center --title='Artian-Apps' \
      --image="${DIRECTORY}/icons/logo-64.png" --image-on-top --text "$motd" \
      --list --no-headers --column=:IMG  --column=Name --column=Sysname:HD --column=tip:HD --column=@fore@:HD \
      --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
      --tooltip-column=4 \
      --dclick-action "env pipe=$pipe '${DIRECTORY}/gui'" --select-action "env pipe=$pipe '${DIRECTORY}/gui'" \
      --button="!${DIRECTORY}/icons/search.png"!'Search':"env pipe=$pipe '${DIRECTORY}/gui' '' '' Search/ Search/" \
      --button="!${DIRECTORY}/icons/options.png"!'Settings':2 \
      "$geometry1"; button=$?; kill "$!"; } < <(exec tail -f --retry $pipe)
    
    case $button in
    2) #settings
      # remove pipe early so that nothing attempts to write to it
      rm -f "$pipe"
      "${DIRECTORY}/settings"
      "${DIRECTORY}/gui" "$@" #run new instance of this script
      exit 0
      ;;
      
    3) #search
      app="$(yadflags+=("$geometry2") ; app_search_gui)"
      
      if [ ! -z "$app" ];then
        "${DIRECTORY}/gui" '' "$app" "/$app" "$app"
      fi
      ;;
    *) #unknown button
      exit 0
      ;;
    esac
  done
  #END of yad main window loop
  
elif [[ "$guimode" == xlunch* ]];then
  
  #create a named pipe to send app list through to yad
  pipe="$(mktemp -u)" #get a random filename to work with
  mkfifo $pipe #make the named pipe
  trap "rm $pipe" EXIT #remove this named pipe on exit
  echo pipe is $pipe
  
  #disabled, but too cool to remove: this can make the transparent background of xlunch blurry - like Windows 7
  if false;then
    scrot -a "$((xoffset+1)),$((yoffset+33)),${width},${height}" blur.png #blur_init.png
    convert -blur 10x5 ~/blur.png ~/blur.png
  fi
  
  #Depending on the xlunch theme, different arguments will be used.
  if [ "$guimode" == xlunch-light-3d ];then
    #light mode
    xlunchflags=(--multiple --dontquit -WoCS -s 64 --bc e0e0e000 --tc 000000 --pc 6060ffff --hc ffffff50 \
      -p "Search: " -a -c $([ $width -lt 550 ] && echo 1 || echo 2) --title "Artian-Apps: Artian app store" \
      --icon "${DIRECTORY}/icons/logo.png" --scrollbarcolor ffffff40 --scrollindicatorcolor 0000ff80 \
      --width $width --height $height --xposition $xoffset --yposition $yoffset \
      --button "${DIRECTORY}/icons/logo-3d.png;;$((($width/2)-(300/2))),0;:exec echo Artian-apps-homepage" \
      --button "${DIRECTORY}/icons/settings-dark.png;;$(($width-140)),30;:exec echo Artian-apps-settings" \
      -g "${DIRECTORY}/icons/background-3d.png")
  elif [ "$guimode" == xlunch-dark-3d ];then
    #dark mode, 3d opaque version
    xlunchflags=(--multiple --dontquit -WoCS -s 64 --bc ffffff00 --tc DCDDDE --pc ffffffa0 --hc ffffff30 \
      -p "Search: " -a -c $([ $width -lt 550 ] && echo 1 || echo 2) --title "Artian-Apps: Artian app store" \
      --icon "${DIRECTORY}/icons/logo.png" --scrollbarcolor ffffff20 --scrollindicatorcolor ffffff40 \
      --width $width --height $height --xposition $xoffset --yposition $yoffset \
      --button "${DIRECTORY}/icons/logo-3d-dark.png;;$((($width/2)-(300/2))),0;:exec echo Artian-apps-homepage" \
      --button "${DIRECTORY}/icons/settings-light.png;;$(($width-140)),30;:exec echo Artian-apps-settings" \
      -g "${DIRECTORY}/icons/background-3d-dark.png")
  else
    #dark mode, transparent version
    xlunchflags=(--multiple --dontquit -WoCS -s 64 --bc 000000A0 --tc ffffffff --pc 6060ffff --hc ffffff30 \
      -p "Search: " -a -c $([ $width -lt 550 ] && echo 1 || echo 2) --title "Artian-Apps: Artian app store" \
      --icon "${DIRECTORY}/icons/logo.png" --scrollbarcolor ffffff40 --scrollindicatorcolor 0000ff80 \
      --width $width --height $height --xposition $xoffset --yposition $yoffset \
      --button "${DIRECTORY}/icons/logo-128.png;;$((($width/2)-(128/2))),0;:exec echo Artian-apps-homepage" \
      --button "${DIRECTORY}/icons/logo-text.png;;$([ -z "$prefix" ] && echo '45' || echo '65'),$([ -z "$prefix" ] && echo '10' || echo '0');:exec echo Artian-apps-homepage" \
      --button "${DIRECTORY}/icons/settings-light.png;;$(($width-140)),30;:exec echo Artian-apps-settings")
  fi
  
  
  #in background process, send initial app list to xlunch; first echo line waits until xlunch is accepting input
  (
    #set initial value to make xlunch keep listening
    echo 'botspot is cool' > $pipe
    echo "$("${DIRECTORY}/preload" xlunch '')" > $pipe) &
  
  #read pipe      pipe to xlunch               read output of xlunch
  tail -f --retry $pipe | xlunch "${xlunchflags[@]}" | while read -r line; do
    echo "Received '$line'"
    
    if [ "$line" == 'Updates/' ];then
      echo > $pipe #clear list
      
      #in subprocess, open details window for app
      geometry2="--center --height=$((height/2)) --width=$width" pipe='' "${DIRECTORY}/gui" '' '' "$line" "$line"
      
      #back to main level
      "${DIRECTORY}/preload" xlunch '' > $pipe
      
    #category selected
    elif [[ "$line" == */ ]];then
      echo > $pipe #clear list
      "${DIRECTORY}/preload" xlunch "$(echo "$line" | sed 's+/$++g')" > $pipe
      
    #Artian-apps logo button clicked
    elif [ "$line" == 'Artian-apps-homepage' ];then
	   x-www-browser "$(cat "https://artianhpc.ir/")" &
     # x-www-browser "$(cat "${DIRECTORY}/etc/git_url")" &
      
    #Settings button clicked
    elif [ "$line" == 'Artian-apps-settings' ];then
      #close xlunch
      echo ':quit' > $pipe
      
      #run settings, then run Artian-apps gui
      "${DIRECTORY}/settings"
      "${DIRECTORY}/gui" "$@"
      
      #exit this script
      exit 0
      
    #app selected
    else
      echo > $pipe #clear list
      
      #in subprocess, open details window for app
      geometry2="--center --height=$((height/2)) --width=$width" pipe='' "${DIRECTORY}/gui" '' '' "$line" "$line"
      
      #show app list again
      "${DIRECTORY}/preload" xlunch "$(dirname "$line" | sed 's/^.$//g')" > $pipe
    fi
  done
  
fi


