-- lib/menu.lua
-- $Id: menu.lua,v 1.2 2005/01/25 05:07:06 cpressey Exp $

-- BEGIN lib/menu.lua --

--[[------]]--
--[[ Menu ]]--
--[[------]]--

-- Global "class" variable:
Menu = {}

-- Global (and public) symbolic constants:
Menu.CONTINUE = {}
Menu.DONE = {}

-- Global (but private) state variables in the class:
local menu_stack = {}	-- stack of the most recently displayed menus
local next_id = 0	-- next unique id to create

-- Create a new menu object instance.
Menu.new = function(opt)
	local menu = {}
	local actions = {}
	local menu_id

	-- Create a new unique identifier.
	local new_id = function()
		next_id = next_id + 1
		return tostring(next_id)
	end

	menu_id = "menu_form_" .. new_id()

	menu.add_item = function(menu, i_opt)
		table.insert(actions, {
			id = "menu_action_" .. new_id(),
			name = i_opt.name,
			short_desc = i_opt.short_desc,
			long_desc = i_opt.long_desc,
			effect = i_opt.effect
		})
	end

	menu.get_name = function(menu)
		return opt.name
	end

	--
	-- Populate this menu with items derived from the Lua script files
	-- in the given directory.  Each script should end with a return
	-- statement that returns a table describing the menu item.
	--
	menu.from_dir = function(menu, dir)
		local i, filename, filenames
	
		filenames = FileSystem.dir(dir)
		table.sort(filenames)
	
		for i, filename in filenames do
			local full_file = dir .. "/" .. filename
	
			if filename ~= FileSystem.basename(CURRENT_SCRIPT) and
			   not FileSystem.is_dir(full_file) and
			   string.find(filename, "^[^%.].*%.lua$") then
				local tab = App.run_script(full_file)
				if tab then
					menu:add_item(tab)
				end
			end
		end

		if opt.exit_item then
			menu:add_item(opt.exit_item)
		else
			local exit_item_name = "Exit"

			if table.getn(menu_stack) > 0 then
				exit_item_name = "Return to " ..
				    menu_stack[table.getn(menu_stack)]:get_name()
			end
			menu:add_item({ name = exit_item_name, effect = function()
				return Menu.DONE
			end})
		end

		return menu
	end

	--
	-- Present this menu to the user.
	--
	menu.present = function(menu)
		table.insert(menu_stack, menu)
		local response = App.c:present({
			id = menu_id,
			name = opt.name,
			short_desc = opt.short_desc,
			long_desc = opt.long_desc,
			role = "menu",
			actions = actions
		})
		table.remove(menu_stack)
		return response
	end

	menu.loop = function(menu)
		local result = Menu.CONTINUE
	
		while result == Menu.CONTINUE do
			result = menu:present().result
			if opt.continue_constraint then
				result = opt.continue_constraint(result)
			end
		end
	end

	return menu
end

-- Create a new menu object instance automatically from
-- the Lua script files in the same directory as the Lua
-- script file that invoked this function.
Menu.auto = function(c, opt)
	local menu = Menu.new(opt)

	menu:from_dir(FileSystem.dirname(CURRENT_SCRIPT) .. "/")
	menu:loop()
end

-- END of lib/menu.lua --
