# This file is part of shellfire core. It is subject to the licence terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT. No part of shellfire core, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
# Copyright © 2014-2015 The developers of shellfire core. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT.


core_usesIn core variable

core_init_defines core_variable_array_delimiter

core_variable_array_warning()
{
	if [ "$core_init_preferred_shell" = 'sh' ]; then
		if core_variable_isSet BASH_VERSINFO; then
			if [ "$BASH_VERSINFO" -eq 3 ]; then
				core_message NOTICE "There's a horrible bug in bash 3, which when run as sh, that treats 'local variableName' as being set to empty, not as unset. We have to support bash 3 for Mac OS X and MinGW."
				core_message NOTICE "There's a horrible bug in bash 3, which when run as sh, that doesn't like IFS='\001'."
			fi
		fi
	fi
}

core_variable_array_initialise()
{
	local variableName="$1"
	local variableNameInitialised="${variableName}_initialised"
	
	if core_variable_isSet "$variableNameInitialised"; then
		
		local core_variable_indirectValue_result
		core_variable_indirectValue "$variableNameInitialised"
		
		if [ -n "$core_variable_indirectValue_result" ]; then
			return 0
		fi
	fi
	
	core_variable_setVariable "$variableName" ''
	core_variable_setVariable "$variableNameInitialised" 0
}

core_variable_array_unset()
{
	local variableName="$1"
	local variableNameInitialised="${variableName}_initialised"
	core_variable_unset "$variableName"
	core_variable_unset "$variableNameInitialised"
}

core_variable_array_isSet()
{
	local variableName="$1"
	local variableNameInitialised="${variableName}_initialised"
	
	if core_variable_isSet "$variableNameInitialised"; then
		
		local core_variable_indirectValue_result
		core_variable_indirectValue "$variableNameInitialised"
		
		if [ ${core_variable_indirectValue_result} -gt 0 ]; then
			return 0
		else
			return 1
		fi
	fi
	
	return 1
}

core_variable_array_isUnset()
{
	! core_variable_array_isSet "$1"
}

core_variable_array_append()
{
	local variableName="$1"
	shift 1
	
	local argument
	for argument in "$@"
	do
		if core_variable_array_isUnset "$variableName"; then
			core_variable_array_initialise "$variableName"
			core_variable_setVariable "$variableName" "$argument"
			core_variable_setVariable "${variableName}_initialised" 1
		else
			core_variable_indirectValue "${variableName}_initialised"
			core_variable_setVariable "${variableName}_initialised" $((core_variable_indirectValue_result+1))
			core_variable_indirectValue "$variableName"
			core_variable_setVariable "$variableName" "${core_variable_indirectValue_result}$core_variable_array_delimiter${argument}"
		fi
	done
}

core_variable_array_appendUniquely()
{
	local variableName="$1"
	shift 1
	
	local argument
	for argument in "$@"
	do
		if ! core_variable_array_contains "$variableName" "$argument"; then
			core_variable_array_append "$variableName" "$argument"
		fi
	done
}

core_variable_array_length()
{
	local variableName="$1"
	shift 1

	local core_variable_indirectValue_result
	core_variable_indirectValue "${variableName}_initialised"
	printf '%s' $core_variable_indirectValue_result
}

_core_variable_array_isEmpty()
{
	local core_variable_indirectValue_result
	core_variable_indirectValue "${variableName}_initialised"
	[ $core_variable_indirectValue_result -eq 0 ]
}

core_variable_array_isEmpty()
{
	local variableName="$1"
	_core_variable_array_isEmpty
}

core_variable_array_at()
{
	local variableName="$1"
	local index=$2

	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"

	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	set -- $core_variable_indirectValue_result
	IFS="$originalIFS"
	
	eval "core_variable_array_index_element=\"\$${index}\""
}

core_variable_array_string()
{
	local variableName="$1"
	local separator="$2"
	
	if _core_variable_array_isEmpty; then
		return 0
	fi
	
	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local count=0
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	for core_variable_array_element in $core_variable_indirectValue_result
	do
		IFS="$originalIFS"
		if [ $count -eq 0 ]; then
			printf '%s' "$core_variable_array_element"
		else
			printf '%s%s' "$separator" "$core_variable_array_element"
		fi
		count=$((count+1))
	done
	IFS="$originalIFS"
}

# Does not allow passing any other arguments, though
core_variable_array_passToFunctionAsArguments()
{
	local variableName="$1"
	local function="$2"
	shift 2
	if [ $# -ne 0 ]; then
		core_exitError $core_commandLine_exitCode_SOFTWARE "Only varargs from array are allowed"
	fi
	
	if _core_variable_array_isEmpty; then
		"$function"
		return 0
	fi
	
	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	set -- $core_variable_indirectValue_result
	IFS="$originalIFS"
	
	"$function" "$@"
}

core_variable_array_iterate()
{
	local variableName="$1"
	local callback="$2"
	shift 2
	
	if _core_variable_array_isEmpty; then
		return 0
	fi

	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	local core_variable_array_element
	for core_variable_array_element in $core_variable_indirectValue_result
	do
		IFS="$originalIFS"
		$callback "$@"
	done
	IFS="$originalIFS"
}

core_variable_array_iterateAsCallbacks()
{
	local variableName="$1"
	shift 1
	
	if _core_variable_array_isEmpty; then
		return 0
	fi

	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	local callback
	for callback in $core_variable_indirectValue_result
	do
		IFS="$originalIFS"
		"$callback" "$@"
	done
	IFS="$originalIFS"
}

core_variable_array_iterateAsCallbacksShortcut()
{
	local variableName="$1"
	shift 1
	
	if _core_variable_array_isEmpty; then
		return 1
	fi
	
	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	local callback
	for callback in $core_variable_indirectValue_result
	do
		IFS="$originalIFS"
		if "$callback" "$@"; then
			return 0
		fi
	done
	IFS="$originalIFS"
	return 1
}

core_variable_array_iterateShortcut()
{	
	local variableName="$1"
	local callback="$2"
	shift 2
	
	if _core_variable_array_isEmpty; then
		return 1
	fi
	
	local core_variable_indirectValue_result
	core_variable_indirectValue "$variableName"
	
	local originalIFS="$IFS"
	local IFS="$core_variable_array_delimiter"
	local core_variable_array_element
	for core_variable_array_element in $core_variable_indirectValue_result
	do
		IFS="$originalIFS"
		
		if $callback "$@"; then
			return 0
		fi
	done
	IFS="$originalIFS"
	return 1
}

_core_variable_array_contains_check()
{
	# return 0 for shortcut
	if [ "$core_variable_array_element" = "$containsValue" ]; then
		return 0
	fi
	return 1
}

core_variable_array_contains()
{
	local variableName="$1"
	local containsValue="$2"
	
	if core_variable_array_iterateShortcut "$variableName" _core_variable_array_contains_check; then
		return 0
	fi
	return 1
}
