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

function disable_colors {
	local cn
	for cn in normal {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do
		eval "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='c_bright_green'
	[ $rcv -ne 0 ] && rcc='c_bright_red'

	local rc dstamp tstamp user host cwdir es
	rc=$(     printf "%s[%s${rcv}%s]" "${bc}" "${!rcc}" "${bc}")
	tstamp=$( printf '[%s\\t%s]'      "${c_bright_yellow}" "${bc}")
	user=$(   printf '[%s\\u%s]'      "${c_cyan}" "${bc}")
	host=$(   printf '{%s\\h%s}'      "${c_cyan}" "${bc}")
	cwdir=$(  printf '%s\w%s '        "${c_green}" "${c_normal}")
	es=$(     printf '%s\$%s '        "${c_red}" "${c_normal}")

	if [ "${PS1_DISPLAY_DATE}" ]; then
		dstamp=$(printf '[%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
