#!/usr/bin/env bash

PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:${PATH}"

################################################################################
#
# CUSTOM PLUGIN SECTION
#
################################################################################

############################################################
# Variables
############################################################

###
### Custom Defines
###
appname="wifi"

if [ -n "${BLOCK_INSTANCE:-}" ]; then
	iface="${BLOCK_INSTANCE}"
else
	iface="$( tail -1 /proc/net/wireless | awk '{print $1}' | sed 's/://g' )"
fi

format=" {status_or_ip} ({ssid} {quality}%)"


###
### Thresholds
###

# Enable
has_threshold=1

# Depending on the conditions in your custom_action()
# you can force the output to be critical or warning
# Set these vars to 1 (in custom_action)
force_crit=0
force_warn=0
force_good=0


###
### Additional arguments
###
arg_params=(
	"-i"
)
arg_vars=(
	"iface"
)
arg_desc_val=(
	"<iface>"
)
arg_desc_long=(
	"Specify the network interface"
)


###
### Format placeholders
###

# bash variable names
format_vars=(
	"ip"
	"ip_nm"
	"ip6"
	"ip6_nm"
	"mac"
	"mtu"
	"iface"
	"status"
	"status_or_ip"
	"status_or_ip6"
	"ssid"
	"freq"
	"freq_unit"
	"tx_power"
	"tx_power_unit"
	"quality"
	"signal"
	"signal_unit"
	"noise"
	"bit_rate"
	"bit_rate_unit"
)

# Format placeholders
format_nodes=(
	"{ip}"
	"{ip_nm}"
	"{ip6}"
	"{ip6_nm}"
	"{mac}"
	"{mtu}"
	"{iface}"
	"{status}"
	"{status_or_ip}"
	"{status_or_ip6}"
	"{ssid}"
	"{freq}"
	"{freq_unit}"
	"{tx_power}"
	"{tx_power_unit}"
	"{quality}"
	"{signal}"
	"{signal_unit}"
	"{noise}"
	"{bit_rate}"
	"{bit_rate_unit}"
)

# Format description (for help display)
format_descs=(
	"IPv4 address"
	"IPv4 address including netmask"
	"IPv6 address"
	"IPv6 address including netmask"
	"MAC address"
	"MTU value"
	"Network interface"
	"Status (up, down, unknown, absent)"
	"Status text if not up or IPv4 address"
	"Status text if not up or IPv6 address"
	"Wireless Network SSID name"
	"Wireless frequency"
	"Wireless requency unit"
	"Wireless tx power"
	"Wireless tx power unit"
	"Wireless quality in percent"
	"Wireless signal"
	"Wireless signal unit"
	"Wireless noise"
	"Bit Rate"
	"Bit Rate unit"
)

# Format examples (for help display)
format_examples=(
	"-f \" {status}: {ip} {ssid}\""
	"-f \" {iface}: {status_or_ip6} {quality}\""
)


############################################################
# custom_actio function
############################################################

###
### Evaluate disk space
###
custom_action() {
	if ! command -v ip > /dev/null 2>&1; then
		echo "Error, ip binary not found, but required"
		exit 1
	fi
	if ! command -v iwconfig > /dev/null 2>&1; then
		echo "Error, iwconfig binary not found, but required"
		exit 1
	fi

	local _ip
	local _iwconfig

	ip=
	ip_nm=
	ip6=
	ip6_nm=
	mac=
	mtu=
	status="unknown"
	status_or_ip="${status}"
	status_or_ip6="${status}"

	ssid=
	freq=
	freq_unit=
	tx_power=
	tx_power_unit=
	quality=
	signal=
	signal_unit=
	noise=
	bit_rate=
	bit_rate_unit=

	if [ ! -d "/sys/class/net/${iface}/" ] || [ ! -f "/sys/class/net/${iface}/operstate" ]; then

		status="absent"
		status_or_ip="${status}"
		status_or_ip6="${status}"
		force_crit=1

	else

		_ip="$( ip addr show "${iface}" 2>/dev/null )"

		# No WIFI device
		if ! _iwconfig="$( iwconfig "${iface}" 2>/dev/null )"; then
			status="absent"
			status_or_ip="${status}"
			status_or_ip6="${status}"
			force_crit=1

		# WIFI device
		else
			# Has WIFI, but is Not connected
			if echo "${_iwconfig}" | grep -iq 'Not-Associated'; then
				status="down"
				status_or_ip="${status}"
				status_or_ip6="${status}"
				force_crit=1

			# Has WIFI and is connected
			else
				ip="$(     echo "${_ip}" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1 )"
				ip_nm="$(  echo "${_ip}" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+' | head -1 )"
				ip6="$(    echo "${_ip}" | grep -oE 'inet6' | grep -oE '[0-9a-fA-F]*::.*/[0-9]+' | sed 's/\/.*//g' )"
				ip6_nm="$( echo "${_ip}" | grep -oE 'inet6' | grep -oE '[0-9a-fA-F]*::.*/[0-9]+' || true)"
				mac="$(    echo "${_ip}" | grep 'link/' | grep -oE '([0-9a-fA-F]{2}:)+[0-9a-fA-F]{2}' | head -1 )"
				mtu="$(    echo "${_ip}" | grep -oE 'mtu\s*[0-9]+' | sed 's/mtu\s//g' )"

				status="up"
				status_or_ip="${ip}"
				status_or_ip6="${ip6}"

				ssid="$( echo "${_iwconfig}" | grep -oE 'ESSID:".*"' | sed 's/ESSID://g' | sed 's/"//g' )"
				freq="$( echo "${_iwconfig}" | grep -ioE 'Frequency:[.0-9]+' | grep -oE '[.0-9]+' )"
				freq_unit="Ghz"
				tx_power="$( echo "${_iwconfig}" | grep -oE 'Tx-Power=[0-9]+' | sed 's/.*=//g' )"
				tx_power_unit="dBm"
				quality="$( awk -v cur="$(echo "${_iwconfig}"|grep -oE 'Link Quality=[/0-9]+'|grep -oE '[0-9]+'|head -1)" -v max="$(echo "${_iwconfig}"|grep -oE 'Link Quality=[/0-9]+'|grep -oE '[0-9]+'|tail -1)" 'BEGIN{printf("%0.f", cur*100/max)}')"
				signal="$( echo "${_iwconfig}" | grep -ioE 'Signal level=[-0-9]+' | sed 's/.*=//g' )"
				signal_unit="dBm"
				noise="$( grep "${iface}" /proc/net/wireless | awk '{print $5}' )"
				bit_rate="$( echo "${_iwconfig}" | grep -ioE 'Bit Rate=[0-9\.]+' | sed 's/.*=//g' | awk '{printf "%.0f", $1}' )"
				bit_rate_unit="$( echo "${_iwconfig}" | grep -ioE 'Bit Rate=[0-9\.]+ [A-Z/]+' | sed 's/.*=//g' | grep -ioE '[A-Z/]+' )"

				force_good=1

			fi
		fi
	fi
}




###
###
###
###    D O   N O T   E D I T   A F T E R   H E R E
###
###
###



################################################################################
#
# BUILT-IN VARIABLES
#
################################################################################

###
### General default values
###
color_def="#666666"		# gray
color_good="#88b090"	# green
color_warn="#ccdc90"	# yellow
color_crit="#e89393"	# red
color_info="#fce94f"	# bright yellow

###
### Extended format arrays
###
fe_placeholder=()
fe_sign=()
fe_value=()
fe_format=()


###
### Threshold arrays
###
tg_placeholder=()
tg_sign=()
tg_value=()

ti_placeholder=()
ti_sign=()
ti_value=()

tw_placeholder=()
tw_sign=()
tw_value=()

tc_placeholder=()
tc_sign=()
tc_value=()


###
### Use of pango markup?
###
pango=1


###
### source configuration file if it exists
###
if [ -f "${HOME}/.config/i3blocks-modules/conf" ]; then
	# shellcheck disable=SC1090
	. "${HOME}/.config/i3blocks-modules/conf"
fi


###
### i3blocks vars info
### https://vivien.github.io/i3blocks/
###
# name=		${BLOCK_NAME}
# instace=	${BLOCK_INSTANCE}
# button=	${BLOCK_BUTTON}
# x-coor	${BLOCK_X}
# y-coor	${BLOCK_Y}


################################################################################
#
# BUILT-IN FUNCTIONS
#
################################################################################

###
### System functions
###
print_usage() {
	custom_args=""

	# program specific arguments
	for (( i=0; i<${#arg_params[@]}; i++ )); do
		custom_args="${custom_args}[${arg_params[$i]} ${arg_desc_val[$i]}] "
	done

	# Show/Hide threshold
	if [ "${has_threshold}" = "1" ]; then
		custom_args="${custom_args}[-tg|-ti|-tw|-tc <p> <s> <int|str>] "
	fi

	echo "Usage: ${appname} [-f <format>] [-fe <p> <s> <int|str> <f>] ${custom_args}[-np] [-cd|-cg|-cw|-cc|-ci <code>]"
	echo "       ${appname} -h"
	echo "       ${appname} -v"
	echo

	if [ "${#custom_args}" -gt "0" ]; then
		echo "Optional variables:"
		echo "--------------------------------------------------------------------------------"

		for (( i=0; i<${#arg_params[@]}; i++ )); do
			printf "  %-13s%s\\n" "${arg_params[$i]} ${arg_desc_val[$i]}" "${arg_desc_long[$i]}"
		done
		echo
	fi

	if [ "${has_threshold}" = "1" ]; then
		echo "Optional threshold arguments:"
		echo "--------------------------------------------------------------------------------"
		echo "You can optionally enable threshold checking against any placeholder value."
		echo "This enables the colorizing of the final output depending on any met"
		echo "conditions specified."
		echo "Default is not to use any threshold"
		echo "You can use unlimited number of threshold for each type."
		echo

		echo "  -tg <p> <s> <int|str>   Enable threshold for 'good status'"
		echo "  -ti <p> <s> <int|str>   Enable threshold for 'info status'"
		echo "  -tw <p> <s> <int|str>   Enable threshold for 'warn status'"
		echo "  -tc <p> <s> <int|str>   Enable threshold for 'crit status'"
		echo
		echo "   Explanation:"
		echo "     <p>   is the placeholder value you want to check against."
		printf "           valid placeholders: "
		for (( i=0; i<${#format_nodes[@]}; i++ )); do
			printf "%s" "${format_nodes[$i]} "
		done
		printf "\\n"
		echo "           Note 1: placeholder values will be converted to integers"
		echo "                   Any decimal places will simply be cut off."
		echo "           Note 2: In equal mode (<s> '=') is a string regex comparison and"
		echo "                   no placeholder will be converted."
		echo "           Note 3: In unequal mode (<s> '!=') is a string comparison and"
		echo "                   no placeholder will be converted."
		echo "           Note 3: In equal mode (<s> '=') regex is allowed :-)"
		echo "     <s>   must either be '<', '>', '=' or '!='  depending on what direction"
		echo "           you want to check the threshold placeholder against."
		echo "     <int> The integer number you want to check against the placeholder."
		echo "     <str> The string you want to check against the placeholder."
		echo "           You can only use a string when in equal mode '='."
		echo "           You can also use regex here."
		echo
		echo "   Examples:"
		echo "     1. Check if value of ${format_nodes[0]} < 50, then format using the good color"
		echo "     -tg '${format_nodes[0]}' '<' 50"
		echo
		echo "     2. Check if value of ${format_nodes[0]} > 90, then format using the warn color"
		echo "     -tw '${format_nodes[0]}' '>' 90"
		echo
		echo "     3. Check if value of ${format_nodes[0]} equals the string 'foo', then format using the info color"
		echo "     -ti '${format_nodes[0]}' '=' 'foo'"
		echo
		echo "     4. Check if value of ${format_nodes[0]} equals the regex '^[0-9]+\$', then format using the info color"
		echo "     -ti '${format_nodes[0]}' '=' '^[0-9]+\$'"
		echo
	fi

	echo "Optional markup (pango):"
	echo "--------------------------------------------------------------------------------"
	echo "  -np          Disable pango markup"
	echo

	echo "Optional color arguments:"
	echo "--------------------------------------------------------------------------------"
	echo "If not specified, script default colors are used"
	echo "If config file with color codes is present in:"
	echo "'${HOME}/.config/i3blocks-modules/conf', these colors will be used."
	echo
	echo "  -cd <code>   Default color (hexadecimal color code)"
	echo "               Default value is: ${color_def}"
	echo "  -cg <code>   Good color (hexadecimal color code)"
	echo "               Default value is: ${color_good}"
	echo "  -cw <code>   Warning color (hexadecimal color code)"
	echo "               Default value is: ${color_warn}"
	echo "  -cc <code>   Critical color (hexadecimal color code)"
	echo "               Default value is: ${color_crit}"
	echo "  -ci <code>   Info color (hexadecimal color code)"
	echo "               Default value is: ${color_info}"
	echo

	echo "Optional Format placeholders:"
	echo "--------------------------------------------------------------------------------"
	echo "  Available color placeholders:"
	echo "  (Use with pango disabled for custom markup) building"
	echo "     {color}        Current active color depending on thresholds"
	echo "     {color_def}    Default color"
	echo "     {color_good}   Good color"
	echo "     {color_warn}   Warning color"
	echo "     {color_crit}   Critical color"
	echo "     {color_info}   Info color"
	echo "  Format example:"
	echo "     -np -f \"<span color='{color}'>Colored text</span>\""
	echo

	echo "  Available specific placeholders:"
	for (( i=0; i<${#format_nodes[@]}; i++ )); do
		printf "     %-15s%s\\n" "${format_nodes[$i]}" "${format_descs[$i]}"
	done

	echo "  Format example:"
	for (( i=0; i<${#format_examples[@]}; i++ )); do
		printf "     %s\\n" "${format_examples[$i]}"
	done
	echo "  Default:"
	echo "     -f \"${format}\""
	echo

	echo "Optional extended Format output:"
	echo "--------------------------------------------------------------------------------"
	echo "You can conditionally set your output text depending on the value of any placeholder."
	echo "For example, If you have a placeholder {status} that either is 'up' or 'down', you"
	echo "can specify different outputs for 'up' and for 'down'."
	echo "Usage"
	echo "  -fe <p> <s> <v> <f>"
	echo
	echo "   Format example:"
	echo "     -fe '{status}' '=' 'up' 'It works ;-)' -fe '{status}' '!=' 'up' 'status is: {status}'"
	echo "   Explanation:"
	echo "     <p>   is the placeholder value you want to check against."
	printf "           valid placeholders: "
	for (( i=0; i<${#format_nodes[@]}; i++ )); do
		printf "%s" "${format_nodes[$i]} "
	done
	printf "\\n"
	echo "           Note 1: placeholder values will be converted to integers"
	echo "                   Any decimal places will simply be cut off."
	echo "           Note 2: In equal mode (<s> '=') is a string regex comparison and"
	echo "                   no placeholder will be converted."
	echo "           Note 3: In unequal mode (<s> '!=') is a string comparison and"
	echo "                   no placeholder will be converted."
	echo "           Note 3: In equal mode (<s> '=') regex is allowed :-)"
	echo "     <s>   must either be '<', '>', '=' or '!='  depending on what direction"
	echo "           you want to check the threshold placeholder against."
	echo "     <int> The integer number you want to check against the placeholder."
	echo "     <str> The string you want to check against the placeholder."
	echo "           You can only use a string when in equal mode '='."
	echo "           You can also use regex here."
	echo "     <f>   Is the format string that should be displayed under the above condition."
	echo "           Of course you can also use placeholders here ;-)."
}

print_version() {
	echo "${appname} v1.8 by cytopia"
	echo "https://github.com/cytopia/i3blocks-modules"
}

###
### Decide about final output color color
###
get_status_color() {
	local _color_def="${1}"
	local _color_good="${2}"
	local _color_warn="${3}"
	local _color_crit="${4}"
	local _color_info="${5}"

	# final color
	local _color="${_color_def}"

	local pval

	# has custom critical color?
	if [ "${force_crit}" = "1" ]; then
		_color="${_color_crit}"
		echo "${_color}"
		return
	fi
	# has custom warning color?
	if [ "${force_warn}" = "1" ]; then
		_color="${_color_warn}"
		echo "${_color}"
		return
	fi


	# has custom good color?
	if [ "${force_good}" = "1" ]; then
		_color="${_color_good}"
	fi

	# has good color?
	for (( i=0; i < ${#tg_placeholder[@]}; i++ )); do

		if [ "${tg_sign[$i]}" = "=" ] || [ "${tg_sign[$i]}" = "!=" ]; then
			pval="${!tg_placeholder[$i]}"
		else
			pval="$( echo "${!tg_placeholder[$i]}" | grep -oE '[0-9]*' | head -1 )"
		fi

		if [ "${tg_sign[$i]}" = "<" ]; then
			if [ "${pval}" -lt "${tg_value[$i]}" ]; then
				_color="${_color_good}"
			fi
		elif [ "${tg_sign[$i]}" = "=" ]; then
			if [[ "${pval}" =~ ${tg_value[$i]} ]]; then
				_color="${_color_good}"
			fi
		elif [ "${tg_sign[$i]}" = "!=" ]; then
			if [[ "${pval}" != "${tg_value[$i]}" ]]; then
				_color="${_color_good}"
			fi
		elif [ "${tg_sign[$i]}" = ">" ]; then
			if [ "${pval}" -gt "${tg_value[$i]}" ]; then
				_color="${_color_good}"
			fi
		fi
	done
	# has info color?
	for (( i=0; i < ${#ti_placeholder[@]}; i++ )); do

		if [ "${ti_sign[$i]}" = "=" ] || [ "${ti_sign[$i]}" = "!=" ]; then
			pval="${!ti_placeholder[$i]}"
		else
			pval="$( echo "${!ti_placeholder[$i]}" | grep -oE '[0-9]*' | head -1 )"
		fi

		if [ "${ti_sign[$i]}" = "<" ]; then
			if [ "${pval}" -lt "${ti_value[$i]}" ]; then
				_color="${_color_info}"
			fi
		elif [ "${ti_sign[$i]}" = "=" ]; then
			if [[ "${pval}" =~ ${ti_value[$i]} ]]; then
				_color="${_color_info}"
			fi
		elif [ "${ti_sign[$i]}" = "!=" ]; then
			if [[ "${pval}" != "${ti_value[$i]}" ]]; then
				_color="${_color_info}"
			fi
		elif [ "${ti_sign[$i]}" = ">" ]; then
			if [ "${pval}" -gt "${ti_value[$i]}" ]; then
				_color="${_color_info}"
			fi
		fi
	done
	# has warning color?
	for (( i=0; i < ${#tw_placeholder[@]}; i++ )); do

		if [ "${tw_sign[$i]}" = "=" ] || [ "${tw_sign[$i]}" = "!=" ]; then
			pval="${!tw_placeholder[$i]}"
		else
			pval="$( echo "${!tw_placeholder[$i]}" | grep -oE '[0-9]*' | head -1 )"
		fi

		if [ "${tw_sign[$i]}" = "<" ]; then
			if [ "${pval}" -lt "${tw_value[$i]}" ]; then
				_color="${color_warn}"
			fi
		elif [ "${tw_sign[$i]}" = "=" ]; then
			if [[ "${pval}" =~ ${tw_value[$i]} ]]; then
				_color="${_color_warn}"
			fi
		elif [ "${tw_sign[$i]}" = "!=" ]; then
			if [[ "${pval}" != "${tw_value[$i]}" ]]; then
				_color="${_color_warn}"
			fi
		elif [ "${tw_sign[$i]}" = ">" ]; then
			if [ "${pval}" -gt "${tw_value[$i]}" ]; then
				_color="${_color_warn}"
			fi
		fi
	done


	# has critical color?
	for (( i=0; i < ${#tc_placeholder[@]}; i++ )); do

		if [ "${tc_sign[$i]}" = "=" ] || [ "${tc_sign[$i]}" = "!=" ]; then
			pval="${!tc_placeholder[$i]}"
		else
			pval="$( echo "${!tc_placeholder[$i]}" | grep -oE '[0-9]*' | head -1 )"
		fi

		if [ "${tc_sign[$i]}" = "<" ]; then
			if [ "${pval}" -lt "${tc_value[$i]}" ]; then
				_color="${_color_crit}"
			fi
		elif [ "${tc_sign[$i]}" = "=" ]; then
			if [[ "${pval}" =~ ${tc_value[$i]} ]]; then
				_color="${_color_crit}"
			fi
		elif [ "${tc_sign[$i]}" = "!=" ]; then
			if [[ "${pval}" != "${tc_value[$i]}" ]]; then
				_color="${_color_crit}"
			fi
		elif [ "${tc_sign[$i]}" = ">" ]; then
			if [ "${pval}" -gt "${tc_value[$i]}" ]; then
				_color="${_color_crit}"
			fi
		fi
	done


	echo "${_color}"
}


###
### Replace custom stuff in format string
###
replace_placeholders() {
	local _format="${1}"
	local _search
	local _replace

	# Select format based on extended placeholders
	for (( i=0; i < ${#fe_placeholder[@]}; i++ )); do

		if [ "${fe_sign[$i]}" = "=" ] || [ "${fe_sign[$i]}" = "!=" ]; then
			pval="${!fe_placeholder[$i]}"
		else
			pval="$( echo "${!fe_placeholder[$i]}" | grep -oE '[0-9]*' | head -1 )"
		fi

		if [ "${fe_sign[$i]}" = "<" ]; then
			if [ "${pval}" -lt "${fe_value[$i]}" ]; then
				_format="${fe_format[$i]}"
			fi
		elif [ "${fe_sign[$i]}" = "=" ]; then
			if [[ "${pval}" =~ ${fe_value[$i]} ]]; then
				_format="${fe_format[$i]}"
			fi
		elif [ "${fe_sign[$i]}" = "!=" ]; then
			if [[ "${pval}" != "${fe_value[$i]}" ]]; then
				_format="${fe_format[$i]}"
			fi
		elif [ "${fe_sign[$i]}" = ">" ]; then
			if [ "${pval}" -gt "${fe_value[$i]}" ]; then
				_format="${fe_format[$i]}"
			fi
		fi
	done



	# Replace placeholders in $format
	for (( i=0; i < ${#format_nodes[@]}; i++ )); do
		_search="${format_nodes[$i]}"
		_replace="${!format_vars[$i]}"
		 _format="${_format/${_search}/${_replace}}"
	done
	echo "${_format}"
}


###
### Replace colors in format string
###
replace_colors() {
	local _format="${1}"
	local _color="${2}"
	local _color_def="${3}"
	local _color_good="${4}"
	local _color_warn="${5}"
	local _color_crit="${6}"
	local _color_info="${7}"

	_format="${_format/'{color}'/${_color}}"
	_format="${_format/'{color_def}'/${_color_def}}"
	_format="${_format/'{color_good}'/${_color_good}}"
	_format="${_format/'{color_warn}'/${_color_warn}}"
	_format="${_format/'{color_crit}'/${_color_crit}}"
	_format="${_format/'{color_info}'/${_color_info}}"

	echo "${_format}"
}



################################################################################
#
# MAIN ENTRY POINT
#
################################################################################

# Enable/Disable threshold argument
if [ "${has_threshold}" = "1" ]; then
	th_chk=""
else
	th_chk="__THRESHOLD_DISABLED__"
fi


while [ $# -gt 0  ]; do
	case "$1" in
		###
		### Extended formats
		###
		-fe)
			# 1/4 Check placeholder
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -fe <p> - no placeholder specified."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			f=0
			for (( i=0; i < ${#format_nodes[@]}; i++ )); do
				if [ "${format_nodes[$i]}" = "${1}" ]; then
					f=1
					break
				fi
			done
			if [ "${f}" = "0" ]; then
				echo "Error, -fe '${1}' no such placeholder."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			fe_placeholder+=("${format_vars[$i]}")

			# 2/4 Check sign
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -fe '{${fe_placeholder[${#fe_placeholder[@]}-1]}}' '${1}' - sign argyment is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${1}" != "<" ] && [ "${1}" != ">" ] && [ "${1}" != "=" ] && [ "${1}" != "!=" ]; then
				echo "Error, -fe '{${fe_placeholder[${#fe_placeholder[@]}-1]}}' '${1}' - invalid sign: '${1}'."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			fe_sign+=("${1}")

			# 3/4 Check value
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -fe '{${fe_placeholder[${#fe_placeholder[@]}-1]}}' '${fe_sign[${#fe_sign[@]}-1]}' '${1}' - value argument is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${fe_sign[${#fe_sign[@]}-1]}" = ">" ] || [ "${fe_sign[${#fe_sign[@]}-1]}" = "<" ]; then
				if ! printf "%d" "${1}" >/dev/null 2>&1; then
					echo "Error, -fe '{${fe_placeholder[${#fe_placeholder[@]}-1]}}' '${fe_sign[${#fe_sign[@]}-1]}' '${1}' - value argument is not a number."
					echo "Type ${appname} -h for help"
					exit 1
				fi
			fi
			fe_value+=("${1}")

			# 4/4 Check placeholder string
			shift
			fe_format+=("${1}")
			;;
		###
		### Threshold good
		###
		"-tg${th_chk}")
			# 1/3 Check placeholder
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tg <p> - no placeholder specified."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			f=0
			for (( i=0; i < ${#format_nodes[@]}; i++ )); do
				if [ "${format_nodes[$i]}" = "${1}" ]; then
					f=1
					break
				fi
			done
			if [ "${f}" = "0" ]; then
				echo "Error, -tg '${1}' no such placeholder."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tg_placeholder+=("${format_vars[$i]}")

			# 2/3 Check sign
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tg '{${tg_placeholder[${#tg_placeholder[@]}-1]}}' '${1}' - sign argument is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${1}" != "<" ] && [ "${1}" != ">" ] && [ "${1}" != "=" ] && [ "${1}" != "!=" ]; then
				echo "Error, -tg '{${tg_placeholder[${#tg_placeholder[@]}-1]}}' '${1}' - invalid sign: '${1}'."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tg_sign+=("${1}")

			# 3/3 Check value
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tg '{${tg_placeholder[${#tg_placeholder[@]}-1]}}' '${tg_sign[${#tg_sign[@]}-1]}' '${1}' - value argyment is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${tg_sign[${#tg_sign[@]}-1]}" = ">" ] || [ "${tg_sign[${#tg_sign[@]}-1]}" = "<" ]; then
				if ! printf "%d" "${1}" >/dev/null 2>&1; then
					echo "Error, -tg '{${tg_placeholder[${#tg_placeholder[@]}-1]}}' '${tg_sign[${#tg_sign[@]}-1]}' '${1}' - value argument is not a number."
					echo "Type ${appname} -h for help"
					exit 1
				fi
			fi
			tg_value+=("${1}")
			;;
		###
		### Threshold info
		###
		"-ti${th_chk}")
			# 1/3 Check placeholder
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -ti <p> - no placeholder specified."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			f=0
			for (( i=0; i < ${#format_nodes[@]}; i++ )); do
				if [ "${format_nodes[$i]}" = "${1}" ]; then
					f=1
					break
				fi
			done
			if [ "${f}" = "0" ]; then
				echo "Error, -ti '${1}' no such placeholder."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			ti_placeholder+=("${format_vars[$i]}")

			# 2/3 Check sign
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -ti '{${ti_placeholder[${#ti_placeholder[@]}-1]}}' '${1}' - sign argument is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${1}" != "<" ] && [ "${1}" != ">" ] && [ "${1}" != "=" ] && [ "${1}" != "!=" ]; then
				echo "Error, -ti '{${ti_placeholder[${#ti_placeholder[@]}-1]}}' '${1}' - invalid sign: '${1}'."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			ti_sign+=("${1}")

			# 3/3 Check value
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -ti '{${ti_placeholder[${#ti_placeholder[@]}-1]}}' '${ti_sign[${#ti_sign[@]}-1]}' '${1}' - value argyment is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${ti_sign[${#ti_sign[@]}-1]}" = ">" ] || [ "${ti_sign[${#ti_sign[@]}-1]}" = "<" ]; then
				if ! printf "%d" "${1}" >/dev/null 2>&1; then
					echo "Error, -ti '{${ti_placeholder[${#ti_placeholder[@]}-1]}}' '${ti_sign[${#ti_sign[@]}-1]}' '${1}' - value argument is not a number."
					echo "Type ${appname} -h for help"
					exit 1
				fi
			fi
			ti_value+=("${1}")
			;;
		###
		### Threshold warning
		###
		"-tw${th_chk}")
			# 1/3 Check placeholder
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tw <p> - no placeholder specified."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			f=0
			for (( i=0; i < ${#format_nodes[@]}; i++ )); do
				if [ "${format_nodes[$i]}" = "${1}" ]; then
					f=1
					break
				fi
			done
			if [ "${f}" = "0" ]; then
				echo "Error, -tw '${1}' no such placeholder."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tw_placeholder+=("${format_vars[$i]}")

			# 2/3 Check sign
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tw '{${tw_placeholder[${#tw_placeholder[@]}-1]}}' '${1}' - sign argument is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${1}" != "<" ] && [ "${1}" != ">" ] && [ "${1}" != "=" ] && [ "${1}" != "!=" ]; then
				echo "Error, -tw '{${tw_placeholder[${#tw_placeholder[@]}-1]}}' '${1}' - invalid sign: '${1}'."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tw_sign+=("${1}")

			# 3/3 Check value
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tw '{${tw_placeholder[${#tw_placeholder[@]}-1]}}' '${tw_sign[${#tw_sign[@]}-1]}' '${1}' - value argyment is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${tw_sign[${#tw_sign[@]}-1]}" = ">" ] || [ "${tw_sign[${#tw_sign[@]}-1]}" = "<" ]; then
				if ! printf "%d" "${1}" >/dev/null 2>&1; then
					echo "Error, -tw '{${tw_placeholder[${#tw_placeholder[@]}-1]}}' '${tw_sign[${#tw_sign[@]}-1]}' '${1}' - value argument is not a number."
					echo "Type ${appname} -h for help"
					exit 1
				fi
			fi
			tw_value+=("${1}")
			;;
		###
		### Threshold critical
		###
		"-tc${th_chk}")
			# 1/3 Check placeholder
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tc <p> - no placeholder specified."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			f=0
			for (( i=0; i < ${#format_nodes[@]}; i++ )); do
				if [ "${format_nodes[$i]}" = "${1}" ]; then
					f=1
					break
				fi
			done
			if [ "${f}" = "0" ]; then
				echo "Error, -tc '${1}' no such placeholder."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tc_placeholder+=("${format_vars[$i]}")

			# 2/3 Check sign
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tc '{${tc_placeholder[${#tc_placeholder[@]}-1]}}' '${1}' - sign argument is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${1}" != "<" ] && [ "${1}" != ">" ] && [ "${1}" != "=" ] && [ "${1}" != "!=" ]; then
				echo "Error, -tc '{${tc_placeholder[${#tc_placeholder[@]}-1]}}' '${1}' - invalid sign: '${1}'."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			tc_sign+=("${1}")

			# 3/3 Check value
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -tc '{${tc_placeholder[${#tc_placeholder[@]}-1]}}' '${tc_sign[${#tc_sign[@]}-1]}' '${1}' - value argyment is empty."
				echo "Type ${appname} -h for help"
				exit 1
			fi
			if [ "${tc_sign[${#tc_sign[@]}-1]}" = ">" ] || [ "${tc_sign[${#tc_sign[@]}-1]}" = "<" ]; then
				if ! printf "%d" "${1}" >/dev/null 2>&1; then
					echo "Error, -tc '{${tc_placeholder[${#tc_placeholder[@]}-1]}}' '${tc_sign[${#tc_sign[@]}-1]}' '${1}' - value argument is not a number."
					echo "Type ${appname} -h for help"
					exit 1
				fi
			fi
			tc_value+=("${1}")
			;;
		###
		### Format overwrite
		###
		-f)
			shift
			if [ "${1}" = "" ]; then
				echo "Error, -f requires a string"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			format="${1}"
			;;
		###
		### Disable pango markup output
		###
		-np)
			pango=0
			;;
		###
		### Color overwrites
		###
		-cd)
			# default color
			shift
			if ! echo "${1}" | grep -qE '#[0-9a-fA-F]{6}' >/dev/null 2>&1; then
				echo "Error, invalid color string: ${1}"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			color_def="${1}"
			;;
		-cg)
			# good color
			shift
			if ! echo "${1}" | grep -qE '#[0-9a-fA-F]{6}' >/dev/null 2>&1; then
				echo "Error, invalid color string: ${1}"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			color_good="${1}"
			;;
		-cw)
			# warning color
			shift
			if ! echo "${1}" | grep -qE '#[0-9a-fA-F]{6}' >/dev/null 2>&1; then
				echo "Error, invalid color string: ${1}"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			color_warn="${1}"
			;;
		-cc)
			# critical color
			shift
			if ! echo "${1}" | grep -qE '#[0-9a-fA-F]{6}' >/dev/null 2>&1; then
				echo "Error, invalid color string: ${1}"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			color_crit="${1}"
			;;
		-ci)
			# info color
			shift
			if ! echo "${1}" | grep -qE '#[0-9a-fA-F]{6}' >/dev/null 2>&1; then
				echo "Error, invalid color string: ${1}"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			color_info="${1}"
			;;
		###
		### System options
		###
		-h)
			print_usage
			exit 0
			;;
		-v)
			print_version
			exit 0
			;;
		###
		### Unknown/Custom option
		###
		*)

			###
			### Evaluate user-specified arguments
			###
			found=0
			if [ "${#arg_params}" -gt "0" ]; then
				for (( i=0; i<${#arg_params[@]}; i++ )); do
					if [ "${arg_params[$i]}" = "${1}" ]; then
						shift
						var_name="${arg_vars[$i]}"
						eval "${var_name}=\"${1}\""
						found=1
						break;
					fi
				done
			fi

			###
			### Unknown option
			###
			if [ "${found}" = "0" ]; then
				echo "Invalid argument: '${1}'"
				echo "Type ${appname} -h for help"
				exit 1
			fi
			;;
	esac
	shift
done




###
### Call custom function
###
custom_action

###
### Get final output color (based on custom specs)
###
color="$( get_status_color "${color_def}" "${color_good}" "${color_warn}" "${color_crit}" "${color_info}" )"

###
### Format (colors)
###
format="$( replace_colors "${format}" "${color}" "${color_def}" "${color_good}" "${color_warn}" "${color_crit}" "${color_info}" )"

###
### Format (custom)
###
format="$( replace_placeholders "${format}" )"


###
### Output pango or plain style?
###
if [ "${pango}" = "1" ]; then
	if [ "${format}" != "" ]; then
		echo "<span color=\"${color}\">${format}</span>"
	fi
else
	echo "${format}"	# Long output
	echo "${format}"	# short output
	echo "\\${color}"	# color code '\#RRGGBB'
fi

exit 0