#!/bin/bash

# Copyright Jean-Philippe Guillemin <jp.guillemin@free.fr>. This program is free software;
# you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version. Please take a look at http://www.gnu.org/copyleft/gpl.htm

if ! command -v yad >/dev/null 2>&1; then
  echo "yad is required but was not found in PATH." >&2
  exit 1
fi

if [ ! "$DISPLAY" ]; then
  echo "This program requires a running X session." >&2
  exit 1
fi

export PATH="${PATH}:/usr/sbin:/sbin"

if [ "$(id -u)" != "0" ]; then
  yad --center --title "Root only" --text "You need to be root to run $(basename $0)" --button="OK:0"
  exit
fi

hour="$(date +%H)"
min="$(date +%M)"
sec="$(date +%S)"
month="$(date +%m)"
day="$(date +%d)"
year="$(date +%Y)"
zone=$(ls -l /etc/localtime | sed -n 's/^.*->.*zoneinfo\/\(.*\)$/\1/p')

mode="$1"

info_box() {
  yad --center --title "$1" --text "$2" --button="OK:0" --image="dialog-information" --width=380
}

warn_box() {
  yad --center --title "Warning" --text "$1" --button="OK:0" --image="dialog-warning" --width=420
}

###############################################
# Main menu

promptaction() {
  mode=$(yad --center --width=480 --height=240 \
    --title "System clock configuration" \
    --text "<b>Current clock set to</b> \"$(date) ($zone)\"" \
    --list --no-headers --separator="" \
    --column="icon:IMG" --column="Action" --column="Description" --column="key:HD" \
    "appointment-new" "Set time" "Configure the time manually" "Set time" \
    "office-calendar" "Set date" "Configure the date manually" "Set date" \
    "preferences-system-time" "Set timezone" "Configure the timezone" "Set timezone" \
    "network-transmit-receive" "NTP" "Use the Network Time Protocol" "NTP" \
    --button="Exit:1" --button="Select:0" \
    --print-column=4 2>/dev/null)
  rc=$?
  mode="$(echo "$mode" | tr -d '\n')"
  if [ $rc -ne 0 ] || [ ! "$mode" ]; then
    mode="none"
  fi
}

setntp(){
  (
  echo "10" ; echo "# Stopping any running ntpd..."
  killall -9 ntpd 1>/dev/null 2>&1
  echo "40" ; echo "# Syncing with pool.ntp.org..."
  ntpdate pool.ntp.org
  rm -f /var/run/ntpd.pid
  echo "70" ; echo "# Starting ntpd..."
  /etc/rc.d/rc.ntpd start
  echo "90" ; echo "# Writing to hardware clock..."
  hwclock --systoh
  echo "100" ; echo "# Done."
  ) | yad --center --title "NTP update in progress" --text "Please wait..." \
    --progress --auto-close --width=400
}

setntpsilent(){
  killall -9 ntpd 1>/dev/null 2>&1
  ntpdate pool.ntp.org
  rm -f /var/run/ntpd.pid
  /etc/rc.d/rc.ntpd start
  hwclock --systoh
}

settime(){
  newtime=$(yad --center --title "Clock adjustment" \
    --text "Enter the new time (HH:MM:SS):" \
    --form --field="Time:" "${hour}:${min}:${sec}" \
    --button="Exit:1" --button="Commit:0")
  rc=$?
  [ $rc -ne 0 ] && return

  clock="${newtime%|}"
  hour="$(echo $clock | cut -d ":" -f1)"
  min="$(echo $clock | cut -d ":" -f2)"
  sec="$(echo $clock | cut -d ":" -f3)"

  if [ "${hour}${min}${sec}" ]; then
    date ${month}${day}${hour}${min}${year}.${sec}
    hwclock --systoh &
  fi
}

setdate(){
  newdate=$(yad --center --title "Date adjustment" \
    --calendar --day="$day" --month="$month" --year="$year" \
    --button="Exit:1" --button="Commit:0")
  rc=$?
  [ $rc -ne 0 ] && return

  day="$(echo $newdate | cut -d "-" -f1)"
  month="$(echo $newdate | cut -d "-" -f2)"
  year="$(echo $newdate | cut -d "-" -f3)"

  if [ "${day}${month}${year}" ]; then
    date ${month}${day}${hour}${min}${year}.${sec}
    hwclock --systoh &
  fi
}

setzone(){
  # Build the timezone list dynamically instead of hardcoding it
  if command -v timedatectl >/dev/null 2>&1; then
    zonelist=$(timedatectl list-timezones 2>/dev/null)
  fi
  if [ ! "$zonelist" ]; then
    zonelist=$(cd /usr/share/zoneinfo 2>/dev/null && find . -type f \
      ! -name "posixrules" ! -name "localtime" ! -path "./right/*" ! -path "./posix/*" \
      | sed -e 's#^\./##' | sort)
  fi

  rowargs=()
  while IFS= read -r tz; do
    [ ! "$tz" ] && continue
    rowargs+=("$tz")
  done <<< "$zonelist"

  newzone=$(yad --center --width=500 --height=560 \
    --title "Time zone configuration" \
    --text "Set the timezone from the list below (current: <b>$zone</b>):" \
    --list --no-headers --column="Timezone" \
    --button="Exit:1" --button="Select:0" \
    --print-column=1 \
    "${rowargs[@]}")
  rc=$?
  newzone="${newzone%|}"
  [ $rc -ne 0 ] && return

  cd /etc
  if [[ "$newzone" && -r /usr/share/zoneinfo/$newzone ]]; then
    ln -sf /usr/share/zoneinfo/$newzone localtime
    zone="$newzone"
  fi
}

[ ! "$mode" ] && promptaction

case $mode in
  "Set time")
    settime
    exec $0
    ;;
  "Set date")
    setdate
    exec $0
    ;;
  "Set timezone")
    setzone
    exec $0
    ;;
  "NTP")
    setntp
    exec $0
    ;;
  --ntp)
    setntpsilent &
    exit
    ;;
  none)
    exit
esac

# end
