#!/usr/bin/env bash
# ==========================================================================
#         ____            _                     _____           _
#        / ___| _   _ ___| |_ ___ _ __ ___     |_   _|__   ___ | |___
#        \___ \| | | / __| __/ _ \ '_ ` _ \ _____| |/ _ \ / _ \| / __|
#         ___) | |_| \__ \ ||  __/ | | | | |_____| | (_) | (_) | \__ \
#        |____/ \__, |___/\__\___|_| |_| |_|     |_|\___/ \___/|_|___/
#               |___/
#                             --- System-Tools ---
#                  https://www.nntb.no/~dreibh/system-tools/
# ==========================================================================
#
# System-Info
# Copyright (C) 2013-2025 by Thomas Dreibholz
#
# 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Contact: thomas.dreibholz@gmail.com

set -eu

export TEXTDOMAIN="System-Info"


# ###### Get current width of the console ###################################
consolewidth()
{
   local terminalInfo
   terminalInfo="$(print-utf8 --terminal-info)"
   local width="${terminalInfo// [0-9]*/}"
   if [[ ! "${width}" =~ ^[0-9]+$ ]] ; then
      # Assume a standard width of 80:
      echo "80"
   fi
   echo "${width}"

   # ====== Old code without Print-UTF8 for reference =======================
   # # Requires:
   # # tput: for obtaining the console width (Ubuntu: ncurses-bin)
   # if [ ! -v TERM ] || [ "${TERM}" == "" ] ; then
   #    # TERM is not defined => assume a standard width of 80:
   #    echo "80"
   # else
   #    tput cols
   # fi
   # ========================================================================
}


# ###### Get width of UTF-8 string in console characters ####################
# For some more details, see also:
# https://unix.stackexchange.com/questions/245013/get-the-display-width-of-a-string-of-characters
stringwidth()
{
   print-utf8 -w "$1"

   # ====== Old code without Print-UTF8 for reference =======================
   # local string
   #
   # # The ANSI escape sequences for coloring have to be filtered out!
   # # shellcheck disable=SC2001
   # string="$(echo "$1" | sed -e 's/\(\\x1b\[[0-9;:]*m\)//g')"
   #
   # # Unfortunately, this seems to only work under Linux:
   # # wc -Lm <<< "${string}" | awk '{ print $2 }'
   #
   # Requires:
   # col:  for computing the display width of a string (Ubuntu: bsdextrautils)
   #
   # awk '
   #    BEGIN {
   #       string = ARGV[1]
   #       len    = length(string)
   #       s1     = ""
   #       s2     = ""
   #       for (i = 0; i < len; i++) {
   #          s1 = s1 ".."     # 2 characters of size 1
   #          s2 = s2 "\b\b"   # 2 backspaces
   #       }
   #       print s1 string s2 s1
   #       exit
   #    }' "${string}" | col -b | awk '{ print length - 2 * length(ARGV[2]); exit }' - "${string}"
   # ========================================================================
}


# ###### Center text in console #############################################
function center ()
{
   print-utf8 --newline --center -- "$1"

   # ====== Old code without Print-UTF8 for reference =======================
   # local text="$1"
   # local consoleWidth
   # local textLength
   #
   # consoleWidth="$(consolewidth)"   # Console width in characters
   # textLength=$( stringwidth "${text}" )
   # indent=$(( (consoleWidth-textLength) / 2 ))
   # if [ ${indent} -lt 0 ] ; then
   #    indent=0
   # fi
   # printf "%${indent}s"
   # echo -e "${text}"
   # ========================================================================
}


# ###### Print centered separator in console ################################
# Parameters:
# $1: separater left border, e.g. " <😀"
# $2: separator, e.g. "="
# $3: separater right border, e.g. "😀> "
# => " <😀====...====😀> "
function separator ()
{
   print-utf8 --newline --separator "$1" "$2" "$3"

   # ====== Old code without Print-UTF8 for reference =======================
   # local separaterLeftBorder="$1"
   # local separatorCharacter="$2"
   # local separaterRightBorder="$3"
   # local separator=""
   # local consoleWidth
   # local i
   #
   # # The example uses an UTF-8 smiley (😀) as border decoration.
   # # It uses 4 bytes, but needs a space of 2 characters in the output.
   # consoleWidth=$(consolewidth)   # Console width in characters
   # # Calculate width of the borders in characters:
   # borderWidth=$( stringwidth "${separaterLeftBorder}${separaterRightBorder}" )
   # separatorCharacterWidth=$( stringwidth "${separatorCharacter}" )
   #
   # i=${borderWidth}
   # while [ $(( i+separatorCharacterWidth )) -lt "${consoleWidth}" ] ; do
   #    separator="${separator}${separatorCharacter}"
   #    i=$(( i+separatorCharacterWidth ))
   # done
   # echo "${separaterLeftBorder}${separator}${separaterRightBorder}"
   # ========================================================================
}


# ###### Make banner with equal-length lines ################################
# Parameters:
# $1: Banner text
# $2: Maximum length. Default is current console width
# Return: success/failure
function make-banner ()
{
   local bannerText="$1"
   local maxWidth="$2"
   if [ "${maxWidth}" == "" ] ; then
      maxWidth=$(consolewidth)   # Console width in characters
   fi

   # ====== Create banner with figlet, toilet or echo as fallback ===========
   local generatedBanner
   generatedBanner=$(
      (
         figlet -w 256 -f standard "${bannerText}" 2>/dev/null || \
         toilet -w 256 -f standard "${bannerText}" 2>/dev/null || \
         if [ ${#bannerText} -le 10 ] ; then sysvbanner "${bannerText}" ; else false ; fi || \
         echo "${bannerText}"
      ) | (
         # ====== Compute maximum line length and pad banner lines ==========
         # Array to store the lines of the banner:
         banner=( )

         # Read lines, and compute the maximum line length
         maxLineLength=0
         while IFS= read -r line ; do
            if [ ${#line} -gt "${maxLineLength}" ] ; then
               maxLineLength=${#line}
            fi
            banner+=( "${line}" )
         done

         # Return, if output is too wide
         if [ "${maxLineLength}" -gt "${maxWidth}" ] ; then
            return
         fi

         # Print maximum-length lines padded with spaces
         for line in "${banner[@]}" ; do
            print-utf8 -n -i "-${maxLineLength}" "${line}"
         done
      )
   )

   # ====== Check resulting banner ==========================================
   if [ "${generatedBanner}" == "" ] ; then
      # Failed -> return error code.
      return 1
   fi
   echo "${generatedBanner}"
}
