# Declare and fill an associative array providing ANSI colors enclosed between
# \[ and \], as per the "PROMPTING" section of man bash:
function declare_colors {
	local ci cj cn
	declare -g -A c
	c['normal']='\[\e[0m\]'
	for cn in {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do
		c["${cn}"]='\[\e['"${ci:=0};${cj:=30}"'m\]'
		((++cj,(cj==38)?(cj=30,++ci):1))
	done
}

function disable_colors {
	local cn
	declare -g -A c
	for cn in normal {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do
		c["${cn}"]=''
	done
}

# Generate the PS1 variable; doing that in a function allows to reflect almost
# anything in the prompt.
function generate_ps1 {
	# Save the return code value (rcv)
	local rcv=$?

	# Color for brackets and braces
	local bc="${c['red']}"

	# Pick the return code color (rcc)
	local rcc='bright_green'
	[ $rcv -ne 0 ] && rcc='bright_red'

	local rc dstamp tstamp user host cwdir es
	printf -v rc     "%s[%s${rcv}%s]" "${bc}" "${c[${rcc}]}" "${bc}"
	printf -v tstamp '[%s\\t%s]'      "${c['bright_yellow']}" "${bc}"
	printf -v user   '[%s\\u%s]'      "${c['cyan']}" "${bc}"
	printf -v host   '{%s\\h%s}'      "${c['cyan']}" "${bc}"
	printf -v cwdir  '%s\w%s '        "${c['green']}" "${c['normal']}"
	printf -v es     '%s\$%s '        "${c['red']}" "${c['normal']}"

	if [ "${PS1_DISPLAY_DATE}" ]; then
		printf -v dstamp '[%s\\D{%%F}%s]' "${c['bright_yellow']}" "${bc}"
	fi

	PS1="${rc}${dstamp}${tstamp}${user}${host}${cwdir}${es}"

	# Also set PS2 and PS4:
	PS2="${c['bright_green']}"
	PS4="+ ${c['cyan']}[trace]${c['normal']} "

	# It makes sense to export PS4 (so that e.g. "bash foobar.sh" benefit from
	# it):
	export PS4
}

# Provide a helper function to swiftly enable or disable the date in the
# prompt:
function ps1_toggle_date {
	if [ "${PS1_DISPLAY_DATE}" ]; then
		unset PS1_DISPLAY_DATE
	else
		PS1_DISPLAY_DATE='yes'
	fi
}

# Provide a helper function to swiftly enable or disable colors in the
# prompt:
function ps1_toggle_colors {
	if [ "${PS1_USE_COLORS}" ]; then
		unset PS1_USE_COLORS
		disable_colors
	else
		declare_colors
		PS1_USE_COLORS='yes'
	fi
}

# Provide a helper function to swiftly reduce the prompt to '$ ' -- this is
# useful e.g. for documentation purposes, when one wants to run a few commands
# and copy the whole terminal output without the prompt (which usually reflects
# undesired details such as user and hostname):
function ps1_toggle_prompt {
	local min_prompt='\$ '
	if [ "${PS1}" == "${min_prompt}" ]; then
		PROMPT_COMMAND='generate_ps1'
		generate_ps1
	else
		unset PROMPT_COMMAND
		PS1="${min_prompt}"
	fi
}

# By default, use colors but do not display the date:
ps1_toggle_colors
#ps1_toggle_date

# Instruct bash to regenerate PS1 before printing the prompt:
PROMPT_COMMAND='generate_ps1'

# Generate PS1 at least once:
generate_ps1
