#!/bin/bash
VERSION='1.2.3'
#########################################################
# NeoTool $VERSION
# By AntiSol, antisol (at) internode (dot) on (dot) net
# GNU GPLv3 licensed
#
# It works for me (tm), No warranty whatsoever: 
# No responsibility taken for furry animals or space-time continuums harmed while using this software
#
# loosely based on a script by 'rorschach'
# Thanks to:
#	Minh Ha Duong (suggestion to flash splash)
# 	Charles Pax (suggestion to fetch dfu-util)
#	David Samblas (info on 'which' command)
#	Shawn "prjktdtnt" Thompson, William Kenworthy, and Al Johnson (help handling multiple dfu-capable devices)
#	William Vidrine (Info on NAND/NOR Menus, suggestion to check for directory's existence)
#########################################################
# ChangeLog:
# 	v1.1 - 15/09/2008 - 17/09/2008: 
#		- Added ChangeLog
#		- Added ability to handle multiple DFU-capable devices
#		- Changed references to 'freerunner' to 'neo' 
#		- name changed to NeoTool (despite implied connection with Keanu Reeves' crotch)
#		- Added 'Reset to defaults' option
#		- Added warning that flashing uboot on neo1973 may result in a paperweight
#		- several small bugfixes
#		- made backup functionality much more versatile:
#			- made backup filenames configurable
#			- Added ability to choose what to backup
#			- Added rootfs backup type option (jffs2 or tar)
#			- Added kernel backup method option (scp or dfu)
#			- Added ability to backup uboot and splash
#	v1.2 - 22/10/2008 - 31/10/2008
#		- Changed information at pre-flash prompt to include instructions for how to get to the NOR menu. 
#			eliminated any mention of NAND, as everything can be flashed from NOR.
#		- bugfix - when user selects a filename under 'customize backup filenames' and then presses cancel, 
#			the selected filename was set to nothing.
#		- NeoTool now checks that the path of backup files exist, and attempts to create it if it doesn't.
#			This allows you to organise your backups in a folder hierarchy, i.e set the backup filename to:
#			/data/openmoko/backups/{date}/{image}_backup
#			and the {date} directory will be created by NeoTool, assuming /data/openmoko/backups exists
#			and you have permission.
#	v1.2.1 - 15/02/2009 - joop_boonen (at) web (dot) de
#		- Can now run as non root the user should be add to group uucp
#		- The config is now written in ~/.neotoolrc
#		- The backup directory can now be choosen default ~/openmoko/backups
#	v1.2.2 - 28/07/2009 - joop_boonen (at) web (dot) de
#		- Corrected a bug
#	
#	v1.2.3 - 23/05/2010 - joop_boonen (at) web (dot) de
#		- Added xterm window to see flas progress
#	
#########################################################

settings_file="$HOME/.neotoolrc"
tmp_error_log_path='/tmp/flash-error-log'
tmpfile='/tmp/neotool.tmp'
xterm_path=`which xterm 2>/dev/null`

function find_dfu {
	#use 'which'...
	dfutils_path=`which dfu-util 2>/dev/null`
	
	if [ -z $dfutils_path ]; then
		#look in current directory...
		if [ -x './dfu-util' ]; then
			dfutils_path='./dfu-util'
		fi
	fi

}

function check_dfu {

	if [ ! -x "$dfutils_path" ]; then
				
		find_dfu
	
		if [ -z "$dfutils_path" ]; then
			#not found. 
			zenity --title "dfu-util not found" --question --text "The dfu utility could not be found, or is not executable. Do you want to automagically download it from downloads.openmoko.org?"
			
			if [ $? = 0 ]; then
				clear
				echo 'Downloading dfu-util...'
				rm ./dfu-util > /dev/null 2>&1
				wget http://downloads.openmoko.org/distro/releases/Om2008.9/dfu-util
				chmod a+x ./dfu-util >/dev/null
				dfutils_path='./dfu-util'
			else
				dfutils_path=$(zenity --file-selection --title="Locate the dfu-util executable:" --filename="$dfutils_path")
				
			fi
			
			if [ -z "$dfutils_path" ]; then
				echo "Cancelled!"
				exit
			fi
			#check selection...
			check_dfu
		fi
	fi
}

function perform_flash {
	# $1 - what we're flashing (for display)
	# $2 - dfu-params
	# $3 - file to flash

	if [ -n "$device" ]; then
		#use a hexcode
		#echo "flashing with hexcode: $dfutils_path -d $device $2 $3 2> $tmp_error_log_path"
		$xterm_path -e $dfutils_path -d $device $2 $3 2> $tmp_error_log_path
	else
		$xterm_path -e $dfutils_path $2 $3 2> $tmp_error_log_path
	fi;

	# add the following line to the '$dfutils_path' lines to get back the zenity progress dialog:
	# | zenity --progress --pulsate --percentage=0 --title "Flashing in progress.." --auto-close

	if [ "${PIPESTATUS[0]}" != "0" ];then
		zenity --error --text "Some error occured while flashing $1.\n\nError message:\n`cat $tmp_error_log_path`\n\nAny other pending flashes will be aborted."
		return 1
	else
		#sleep to allow dfu to reset...
		sleep 2
	fi
}

function handle_multiple_devices {
	#check for multiple DFU-capable devices
	$dfutils_path -l | grep Found > $tmpfile
	
	#for testing, simulate multiple devices.
	#cp ./testfile $tmpfile
	
	devcount="`wc -l < $tmpfile`"
	
	if [ "$devcount" -gt 1 ]; then
	
		#multiple devices attached, show a list.
		frcount=0
		neocount=0
		
		exec < $tmpfile
		while read line; do 
			#a=$(($a + 1))
			hex=`echo "$line" | awk '{print substr($3,2,13)}'`
			
			devlist="$devlist $hex"
			if [ "$hex" = "0x1d50:0x5119" ]; then
				devlist="$devlist FreeRunner"
				frcount=$(($frcount+1))
			elif [ "$hex" = "0x1457:0x5119" ]; then
				devlist="$devlist Neo1973"
				neocount=$(($neocount+1))
			else
				devlist="$devlist Unknown"
			fi;
			
		done
			
		if [ "$frcount" -gt 1 ] || [ "$neocount" -gt 1 ]; then
			zenity --info --title "Multiple Devices detected" --text "It has been determined that you have more than one of the same type of device attached (i.e two FreeRunners or two Neo1973s). Unfortunately there is no known way to specify which device to flash in this situation. Please disconnect the device you do not wish to flash, and try again."
			return -1
			
		fi
		
		device=$(zenity --title "NeoTool" --text "Multiple DFU-capable devices were detected, please choose which one to flash:" --list --height=300 --width=400 --column "Hex Code" --column "Device Type" $devlist)
		
		if [ -z "$device" ]; then
			return -1
		fi;
	
	fi;
	
	return 0
}

function check_dir {
	#Checks that the path where $1 is located exists, and tries to create it if it doesn't.
	#nonzero return indicates that it couldn't create the path (permissions?)
	DESTDIR="`dirname $1`"
	if [ ! -d "$DESTDIR" ]; then
		echo "$DESTDIR does not exist, attempting to create it..."
		mkdir  -p $DESTDIR
		if [ $? != 0 ]; then
			zenity --error --text "The directory $DESTDIR Specified for the file $1 does not exist, and could not be created!\n\nThis is probably because you don't have permission, or because the path specified is invalid.\n\nPlease check your settings and try again." --title "Error!"
			return -1
		fi
	fi
	return 0
}

function flash {

	if [ "$user" != "root" ]; then
		zenity --error --text "You can only flash your device if you are root!"
		return
	fi
	
	#set these to null incase we've already flashed in the same frutil session
	uboot=""
	kernel=""
	rootfs=""
	splash=""
	
	check_dfu

	ans=$(zenity  --list --text "What do you wanna flash?" --title "NeoTool" --height=300 --checklist --column "Pick" --column "Option" TRUE Root-Filesystem TRUE Kernel FALSE Bootloader FALSE Splash)

	if [ -z "$ans" ]; then
		#handle cancel / no selection...
		#echo "Nothing to do!"
		return
	fi

	txt="The flashing will now start.\n\nNow is the time to connect your Neo via the USB cable, and boot it into the menu. Do not proceed until the device has the menu showing.\n\nTo get to the menu, power down the device, then press and hold AUX, the press and hold the power button, while still holding AUX, until the menu appears.\n\nRemember that flashing a large image like a rootfs will take some time. Flashing progress will be displayed in the console window.\n\nDo not abort the flashing process, this would be a bad thing.\n\n"

	if [ -n "`echo $ans | grep Root-Filesystem`" ];then
		du_param_r='-a rootfs -R -D'
		rootfs=True
		img_file_r=$(zenity --file-selection --title="Select an image-file for the ROOTFS:")
		if [ "$img_file_r" = "" ]; then
			#echo "Cancelled!"
			return
		fi
		txt="$txt - Flashing rootfs with $img_file_r \n\n"
	fi

	if [ -n "`echo $ans | grep Kernel`" ];then
		du_param_k='-a kernel -R -D'
		kernel=True
		img_file_k=$(zenity --file-selection --title="Select an image-file for the KERNEL:")
		if [ "$img_file_k" = "" ]; then
			#echo "Cancelled!"
			return
		fi
		txt="$txt - Flashing kernel with $img_file_k \n\n"
	fi

	if [ -n "` echo $ans | grep Bootloader`" ];then
		du_param_u='-a u-boot -R -D'
		uboot=True
		img_file_u=$(zenity --file-selection --title="Select an image-file for UBOOT:")
		if [ "$img_file_u" = "" ]; then
			#echo "Cancelled!"
			return
		fi
		txt="$txt - Flashing uboot with $img_file_u \n\n"
	fi
	
	if [ -n "` echo $ans | grep Splash`" ];then
		du_param_s='-a splash -R -D'
		splash=True
		img_file_s=$(zenity --file-selection --title="Select an image-file for SPLASH:")
		if [ "$img_file_s" = "" ]; then
			#echo "Cancelled!"
			return
		fi
		txt="$txt - Flashing splash with $img_file_s \n\n"
	fi

	touch $tmp_error_log_path

	if [ "$uboot" = True ]; then
		txt="$txt\n\n*** WARNING! WARNING! DANGER WILL ROBINSON! ***\n\nFlashing u-boot on a Neo1973 may result in a paperweight! It is not recommended unless you have a debug board, and/or really know what you're doing!\n(This does not apply for the FreeRunner)" 
	fi

	zenity --question --text "$txt" --title "Ready to flash"
	
	if [ $? != 0 ]; then 
		return
	fi
	
	handle_multiple_devices
	if [ $? != 0 ]; then
		return
	fi

	if [ "$rootfs" = True ]; then
		echo
		echo "*** Flashing rootfs with $img_file_r..."
		echo
		perform_flash rootfs "$du_param_r" "$img_file_r"
		if [ $? != 0 ]; then 
			return
		fi
	fi

	if [ "$kernel" = True ]; then
		echo
		echo "*** Flashing kernel with $img_file_k..."
		echo
		perform_flash kernel "$du_param_k" "$img_file_k"
		if [ $? != 0 ]; then 
			return
		fi
	fi

	if [ "$uboot" = True ]; then
		echo
		echo "*** Flashing u-boot with $img_file_u..."
		echo
		perform_flash uboot "$du_param_u" "$img_file_u"
		if [ $? != 0 ]; then 
			return
		fi
	fi

	if [ "$splash" = True ]; then
		echo
		echo "*** Flashing splash with $img_file_s..."
		echo
		perform_flash splash "$du_param_s" "$img_file_s"
		if [ $? != 0 ]; then 
			return
		fi
	fi

	rm $tmp_error_log_path

}

function show_menu {
	ans=`zenity --title "NeoTool" --text "Choose an option" --list --height=300 --width=400 --column "" --column "" 1 "Setup NeoTool" 2 "Flash your Neo" 3 "Backup Your Neo" 4 "Quit"`
}

function setup_menu {
	sans=`zenity --title "NeoTool Configurification" --text "Choose an option" --list --height=320 --width=500  --column "" --column "" 1 "Locate dfu-util ($dfutils_path)" 2 "Set your device's IP ($FRIP)" 3 "Choose backup filename ($backupfn)" 4 "Setup date command ($datecmd)" 5 "Choose backup directory ($backupdir)" 6 "Test settings defined in (3), (4) and (5)" 7 "Save These Settings" 8 "Reset to defaults" 9 "Back to Main Menu"`
}


function setup {

	setup_menu
	while [ -n "$sans" ]; do

	case "$sans"
        in
                1) 
			check_dfu
			zenity --question --text "The dfu-utility was located at $dfutils_path, is this correct? (Cancel for no)"
			if [ $? != 0 ]; then
				dfutils_path=$(zenity --file-selection --title="Locate the dfu-util executable:" --filename="$dfutils_path")
				check_dfu
			fi
			;;
                2) 
			FRIP=$(zenity --entry --text "Enter the IP / hostname for your Neo:" --entry-text "$FRIP")
			;;
		3) 
			oldbackupfn="$backupfn"
			backupfn=$(zenity --entry --text "`printf "Enter the default filename to be used for backups.\nuse '{image}' for the Image type (kernel, rootfs, etc), \nand '{date}' for the date.\n the file extension will be added automatically."`" --entry-text "$backupfn" --title "Configure Backup Filename")
			if [ -z "$backupfn" ]; then
				backupfn=$oldbackupfn
			fi
			;;
		4)
			olddatecmd="$datecmd"
			datecmd=$(zenity --entry --text "`printf "Enter the 'date' command to be used in backup filenames.\nthe output of this command will replace the {date} tag in \nbackup filenames.\n\nThis is intended to allow you to use different date formats, \nbut may use any command which produces output to stdout.\n\nSee 'man date' for details on date formats"`" --entry-text "$datecmd" --title "Configure Date Command")
			if [ -z "$datecmd" ]; then
				datecmd=$olddatecmd
			fi
			;;
		5) 
			oldbackupdir="$backupdir"
			backupdir=$(zenity --entry --text "`printf "Enter the default directoryname to be used for backups.\nuse '{image}' for the Image type (kernel, rootfs, etc), \nand '{date}' for the date.\n the file extension will be added automatically."`" --entry-text "$backupdir" --title "Configure Backup Directoryname")
			if [ -z "$backupdir" ]; then
				backupdir=$oldbackupdir
			fi
			;;
		6) 
			tmp=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}
			tmp=${tmp//"{image}"/"rootfs"}".jffs2\n"${tmp//"{image}"/"kernel"}".bin"
			zenity --info --title "Example Backup File" --text "Using the rules defined by current settings, backup filenames will look something like this:\n\n$tmp"
			;;
			
                7) 
			echo "dfutils_path='$dfutils_path'" > $settings_file
			echo "FRIP='$FRIP'" >> $settings_file
			echo "backupfn='$backupfn'" >> $settings_file
			echo "datecmd='$datecmd'" >> $settings_file
			echo "backupdir='$backupdir'" >> $settings_file
			zenity --info --text "Settings saved to $settings_file" --title "Done."
			;;
		
                8) 
			rm -f $settings_file
			zenity --info --text "Settings will reset to default once you restart this tool" --title "Done."
			;;


		 *) return;;
        esac

	setup_menu

done	

}

function show_dfu_msg {
	if [ "$user" != "root" ] || [ "$groups" != "${groups/uucp/}" ]; then
		zenity --error --text "The remaining backup tasks cannot be completed, because you are not running NeoTool while your in the uucp group!"
		return -1
	fi
	
	if [ "$msg_shown" = "" ]; then
		zenity --question --title "About to backup using DFU" --text "The remaining backup portion(s) need access to the device's DFU, please reboot your device into NAND/NOR and press OK to proceed."
		if [ $? != 0 ]; then
			return -1
		fi
		msg_shown=True
		
		handle_multiple_devices
		if [ $? != 0 ]; then
			return -1
		fi
		
		return 0
	fi
}

function ip_test {
	if [ "$iptested" != "" ]; then 
		return 0
	fi

	echo " - Checking validity of device IP ($FRIP)..."

	if [ -z "$FRIP" ]; then
		zenity --error --text "You have not setup your device's IP address / hostname! Do this via the settings menu and try again."
		return -1
	fi
	
	#ping the IP to make sure it's valid...
	ping -c 1 $FRIP > /dev/null
	
	if [ $? != 0 ]; then
		zenity --error --text "There was no ping response from a device at $FRIP! Please ensure it is connected and that networking is working, and try again."
		return -1
	fi

	#echo " - Checking for authorized_keys file..."
	
	if [ -z "`ssh root@$FRIP 'ls /home/root/.ssh/authorized_keys 2>/dev/null'`" ]; then
		zenity --question --text "it is recommended that you set up an authorized key on your device to eliminate the need to enter a password.\n\nIf you do not do this, you will likely be prompted for the device's password repeatedly during this procedure.\n\nThis is done by running 'ssh-keygen' on your host, and then copying the contents of ~/.ssh/id_rsa.pub on your host into home/root/.ssh/authorized_keys on your device. See the man pages for 'ssh' and 'ssh-keygen' for more info.\n\nDo you want to cancel the backup and do this now?\n(press cancel to proceed with the backup anyway)"
		#maybe even set it up automatically(?)
		if [ $? = 0 ]; then
			return -1
		fi
	fi
}

function backup {

	msg_shown=""
	iptested=""
	
	clear
	
	echo "Performing backup of the following data: $backup_items"
	
	text="Backup Complete.\n"
	
	if [ "$backup_rootfs" = True ]; then
		
		echo " - Backing up rootfs at $FRIP..."
		
		check_dir $FSIMG
		if [ $? != 0 ]; then
			return -1
		fi		
		
		case "$rootfs_type"
		in
			"jffs2")
			
				ip_test
				if [ $? != 0 ]; then
					return
				fi
				
				echo ' - Checking device for mkfs-jffs...'
				if [ -z "`ssh root@$FRIP 'opkg status mkfs-jffs2'`" ]; then
					zenity --error --text 'prerequisite mkfs-jffs2 is not installed on the device! \n\n do "opkg install mkfs-jffs2" and try again.'
					return
				fi

				echo " - Mounting flash at /var/tmp/root..."
				ssh root@$FRIP "mkdir /var/tmp/root; mount -t jffs2 /dev/mtdblock6 /var/tmp/root"
				#ssh root@$FRIP "mkdir /var/tmp/root"
				#ssh root@$FRIP "mount -t jffs2 /dev/mtdblock6 /var/tmp/root"
				echo ' - Performing backup... (this will take a while)'
				
				if [ -z "`which pv 2>/dev/null`" ]; then	
					#pv is not installed, so don't use it...
					ssh root@$FRIP "mkfs.jffs2 -d /var/tmp/root -e 128 --pad --no-cleanmarkers -x lzo" > $FSIMG
				else
					ssh root@$FRIP "mkfs.jffs2 -d /var/tmp/root -e 128 --pad --no-cleanmarkers -x lzo" | pv -W > $FSIMG
				fi
				
				echo Cleanup...
				ssh root@$FRIP "umount /var/tmp/root; rmdir /var/tmp/root"
				;;

			"tar")
				echo ' - Performing backup... (this will take a while)'
				if [ -z "`which pv 2>/dev/null`" ]; then	
					#pv is not installed, so don't use it...
					ssh root@$FRIP "tar c /bin /etc /home /lib /opt /sbin /tmp /usr /var" > $FSIMG
				else
					ssh root@$FRIP "tar c /bin /etc /home /lib /opt /sbin /tmp /usr /var" | pv -W > $FSIMG
				fi
				;;
			*) return;;
		esac
		text="$text\n - rootfs backed up to $FSIMG"
	fi
	
	if [ "$backup_kernel" = True ]; then
		
		check_dir $KIMAGE
		if [ $? != 0 ]; then
			return -1
		fi		
		
		case "$kernel_type" 
		in
			scp)
				ip_test
				if [ $? != 0 ]; then
					return
				fi
				echo " - Backing up Kernel image..."
				scp root@$FRIP:/boot/uImage $KIMAGE
				;;
			dfu)
				show_dfu_msg
				if [ $? != 0 ]; then return; fi
				echo " - Backing up Kernel image..."
				perform_flash kernel "-a kernel -R -U" "$KIMAGE"
				if [ $? != 0 ]; then 
					return
				fi
				;;
			*) return;;
		esac
		text="$text\n - kernel backed up to $KIMAGE"
	fi
	
	if [ "$backup_uboot" = True ]; then
		
		check_dir $UIMAGE
		if [ $? != 0 ]; then
			return -1
		fi		

		show_dfu_msg
		if [ $? != 0 ]; then return; fi
		echo " - Backing up u-boot image..."
		perform_flash uboot "-a u-boot -R -U" "$UIMAGE"
		if [ $? != 0 ]; then 
			return
		fi
		text="$text\n - uboot backed up to $UIMAGE"
	fi

	if [ "$backup_splash" = True ]; then
		
		check_dir $SIMAGE
		if [ $? != 0 ]; then
			return -1
		fi		

		show_dfu_msg
		if [ $? != 0 ]; then return; fi
		echo " - Backing up splash image..."
		perform_flash splash "-a splash -R -U" "$SIMAGE"
		if [ $? != 0 ]; then 
			return
		fi
		text="$text\n - splash backed up to $SIMAGE"
	fi

	#ssh root@$FRIP "umount /var/tmp/root"
	#ssh root@$FRIP "rmdir /var/tmp/root"

	zenity --info --title "Done." --text "$text"
	#"Done!\n\n- rootfs backed up to $FSIMG\n- Kernel backed up to $KIMAGE"

}

function show_backup_menu {
	
	IFS=";"
	bk_menu_items="1;Choose what to backup ($backup_items)"
	
	if [ "$backup_rootfs" = True ]; then
		bk_menu_items=$bk_menu_items";2;Choose rootfs backup type ($rootfs_type)"
	fi
	
	if [ "$backup_kernel" = True ]; then
		bk_menu_items=$bk_menu_items";3;Choose kernel backup method ($kernel_type)"
	fi
	
	bk_menu_items=$bk_menu_items";4;Customise Backup Filenames;5;Go!;6;Back to Main Menu"
	
	bans=`zenity --title "NeoTool" --text "Choose an option" --list --height=300 --width=400  --column "" --column "" $bk_menu_items`
	
	IFS=" "

}

function backup_what {
	
	backup_rootfs=""
	backup_kernel=""
	backup_uboot=""
	backup_splash=""
	
	backup_items=$(zenity  --list --text "What do you wanna backup?" --title "NeoTool" --height=300 --checklist --separator="," --column "Pick" --column "Option" TRUE Root-Filesystem TRUE Kernel FALSE Bootloader FALSE Splash)
	
	
	if [ -z "$backup_items" ]; then
		return
	fi

	if [ -n "`echo $backup_items | grep Root-Filesystem`" ];then
		backup_rootfs=True
	fi
	
	if [ -n "`echo $backup_items | grep Kernel`" ];then
		backup_kernel=True
	fi
	
	if [ -n "`echo $backup_items | grep Bootloader`" ];then
		backup_uboot=True
	fi

	if [ -n "`echo $backup_items | grep Splash`" ];then
		backup_splash=True
	fi

	
}

function root_backup_type {
		old_rootfs_type=$rootfs_type
		rootfs_type=$(zenity --list --text "Choose rootfs backup type:\n\nIf you have modified your rootsf filename, this will reset it to the default." --column "Format" --column "Description" jffs2 "Flashable JFFS2 Image" "tar" "For SD card install")
		if [ -z "$rootfs_type" ]; then
			rootfs_type=$old_rootfs_type
		fi
		FSIMG=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}".$rootfs_type"
		FSIMG=${FSIMG//"{image}"/"rootfs"}
		
		#echo fsimg = $FSIMG

}

function kernel_backup_type {
		old_kernel_type=$kernel_type
		kernel_type=$(zenity --list --text "Choose kernel backup method:" --column "Method" --column "Description" scp "Copy via SCP" "dfu" "Extract using DFU")
		if [ -z "$kernel_type" ]; then
			kernel_type=$old_kernel_type
		fi

}

function show_bkfn_menu {
	bk_menu_items=""

	if [ "$backup_rootfs" = True ]; then
		bk_menu_items=$bk_menu_items";rootfs;$FSIMG"
	fi
	
	if [ "$backup_kernel" = True ]; then
		bk_menu_items=$bk_menu_items";kernel;$KIMAGE"
	fi
	
	if [ "$backup_uboot" = True ]; then
		bk_menu_items=$bk_menu_items";uboot;$UIMAGE"
	fi
	
	if [ "$backup_splash" = True ]; then
		bk_menu_items=$bk_menu_items";splash;$SIMAGE"
	fi
	
	bk_menu_items=${bk_menu_items:1}";;Return to Backup Menu"
	
	IFS=";"
	customise_what=$(zenity --list --height=300 --width=500 --text "Choose what filename you want to customise:" --column "Item" --column "Filename" $bk_menu_items)
	IFS=" "
}

function backup_filenames {

	show_bkfn_menu
	
	while [ -n "$customise_what" ]; do

		case "$customise_what"
		in
			#TODO: write code here...
			rootfs) 
				OLDFN=$FSIMG
				FSIMG=$(zenity --file-selection --save --title "Choose the filename for the rootfs backup:" --filename "$FSIMG")
				if [ -z "$FSIMG" ]; then
					FSIMG=$OLDFN
				fi
				;;
			kernel) 
				OLDFN=$KIMAGE
				KIMAGE=$(zenity --file-selection --save --title "Choose the filename for the kernel backup:" --filename "$KIMAGE")
				if [ -z "$KIMAGE" ]; then
					KIMAGE=$OLDFN
				fi			
				;;
			uboot) 
				OLDFN=$UIMAGE
				UIMAGE=$(zenity --file-selection --save --title "Choose the filename for the u-boot backup:" --filename "$UIMAGE")
				if [ -z "$UIMAGE" ]; then
					UIMAGE=$OLDFN
				fi						
				;; 
			splash) 
				OLDFN=$SIMAGE
				SIMAGE=$(zenity --file-selection --save --title "Choose the filename for the splash backup:" --filename "$SIMAGE")
				if [ -z "$SIMAGE" ]; then
					SIMAGE=$OLDFN
				fi						
				;;

			*) return;;
		esac

		show_bkfn_menu

	done


}


function backup_menu {

	rootfs_type=jffs2
	kernel_type=scp
	
	FSIMG=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}".$rootfs_type"
	FSIMG=${FSIMG//"{image}"/"rootfs"}
	
	KIMAGE=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}".bin"
	KIMAGE=${KIMAGE//"{image}"/"kernel"}
	
	UIMAGE=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}".bin"
	UIMAGE=${UIMAGE//"{image}"/"u-boot"}

	SIMAGE=$backupdir"/"${backupfn//"{date}"/"`$datecmd`"}".gz"
	SIMAGE=${SIMAGE//"{image}"/"splash"}
	
	#echo fsimg = $FSIMG
	#echo kimage = $KIMAGE

	backup_what
	
	show_backup_menu
	
	while [ -n "$bans" ]; do

		case "$bans"
		in
			#TODO: write code here...
			1) backup_what;;
			2) root_backup_type;;
			3) kernel_backup_type;; 
			4) backup_filenames;;
			5) backup;;

			*) return;;
		esac

		show_backup_menu

	done


}

##################################################
# Main

echo "NeoTool v$VERSION, By Dale Maggee. (C) 2008-2009. GNU GPLv3 Licensed."

#check for zenity...
#TODO: Once we're handling command-line params, this will have to happen later...
if [ -z "`which zenity 2>/dev/null`" ]; then
	echo "it looks like zenity isn't installed, and this tool requires it!"
	exit
fi	

#check user...
user=`whoami`
#check groups... uucp is needed to allow access to the serial usb interface
groups=`groups`

if [ "$user" != "root" ] || [ "$groups" != "${groups/uucp/}" ]; then
	zenity --title "You are not root or in group uucp!" --question --text 'You should be root otherwise you wont be able to flash and contact your Neo via the serial usb interface, connectivity via serial also works when youre in group uucp.\n\n Do you want to continue?'
	
	if [ $? != 0 ]; then
		echo "exiting."
		exit
	fi;
fi

#load settings file if it exists...
if [ -e $settings_file ]; then
	echo "loading settings from $settings_file ..."
	. $settings_file
fi

check_dfu

if [ -z "$backupfn" ]; then
	backupfn="Neo_{image}_Backup_{date}"
fi

if [ -z "$backupdir" ]; then
	backupdir="$HOME/openmoko/backups"
fi

if [ -z "$datecmd" ]; then
	datecmd="date +%Y%m%d%H%M"
fi

if [ -z "$FRIP" ]; then
	FRIP="192.168.0.202"
fi

#main Menu...

show_menu

while [ -n "$ans" ]; do

	case "$ans"
        in
	
                1) setup;;
                2) flash;;
                3) backup_menu;;

		*) exit;;
        esac

	show_menu

done



