#! /bin/bash
#--------------------------------------------------------------------------------------------------------
# Modified Code and Software List for Pearl Linux PDE 12
# Name: Pearl Linux - Pearl Software
# Architecture: all
# Website: https://www.pearllinux.net
#
# #########################################################
#
# Original Author of Code
# Authors: Misko_2083, Jerry Bezencon, gerito1, Johnathan "ShaggyTwoDope" Jenkins, Ralphy
# Website: https://www.linuxliteos.com
#--------------------------------------------------------------------------------------------------------

# Ensure multi-language support
export LANG=C

# Variables
_ICON="/usr/share/icons/hicolor/24x24/apps/pearlsoftware.png"		# Pearl Software icon variable
_APPNAME="Pearl Software"                                 # Application name
_APPINST="/usr/share/pearlappsicons/pearlsoftware/pearl-install-software_32x32.png"
_APPREM="/usr/share/pearlappsicons/pearlsoftware/pearl-remove-software_32x32.png"
# ask for administrative credentials
if [ "$EUID" -ne "0" ]; then pkexec "$0"; exit 0 ; if [ "${PIPESTATUS[@]}" -eq "126" ]; then exit 0 ; fi; else :; fi

# Kill off any package managers that may be running
if [ "$(pidof synaptic)" ]; then killall -9 synaptic; fi
if [ ! -z "$(pgrep gdebi-gtk)" ]; then killall -9 gdebi-gtk; fi
# Set up log facilities
# Example output: [02/06/15 20:03:12] message input
LOGFILE="/var/log/pearl-software.log"
lslog() {
    message="$@"
    echo '['$(date +%D\ %H:%M:%S)']'"$message" >> "$LOGFILE"
}
# Log last activities to retrieve errors
TMP_LOG="/tmp/pearl-software.log"

prepare() {
  # Check internet access
  if eval "curl -sk google.com" >> /dev/null 2>&1; then :; else # Prompt ERROR internet connection
    zenity --info --width="390" --ok-label="Got it!" --title=" $_APPNAME - No Internet access" \
            --text="\n<b>Your computer does not seem to be connected to the Internet</b> \n \nYou need to be connected to the Internet to download and install applications." 2>/dev/null
    return
  fi
  # Check if apt-cache was built and ask to update
  if zenity --question --width="380" --height="180" --window-icon="$_ICON" --title=" Update Software Sources" \
            --text="\n<b>Would you like to update software sources now?</b>\n\nIt is recommended to always update software
sources before installing applications. \
\n\nClick <b>No</b> to continue without updating or <b>Yes</b> to
update software sources next." 2>/dev/null; then
      TOTALREPOS=$(cat /etc/apt/sources.list.d/official-package-repositories.list | grep '^deb' -c) # Total of repositories registered, this is approximated
      apt-get update 2>&1 | awk -v total=$TOTALREPOS '/^Ign|^ Get/{count++;$1=""} FNR { if (total != 0){percentage=int (1000*count/total);print (percentage < 90?percentage:99),"\n#",$0 }; fflush(stdout)}' \
      | zenity --progress --window-icon="$_ICON" --width="600" --pulsate --no-cancel --text="Updating package lists..." --title="Updating Software Sources. Please wait..." --percentage="0" --auto-close 2>/dev/null
      if [ "${PIPESTATUS[0]}" -ne "0" ]; then
        zenity --error --width="300" --height="90" --title="  $_APPNAME - Error" \
               --text="\n<b>Updating sources has failed</b>\n\nRefer to /var/log/pearl-software.log for more information." 2>/dev/null
        lslog "ERROR: Updating sources has failed."
      fi
        lslog "INFO: Software sources were updated."
      else
        lslog "INFO: The updating of packages was canceled by the user"
  fi
}
# Set app icon variable
APPICON="/usr/share/pearlappsicons/pearlsoftware/appicons/"

#--------------------------------------------------------------------------------------------------------
# soft_list is the list of package aliases to check/install/remove
# Consist in a list describing aspect for every package
# package_alias=( "element 0" "element 1" "element 2" "element 3" "element 4" "element 5" "element 6")
# element 0: TRUE\FALSE for being selected
# element 1: The Application name ie: Google Chrome, iDevices Manager
# element 2: The category which belongs to (one only) ie:  Internet, Multimedia
# element 3: Status of the package ie: Installed, Not Installed
# element 4: Description of the package ie: "Easily locate files and folders in your computer", "Clementine is a modern music player and library organizer"
# element 5: List of packages needed to provide the application ie: "aisleriot gnome-mahjongg gnome-mines gnome-hearts"
# element 6: List of additional packages (this is optional) ie: libavformat-extra-54
#--------------------------------------------------------------------------------------------------------
soft_list=(allinone
  ardour
  audacious
  audacity
  calibre
  clementine
  dropbox
  etherape
  evolution
  extras
  filezilla
  firefoxesr
  gamespack
  gnomenettool
  geany
  googlechrome
  guvcview
  handbrake
  hypnotix
  imessenger
  ipscan
  kdenlive
  kodi
  lingot
  losslesscut
  masterme
  motion
  msedge
  nomachine
  obs
  passmgr
  pearlgrab
  pearlthemesfull
  playonlinux
  redshift
  remote
  skype
  soundjuicer
  spotify
  ssr
  steam
  systemmonitor
  teamviewer
  torrent
  tor
  ulauncher
  ventoy
  videoedit
  vbox
  vokoscreenng
  weather
  webappmanager
  wine
  yadbridge
  zim
  zoom )

# Check system arch, don't list 64bit only apps in i686 system eg. skypeforlinux is only available in 64bit
# The unset soft_list number corresponds to the item above the application you DON'Twant to list in 32bit systems
# eg. skypeforlinux is actually number 18 in the list, so its unset soft_list number becomes 17
#UNAME=$(uname -m)
#if [ "i686" == ${UNAME} ]; then
#    unset soft_list[17]
#    unset soft_list[5] # list another application here, and so on
#else
#    :
#fi
allinone=("$APPICON/allinone.png" "All-In-One-Messenger" "Internet" "" "Many Messenger Services One App" "all-in-one-messenger" "" )
ardour=("$APPICON/ardour.png" "Ardour" "Multimedia" "" "Software for recording and editing sounds" "ardour" "" )
audacious=("$APPICON/audacious.png" "Audacious" "Multimedia" "" "Software for recording and editing sounds" "audacious" "" )
audacity=("$APPICON/audacity.png" "Audacity" "Multimedia" "" "Software for recording and editing sounds" "audacity" "" )
calibre=("$APPICON/calibre.png" "Calibre" "Office" "" "An open source e-book library management application" "calibre" "" )
clementine=("$APPICON/clementine.png" "Music Player" "Multimedia" "" "Clementine is a modern music player and library organizer" "clementine" "")
dropbox=("$APPICON/dropbox.png" "Dropbox" "Internet" "" "A popular cloud storage application" "dropbox thunar-dropbox-plugin python3-gpg" "" )
etherape=("$APPICON/etherape.png" "Etherape" "Internet" "" "Full local network activity display" "etherape" "" )
evolution=("$APPICON/evolution.png" "Evolution" "Internet" "" "An open source email suite" "evolution" "" )
extras=("$APPICON/extras.png" "Restricted Extras" "Multimedia" "" "Additional codecs and file formats (highly recommended)" "ubuntu-restricted-extras" "libavcodec-extra60" )
filezilla=("$APPICON/filezilla.png" "Filezilla" "Internet" "" "A full-featured FTP/FTPS/SFTP client application" "filezilla" "" )
firefoxesr=("$APPICON/firefox.png" "Firefox" "Internet" "" "A popular extended release open source web browser" "firefox-esr" "" )
gamespack=("$APPICON/gamespack.png" "Games Pack" "Games" "" "Solitaire, Mahjongg, Chess, Mines, Sudoku and Tetris" "aisleriot gnome-chess gnome-mahjongg gnome-mines gnome-sudoku quadrapassel" "" )
geany=("$APPICON/geany.png" "Geany" "Accessories" "" "A full featured IDE and text editor for developers" "geany" "geany-plugins" )
gnomenettool=("$APPICON/gnome-nettool.png" "Gnome-Nettool" "Internet" "" "Many network tools in one package" "gnome-nettool" "")
googlechrome=("$APPICON/googlechrome.png" "Google Chrome Stable" "Internet" "" "The Google Chrome Web Browser" "google-chrome-stable" "" )
guvcview=("$APPICON/guvcview.png" "Webcam Software" "Internet" "" "Guvcview, webcam software for your computer" "guvcview" "" )
handbrake=("$APPICON/handbrake.png" "Handbrake" "Multimedia" "" "Convert video to nearly any format" "handbrake" "" )
hypnotix=("$APPICON/hypnotix.png" "Hypnotix" "Multimedia" "" "FREE IPTV App with hundreds of channels worldwide" "hypnotix" "" )
imessenger=("$APPICON/pidgin.png" "Instant Messenger" "Internet" "" "Pidgin, a multi-protocol Instant Messenging client" "pidgin" "" )
ipscan=("$APPICON/ipscan.png" "IP Scan" "Internet" "" "Scans your LAN for active hosts and ports" "ipscan" "" )
kdenlive=("$APPICON/kdenlive.png" "Kdenlive" "Multimedia" "" "The Best Video Editor for Linux" "kdenlive" "" )
kodi=("$APPICON/kodi.png" "Kodi" "Multimedia" "" "The Kodi Media Center" "kodi" "" )
lingot=("$APPICON/gtuner.png" "Lingot" "Multimedia" "" "A Guitar Tunar" "lingot" "" )
losslesscut=("$APPICON/losslesscut.png" "Lossless-Cut" "Multimedia" "" "The quickest way to create clips from a video" "losslesscut" "" )
masterme=("$APPICON/masterme.png" "MasterMe" "Multimedia" "" "An audio plugin for audio mastering" "master-me" "" )
motion=("$APPICON/motion.png" "Motion" "Multimedia" "" "Webcam Motion detection software" "motion" "" )
msedge=("$APPICON/microsoft-edge.png" "Microsoft Edge Browser" "Internet" "" "Microsoft Edge is a cross-platform web browser" "microsoft-edge-stable" "" )
nomachine=("$APPICON/nomachine.png" "No Machine" "Internet" "" "Connect to Windows PC, Mac or Linux Box on your LAN as well as Remotely" "nomachine" "")
obs=("$APPICON/obs.png" "OBS Studio" "Multimedia" "" "A popular tool to record and stream desktop content" "obs-studio obs-plugins" "")
passmgr=("$APPICON/keepassxc.png" "Password Manager" "Accessories" "" "KeePassXC, a full featured password manager" "keepassxc" "" )
pearlgrab=("$APPICON/pearlgrab.png" "PearlGrab" "Accessories" "" "Automated Screenshot by Draging Mouse and Hightight an Area" "pearlgrab" "" )
pearlthemesfull=("$APPICON/pearllinux.png" "Pearl Themes" "System" "" "Standard Pearl themes and icons complete" "pearl-themes pearl-y-icons pearl-x-icons pearl-l-theme pearl-l-icons" "" ) 
playonlinux=("$APPICON/playonlinux.png" "PlayOnLinux" "Cross Platform" "" "Use many games and apps designed to run on Windows" "playonlinux" "" )
redshift=("$APPICON/redshift.png" "Redshift" "Accessories" "" "Adjusts the color temperature of your screen automatically" "redshift redshift-gtk" "" )
remote=("$APPICON/remmina.png" "Remote Desktop Software" "Internet" "" "Remmina - Remotely connect to a Windows PC" "remmina" "" )
skype=("$APPICON/skype.png" "Skype" "Internet" "" "A popular audio and video chat application" "skypeforlinux" "" )
soundjuicer=("$APPICON/sound-juicer.png" "Sound Juicer" "Multimedia" "" "A tool to extract music tracks from CD's" "sound-juicer" "ubuntu-restricted-extras" )
spotify=("$APPICON/spotify.png" "Spotify" "Multimedia" "" "A digital music service" "spotify-client" "" )
ssr=("$APPICON/ssr.png" "Simple Screen Recorder" "Multimedia" "" "A simple to use screen and audio recorder" "simplescreenrecorder" "" )
steam=("$APPICON/steam.png" "Steam" "Games" "" "A cross platform gaming client" "steam-installer steam-devices steam:i386" "" )
systemmonitor=("$APPICON/system-monitoring-center.png" "System Monitoring Center" "System" "" "Your Complete System Performance Monitor" "system-monitoring-center" "" )
teamviewer=("$APPICON/teamviewer.png" "Teamviewer" "Internet" "" "Remote Desktop Support software" "teamviewer" "" )
torrent=("$APPICON/deluge.png" "Torrent Software" "Internet" "" "Deluge Torrent client software" "deluge deluge-common" "" )
tor=("$APPICON/tor.png" "Tor Web Browser" "Internet" "" "A privacy respecting web browser" "tor-web-browser" "" )
ulauncher=("$APPICON/ulauncher.png" "ULauncher" "System" "" "A great App Search and Launcher" "ulauncher" "" )
ventoy=("$APPICON/ventoy.png" "Ventoy" "System" "" "The Ultimate Multi ISO USB imager" "ventoy" "" )
videoedit=("$APPICON/shotcut.png" "Video Editing Software" "Multimedia" "" "Shotcut - a simple yet powerful video editor" "shotcut" "")
vbox=("$APPICON/virtualbox.png" "VirtualBox" "System" "" "Install operating systems like Windows within Pearl Linux" "virtualbox-qt virtualbox-guest-additions-iso virtualbox-guest-utils virtualbox-guest-x11 virtualbox-dkms" "" )
vokoscreenng=("$APPICON/vokoscreen-ng.png" "Vokoscreen-NG" "Multimedia" "" "a powerful and easy to use screen recorder" "vokoscreen-ng" "")
weather=("$APPICON/weather.png" "Weather Monitor" "System Tray" "" "A Weather Monitor Plugin for your tray" "xfce4-weather-plugin" "" )
webappmanager=("$APPICON/webapp-manager.png" "WebApp Managerr" "System" "" "Turnwebpage into a desktop app" "webapp-manager" "" )
wine=("$APPICON/wine.png" "Wine" "Cross Platform" "" "Install and run Windows programs plugins and games on Pearl Linux"  "wine-stable wine32-preloader wine64-preloader wine64-tools winetricks wine-menu-pearllinux" "" )
yadbridge=("$APPICON/yadbridge.png" "YADBridge" "Multimedia" "" "Use windows VST's on Linux includes both yabridge and yadbridge the GUI to manage" "yadbridge" "")
zim=("$APPICON/zim.png" "Note Taking Journal" "Accessories" "" "Zim is a Note taking/Wiki editing application" "zim" "" )
zoom=("$APPICON/zoom.png" "Zoom" "Internet" "" "A cross platform video and audio conferencing application" "zoom" "" )

get_pkg_status() {
  result="Installed"
  for PKG in  $@
  do
    TEST_PKG=(`apt-cache policy "$PKG" | grep "Installed:"`)
    if [ "${TEST_PKG[1]}" == "(none)" ];then
      result="Not Installed"
      break
    fi
  done
  read ${2} <<< ${result}
  unset result
  unset TEST_PKG
}

# Check for installed packages
check_installed() {
  for element in ${soft_list[*]}
  do
    current_pkg="$element[5]"
    status="$element[3]"
    get_pkg_status "${!current_pkg}" status # Get the status of the main package
    read ${element}"[3]" <<< ${status}      # Write the status in the package status
  done
}

install_pkgs() {
  declare -a pkg_arr=("${!1}")

  lslog "INFO: Installation of packages initiated: ${pkg_arr[@]}"
  apt-get install -f --show-progress ${pkg_arr[@]} -y 2>&1 | tee "$TMP_LOG" | awk ' BEGIN { FS=" "; total=1;end_download=0} /upgraded/ {total= $1 + $3;FS="[ :]" } /^Get:[[:digit:]]+/ {printf "#Downloading %s %s %s\n",$7,$(NF-1),$NF;print int(($2 - 1) * 100 / total); fflush(stdout)} /^\(Reading / {if (end_download==0){print 100;fflush(stdout);end_download=1}} /^(Preparing|Unpacking|Selecting|Processing|Setting|Download)/ {print "#", $0; fflush(stdout)}  /^Progress/ {print  match($0, /([0-9]+)/, arr); if(arr[1] != "") print arr[1] ; fflush(stdout)}' \
   | ( zenity --window-icon="$_ICON" --progress --no-cancel --width="600" --text="Downloading package(s)...\nThis may take a while." --title="$_APPNAME - Downloading. Please wait..." --percentage="0" --auto-close 2>/dev/null ; zenity --progress --no-cancel --window-icon="$_ICON" --width="600" --text="Installing and configuring packages...\nThis may take a while." --title="$_APPNAME - Installing. Please wait..." --auto-close 2>/dev/null)
  if [ "${PIPESTATUS[0]}" -ne "0" ]; then
    err_msg=$(awk '/^E:/{$1=""; print $0}' "$TMP_LOG" | tail -n 1)
    lslog "ERROR:$err_msg"
    zenity --error --width="340" --height="80" --title="  $_APPNAME - Error" --text="\n$_APPNAME Error:\n\n-$err_msg \n\n- Make sure your computer is connected to the Internet and try again If installing wine you must add i386 to your architecture first from terminal do sudo dpkg --add-architecture i386." 2>/dev/null
    return
  else
    zenity --info --window-icon="$_ICON" --width="280" --height="80" --title="   $_APPNAME - Installation" --text="\nInstallation successfully completed." 2>/dev/null
    lslog "INFO: Installation was a success."
  fi
}

remove_pkgs() {
  declare -a pkg_arr=("${!1}")

  lslog "INFO: Removal of packages initiated: ${pkg_arr[@]}"
  apt-get remove -f ${pkg_arr[@]} -y 2>&1 | tee "$TMP_LOG" | awk ' BEGIN { FS=" "; total=0; pkg=0}  /upgraded/ {total=$6 } /^Removing/ {print "#", $0;pkg+=1;print int((pkg - 1) * 100 / total); fflush(stdout)}' \
    | zenity --progress --window-icon="$_ICON" --no-cancel --width="600" --text="Removing package(s)...\nThis may take a while." --title="$_APPNAME - Removing. Please wait..." --percentage="0" --auto-close 2>/dev/null
  if [ "${PIPESTATUS[0]}" -ne "0" ]; then
    err_msg=$(awk '/^E:/{$1=""; print $0}' "$TMP_LOG" | tail -n 1)
    lslog "ERROR:$err_msg"
    zenity --error --title="  $_APPNAME - Error" --text="\n$_APPNAME Error:\n\n-$err_msg" 2>/dev/null
    return
  else
    zenity --info --window-icon="$_ICON" --width="280" --height="80" --title="   $_APPNAME - Removal" --text="\nRemoval successfully completed." 2>/dev/null
    lslog "INFO: Removal was a success."
  fi
}

# The installation menu
install_menu() {
  while (true); do
  check_installed

  selection=$(for element in ${soft_list[*]}
    do
      pkg_status="$element[3]"
      #Only list Not Installed applications
      if [ "${!pkg_status}" == "Installed" ]; then
        continue;
      fi
      row="$element[@]"                          #grab the whole row
      printf  '%s\n' "${!row}"                 #print every element in the row separated with a newline
    done | zenity --window-icon="$_ICON" --list --imagelist --multiple --width="920" --height="740" --print-column="2,6,7" --separator="| " --column="Select" --column="Name" --column="Category" --column="Status" \
      --column="Description" --column="Packages" --column="Optional Packages" \
      --text='    <span font="Roboto 13">Select the program or programs you want then click the <b>Install</b> button. \n\n<b> - Sort</b> columns by clicking on the column headers. \n<b> - Ctrl key:</b> Hold down <b>Ctrl</b> and click on applications <b>anywhere</b> on the list. \n<b> - Shift key:</b> Hold down <b>Shift</b> and click the <b>first</b> and then the <b>last</b> application you want from the list.\n </span>' \
      --title=" Install Software" --cancel-label="Back to Task Selector" --ok-label="Install" --hide-column="6,7" 2>/dev/null)

  # If Cancel is clicked then return to main loop
  if [ "${PIPESTATUS[0]}" -ne "0" ]; then return; fi

  # Check if anything is selected
  echo "$selection" | grep '[a-zA-Z0-9]'
  if [ "${PIPESTATUS[1]}" -ne "0" ]; then
    zenity --info  --width="280" --title="  Install Software" --text="\nNo application was selected for installation." 2>/dev/null
    continue
  fi

  # Split selection
  OIFS=$IFS
  IFS='|'
  selection_array=($selection)
  PKGS_NAMES=""
  PKGS=""
  for ((i=0; i<${#selection_array[@]}; ++i));
  do
    if (( i % 3 == 0 )); then
      PKGS_NAMES=$PKGS_NAMES${selection_array[$i]}"\n"
      continue
    fi
    PKGS=$PKGS${selection_array[$i]}" "
  done
  IFS=$OIFS

  zenity --question --width="320" --window-icon="$_ICON" --title="  $_APPNAME - Install" \
         --text="\nThe following software has been selected:<b>\n\n ${PKGS_NAMES} </b>\nDo you want to proceed with the installation?" 2>/dev/null
  if [ "$?" -eq "0" ]; then
    install_pkgs PKGS[@]; return; else continue
  fi
  done
}

# The installation menu
remove_menu() {
  while (true); do
  check_installed

  selection=$(for element in ${soft_list[*]}
    do
      pkg_status="$element[3]"
      #Only list Installed applications
      if [ "${!pkg_status}" == "Not Installed" ]; then
        continue;
      fi
      row="$element[@]"                          #grab the whole row
      printf  '%s\n' "${!row}"                 #print every element in the row separated with a newline
    done | zenity --window-icon="$_ICON" --list --imagelist --multiple --width="920" --height="740" --print-column="2,6" --separator="| " --column="Select" --column="Name" --column="Category" --column="Status" \
      --column="Description" --column="Packages" --column="Optional Packages" \
      --text='    <span font="Roboto 13">Select the program or programs you want to remove, then click the <b>Remove</b> button. \n\n<b> - Sort</b> columns by clicking on the column headers. \n<b> - Ctrl key:</b> Hold down <b>Ctrl</b> and click on applications <b>anywhere</b> on the list. \n<b> - Shift key:</b> Hold down <b>Shift</b> and click the <b>first</b> and then the <b>last</b> application you want from the list.\n </span>' \
      --title="Remove Software" --cancel-label="Back to Task Selector" --ok-label="Remove" --hide-column=6,7 2>/dev/null)

  # if cancel is clicked then return to main loop
  if [ "${PIPESTATUS[0]}" -ne "0" ]; then return; fi

  # Check if anything is selected
  echo "$selection" | grep '[a-zA-Z0-9]'
  if [ "${PIPESTATUS[1]}" -ne "0" ]; then
    zenity --info --width="260" --title="  Remove Software" --text="\nNo application was selected for removal." 2>/dev/null
    continue
  fi

  # Split selection
  OIFS=$IFS
  IFS='|'
  selection_array=($selection)
  PKGS_NAMES=""
  PKGS=""
  for ((i=0; i<${#selection_array[@]}; ++i));
  do
    if (( i % 2 == 0 )); then
      PKGS_NAMES=$PKGS_NAMES${selection_array[$i]}"\n"
      continue
    fi
    PKGS=$PKGS${selection_array[$i]}" "
  done
  IFS=$OIFS
  zenity --question --width="320" --window-icon="$_ICON" --title="  $_APPNAME - Remove" \
         --text="\nThe following software has been selected:<b>\n\n ${PKGS_NAMES} </b>\nDo you want to proceed with the removal?" 2>/dev/null
  if [ "$?" -eq "0" ]; then
    remove_pkgs PKGS[@]; return; else continue
  fi
  done
}
# We begin here
prepare
# The main loop
while (true); do
  TASK=$(zenity --list --imagelist --width="240" --height="300" --cancel-label="Quit" --window-icon="$_ICON" \
  --text='    <span font="Sans Bold 9">Please select a Task below</span>:\n' \
  --title="  $_APPNAME" --hide-header --column="Icons" --column="Task" --column="Code Task" --hide-column="3" --print-column="3" \
  "$_APPINST" "  Install Software" "1" "$_APPREM" "  Remove Software" "2" 2>/dev/null)
  if [ "${PIPESTATUS[0]}" -ne "0" ]; then
    exit 0
  elif [ -n "${TASK}" ];then
    case "$TASK" in
      "1") install_menu ;;
      "2") remove_menu ;;
    esac
  fi
done
exit 0
