#!/bin/bash

# This script compiles and sets given
# gnome-shell theme as GDM3 theme

bold=$(tput bold)          # make text bold
underlined=$(tput smul)    # make text underlined
normal=$(tput sgr0)        # restore text to normal

# Here are some variables to be used in the script
ProgName=$(basename "$0")       # Program's Name
setVars(){
  declare -g ThemesDir=/usr/share/themes       # Directory that contains themes
  declare -g tempDir="$(mktemp -d)"            # Directory for storing temprary files
  declare -g tempThemeDir=$tempDir/theme       # Directory to temprarily store theme files for processing
  declare -g tempExtractedDir=$tempDir/extracted      # Directory to temprarily store theme files extracted from some gresource file
  declare -g gnomeShellDir=/usr/share/gnome-shell     # Directory that contains gnome-shell and GDM related files
  declare -g gdmGresourceFile=$gnomeShellDir/gnome-shell-theme.gresource # Gresource file to be used by GDM
  declare -g ubuntuGresourceFile=$gnomeShellDir/gdm-theme.gresource     # Gresource file to be used by GDM on Ubuntu and derivatives
  declare -g ubuntuGresourceFile_Old=$gnomeShellDir/gdm3-theme.gresource # Gresource file to be used by GDM on Ubuntu (21.04 and older) and derivatives
  declare -g gdmGresourceManualBackup=$gdmGresourceFile.bak              # Manual Backup of distro default or official GDM gresource file
  declare -g gdmGresourceAutoBackup=$gdmGresourceFile.default            # Automatic Backup of original/default GDM gresource file
  declare -g deprecatedGresourceBackups=$gdmGresourceFile.original       # Files that were previously used as backup but now they don't
  declare -g distroDefaultGresourceFile=$gdmGresourceFile.distro-default # File to store distro default gresource file
  declare -g currentThemeFile=/etc/gdm-tools/currentTheme                # File to store name of the current GDM theme
  declare -g currentBackgroundFile=/etc/gdm-tools/currentBackground      # File to store type of the current GDM background
  declare -g gdm3css=/etc/alternatives/gdm3.css      # Symlink used by update-alternatives program to provide gdm3.css file
  declare -g customCSS=/etc/gdm-tools/custom.css     # User's custom CSS to apply to every theme
  declare -g gresource=gnome-shell-theme.gresource   # Short alias/name for a long file name
  declare -g customThemeIdentity=custom-theme        # File that will be used to distinguish gresource file generated by this script from original/default gresource file
  # Names of the supported colors
  declare -g colorNames=(
                         black
                         silver
                         gray
                         white
                         maroon
                         red
                         purple
                         fuchsia
                         green
                         lime
                         olive
                         yellow
                         navy
                         blue
                         teal
                         aqua
                         
                         aliceblue
                         antiquewhite
                         aqua
                         aquamarine
                         azure
                         beige
                         bisque
                         black
                         blanchedalmond
                         blue
                         blueviolet
                         brown
                         burlywood
                         cadetblue
                         chartreuse
                         chocolate
                         coral
                         cornflowerblue
                         cornsilk
                         crimson
                         cyan
                         darkblue
                         darkcyan
                         darkgoldenrod
                         darkgray
                         darkgreen
                         darkgrey
                         darkkhaki
                         darkmagenta
                         darkolivegreen
                         darkorange
                         darkorchid
                         darkred
                         darksalmon
                         darkseagreen
                         darkslateblue
                         darkslategray
                         darkslategrey
                         darkturquoise
                         darkviolet
                         deeppink
                         deepskyblue
                         dimgray
                         dimgrey
                         dodgerblue
                         firebrick
                         floralwhite
                         forestgreen
                         fuchsia
                         gainsboro
                         ghostwhite
                         gold
                         goldenrod
                         gray
                         green
                         greenyellow
                         grey
                         honeydew
                         hotpink
                         indianred
                         indigo
                         ivory
                         khaki
                         lavender
                         lavenderblush
                         lawngreen
                         lemonchiffon
                         lightblue
                         lightcoral
                         lightcyan
                         lightgoldenrodyellow
                         lightgray
                         lightgreen
                         lightgrey
                         lightpink
                         lightsalmon
                         lightseagreen
                         lightskyblue
                         lightslategray
                         lightslategrey
                         lightsteelblue
                         lightyellow
                         lime
                         limegreen
                         linen
                         magenta
                         maroon
                         mediumaquamarine
                         mediumblue
                         mediumorchid
                         mediumpurple
                         mediumseagreen
                         mediumslateblue
                         mediumspringgreen
                         mediumturquoise
                         mediumvioletred
                         midnightblue
                         mintcream
                         mistyrose
                         moccasin
                         navajowhite
                         navy
                         oldlace
                         olive
                         olivedrab
                         orange
                         orangered
                         orchid
                         palegoldenrod
                         palegreen
                         paleturquoise
                         palevioletred
                         papayawhip
                         peachpuff
                         peru
                         pink
                         plum
                         powderblue
                         purple
                         red
                         rosybrown
                         royalblue
                         saddlebrown
                         salmon
                         sandybrown
                         seagreen
                         seashell
                         sienna
                         silver
                         skyblue
                         slateblue
                         slategray
                         slategrey
                         snow
                         springgreen
                         steelblue
                         tan
                         teal
                         thistle
                         tomato
                         turquoise
                         violet
                         wheat
                         white
                         whitesmoke
                         yellow
                         yellowgreen
		        )



  ###################################
  # Variables read from configFile  #
  ###################################
                           
  # Location of the file where your distro puts default gresource file instead of the default location
  if [ -z "$defaultGresource" ] || isNotDefaultGresource "$defaultGresource"; then
    declare -g defaultGresource="$gdmGresourceFile"
  elif [ "$defaultGresource" != "$gdmGresourceFile" ]; then
    declare -g customDefaultGresource=true
  fi

  # Overlay mode
  declare -g overlayMode=${overlayMode:-resources}
}

getCurrentTheme(){
  declare -g currentTheme="$(cat "$currentThemeFile" 2>/dev/null)"
  [ -z "$currentTheme" ] && currentTheme=default
}

printCurrentTheme(){
  [ -z "$currentTheme" ] && getCurrentTheme
  echo "$currentTheme"
}

saveCurrentTheme(){
  [ -z "$currentTheme" ] && CurrentTheme=default
  printCurrentTheme > "$currentThemeFile"
}

getCurrentBackground(){
  declare -g currentBackground="$(cat "$currentBackgroundFile" 2>/dev/null)"
  case "$currentBackground" in
  'image')
    currentBackground=/usr/share/gnome-shell/theme/gdm-background
    ;;
  '')
    currentBackground=none
    ;;
  esac
}

printCurrentBackground(){
  [ -z "$currentBackground" ] && getCurrentBackground
  echo "$currentBackground"
}

saveCurrentBackground(){
  printCurrentBackground > "$currentBackgroundFile"
}

printBackgroundCSS(){
  imgBgr="
#lockDialogGroup {
  background-image: url('resource:///org/gnome/shell/theme/background');
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-position: center;
}"
  colorBgr="
#lockDialogGroup {
  background-color: $currentBackground;
}"


  case "$(background-type "$currentBackground")" in
   (image)
     echo "$imgBgr"
   ;;
   (color)
     echo "$colorBgr"
   ;;
  esac
}

initFun(){
  if [ -r "/etc/gdm-tools/${ProgName}" ]; then
    configFile=/etc/gdm-tools/${ProgName}
    echo "${bold}Warning:${normal} Configuration file '${configFile}' is deprecated. Use '${configFile}.conf' instead" >&2
  elif [ -r "/etc/gdm-tools/${ProgName}.conf" ]; then
    configFile=/etc/gdm-tools/${ProgName}.conf
  fi
  [ -r $configFile ] && source $configFile
  setVars
  getCurrentTheme
  getCurrentBackground
  case $1 in
    -s | set )
      if ! which glib-compile-resources gresource > /dev/null; then
        echo "This script needs GLib (developer edition) in order to work. But it was not found." > /dev/stderr
        exit 4
      fi
    ;;
  esac

  if [ $UID != 0 ]; then
    local rootNeeded
    case $1 in
      -r | reset | -s | set | -b | backup )
        rootNeeded=true
      ;;
      -x | extract)
        rootNeeded=true
        if [ -n "$2" ];then
          local dirToCheck="$(realpath -m "$2")"
          if mkdir -p "$dirToCheck" 2>/dev/null && [ -w "$dirToCheck" ]; then
		  rootNeeded=false
          fi
        fi
      ;;
      *)
        rootNeeded=false
      ;;
    esac

    if [[ $rootNeeded = true ]]; then
      # check if user has sudo installed
      if which sudo &> /dev/null; then
        # run this script with sudo
        sudo "$0" "$@"
        exit $?
      elif which su &> /dev/null; then
        # run this script as root
        su -c "$0 $@"
        exit $?
      else
        echo "Plz, run this program as root" > /dev/stderr
        exit 1
      fi
    fi
  fi
}

notRecognized() {
  echo "action '$1' was not recogninzed, use -h, [--]help for help" > /dev/stderr && exit 2
}

help() {
  echo -en "${ProgName}: a program to change gnome login theme and background
Usage: ${ProgName} <Option> [arguments]
Options:
  -l,list \t\t\t\t List available theme options
  -lc,list-colors \t\t\t List acceptable color names
  -s,set <theme> [image|none|color] \t Set theme and optionaly background
  -s,set -b,--background [image|color]\t Set background image only
  -r,reset \t\t\t\t Reset everything to default
  -b,backup {update|restore} \t\t Update/Restore backup of default theme
  -x,extract [location] \t\t Extract default theme to specified location
  -h,[--]help \t\t\t\t Print this help message
  -m,manual \t\t\t\t Provide detailed help
  -e,examples \t\t\t\t Explain this program with examples
You can also run 'man $ProgName' for more detailed help
"
}

examples() {
  echo -n "${ProgName}: a program to change gnome login theme and background

EXAMPLES:

$ProgName -l
$ProgName list
    Either of the above commands will list all the themes that can be set as Gnome/Ubuntu Login (GDM) theme

$ProgName -lc
$ProgName list-colors
    Either of the above commands will list all the color names that can be accepted as Gnome/Ubuntu Login (GDM) background

$ProgName -s Materia
$ProgName set Materia
    Either of the above commands will set 'Materia' as GDM theme without changing the background image

$ProgName -s default
$ProgName set default
    Either of the above commands will set GDM theme to default/original without changing the background image

$ProgName -s Materia ~/Pictures/MyWallpaper.jpg
$ProgName set Materia ~/Pictures/MyWallpaper.jpg
    Either of the above commands will set GDM theme to 'Materia' while also setting ~/Pictures/MyWallpaper.jpg as GDM background image

$ProgName -s default ~/Pictures/MyWallpaper.jpg
$ProgName set default ~/Pictures/MyWallpaper.jpg
    Either of the above commands will set GDM theme to default while also setting ~/Pictures/MyWallpaper.jpg as GDM background image

$ProgName -s Materia none
$ProgName set Materia none
    Either of the above commands will set GDM theme to 'Materia' while also unsetting the GDM background image

$ProgName -s default none
$ProgName set default none
    Either of the above commands will set GDM theme to default while also unsetting the GDM background image

$ProgName set --background ~/Pictures/MyWallpaper.jpg
$ProgName set -b ~/Pictures/MyWallpaper.jpg
$ProgName -s --background ~/Pictures/MyWallpaper.jpg
$ProgName -s -b ~/Pictures/MyWallpaper.jpg
    Any of the above commands will set ~/Pictures/MyWallpaper.jpg as GDM background image without changing the theme

$ProgName set --background none
$ProgName set -b none
$ProgName -s --background none
$ProgName -s -b none
    Any of the above commands will unset GDM background image without changing the theme

$ProgName set --background cyan
$ProgName set -b cyan
$ProgName -s --background cyan
$ProgName -s -b cyan
    Any of the above commands will set GDM background to color 'cyan' without changing the theme

$ProgName set --background '#65af21'
$ProgName set -b '#65af21'
$ProgName -s --background '#65af21'
$ProgName -s -b '#65af21'
    Any of the above commands will set GDM background to color with color code '#65af21' without changing the theme

$ProgName backup update
$ProgName -b update
$ProgName backup -u
$ProgName -b -u
    Will update the backup to the current version of default GDM theme

$ProgName backup restore
$ProgName -b restore
$ProgName backup -r
$ProgName -b -r
    Will restore default GDM theme from backup

$ProgName -r
$ProgName reset
    Will reset everything back to the way it was before you ever run this program

$ProgName -x
$ProgName extract
    Will extract the default GDM theme to system-wide themes directory

$ProgName -x ~/.themes
$ProgName -x ~/.themes default
$ProgName extract ~/,themes
$ProgName extract ~/.themes/ default
    Will extract the default GDM theme to '.themes' directory in your home folder

$ProgName -x ~/.themes distro-default
$ProgName extract ~/.themes/ distro-default
    Will extract distro-default GDM theme to '.themes' directory in your home folder
    (only in some cases)

$ProgName -e
$ProgName examples
    Will print this 'examples' page

man $ProgName
    Will print detailed help message (manual)
"
}

pagedHelp() {
  if [ -x "$(which $PAGER 2>/dev/null)" ];then
    $1 | $PAGER
  elif type less &> /dev/null; then
    $1 | less
  elif type more &> /dev/null; then
    $1 | more
  else
    $1
  fi
}

contains() {
  first="$1"
  shift
  for element in "$@"; do
    [ "$first" = "$element" ] && return 0
  done
  return 1
}

isDefaultGresource() {
  local targetGresourceFile
  if [ -z "$1" ]; then
    echo "no file provided"
    return 9
  elif [ -f "$1"  ]; then
    targetGresourceFile="$1"
  else
#    echo "file '$1' not found"
    return 10
  fi
  if [  -n "$(gresource list $targetGresourceFile /org/gnome/shell/theme/gnome-shell.css 2>/dev/null)" ]; then
    if [ -z "$(gresource list $targetGresourceFile /org/gnome/shell/theme/$customThemeIdentity 2>/dev/null)" ]; then
      return 0
    fi
  fi
  return 1
}

isNotDefaultGresource(){
  ! isDefaultGresource "$@"
  return $?
}

getDefaultGresource() {
  local gresourcefile
  for gresourcefile in "$defaultGresource" $gdmGresourceFile $gdmGresourceAutoBackup $deprecatedGresourceBackups $gdmGresourceManualBackup; do
    if isDefaultGresource $gresourcefile; then
      echo $gresourcefile
      return 0
    fi
  done
  return 1
}

getDistroGresource() {
  local gresourceFiles=("$gdmGresourceFile" "$distroDefaultGresourceFile")
  local gresourcefile
  for gresourcefile in "${gresourceFiles[@]}"; do
    if isDefaultGresource "$gresourcefile"; then
      echo "$gresourcefile"
      return 0
    fi
  done
  return 1
}

# This function will backup default gresource file if and only if it needs to be backed up
smart_backup() {
  if [ "$customDefaultGresource" = true ]; then
    local sourceGresource="$(getDistroGresource)"
    local targetGresource="$distroDefaultGresourceFile"
    local themeName="Distro-Default"
  else
    local sourceGresource=$(getDefaultGresource)
    local targetGresource="$gdmGresourceAutoBackup"
    local themeName="Default"
  fi
  if [ -n "$sourceGresource" ]; then
    if [ "$sourceGresource" != "$targetGresource" ]; then
      if [ -f "$targetGresource" ]; then
        local action=updated
      else
        local action=saved
      fi
      cp "$sourceGresource" "$targetGresource"
      echo "$themeName theme $action"
    fi
    [ ! -f $gdmGresourceManualBackup ] && cp "$targetGresource" $gdmGresourceManualBackup
  fi
  rm -f $deprecatedGresourceBackups
}

backup_action() {
  if [ "$customDefaultGresource" = true ]; then
    local sourceGresource="$(getDistroGresource)"
    local themeName="Distro-Default"
  else
    local sourceGresource=$(getDefaultGresource)
    local themeName="Default"
  fi
  case $1 in 
    -u | update)
      if isDefaultGresource "$sourceGresource"; then
        cp "$sourceGresource" $gdmGresourceManualBackup
        echo "Backup updated from $themeName theme"
      else
        echo Default GDM theme not found. > /dev/stderr
        echo Backup cannot be updated. > /dev/stderr
        return 1
      fi
    ;;
    -r | restore)
      if [ -f $gdmGresourceManualBackup ]; then
        cp $gdmGresourceManualBackup "$sourceGresource"
        echo "$themeName Theme restored from Backup"
      else
        echo no backup found to restore from > /dev/stderr
        return 2
      fi
    ;;
    *)
      echo backup action not recogninzed > /dev/stderr
      return 10
    ;;
  esac
}

reset() {
  if [ "$customDefaultGresource" = true ]; then
    local backupFile="$distroDefaultGresourceFile"
  else
    local backupFile="$gdmGresourceAutoBackup"
  fi
  if [ -f "$backupFile" ]; then
    mv "$backupFile" "$gdmGresourceFile"
  fi
  [ -f $ubuntuGresourceFile_Old ] && update-alternatives --auto gdm3-theme.gresource
  [ -f $ubuntuGresourceFile ] && update-alternatives --auto gdm-theme.gresource
  rm -f $gdmBackground $currentThemeFile $currentBackgroundFile
  echo "Everything reset to default values"
}

compile() {
  local targetThemeShellDir="$1"
  if [[ ! -z "$targetThemeShellDir" && -d "$targetThemeShellDir" ]]; then
    rm -rf $tempThemeDir
    mkdir -p $tempThemeDir
    case $overlayMode in
      none)
        cp -r "$targetThemeShellDir"/* $tempThemeDir
        ;;
      resources)
        if [[ "$theme" != 'default' ]]; then
          extract $(getDefaultGresource)
          cp -rT "$tempExtractedDir" "$tempThemeDir"
        fi
        cp -r "$targetThemeShellDir"/* $tempThemeDir
        ;;
      full)
        if [[ "$theme" != 'default' ]]; then
          extract $(getDefaultGresource)
          for cssFileName in pad-osd gnome-shell{,-high-contrast}; do
            mv "$tempExtractedDir"/${cssFileName}{,-default}.css
          done
          cp -rT "$tempExtractedDir" "$tempThemeDir"
          cp -rT "$targetThemeShellDir" $tempThemeDir
          for cssFileName in pad-osd gnome-shell{,-high-contrast}; do
            if [ -r "$tempThemeDir"/${cssFileName}.css ]; then
              cat "$tempThemeDir"/${cssFileName}.css >> "$tempThemeDir"/${cssFileName}-default.css
            fi
            mv "$tempThemeDir"/${cssFileName}{-default,}.css
          done
        else
          cp -r "$targetThemeShellDir"/* $tempThemeDir
        fi
        ;;
      *)
        { echo "overlayMode '$overlayMode' not supported!"
          echo "Please! set overlayMode in configuration file to an appropriate value:"
          echo "    none, resources, full"
        } >&2
        exit 1
        ;;
    esac
  else
    return 1
  fi
  set-background
  printBackgroundCSS >> $tempThemeDir/gnome-shell.css
  if [ -f "$customCSS" ]; then
    cat "$customCSS" >> $tempThemeDir/gnome-shell.css
  fi
  cp $tempThemeDir/gnome-shell.css $tempThemeDir/gdm3.css
  cp $tempThemeDir/gnome-shell.css $tempThemeDir/gdm.css
  touch $tempThemeDir/$customThemeIdentity
  # Generate gresource xml file for current theme
  { echo '<?xml version="1.0" encoding="UTF-8"?>'
    echo '<gresources>'
    echo ' <gresource prefix="/org/gnome/shell/theme">'
    local file
    while read file; do
      rpath=${file/"$tempThemeDir/"/}
      echo "  <file>$rpath</file>"
    done <<<$(find ${tempThemeDir} -type f,l)
    echo ' </gresource>'
    echo '</gresources>'
  } > $tempThemeDir/$gresource.xml
  glib-compile-resources --sourcedir=$tempThemeDir $tempThemeDir/$gresource.xml
}

extract() {
  local gresourcefile=$1 r rDir
  if [ ! -f "$gresourcefile" ]; then
    echo "file '$gresourcefile' doesn't exist, so couldn't be extracted" > /dev/stderr
    return 1
  fi
  for r in $(gresource list $gresourcefile); do
    # correctly generate necessary folder structure from actual resource
    rDir=${r%/*}
    rDir=${rDir#'/org/gnome/shell/theme'}
    test ! -d "$tempExtractedDir/$rDir" && mkdir -p "$tempExtractedDir/$rDir"
    # extract the resource to the folder
    gresource extract $gresourcefile $r > $tempExtractedDir/${r#'/org/gnome/shell/theme/'}
  done
}

extract_default_theme() {
  local extractedDir
  if [ ! -z "$1" ]; then
    extractedDir="$1"
  else
    extractedDir="$ThemesDir"
  fi
  if [ "$2" = 'distro-default' ] && [ "$customDefaultGresource" = true ]; then
    local gresourceToExtract="$(getDistroGresource)"
    local themeName='distro-default'
  elif [ -z "$2" ] || [ "$2" = 'default' ]; then
    local gresourceToExtract="$(getDefaultGresource)"
    local themeName='default'
  else
    echo "Can't extract '$2'"
    return 2
  fi
  if [ -n "$gresourceToExtract" ]; then
    local extractedShellDir="$extractedDir"/default-extracted/gnome-shell
    extract "$gresourceToExtract"
    rm -rf "$extractedDir"/default-extracted
    mkdir -p "$extractedShellDir"
    mv -T "$tempExtractedDir" "$extractedShellDir"
    echo "$themeName theme extracted to '$extractedDir'"
  else
    echo "$themeName theme not found, cannot extract" > /dev/stderr
    return 1
  fi
}

# list acceptable color names
list_colors(){
  echo "${colorNames[@]}" | tr ' ' '\n'
}

# list themes
list() {
  local theme
  echo default
  if [ "$customDefaultGresource" = true ]; then
    echo distro-default
  fi
  ls -1 $ThemesDir | while read theme; do
    [ -f $ThemesDir/"$theme"/gnome-shell/gnome-shell.css ] && echo "$theme"
  done
}

background-type() {
  if [ "$1" = none ]; then
    echo "none"
  elif [ -f "$1" ]; then
    if file -b --mime-type "$1" | grep image/.* > /dev/null ; then
      echo "image"
    else
      echo "invalid-file-type"
    fi
  elif contains "$1" "${colorNames[@]}" ||
       echo "$1" | grep -E '^#(([0-9a-fA-F]){3}){1,2}$' > /dev/null
  then
    echo "color"
  else
    echo "invalid"
  fi
}

set-background() {
  background=${image:-$currentBackground}
  case "$(background-type "$background")" in
  none)
    echo "Background set to 'none'"
    ;;
  image)
    cp "$background" "$tempThemeDir"/background
    echo "Background set to image '$background'"
    ;;
  invalid-file-type)
    echo "'$background' is not an image file" > /dev/stderr
    status=1
    ;;
  color)
    echo "Background set to color '$background'"
    ;;
  invalid)
    echo "image '$background' not found" > /dev/stderr
    echo "GDM background was not changed" > /dev/stderr
    status=10
    ;;
  esac
  if [ "$status" != 10 ]; then
    currentBackground="$background"
    saveCurrentBackground
  fi
  return ${status:-0}
}

set-alternatives() {
  [ -f $ubuntuGresourceFile_Old ] && update-alternatives --set gdm3-theme.gresource $gdmGresourceFile
  [ -f $ubuntuGresourceFile ] && update-alternatives --set gdm-theme.gresource $gdmGresourceFile
}

set-custom-theme() {
  local targetThemeShellDir="$1"
  compile "$targetThemeShellDir"
  cp $tempThemeDir/$gresource "$gdmGresourceFile"
  set-alternatives
  echo "Theme set to '$theme'"
  #eval local GNOME_SHELL_THEME=$(gsettings get org.gnome.shell.extensions.user-theme name 2>/dev/null)
  #if [ "$XDG_CURRENT_DESKTOP" = GNOME ]; then
  #  echo "Please, Log Out and Log In again!"
  #fi
}

set-default-theme() {
  theme=default
  extract "$gdmGresourceAutoBackup"
  set-custom-theme $tempExtractedDir
}

set-distro-theme() {
  theme=distro-default
  local distroGresource="$(getDistroGresource)"
  if [ -n "$distroGresource" ]; then
    extract "$distroGresource"
    set-custom-theme $tempExtractedDir
  else
    echo "'$theme' is not a valid GDM theme"
  fi
}

set-theme() {
  theme="$1"
  image="$2"
  ThemeShellDir=$ThemesDir/"$theme"/gnome-shell
  if [ "$theme" = 'default' ]; then
    set-default-theme
    currentTheme="$theme"
    saveCurrentTheme
  elif [ "$theme" = 'distro-default' ]; then
    set-distro-theme
    currentTheme="$theme"
    saveCurrentTheme
  elif [[ "$theme" = "-b" || "$theme" = "--background" ]]; then
    if isDefaultGresource "$gdmGresourceFile"; then
      if [ "$customDefaultGresource" = true ]; then
        set-distro-theme
        currentTheme=distro-default
        saveCurrentTheme
      else
        set-default-theme
        currentTheme=default
        saveCurrentTheme
      fi
    else
      set-theme "$currentTheme" "$image"
    fi
  elif [ -f "$ThemeShellDir"/gnome-shell.css ]; then
    set-custom-theme "$ThemeShellDir"
    currentTheme="$theme"
    saveCurrentTheme
  elif [ -z "$theme" ]; then
    select theme in $(list); do
      set-theme "$theme"
      break
    done
  else
    echo "'$theme' is not a valid GDM theme" > /dev/stderr
    exit 3
  fi
}

main() {
  initFun "$@"
  case $1 in
    -s | set)
      smart_backup    # Run intelligent backup before doing anything to the system
      set-theme "$2" "$3"
    ;;
    -r | reset)
      reset
    ;;
    -l | list)
      list
    ;;
    -lc | list-colors)
      list_colors
    ;;
    -b | backup)
      backup_action "$2"
    ;;
    -x | extract)
      extract_default_theme "$2" "$3"
    ;;
    -h | --help | help )
      help
    ;;
    -m | manual)
    man $ProgName
    ;;
    -e | examples)
      pagedHelp examples
    ;;
    *)
      notRecognized "$1"
    ;;
  esac
  rm -rf $tempDir
}

main "$@"
