#!/bin/bash

. /usr/local/Reductor/etc/const

checkipaddr()
{
	[ -z "$1" ] && return 1
	local ip="$1" RET=1
	shopt -s extglob
	if [[ "$ip" = +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]]; then
		RET=0
		for ip in ${ip//./ }; do
			[ "${#ip}" -gt "3" ] && { RET=1; break; }
			ip="${ip##+(0)}"
			[ -z "$ip" ] && ip=0
			[ "$ip" -gt "255" ] && { RET=1; break; }
		done
	fi
	shopt -u extglob
	return "$RET"
}

checkmask()
{
	[ -z "$1" ] && return 1
	local mm="$1" RET=1 tmp
	shopt -s extglob
	tmp=
	[[ "$mm" = +([0-9])"."@(0|00|000)"."@(0|00|000)"."@(0|00|000) ]] && { tmp=0;                 mm="${mm%%.*}"; }
	[[ "$mm" = "255."+([0-9])"."@(0|00|000)"."@(0|00|000)         ]] && { tmp=8;  mm="${mm:4}";  mm="${mm%%.*}"; }
	[[ "$mm" = "255.255."+([0-9])"."@(0|00|000)                   ]] && { tmp=16; mm="${mm:8}";  mm="${mm%%.*}"; }
	[[ "$mm" = "255.255.255."+([0-9])                             ]] && { tmp=24; mm="${mm:12}"; }
	if [ -n "$tmp" ]; then
		RET=0
		case "$mm" in
			0|00|000) ((tmp+=0)) ;;
			128) ((tmp+=1)) ;;
			192) ((tmp+=2)) ;;
			224) ((tmp+=3)) ;;
			240) ((tmp+=4)) ;;
			248) ((tmp+=5)) ;;
			252) ((tmp+=6)) ;;
			254) ((tmp+=7)) ;;
			255) ((tmp+=8)) ;;
			*) RET=1 ;;
		esac
	else
		if [[ "$mm" = @([0-9]|[1-3][0-9]) ]] && [ "$mm" -ge "0" -a "$mm" -le "32" ]; then
			RET=0
			tmp=$1
		fi
	fi
	shopt -u extglob
	[ "$RET" = "0" ] && eval "$2='$tmp'"
	return "$RET"
}

LOG() {
	[[ "$GLOBAL_PARAMS" = *log* ]] && echo $@ >> /var/log/menu.log
	return 0
}

check_value_filter() {
	[ "$#" = '3' ] || return 0
	local filter="$1" value="$2" varname="$3"
	$filter $value $varname
}

__show_interface_list() {
	LOG ${FUNCNAME[0]} $@
	local cmd='' ITEM_COUNT=$DEF_COUNT input="$1" array="$2" REZ
	declare -A item
	item_name="Выбор интерфейса"
	while read dev; do
		local mac=$(ip -o link show dev $dev | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' | grep -v 'ff:ff:ff:ff:ff:ff')
		cmd="$cmd '$(echo $dev | tr -d '[A-Z]')' '$mac' ''"
	done <<< "$(cat /proc/net/dev | awk -F : '{if (NR>2) print $1}' | egrep -v "(lo|imq|tunl|teql|gre|vnet)" )"
	local baseopts="$baseopts --menu '$item_name'"
	cmd="$cmd 'Назад' '' 'Вернуться в предыдущее меню'" ;
	((ITEM_COUNT++))
	REZ=$(eval dialog $baseopts $((ITEM_COUNT+5)) 70 $((ITEM_COUNT+5)) $cmd 3>&1 1>&2 2>&3 )
	[ "$?" != 0 ] && return 1
	[ "$REZ" = "Назад" ] && return 1
	eval $array[$input]=\"$REZ\"
	LOG ${FUNCNAME[0]} REZ2 ${REZ}
	echo $REZ
	return 0

}

__show_menu_filter() {
	LOG ${FUNCNAME[0]} $@
	local cmd='' input="$1" table="$2" REZ ITEM_COUNT=$DEF_COUNT
	declare -A item
	[ -n "$table" ] && eval item_name=\${$input[$table.name]}
	eval item=$(set | grep "^$input=" | sed s/$input=// | grep "$table[^0-9]" )
	while IFS== read -r var val; do
		[[ "$var" == \#* ]] && continue
		[ "$var" = '' ] && continue
		[[ "$var" = declare* ]] && continue
		[[ "$var" != ${input}* ]]  && continue
		local array=${var%%[*}
		local key="$(echo ${var##*[\'} | sed -s "s/'.*//g")"
		[[ "$key" != *$table* ]] && continue
		[ -n "$table" ] && item[$key.widget]=${item[${key//[0-9]}.widget]}
		[ $key = widget ] && eval widget=( ${item[$key]} ) && item_name=${widget[1]}
		if [ -n "${item[$key.widget]}" ]; then
			eval widget=( ${item[$key.widget]} )
			case "${widget[0]}" in
				table | menu | menunew )
					widget[1]="${widget[1]}..."
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"	
					;;
				checkbox )
					[ "${item[$key]}" = '1' ] && widget[1]="[*] ${widget[1]}" || widget[1]="[ ] ${widget[1]}"
					cmd="$cmd '${widget[1]}' '' '${widget[2]}'"	
					;;
				cmd )
					cmd="$cmd '${widget[1]}' '' '${widget[3]}'"
					;;
				* )
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"	
					;;
			esac
			((ITEM_COUNT++))
		fi
	done < $CONFIG
	local baseopts="$baseopts --menu '$item_name'"
	cmd="$cmd 'Назад' '' 'Вернуться в предыдущее меню'" ;
	((ITEM_COUNT++))
	REZ=$( eval dialog $baseopts $((ITEM_COUNT+5)) 80 $((ITEM_COUNT+5)) $cmd  3>&1 1>&2 2>&3 )
	[ "$?" != 0 -o "$REZ" = "Назад" ] && return 1
	REZ=${REZ//.../}
	REZ=${REZ##\[?\] }
	for key in ${!item[@]}; do
		[[ "$key" != *$table* ]] && continue
		[[ "${item[$key]}" == *$REZ* ]] && REZ=${key//.widget} && break
	done
	echo $REZ
	return 0
}

__show_menu() {
	LOG ${FUNCNAME[0]} $@
	local cmd='' input="$1" REZ ITEM_COUNT=$DEF_COUNT
	declare -A item
	eval item=$(set | grep "^$input=" | sed s/$input=//)
	while IFS== read -r var val; do
		[[ "$var" == \#* ]] && continue
		[ "$var" = '' ] && continue
		[[ "$var" = declare* ]] && continue
		[[ "$var" != ${input}* ]]  && continue
		local array=${var%%[*}
		local key="$(echo ${var##*[\'} | sed -s "s/'.*//g")"
		if [ $key = widget ]; then
			eval widget=( ${item[$key]} )
			item_name=${widget[1]}
		fi
		if [ -n "${item[$key.widget]}" ]; then
			eval widget=( ${item[$key.widget]} )
			case "${widget[0]}" in
				table | menu | menunew )
					widget[1]="${widget[1]}..."
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"
					;;
				checkbox )
					[ "${item[$key]}" = '1' ] && widget[1]="[*] ${widget[1]}" || widget[1]="[ ] ${widget[1]}"
					cmd="$cmd '${widget[1]}' '' '${widget[2]}'"
					;;
				cmd )
					cmd="$cmd '${widget[1]}' '' '${widget[3]}'"
					;;
				* )
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"
					;;
			esac
			((ITEM_COUNT++))
		fi
	done < $CONFIG
	local baseopts="$baseopts --menu '$item_name'"
	cmd="$cmd 'Назад' '' 'Вернуться в предыдущее меню'" ;
	echo "$cmd"
	((ITEM_COUNT++))
	REZ=$( eval dialog $baseopts $((ITEM_COUNT+5)) 70 $((ITEM_COUNT+5)) $cmd  3>&1 1>&2 2>&3 )
	[ "$?" != 0 ] && return 1
	[ "$REZ" = "Назад" ] && return 1
	REZ=${REZ//.../}        #Настройка интерфейсов
	REZ=${REZ##\[?\] }      #отрезаем checkbox
	for key in ${!item[@]}; do
		if [[ "${item[$key]}" == *$REZ* ]]; then
			REZ=${key//.widget}
			break
		fi
	done
	echo $REZ
	return 0
}


__show_mainmenu() {
	LOG ${FUNCNAME[0]} $@
	local cmd='' ITEM_COUNT=$DEF_COUNT input="$1" REZ
	declare -A item
	eval item=$(set | grep "^$input=" | sed s/$input=// | sort -n)
	for key in ${!item[@]}; do
		if [ $key = widget ]; then
			eval widget=( ${item[$key]} )
			item_name=${widget[1]}
		fi
		if [ -n "${item[$key.widget]}" ]; then
			eval widget=( ${item[$key.widget]} )
			case "${widget[0]}" in
				table | menu | menunew )
					widget[1]="${widget[1]}..."
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"	
					;;
				checkbox )
					[ "${item[$key]}" = '1' ] && widget[1]="[*] ${widget[1]}" || widget[1]="[ ] ${widget[1]}"
					cmd="$cmd '${widget[1]}' '' '${widget[2]}'"	
					;;
				cmd )
					cmd="$cmd '${widget[1]}' '' '${widget[3]}'"
					;;
				* )
					cmd="$cmd '${widget[1]}' '${item[$key]}' '${widget[2]}'"	
					;;
			esac
			((ITEM_COUNT++))
		fi
	done
	local current_ver=$(<$MAINDIR/etc/version)
	local baseopts="--stdout --output-fd 2 --colors --trim  --backtitle '${app[name]} ($(<$MAINDIR/etc/branch)) $current_ver: $(get_reductor_state), код регистрации: $REGNUM' --cancel-label 'Выход' --ok-label 'Выбрать' --no-shadow --item-help --menu '$item_name'"
	cmd="$cmd 'Выход' '' ''"
	((ITEM_COUNT++))
	REZ=$( eval dialog $baseopts $((ITEM_COUNT+5)) 70 $((ITEM_COUNT+5)) $cmd  3>&1 1>&2 2>&3 )
	[ "$?" != 0 ] && return 1
	[ "$REZ" = "Выход" ] && return 1
	REZ=${REZ//.../} 	#Настройка интерфейсов
	REZ=${REZ##\[?\] } 	#отрезаем checkbox
	for key in ${!item[@]}; do
		if [[ "${item[$key]}" == *$REZ* ]]; then
			REZ=${key//.widget}
			break
		fi
	done
	echo $REZ
	return 0
}

__show_inputbox() {
	LOG ${FUNCNAME[0]} $@
	local REZ key="$1" arr="$2" index=${arr##*[}
	eval VAL="\${$arr[$key]}"
	eval widget=( ${widget[@]} )
	REZ="$( dialog --inputbox "${widget[1]}" 8 30 "$VAL" 3>&1 1>&2 2>&3 )"
	[ "$?" != 0 ] && return 1
	[ "$REZ" = "Назад" ] && return 1
	if [[ "$arr" == *\[*\]* ]]; then 			# вложенный вариант
		eval $key=\"$REZ\"
	else 							 # обычный вариант
		eval $arr[$key]=\"$REZ\"
	fi
	return 0
}

__show_ip_list() {
	LOG ${FUNCNAME[0]} $@
	__show_list_inputbox "$1" "$2" check_ipmask
}

__show_list_inputbox() {
	LOG ${FUNCNAME[0]} $@
	local REZ key="$1" arr="$2" filter="$3" index=${arr##*[}
	local ITEM_COUNT=$DEF_COUNT
	eval VAL="\${$arr[$key]}"
	eval widget=( ${widget[@]} )
	local item_name="Список IP адресов:" #TODO: No const
	local baseopts="$baseopts --ok-label 'Изменить' --extra-button --extra-label 'Удалить' --help-button --help-label 'Назад' --cancel-label 'Добавить' --menu '$item_name'"
	while true; do
		local ITEM_COUNT=$DEF_COUNT
		local cmd=''
		for ip in $VAL; do
			cmd="$cmd '$ip' '' ''"
			((ITEM_COUNT++))
		done
		cmd="$cmd 'Назад' '' 'Вернуться в предыдущее меню'" ;
		((ITEM_COUNT++))
		eval SELECT_VAL="\$( dialog $baseopts $((ITEM_COUNT+5)) 70 $((ITEM_COUNT+5)) $cmd  3>&1 1>&2 2>&3 )"
		ERRCODE=$?
		[ "$ERRCODE" = 0 -a "$SELECT_VAL" = "Назад" ] && break
		case $ERRCODE in
			0 )
				CHANGE_VAL="$( dialog --inputbox "Введите IP адрес:" 8 30 "$SELECT_VAL" 3>&1 1>&2 2>&3 )"
				retval=$?
				if [ -n "$filter" -a "$retval" = '0' ]; then
					check_value_filter $filter $CHANGE_VAL CHANGE_VAL
					retval=$?
				fi
				[ "$retval" = '0' ] && VAL="${VAL//$SELECT_VAL/$CHANGE_VAL}"
				;;
			1 )
				CHANGE_VAL="$( dialog --inputbox "Новый IP адрес:" 8 30 "" 3>&1 1>&2 2>&3 )"
				retval=$?
				if [ -n "$filter" -a "$retval" = '0' ]; then
					check_value_filter $filter $CHANGE_VAL CHANGE_VAL
					retval=$?
				fi
				[ "$retval" = '0' ] && VAL="$VAL $CHANGE_VAL"
				;;
			2 )
				break
				;;
			3 )
				if dialog --yesno "Удалить адрес ${SELECT_VAL}?" 0 0; then
					VAL="${VAL/$SELECT_VAL}"
				fi
				;;
		esac
	done
	REZ="$VAL"
	if [[ "$arr" == *\[*\]* ]]; then 			# вложенный вариант
		eval $key=\"$REZ\"
	else 							 # обычный вариант
		eval $arr[$key]=\"$REZ\"
	fi
	return 0
}

check_ipmask() {
	local ipmask="$1" varname="$2" retval=0
	local ip=${ipmask%%/*}
	local mask=${ipmask##*/}
	if ! checkipaddr $ip; then
		dialog --msgbox "Введен неправильный IP адрес!" 0 0
		retval=1
	fi
	if ! checkmask $mask mask; then
		dialog --msgbox "Введена неправильная маска!" 0 0
		retval=2
	fi
	[ "$retval" = 0 ] && eval $varname="${ip}/${mask}"
	return $retval
}

__show_ipmask() {
	# может быть бага с интерфейсами где-то здесь
	LOG ${FUNCNAME[0]} $@
	local REZ key="$1" arr="$2"
	local index=${arr##*[}
	eval VAL="\${$arr[$key]}"
	eval widget=( ${widget[@]} )
	while true; do
		REZ="$( dialog --inputbox "${widget[1]}" 8 30 "$VAL" 3>&1 1>&2 2>&3 )"
		[ "$?" != 0 ] && return 1
		[ "$REZ" = "Назад" ] && return 1
		local IP=${REZ%%/*}
		local MASK=${REZ##*/}
		#if [ "$MASK" -lt 0 -o "$MASK" -gt 32 ]; then
		if ! checkmask "$MASK" MASK; then
			dialog --msgbox "Введена неправильная маска сети!" 0 0
			continue
		fi
		if ! checkipaddr $IP; then
			dialog --msgbox "Введен неправильный IP адрес!" 0 0
			continue
		fi
		# соберем прочеканный REZ обратно
		REZ=$IP/$MASK
		if [[ "$arr" == *\[*\]* ]]; then 			# вложенный вариант
			eval $key=\"$REZ\"
		else 							 # обычный вариант
			eval $arr[$key]=\"$REZ\"
		fi
		return 0
	done
}

get_table_list() {
	local array=$1 index=$2
	for i in $(eval echo \${!$array[@]}); do
		if [[ "$i" = *$index[0-9]*.name ]]; then
			echo $i
		fi
	done | sort
}

delete_from_table() {
	LOG ${FUNCNAME[0]} $@
	local array=$1 key=$2 index=$3
	for i in $(eval echo \${!$array[@]}); do
		if [[ "$i" = $key$index* ]]; then
			local subvar=${i##*.}
			if [ "$subvar" = "name" ]; then
				eval $array[$i]=\"\${$array[$key.$subvar.default_value]} $index\"
			else
				eval $array[$i]=\"\${$array[$key.$subvar.default_value]}\"
			fi
		fi
	done
	return 0
}

add_to_table() {
	local array=$1 key=$2
	local index=$((get_max_index $array $key))
	return 0
}

getindex() {
	while read i; do
		echo ${i%%.*}
	done <<< "$(get_table_list $1 $2)"
}

getindex_numonly() {
	while read i; do
		echo ${i%%.*} | sed -s 's/[a-z]//g'
	done <<< "$(get_table_list $1 $2)"
}

get_max_index() {
	getindex_numonly $1 $2 | sort -n | tail -1
}

__show_table() {
	LOG ${FUNCNAME[0]} $@
	local input="$1"
	local array=${input%%[*}
	local index=${input##*[}
	index=${index%]}
	eval widget=( ${widget[@]} )
	local baseopts="$baseopts --ok-label 'Изменить' --extra-button --extra-label 'Удалить' --help-button --help-label 'Назад' --cancel-label 'Добав.(n/a)' --menu '${widget[1]}'"

	if [ "$index" = "$array" -a -n "$sub_table" ]; then
		BUGGED=1
		index=${sub_table//[0-9]/}
	fi

	while true; do
		local cmd=''
		local ITEM_COUNT=$DEF_COUNT
		local REZ

		for i in $(get_table_list $array $index); do
			if [[ "$i" = *$index[0-9]*.name ]]; then
				cmd="$cmd '$( eval echo "\${$array['$i']}" )' '' ''"
				((ITEM_COUNT++))
			fi
		done
		cmd="$cmd 'Назад' '' ''"
		((ITEM_COUNT++))

		REZ=$(eval dialog $baseopts $((ITEM_COUNT+5)) 60 $((ITEM_COUNT+5)) $cmd  3>&1 1>&2 2>&3)
		ERRCODE=$?
		case $ERRCODE in
			# изменение и удаление
			0 | 3 )
				[ "$REZ" = "Назад" ] && return 1
				for key in $( eval echo \${!$array[@]} ); do
					if [ "$(eval echo \${$array[$key]})" = "$REZ" ]; then
						echo ${key%.*}
						break
					fi
				done	
				return $ERRCODE
				;;
			1 )
				continue
				# pre add work
				# echo  $array $index $(get_max_index $array $index)
				# return 2
				;;
			2 )
				return 1
				;;
			* )
				continue
				;;
		esac
	done
	return 0
}

#TODO
__show_radiolist() {
	LOG ${FUNCNAME[0]} $@
	local input=$1                  # pptpd.mppe    # network[if.role]
	local array_name=$2             # srv           # network[if0]
	local ITEM_COUNT=$DEF_COUNT cmd='' tmpcmd='' REZ
	eval local VALUE=\${$array_name[$input]}
	unset item
	declare -A item
	eval widget=( ${widget[@]} )
	local baseopts="$baseopts --menu '${widget[1]}'"
	eval item=$(set | grep ^$array_name= | sed s/$array_name=//)
	declare -a RADIOLIST
	eval eval RADIOLIST=( \${$array_name[${input//[0-9]}.list]} )
	i=0
	local status
	# format: 'value' 'label' 'status' 'itemhelp'
	for key in ${!RADIOLIST[@]}; do
		((i++)) # 0 - пустой массив | 1 - mppe-optional | 2 - label | 3 - itemhelp
		if [ "$i" = '1' ]; then
			if [ "$VALUE" = "${RADIOLIST[$key]}" ]; then
				tmpcmd="$tmpcmd '[x] ${RADIOLIST[$key]}'"
			else
				tmpcmd="$tmpcmd '[ ] ${RADIOLIST[$key]}'"
			fi
		fi

		if [ "$i" = '2' ]; then
			tmpcmd="$tmpcmd '${RADIOLIST[$key]}'"
		fi

		if [ "$i" = '3' ]; then
			tmpcmd="$tmpcmd '${RADIOLIST[$key]}'"
			cmd="$cmd $tmpcmd"
			unset tmpcmd
			unset status
			i=0
		fi
	done
	unset RADIOLIST
	REZ=$(eval dialog $baseopts $((ITEM_COUNT+5)) 60 $((ITEM_COUNT+5)) $cmd 3>&1 1>&2 2>&3)
	[ "$?" != 0 ] && return 1
	[ "$REZ" = "Назад" ] && return 1
	REZ=${REZ##*] }
	[ "$REZ" != '' ] && eval $array_name['$input']="$REZ"
	return 0
}

__show_checkbox() {
	LOG ${FUNCNAME[0]} $@
	local input=$1 array_name=$2 ITEM_COUNT=$DEF_COUNT cmd='' REZ
	unset item
	declare -A item
	eval widget=( ${widget[@]} )
	eval local value=\${$array_name[$input]}
	[ "$value" = 1 ] && value=0 || value=1
	eval $array_name[$input]=$value
	return 0
}

__show_cmd_output() {
	local tmpfile=/tmp/show_cmd_output.$$
	eval widget=( "${widget[@]}" )
	cmd=${widget[2]}
	eval $cmd &>$tmpfile
	show_file $tmpfile
	rm -f $tmpfile
	return 0
}

__show_cmd() {
	LOG ${FUNCNAME[0]} $@
	eval widget=( "${widget[@]}" )
	cmd=${widget[2]}
	eval $cmd
	return 0
}

__show_textbox() {
	LOG ${FUNCNAME[0]} $@
	eval dialog "--title ${widget[1]} --textbox ${widget[2]} -1 -1"
}

__show_readonly() {
	return 0
}

save_and_exit() {
	local TMPCONFIG=$CONFIG.tmp
	local PREVCONFIG=$(get_last_config)
	while IFS== read -r var val; do
		[[ "$var" == \#* ]] && echo $var $val && continue
		[ "$var" = '' ] && echo && continue
		[[ "$var" = declare* ]] && echo $var $val && continue
		echo "$var='${!var}'"
	done < $CONFIG > $TMPCONFIG
	if [ -s "$TMPCONFIG" ]; then
		mkdir -p $USERDIR/backups
		if [ -z "$PREVCONFIG" ] || ! cmp -s $CONFIG $PREVCONFIG; then
	        	mv -f $CONFIG $USERDIR/backups/config_$(date +%H.%M.%S_%d-%m-%Y)
		fi
		mv -f $TMPCONFIG $CONFIG
	fi
}

save_quagga_config() {
	ORIG="$CURRENT_DIR/etc/quagga/ospfd.conf"
	TMPLT="$CURRENT_DIR/etc/quagga/ospfd.conf.tmplt"
	TMP="/tmp/ospfd.conf.$$"
	while read line; do
		[[ "$line" = password* ]] && continue
		[[ "$line" = "enable password"* ]] && continue
		[[ "$line" = "log file"* ]] && continue
	done < $ORIG > /tmp/ospfd.conf.$$
	echo "password ${srv[quagga.password]}" >> /tmp/osfpd.conf.$$
	echo "password ${srv[quagga.enable_password]}" >> /tmp/osfpd.conf.$$
	echo "/var/log/ospfd.log" >> /tmp/osfpd.conf.$$
	mv -f "$TMP" "$TMPLT"
}

__show_file_content() {
	LOG ${FUNCNAME[0]} $@
	eval widget=( "${widget[@]}" )
	file=${widget[2]}
	dialog --textbox "$file" 0 0 
	return 0
}

__show_() {
	LOG ${FUNCNAME[0]} $@
	dialog $baseopts --msgbox 'Кривые руки разработчика' 5 30
	return 0
}

#Показывает меню
show_recur() {
	LOG ${FUNCNAME[0]} $@
	local menu_array=$1 menu_type=$2 table=$3 RESULT RETVAL
	while true; do
		RESULT=$( __show_$menu_type $menu_array $table ) #	|| return 0 ## выйти из меню
		RETVAL=$?
		case $RETVAL in
			0 )
				: #normal
				;;
			3 )
				delete_from_table ${menu_array%%[*} ${RESULT//[0-9]} ${RESULT//[a-z]/}
				continue
				;;
			2 )
				add_to_table ${menu_array%%[*} ${RESULT//[0-9]} ${RESULT//[a-z]/}
				;;
			* )
				: # debug, exit
				# dialog --yesno "$RETVAL $RESULT" 0 0
				return 0
				;;
		esac
		[[ "$menu_array" == *\[*\] ]] && menu_array=${menu_array%%\[*}
		eval widget=( \${$menu_array[$RESULT.widget]} )
		item_type=${widget[0]}
		if [ "$menu_type" = "table" ]; then
			eval widget=( \${$menu_array[${RESULT//[0-9]}.widget]} )
			item_type=menu
			local sub_table=$RESULT
			RESULT=$menu_array
		fi

		if [ -n "$table" ]; then
			eval widget=( \${$menu_array[${RESULT//[0-9]}.widget]} )
			item_type=${widget[0]}
		fi
		LOG item_type $item_type
		case $item_type in
			menu | menunew )
				show_recur $RESULT menu_filter $sub_table		# рекурсия для подменю
				;;
			table )
				show_recur $menu_array[$RESULT] table 	# рекурсия для подменю
				;;
			iface )
				show_recur $RESULT iface	# рекурсия для интерфейса
				;;
			* ) 	
				__show_$item_type $RESULT $menu_array
				;;
		esac
	done
}
