
# kernel information directory
kernelsdir="${SPELL_DIRECTORY}/info/kernels"
# patches information directory
patchesdir="${SPELL_DIRECTORY}/info/patches"
# sourced from DETAILS to create SOURCE_URL SOURCE
# KERNEL_VERSION environmental vars
detailsdefaults="${CONFIG_CACHE}/details.defaults"
dependsmakefile="${CONFIG_CACHE}/makefile.patches"
# Latest versions of your favorite kernel sources and patches
latestdefaults="${SPELL_DIRECTORY}/latest.defaults"
# debug log duh ;)
debug="${SPELL_DIRECTORY}/debug.log"

# Source patch info for the patch
# this is used for getting specific information about the source name source url
# verification checking what the dependancies are, things like that.
source_patch()
{	
	local tmploc
	case $1 in
		LATEST*)
			tmploc=$(find $patchesdir/*/${!1} | head -n 1)
			;;
		*)
			tmploc=$(find $patchesdir/*/${1} | head -n 1)
	esac &&
	[ -f $tmploc ] && . $tmploc
}

# Source info for patch
# this is used for general info about the patch, what the patch is, contains,
# made by, things like that.
source_info()
{
	local tmploc
	case $1 in
		LATEST*)
			tmploc=$(find $patchesdir/*/${!1} | head -n 1)
			;;
		*)
			tmploc=$(find $patchesdir/*/$1 | head -n 1)
			;;
	esac &&
	[ -f `dirname $tmp`/.info ] && . `dirname $tmploc`/.info
}

# Create the default KERNEL_ARCH variable
arch_default()
{
	if [ -z "$KERNEL_ARCH" ]
	then
		case  `uname -m`  in
			alpha) KERNEL_ARCH=alpha   ;;
			arm) KERNEL_ARCH=arm     ;;
			cris) KERNEL_ARCH=cris    ;;
			ia64) KERNEL_ARCH=ia64    ;;
			i*86) KERNEL_ARCH=i386    ;;
			m68k) KERNEL_ARCH=m68k    ;;
			mips) KERNEL_ARCH=mips    ;;
			mips64) KERNEL_ARCH=mips64  ;;
			parisc) KERNEL_ARCH=parisc  ;;
			powerpc) KERNEL_ARCH=ppc     ;;
			ppc) KERNEL_ARCH=ppc     ;;
			powerpc64) KERNEL_ARCH=ppc64   ;;
			s390) KERNEL_ARCH=s390    ;;
			s390x) KERNEL_ARCH=s390x   ;;
			sh*) KERNEL_ARCH=sh      ;;
			sparc) KERNEL_ARCH=sparc   ;;
			sparc64) KERNEL_ARCH=sparc64 ;;
			x86_64) KERNEL_ARCH=x86_64  ;;
		esac		
	fi
}

# create the defaults file from scratch
# do this with every command
create_defaults()
{
	arch_default
	kernel_arch=$KERNEL_ARCH
	# add variables that I need
	
	# what arch the kernel is being made for
	persistent_add kernel_arch
	
	# what are we doing, 
	# making a new kernel tree: newktree
	# recompiling an old kernel tree: oldktree
	# using a custom existing kernel tree: expert
	persistent_add mode

	# internal semi-copy of RECONFIGURE so that the spell can call
	# menuconfig in PRE_BUILD
	persistent_add reconf

	# kernel version for the base kernel source, or in case of expert the
	# full kernel version of the source tree
	persistent_add kver

	# list of final patches after depends resolution
	persistent_add patches

	# list of patches that the user selected
	persistent_add selected_patches

	# make sure that the state of the spell is good when we compile
	# since users can put the spell into a state where it will always fail
	# do some sanity checks to get a working installed configuration

	# check if the grimoire version was completed successfully and load
	# it's set of persistent vars and change the mode to oldktree if the
	# mode that made the kernel wasn't expert
	VERSION="`gaze version $SPELL | awk 'NR == 3 {print $4}'`"
	if [ -f ${BUILD_DIRECTORY}/linux-${VERSION}/.spell-config.p ]
	then
		cp ${BUILD_DIRECTORY}/linux-${VERSION}/.spell-config.p \
		   ${SPELL_CONFIG}.p
		persistent_load
		if [[ "$mode" != "expert" ]]
		then
			mode="oldktree"
		fi
	
	# upgrade path: if the installed version of the spell was installed
	# successfully then use it's persistent vars and switch to newktree
	# so the update can be performed.
	elif [ -f ${BUILD_DIRECTORY}/linux-$(installed_version $SPELL)/.spell-config.p ]
	then
		cp ${BUILD_DIRECTORY}/linux-$(installed_version $SPELL)/.spell-config.p ${SPELL_CONFIG}.p
		persistent_load
		mode="newktree"
		
	# we don't have any configuration and we need to set some sane defaults
	# so that things won't break.
	# these defaults are the vanilla kernel with the latest maintenance
	# patches
	else
		[ -z "$mode" ] && mode="newktree"
		[ -z "$kver" ] && kver="LATEST_2_6"
		[ -z "$selected_patches" ] && selected_patches="LATEST_maintenance_patches"
	fi

	# check RECONFIGURE for cast -r linux and set reconf appropriately
	# since the questions afterwards are saved with the persistent vars we
	# need to remove them from the persistent var table so that the 
	# questions will be asked again.
	if [[ $RECONFIGURE ]]
	then
		persistent_remove MAKEMODE &&
		persistent_remove UPDATE_BL &&
		persistent_remove CONFIG_KERNEL 
		reconf="true"
	else
		reconf="false"
	fi

	# do this just to make sure
	persistent_save
	persistent_load
}

# dialog command works even if you add --nocancel as part of the arguments
dialog=( "dialog" "--stdout" )

# used for checking the current version against the updated version in the
# spell
# output is the kernel version that is the updated version of the spell...
# might need to be modified...
get_usr_src_kver()
{
	local spell_config=$1
	local newkver
	local ret
	. $spell_config
	calculate_depends > /dev/null
	if [[ ! -z $patches ]]
	then
		for patch in $patches
		do
			source_patch ${patch}
			if [[ ! -z $patchversion ]]
			then
				newkver=$patchversion
			fi
		done
		echo $newkver
	else
		case $kver in
			LATEST*)
				echo ${!kver}
				;;
			*)
				echo $kver
				;;
		esac
	fi
}

# simply list ${BUILD_DIRECTORY} linux sources 
# these source directories are only spells that have been successfully installed
# this is accomplished by puting the persistent config file when that kernel was
# installed into the source directory
# also the check is done to determine the version of each linux source to see if
# the kernel source needs updating
list_usr_src()
{
	local tmpkver
	local linuxsrcs
	local linuxsrc
	if find ${BUILD_DIRECTORY}/linux*/.spell-config.p >> /dev/null 2>&1 
	then
		linuxsrcs="`ls -1d ${BUILD_DIRECTORY}/linux*`"
		for linuxsrc in $linuxsrcs
		do
			if [ -d $linuxsrc ] && [ -f $linuxsrc/.spell-config.p ]
			then
				echo "$linuxsrc"
				echo "\"Source Tree\""
				echo "\"Use ${linuxsrc} as the source tree\""
			fi
		done
	else
		echo "No"
		echo "\"Available Source trees\""
		echo "\"Maybe you need to compile a new one?\""
	fi
}
																			
# main menu uhhh, what else is there to say?
main_menu()
{
	while true
	do
		command=$( "${dialog[@]}" --title "New or Used Kernel Tree" \
		--item-help --default-item "$mode" \
		--cancel-label "Exit" --menu \
		"Would you like to use a new kernel tree or an existing one?\nThe Current kernel is $kver\nThe current selected patches: ${selected_patches}" 0 0 0 \
		"newktree" "New Kernel Tree" "I want to use a new kernel tree"  \
		"oldktree" "Old Kernel Tree" "I want to use an old kernel tree"  \
		"expert"   "User Generated Kernel Tree" "I want to use a kernel tree that I made" \
		"Options"  "Menu" "Kernel Arch, Build Dir, Cleaning" )
		retval="$?"
		if [ "$retval" == "0" ]
		then
			case "$command" in
				"newktree") 
					mode=$command
					new_tree_menu 
					;;
				"oldktree")
					mode=$command
					old_src_menu
					;;
				"expert")
					mode=$command
					custom_kernel
					;;
				"Options")
					options_menu
					;;
				*) break ;;
			esac
		else
			break
		fi
	done
}

# clean a source directory ($1)
clean_src_menu()
{
	while true
	do
		clean_options=$( "${dialog[@]}" --title "Clean Menu" \
			--item-help --menu \
			"How to Clean" 0 0 0 \
			"mrproper" "Clean $1 with mrproper" "Clean Source" \
			"clean" "Clean $1 with clean" "Clean Source" )
		retval="$?"
		if [ "$retval" == "0" ]
		then
			tmpdir="`pwd`"
			cd $1
			make ${clean_options}
			cd ${tmpdir}
		else
			break
		fi
	done
}
# select which kernel source to clean
# pass that kernel source to clean_src_menu
clean_menu()
{
        while true
        do
                eval 'menu_option=$( "${dialog[@]}" --title "Clean Menu" \
			--item-help --menu \
			"Which Kernel" 0 0 0 '`list_usr_src`' )'
		retval="$?"
		if [[ "$retval" == "0" && "$menu_option" != "No" ]]
		then
			clean_src_menu ${menu_option}
		else
			break
		fi
	done
}

# making other package types for other Linux distros
other_pkg_src_menu()
{
	while true
	do
		menu_option=$( "${dialog[@]}" --title "Options Menu" \
			--item-help --menu \
			"Other Package Creation\nThese only work if you have the respective applications installed" 0 0 0 \
			"rpm" "Make an RPM package" "Requires RPM" \
			"rpm-pkg" "Make another RPM package" "Requires RPM" \
			"binrpm-pkg" "Okay more RPM packages" "Requires RPM" \
			"deb-pkg" "Make a Debian Package" "Requires Debian Package Utilities" 
			)
		retval="$?"
		if [ "$retval" == "0" ]
		then
			tmpdir="`pwd`"
			cd $1
			make ${menu_option}
			cd $tmpdir
		else
			break
		fi
	done
}

# list the linux sources to make other package types
other_package_menu()
{
	while true
	do
		eval 'menu_option=$( "${dialog[@]}" --title "Options Menu" \
			--item-help --menu \
			"Select a Kernel Source" 0 0 0 '`list_usr_src`' )'
		retval="$?"
		if [[ "$retval" == "0" && "$menu_option" != "No" ]]
		then
			other_pkg_src_menu ${menu_option}
		else
			break
		fi
	done
}

# select other arch to compile for
arch_menu() 
{
	arch_default
	local DEFAULT=${KERNEL_ARCH}
	local COMMAND
	while true
	do
		COMMAND=$( "${dialog[@]}" --title "Select Kernel Architecture"       \
		--item-help --default-item "$DEFAULT" --menu      \
		"Select a kernel architecture to use" 0 0 0            \
		"CUSTOM"             "Manually enter some other Architecture"           "You can enter any valid architecture" \
		"DEFAULT"            "Default Kernel Architecture"                      "The detected architecture for your platform, $DEFAULT" \
		"alpha"              "DEC/Compaq 64-bit Alpha"                          "DEC Alpha" \
		"arm"                "Embedded Processors using 32-bit ARM processors"  "ARM 32-bit" \
		"cris"               "Embedded Axis ETRAX CRIS processors 32-bit"       "Axis ETRAX CRIS" \
		"ia64"               "Intel Architecture 64-bit Itanium"                "Intel IA64 64-bit" \
		"i386"               "Intel Architecture 32-bit 386 through Pentium 4"  "Intel x86 32-bit" \
		"m68k"               "Motorola 68000 series 32-bit (older Macintosh)"   "m68k 32-bit" \
		"mips"               "MIPS Technologies 32-bit compatible processors"   "MIPS32 platforms" \
		"mips64"             "MIPS Technologies 64-bit compatible processors"   "MIPS64 platforms" \
		"parisc"             "HP PA-RISC 32 and 64-bit processors"              "PA-RISC 32-bit mode" \
		"ppc"                "PowerPC 32-bit (IBM and Motorola) G3/G4 Mac"      "PPC32 G3/G4" \
		"ppc64"              "PowerPC 64-bit (IBM) G5 Mac"                      "PPC64 G5" \
		"s390"               "IBM s390  31-bit systems"                         "IBM s390 31-bit" \
		"s390x"              "IBM s390x 64-bit systems"                         "IBM s390 64-bit" \
		"sh"                 "SuperH processors sh4 is 32-bit, sh5 is 64-bit"   "SH4 and SH5 32-bit mode" \
		"sparc"              "Sun SPARC 32-bit processors"                      "Sun SPARC 32-bit" \
		"sparc64"            "Sun SPARC 64-bit processors"                      "Sun SPARC 64-bit" \
		"x86_64"             "AMD x86-64 64-bit Hammer/Opteron/Athlon64 chips"  "AMD x86-64 Hammer" \
		"um"                 "User Mode Linux arch used for creating UML kernels" "User Mode Linux" \
		"xen"                "Xen kernel arch used for creating Xen kernels" "Xen Kernel"
		)
		retval=$?
		if [[ "$retval" == "0" ]]
		then
			if [[ $COMMAND == "CUSTOM" ]]
			then
				COMMAND=$("${dialog[@]}" --nocancel --inputbox "Which Architecture do you want to build?\nYou can enter any valid architecture.\nExamples:\n$i386\nppc\nx86_64\nsparc\nsparc64" 0 0 ${KERNEL_ARCH})
			elif [[ $COMMAND == "DEFAULT" ]]
			then
				COMMAND="$DEFAULT"
			fi
			kernel_arch=$COMMAND
			break
		else
			break
		fi
	done
}

# change the O option for the kernel
# doesn't work with some patched kernels
build_dir_menu()
{
	output_dir=$( "${dialog[@]}" --nocancel --inputbox \
	"Would you like to select a kernel output dir.\n\
	Leave it blank for no output dir\n" 0 0 ${output_dir} )
	retval="$?"
	echo $retval
	if [[ "$retval" == "0" && "$output_dir" != "" ]]
	then
		OPTIONAL_BUILD_DIR=$output_dir
		persistent_add OPTIONAL_BUILD_DIR
		echo "first ifstatment"
	elif [[ "$retval" == "0" && "$output_dir" == "" ]]
	then
		persistent_remove OPTIONAL_BUILD_DIR
		echo "second ifstatment"
	else
		echo "Do nothing"
	fi
}

# restore a config file from a different location
restore_config()
{
	. ${SPELL_DIRECTORY}/DETAILS
	while true
	do
		CONFIG_RESTORE=$( "${dialog[@]}" --title "Config Restore" \
			--item-help --menu \
			"Restore Config From:" 0 0 0 \
			"/proc/config.gz" "Restore" "Save /proc/config.gz your kernel tree" \
			"/boot/config-$VERSION" "Restore" "Save /boot/config-$VERSION to your kernel tree" \
			"Custom" "Restore" "Save custom config file to your kernel tree" \
			)
		retval="$?"
		if [ "$retval" == "0" ]
		then
			persistent_add CONFIG_RESTORE
			case "${CONFIG_RESTORE}" in
				"Custom")
					CONFIG_RESTORE=$( "${dialog[@]}" --title "Config Restore" \
						--nocancel --inputbox \
						"Enter Custom File to Save to /usr/src/linux/.config" \
						0 0 ${CONFIG_RESTORE} )
					;;
					*)
					;;
			esac
			break
		else
			break
		fi
	done
}

# other misc options menu
options_menu()
{
	while true
	do
		menu_option=$( "${dialog[@]}" --title "Options Menu" \
			--item-help --menu \
			"Options Menu Yeah Fun" 0 0 0 \
			"Clean" "Options" "Clean the Source Tree" \
			"Arch" "Selection" "Select Arch Default is $ARCH" \
			"Config" "Restoration" "Optional config restoration" \
			"Other" "Packages" "Make an RPM or Debian Package" \
			"Make" "Options" "Options passed to make for compiling" 
			)
		retval="`echo $?`"
		if [[ "$retval" == "0" ]]
		then
			case "${menu_option}" in
				"Clean")
					clean_menu
					;;
				"Arch")
					arch_menu
					;;
				"Other")
					other_package_menu
					;;
				"Config")
					restore_config
					;;
				"Make")
					EXTRA_MAKE_OPTIONS=$("${dialog[@]}" --inputbox "These Options are passed to make when compiling your kernel\nFor Example\nV=1 will change the 2.6 output to look more like the 2.4 output\nEXTRA_CFLAGS=$CFLAGS will add sorcery cflags to your kernel" 0 0 "")
					persistent_add EXTRA_MAKE_OPTIONS
					;;
				*) break ;;
			esac
		else
			break
		fi
	done
}

custom_kernel()
{
	. $latestdefaults
	command=$("${dialog[@]}" --inputbox "Enter the kernel version for the source you want to build?\nExamples:\n2.4.31\n2.6.13.4-selinux1\n${LATEST_2_6}" 0 0 "")
	retval=$?
	echo $command
	if [[ "$?" == "0" ]] 
	then
		kver=$command
		old_src_tree="/usr/src/linux-${kver}"
		persistent_add old_src_tree
		reconf="true"
		persistent_remove MAKEMODE
		persistent_remove UPDATE_BL
		persistent_remove CONFIG_KERNEL
		selected_patches=""
		patches=""
	fi
}

# create a new linux source tree
# I use awk to parse the latest.defaults file
# that should be changed but how?
new_tree_menu() 
{
	while true
	do
		menu=""
		versions="`ls -r1 $kernelsdir`"
		for version in $versions
		do
			menu="${menu}${version} Linux_Kernel Select_one "
		done
		menu="$( awk -F= '$1 ~ /LATEST_2/ {print $1 " Linux_Kernel " $2 }' $latestdefaults ) ${menu}"
		command=$( "${dialog[@]}" --title "Select Kernel Version" \
		--item-help --cancel-label "Exit" --default-item "$kver" --menu \
		"Select a kernel version to use" 0 0 0 \
		$menu )
		retval="$?"
		if [ "$retval" == "0" ]
		then
			case "$command" in
				2.[0-9].[0-9]*) 
					kver=$command
					patch_menu $kver
					;;
				LATEST*)
					kver=$command
					patch_menu $kver
					;;
				CUSTOM*)
					custom_kernel
					;;
				*) 
					break 
					;;
			esac
		else
			break
		fi
	done
}

# find all patches list the directories and LATEST patches for the kernel version $1
patch_list()
{
	local tmp
	local found
	local patchvers
	local patchver
	local patches
	local patch
	. $latestdefaults
	patches="`ls -1 $patchesdir/`"
	for patch in $patches
	do
		tmp="LATEST_$patch"
		if [ "${!tmp}" != "" ]
		then
			source_patch ${tmp}
			for applied in $appliedkernels
			do
				if [[ $applied == $1  || $applied == ${!1} ]]
				then
					echo LATEST_$patch
					echo ${!tmp}
#					echo $patch
				fi
			done
		fi
		patchvers="`ls -1r $patchesdir/${patch}`"
		found="false"
		for patchver in $patchvers
		do
			source_patch $patchver
			for applied in $appliedkernels
			do
				if [[ $applied == $1 || $applied == ${!1} ]]
				then
					found="true"
				fi
			done
		done
		if [ "$found" == "true" ]
		then
			echo $patch
			echo '"Patch Sub Menu"'
		fi
	done
}

# list all patches for kernel version $1 and for patch $2
list_specific_patch_dir()
{
	. $latestdefaults
	patchvers="`ls -1r $patchesdir/$2`"
	for patchver in $patchvers
	do
		source_patch $patchver
		for applied in $appliedkernels
		do
			if [[ $applied == $1 || $applied == ${!1} ]]
			then
				echo $patchver
				echo PATCH
				echo $2
			fi
		done
	done
}

# main patch menu called from main_menu
# list directories and valid latest patches
# that apply to the kernel version $1
patch_menu() 
{
#	new_patch_list=$selected_patches
	new_patch_list=""
	while true
	do
		menu=$(patch_list $1)
		if [ "$menu" == "" ]
		then
			menu='"No Patches Available Sorry"'
		fi
		eval 'command=$( "${dialog[@]}" --title "Select Patches" \
			--help-button --cancel-label "Commit" \
			--ok-label "Toggle" --menu \
			"Currently selected kernel: $1\nCurrently selected patches: $new_patch_list" 0 0 0 '${menu}' )'
		retval="$?"
		if [[ "$retval" == "0" && "$command" != "No_Patches" ]]
		then
			case "$command" in
				LATEST*)
					;;
				*)
					. $patchesdir/$command/.info	
					command=$( "${dialog[@]}" --title "Select Patches" \
						--item-help --cancel-label "Commit" \
						--ok-label "Toggle" --menu \
						"$help\n\nCurrently seleted kernel: $1\nCurrently selected patches: $new_patch_list" 0 0 0 \
						$(list_specific_patch_dir $1 $command) )
					;;
			esac
			found=false
			tmp_patch_list=""
			for patch in $new_patch_list
			do
				if [ "$command" != "$patch" ]
				then
					tmp_patch_list="${tmp_patch_list}${patch} "
				else
					found="true"
				fi
					
			done
			if [ "$found" == "true" ]
			then
				new_patch_list=$tmp_patch_list
			else
				new_patch_list="${new_patch_list}${command} "
			fi
		elif [[ "$retval" == "2" && "${command}" != "No_Patches" ]]
		then
			if [[ "LATEST_${command/HELP LATEST_/}" == "${command/HELP /}" ]]
			then
				tmp=${command/HELP /}
				. $latestdefaults 
				source_info ${tmp}
				"${dialog[@]}" --msgbox "Selecting this will keep the kernel tree updated.\n$help" 0 0
			else
				tmp=${command/HELP /}
				. $patchesdir/${command/HELP /}/.info
				"${dialog[@]}" --msgbox "$help" 0 0
			fi
		else
			selected_patches=$new_patch_list
			break
		fi
	done
}

# list the old source menu to reconfigure an old source tree
old_src_menu()
{
	while true
	do
		eval 'old_src_tree=$( "${dialog[@]}" --title "Select Old Source Tree" \
				--item-help \
				--default-item "$BUILD_DIRECTORY/$old_src_tree"\
				--menu \
				"Select Old Source Tree\nSome source trees may \
need updating" \
				0 0 0 '`list_usr_src`' )'
		retval="$?"
		if [[ "$retval" == "0" && "$old_src_tree" != "No" ]]
		then
			if [[ "${old_src_tree}" == "${BUILD_DIRECTORY}/linux" && -L "${old_src_tree}" ]]
			then
				old_src_tree="`readlink -f ${old_src_tree}`"
			fi
			if [[ "${old_src_tree}" != "${BUILD_DIRECTORY}/linux-`get_usr_src_kver ${old_src_tree}/.spell-config.p`" ]]
			then
				if dialog --yesno "${old_src_tree} will be updated to `get_usr_src_kver ${old_src_tree}/.spell-config.p`.\nDo you want to continue?" 0 0
				then
					load_old_src_tree

					break
				fi
			else
				load_old_src_tree

				break
			fi
		else
			break
		fi
	done
}

load_old_src_tree()
{
	local tmp
	cp ${old_src_tree}/.spell-config.p ${SPELL_CONFIG}.p
	tmp=$old_src_tree
	persistent_load
	persistent_add old_src_tree
	if [[ $mode != "expert" ]]
	then
		mode="oldktree"
	fi
	old_src_tree=$tmp
	reconf="true"
	persistent_remove MAKEMODE
	persistent_remove UPDATE_BL
	persistent_remove CONFIG_KERNEL
	persistent_save
	persistent_load
}

# if any of the patches needs any other patches applied before it is
# for example the mm patches apply against the pre patched kernel
calculate_depends()
{
	# create Makefile
	dependslist=""
	new_patches_list=""
	all_patches_list=""
	. $latestdefaults
	if [[ "$selected_patches" != "" ]]
	then
		# check for post patches and add those to the new_patches_list
		for patch in $selected_patches
		do
			source_patch ${patch}
			if [ "$post_patch" != "" ]
			then
				new_patches_list="${new_patches_list}${patch} ${post_patch} "
				case "${patch}" in
					LATEST*)
						all_patches_list="${all_patches_list}${!patch} ${post_patch} "
					;;
					*)
						all_patches_list="${all_patches_list}${patch} ${post_patch} "
					;;
				esac
			else
				new_patches_list="${new_patches_list}${patch} "
				case "${patch}" in
					LATEST*)
						all_patches_list="${all_patches_list}${!patch} "
					;;
					*)
						all_patches_list="${all_patches_list}${patch} "
					;;
				esac
			fi
		done
		rm $dependsmakefile
		(
		makefile_targets="all "
		echo "all: $all_patches_list"
		echo ""
		for i in $new_patches_list
		do
			rec_dep_make $i
		done
		echo ".PHONY : ${makefile_targets}"
		) > $dependsmakefile
		# this doesn't work with persistent vars don't know why?
		patches=$(make -sf $dependsmakefile all)
		echo $patches
	fi
}

rec_dep_make()
{
	depends=""
	case "$1" in
		LATEST*)
			source_patch ${1}
			if [[ "${depends}" == "" ]] 
			then
				makefile_targets="${makefile_targets} ${!1} "
				echo "${!1}:"
				echo "	@echo -n \"${1} \""
				echo ""
			else
				makefile_targets="${makefile_targets} ${!1} ${depends} "
				echo "${!1}: ${depends}"
				echo "	@echo -n \"${1} \""
				echo ""
				rec_dep_make ${depends}
			fi	
		;;
		*)
			source_patch ${1}
			if [[ "${depends}" == "" ]] 
			then
				makefile_targets="${makefile_targets} ${1} "
				echo "${1}:"
				echo "	@echo -n \"${1} \""
				echo ""
			else
				makefile_targets="${makefile_targets} ${1} ${depends} "
				echo "${1}: ${depends}"
				echo "	@echo -n \"${1} \""
				echo ""
				rec_dep_make ${depends}
			fi
		;;
	esac
}

# created details.defaults file to be sourced by DETAILS file for VERSION SOURCE_URL SOURCE
# stuff like that
create_details()
{
	. $latestdefaults
	local counter="3"
	local patches 
	local basekver 
	local source_gpg
	local source_gpg_list 
	local source_gpg_list_url
	local gpg_source_url
	local version_append_list
	local depends
	local patch
	local md5sum
	local sha1sum
	local patch_det_version="false"
	case "$mode" in
		*ktree)
			patches=""
			basekver=""
			source_gpg_list=""
			source_gpg_list_url=""
			
			calculate_depends
			(
			depends=""
			echo 'TXTMESSAGE=""'
			
			# deal with the basic sources for the patches
			# involes the main source for each patch and figuring
			# out the base kernel version to use
			for patch in $patches
			do
				source=""
				source_url=""
				source_gpg=""
				gpg_source_url=""
				md5sum=""
				sha1sum=""
				appliedkernels=""
				patchversion=""
				appendversion=""
				source_patch $patch
				case "$patch" in
					LATEST*)
						echo "PATCH[${counter}]=\$${patch}"
						;;
					*)
						echo "PATCH[${counter}]=${patch}"
						;;
				esac
				echo -n '. ${SPELL_DIRECTORY}/info/patches/*/${PATCH['
				echo -n $counter
				echo ']}'
				echo "SOURCE${counter}=\$source"
				echo "SOURCE${counter}_URL=\$source_url"
				echo 'TXTMESSAGE="${TXTMESSAGE}${txtmessage} "'
				echo 'SHORT="${SHORT}${short} "'
				if [[ "" != "$patchversion" ]]
				then
					basekver="$appliedkernels"
					echo 'KERNEL_VERSION=${patchversion}'
					patchversion=""
					patch_det_version="true"
				fi
				if [[ "$appendversion" != "" ]]
				then
					version_append_list="${version_append_list}${patch}:${counter} "
					patch_det_version="true"
				fi
				if [[ "$source_gpg" != "" ]] 
				then
					echo "SOURCE${counter}_GPG=\$source_gpg"
					if [[ "$gpg_source_url" != "" ]]
					then
						source_gpg_list_url="${source_gpg_list_url}${patch}:${counter} "
					fi
				elif [[ "$sha1sum" != "" ]]
				then
					echo "SOURCE${counter}_HASH=\"sha1:\$sha1sum\""
				elif [[ "$md5sum" != "" ]]
				then
					echo "SOURCE${counter}_HASH=\"md5:\$md5sum\""
				else
					echo "SOURCE${counter}_IGNORE=UNVERIFIED"
				fi
				(( counter++ ))
			done
			# deal with the version appending
			for patch in $version_append_list
			do
				echo -n '. ${SPELL_DIRECTORY}/info/patches/*/${PATCH['
				echo -n ${patch/*:}
				echo ']}'
				echo 'KERNEL_VERSION=${KERNEL_VERSION}${appendversion}'
			done
			# deal with the signatures for each patch if there is
			# any
			for patch in $source_gpg_list_url 
			do
				source_gpg=""
				gpg_source_url=""
				source_patch ${patch/:*}
				case "${patch/:*}" in
					LATEST*)
						tmp=${patch/:*}
						;;
					*)
						;;
				esac &&
				echo -n '. ${SPELL_DIRECTORY}/info/patches/*/${PATCH['
				echo -n ${patch/*:}
				echo ']}'
				echo "SOURCE${counter}=\$(echo \$source_gpg | cut -d: -f2)"
				echo "SOURCE${counter}_URL=\$gpg_source_url"
				echo "SOURCE${counter}_IGNORE=signature"
				(( counter++ ))
			done
			if [[ "$basekver" != "" ]]
			then
				kver="$basekver"
			fi
                        case "$kver" in
				2.[0-9]*)
					. $kernelsdir/${kver}
					echo ". \${SPELL_DIRECTORY}/info/kernels/${kver}"
					echo "SOURCE=\$source"
					echo "SOURCE_URL=\$source_url"
					echo "SOURCE2=\${source}.sign"
					echo "SOURCE_GPG=kernel.gpg:\${SOURCE2}:ESTABLISHED_UPSTREAM_KEY"
					echo "SOURCE2_URL=\${source_url}.sign"
					;;
				*)
					. $kernelsdir/${!kver}
					echo ". \${SPELL_DIRECTORY}/info/kernels/\$$kver"
					echo "SOURCE=\$source"
					echo "SOURCE_URL=\$source_url"
					echo "SOURCE2=\${source}.sign"
					echo "SOURCE_GPG=kernel.gpg:\${SOURCE2}:ESTABLISHED_UPSTREAM_KEY"
					echo "SOURCE2_URL=\${source_url}.sign"
					;;
			esac
			# if there are no patches then KERNEL_VERSION isn't put in the details.defaults file so
			# you have to check to make sure KERNEL_VERSION is in the file and used
			if [[ "$patch_det_version" == "false" ]]
			then
				echo 'KERNEL_VERSION=${version}'
			fi
			) > $detailsdefaults
			;;
		expert)
			# shouldn't have any source information when expert
			# is being used
			echo "KERNEL_VERSION=$kver" > $detailsdefaults
			;;
		*)
			echo "I don't know what the hell is $mode"
			;;
	esac
}

# Start of the execution

# if it's not there create it
create_defaults

if [[ "$reconf" == "true" || "$kver" == "" ]]
then
	main_menu
	if [ "$kver" == "" ]
	then
		echo "You really need to tell the spell what linux kernel you are dealing with."
		sleep 5
	fi
	while [ "$kver" == "" ]
	do
		main_menu
		if [ "$kver" == "" ]
		then
			echo "You really need to tell the spell what linux kernel you are dealing with."
			sleep 5
		fi	
	done
else
	echo "No Reconfigure, using ${SPELL_CONFIG}.p for defaults"
fi
create_details
