/**
 * File:
 *      include/bootloader/grub/widgets.ycp
 *
 * Module:
 *      Bootloader installation and configuration
 *
 * Summary:
 *      Widgets specific for GRUB bootloader
 *
 * Authors:
 *      Jiri Srain <jsrain@suse.cz>
 *
 * $Id: widgets.ycp 22285 2005-03-04 11:21:56Z jsrain $
 *
 */


{

    import "BootCommon";
    import "Label";
    include "bootloader/routines/popups.ycp";
    include "bootloader/grub/helps.ycp";
    include "bootloader/routines/routines.ycp";

    textdomain "bootloader";

    import "Popup";
    import "Mode";
    import "TablePopup";

    global define list<string> getDisksOrder ();
    global define void storeOrderPopup (any opt_id, string opt_key);

    /**
      * Ask how to chang section floppy <-> hard disk when changing bootloader
      * location between disk and floppy
      * @param to string new bootloader location ("floppy" or "hard disk")
      * @return boolean true if user wants to change the section
      */
    global define boolean changeSection (string to) ``{
	string message = "";
	if (to == "floppy")
		// yes-no popup
	    message = _("You chose to install the boot loader to the floppy.
The menu of the boot loader contains an entry to boot from the floppy.
Replace it with an entry to boot from the hard disk?");
	else
		// yes-no popup
	    message = _("You chose to install the boot loader to the hard disk.
The menu of the boot loader contains an entry to boot from the hard disk.
Replace it with an entry  to boot from the floppy?");
	return Popup::YesNo (message);
    }

    /**
      * Store function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void targetStore (any opt_id, string opt_key) ``{
	BootCommon::targetStore (opt_id, opt_key);
	list<list<map> > sections = BootCommon::current_sections;
	if (issubstring (BootCommon::loader_device, "/dev/fd")||
	    BootCommon::installingToFloppy ())
	{
	    sections = maplist (list<map> s, sections, ``{
		if ((getCreationType (s) == "floppy"
			|| lookup_value (s, "root", "") == "(fd0)")
		    && changeSection ("floppy"))
		{
		    s = [
			$[ "key" : "title", "value" : BootCommon::translateSectionTitle ("hard disk")],
			$[ "key" : "root", "value" : "(hd0)"],
			$[ "key" : "chainloader", "value"  : "+1"],
	                $[ "key" : "__intern__", "value" : $[
		            "changed" : false,
		            "auto" : true,
		            "devs" : [],
			    "type" : "hard_disk",
		        ]],
		    ];
		}
		return s;
	    });
	}
	else
	{
	    sections = maplist (list<map> s, sections, ``{
		if ((getCreationType (s) == "hard_disk"
			    || lookup_value (s, "root", "") == "(hd0)")
			&& changeSection ("disk"))
		{
		    s = [
			$[ "key" : "title", "value" : BootCommon::translateSectionTitle ("floppy")],
			$[ "key" : "root", "value" : "(fd0)"],
			$[ "key" : "chainloader", "value" : "+1"],
                        $[ "key" : "__intern__", "value" : $[
                            "changed" : false,
                            "auto" : true,
                            "devs" : [],
			    "type" : "floppy",
                        ]],
		    ];
		}
		return s;
	    });
	}
	disks_order = getDisksOrder ();
	if (BootCommon::IsMbr (BootCommon::loader_device)
	    && disks_order[0]:"" != BootCommon::loader_device)
	{
	    if (Popup::YesNo (sformat (
// yes-no popup, %1 is device name (eg. /dev/hda)
_("You selected the master boot record of %1. According to the
current configuration, %1 is not meant to be the boot disk
of your machine.
If your machine is configured to boot from %1, the order
of the disks in the configuration of the boot loader should
be adapted.
Adapt it?
"), BootCommon::loader_device)))
	    {
		disks_order = filter (string o, disks_order, {
		    return o != BootCommon::loader_device;
		});
		disks_order = prepend (disks_order, BootCommon::loader_device);
		storeOrderPopup (nil, opt_key);
	    }
	}
	BootCommon::current_sections = sections;
	BootCommon::embed_stage15 = allowEmbed15 ();
    }

    /**
      * Get map of Target widget
      * @return map of Target widget
      */
    global define map<string,any> getTargetWidget () ``{
	map<string,any> ret = BootCommon::getTargetOption ();
	ret["popup", "store"] = BootGRUB::targetStore;
	return ret;
    }

    /**
      * Create a list of options for the table
      * @param descr map description of the table
      * @return list of option ids as it should be displayed
      */
    global define list getTableContents (map descr) ``{
	list<string> prependlist = [];
	list<string> forbidden_keys = [];
	any type = BootCommon::getSectionType (BootCommon::current_section);
	if (type == `global)
	{
	    prependlist = ["__loader_type", "__sep2", "__location",
		"__diskorder", "default", "__sections", "__activate",
		"__repl_mbr", "__embed_15", "__backup_mbr", "__add_orig_mbr",
		"__save_method", "__sep1"];
	    forbidden_keys = ["default"];
	    if (! allowEmbed15 ())
	    {
		prependlist = filter (string i, prependlist, {
		    return i != "__embed_15";
		});
	    }
	}
	else
	{
	    prependlist = ["title", "__section_type", "__sep1"];
	}
	return BootCommon::createSectionItemsList (
	    prependlist, forbidden_keys, false);
    }

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getGlobalSectionWidget () ``{
	return (map<string,any>)TablePopup::CreateTableDescr (
	    $[
		"add_delete_buttons" : true,
		"up_down_buttons" : false,
		"changed_column" : true,
		"unique_keys" : true,
	    ],
	    $[
		"init" : BootCommon::globalSectionInit,
		"handle" : BootCommon::globalSectionHandle,
		"store" : BootCommon::globalSectionStore,
		"options": BootCommon::cwm_options,
		"id2key": BootCommon::id2key,
		"ids": BootGRUB::getTableContents,
                "help": BootCommon::getGlobalSectionHelp (),
                "fallback" : $[
		    "init": BootCommon::commonPopupInit,
		    "store": BootCommon::commonPopupStore,
		    "summary": BootCommon::commonTableEntrySummary,
		    "changed" : BootCommon::commonTableChanged,
                ],
		"option_move" : BootCommon::moveTableItem,
		"option_delete": BootCommon::commonTableEntryDelete,
                "add_items":  GetOptions ()[`global]:[],
	    ]
	);
    }

    /**
      * Redraw table of sections
      * @param sects list of sections
      */
    global define void sectionsRedrawTable (list<list<map> > sects) ``{
	y2milestone ("Redrawing list of GRUB's sections");
	integer order = -1;
	list sec = maplist (list<map> s, sects, ``{
	    order = order + 1;
	    string other_dev
		= (string)lookup_value (s, "root",
		    (string)lookup_value (s,
			"rootnoverify", ""));
	    string kernel_img
		= (string)lookup_value (s, "kernel", "");
	    kernel_img = filter (string p, splitstring (kernel_img, " "),
		{
		    return p != "";
		})[0]:"";
	    string root = BootCommon::getKernelParamFromLine
		((string)lookup_value (s, "kernel", ""),
		    "root");
	    if (root != "" && root != "false")
		root = sformat (", root=%1", root);
	    else
		root = "";
	    if (substring (kernel_img, 0, 1) != "(")
		kernel_img = other_dev + kernel_img;
	    return `item (`id (lookup_value (s,
		    "title", "")),
		lookup_value (
			BootCommon::current_globals, "default", 0)
		== order
		    ? UI::Glyph (`CheckMark) : "",
		lookup_value (s, "title", ""),
		lookup_value (s, "kernel", nil)
			// table cell
		    == nil ? _("other")
			// table cell
		    : _("image"),
		lookup_value (s, "kernel", "")
		    != ""
		? sformat ("%1   (%2%3)",
		    kernel_img,
		    BootGRUB::grubDev2unixDev ((string)
			BootGRUB::splitDevPath (kernel_img)[0]:""
		    ),
		    root
		)
		: sformat ("%1   (%2)", other_dev,
		    BootGRUB::grubDev2unixDev (other_dev))
	    );

	});
	UI::ChangeWidget (`id (`sects), `Items, sec);
    }

    /**
      * Assign default section
      * @param title string title of section to become default
      */
    global define void sectionsAssignDefault (string title) ``{
	integer index = 0;
	integer counter = 0;
	foreach (list<map> s, BootCommon::current_sections, ``{
	    if ((string)lookup_value (s, "title", "")
		== title)
	    {
		index = counter;
	    }
	    counter = counter + 1;
	});
	BootCommon::addValueToBootloaderSection (
	    `current_globals, "default", index);
    }

    /**
      * Init function of widget
      * @param widget_id any id of the widget
      */
    global define void sectionsInit (string widget_id) ``{
	sectionsRedrawTable (BootCommon::current_sections);
	UI::SetFocus (`id (`sects));
    }

    /**
      * Handle function of a widget
      * @param widget_id any widget key
      * @param event map event description of event that occured
      * @return symbol to return to wizard sequencer, or nil
      */
    global define symbol sectionsHandle (string widget_id, map event) ``{
	any op = event["ID"]:nil;
	if (event["ID"]:nil == `sects
	    && event["EventReason"]:"" == "Activated"
	    && event["EventType"]:"" == "WidgetEvent")
	{
	    op = `edit;
	}
        string current = (string)UI::QueryWidget (`id (`sects), `CurrentItem);
        integer counter = 0;
        integer index = 0;
	integer default = (integer)lookup_value (
	    BootCommon::current_globals, "default", 0);
	string default_title
	    = (string)lookup_value (
		BootCommon::current_sections[default]:[], "title", "");
        foreach (list<map> s, BootCommon::current_sections, ``{
            if (lookup_value (s, "title", "")
		== current)
	    {
                index = counter;
	    }
            counter = counter + 1;
        });
        list<list<map> > sects = BootCommon::current_sections;
        if (op == `up)
        {
            if (index > 0)
            {
                sects = (list<list<map> >)BootCommon::swapItems(sects, index, index - 1);
                index = index - 1;
                BootCommon::current_sections = sects;
		sectionsAssignDefault (default_title);
                sectionsRedrawTable (sects);
                UI::ChangeWidget (`id (`sects), `CurrentItem,
                    lookup_value (
			sects[index]:[], "title", 0));
		BootCommon::sections_changed = true;
            }
        }
        else if (op == `down)
        {
            if (index < (size(sects) - 1))
            {
                sects = (list<list<map> >)BootCommon::swapItems(sects, index, index + 1);
                index = index + 1;
                BootCommon::current_sections = sects;
		sectionsAssignDefault (default_title);
                sectionsRedrawTable (sects);
                UI::ChangeWidget (`id (`sects), `CurrentItem,
                    lookup_value (sects[index]:[],
			"title", 0));
		BootCommon::sections_changed = true;
            }
        }
	else if (op == `default)
	{
	    BootCommon::addValueToBootloaderSection (
		`current_globals, "default", index);
	    sectionsRedrawTable (sects);
	    UI::ChangeWidget (`id (`sects), `CurrentItem,
		lookup_value (sects[index]:[],
		"title", 0));
	    BootCommon::sections_changed = true;
	}
	else if (op == `add)
	{
	    list<map> selected = sects[index]:[];
	    string name = (string)lookup_value (selected,
		BootCommon::getSectionTitle (), "");
	    if (askClone (name))
	    {
		selected = modifySection (
		    (list<map>)eval (selected),
		    BootCommon::getSectionTitle (),
		    BootCommon::getFreeSectionLabel ());
		BootCommon::current_section = selected;
	    }
	    else
	    {
		BootCommon::current_section = BootCommon::convertSection
		    (nil, "image", nil);
	    }
            BootCommon::current_section_name = "";
	    BootCommon::one_section_changed = true;
	    return `add;
	}
	else if (op == `edit)
	{
            y2milestone ("Editing title %1, index %2", current, index);
            BootCommon::current_section = (list<map>)eval (sects[index]:[]);
            BootCommon::current_section_name
                = lookup_value (sects[index]:[], "title", "");
	    BootCommon::one_section_changed = false;
	    return `edit;
	}
	else if (op == `delete && confirmSectionDeletePopup (current))
	{
	    map del_intern = (map)
		lookup_value (sects[index]:[], "__intern__", $[]);
	    if (del_intern["type"]:"" == "memtest86")
	    {
		BootCommon::memtest_removed = true;
	    }
	    if (del_intern["type"]:"" == "xen")
	    {
		xen_removed = true;
	    }
	    sects = remove (sects, index);
	    BootCommon::current_sections = sects;
	    if (size (sects) <= lookup_value (
		BootCommon::current_globals, "default", 0))
	    {
		BootCommon::addValueToBootloaderSection (`current_globals,
		    "default", 0);
	    }
	    sectionsRedrawTable (sects);
	    BootCommon::sections_changed = true;
	}
	UI::SetFocus (`id (`sects));
	return nil;
    }

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getSectionsWidget () ``{
	map<string,any> ret = BootCommon::getSectionsWidget ();
	ret["init"] = BootGRUB::sectionsInit;
	ret["handle"] = BootGRUB::sectionsHandle;
	return ret;
    }

// grub-specific dialogs

    /**
      * get current order of disks from device map
      * @return a list of disks as string
      */
    global define list<string> getDisksOrder () ``{
        list<list<string> > dl = filter (list<string> i, device_map,
            ``(substring (i[0]:"", 0, 3) == "(hd"));
        dl = sort (list<string> a, list<string> b, dl, {
	    integer i1 = tointeger (
		regexpsub (a[0]:"", "\\(hd(.*)\\)", "\\1"));
	    integer i2 = tointeger (
		regexpsub (b[0]:"", "\\(hd(.*)\\)", "\\1"));
	    return i1 < i2;
	});
        return maplist (list<string> i, dl, ``{return i[1]:"";});

    }

    /**
      * Summary function of a table entry
      * @param opt_id any option id
      * @param opt_key any option key
      * @return string summary to the table
      */
    global define string orderSummary (any opt_id, string opt_key) ``{
	disks_order = getDisksOrder ();
	return mergestring (disks_order, ", ");
    }

    /**
      * Handle function of widget
      * @param opt_id any option id
      * @param opt_key any option key
      * @param event map event that occured
      */
    global define void handleOrderPopup (any opt_id, string opt_key, map event) ``{
	any op = event["ID"]:nil;
	string active = (string)UI::QueryWidget (`id (`disks), `CurrentItem);
	integer pos = 0;
	while (pos < size (disks_order) && disks_order[pos]:"" != active)
	    pos = pos + 1;
	UI::ChangeWidget (`id (`up), `Enabled, pos > 0);
	UI::ChangeWidget (`id (`down), `Enabled, pos < size (disks_order) - 1);
	    if (op == `up)
	    {
		disks_order = (list<string>)BootCommon::swapItems (disks_order, pos, pos - 1);
		UI::ReplaceWidget (`id (`disks_rp), `SelectionBox(`id (`disks),
		    `opt (`notify, `immediate),
		    _("D&isks"), disks_order));
		UI::ChangeWidget (`id (`disks), `CurrentItem, active);
	    }
	    else if (op == `down)
	    {
		disks_order = (list<string>)BootCommon::swapItems (disks_order, pos, pos + 1);
		UI::ReplaceWidget (`id (`disks_rp), `SelectionBox(`id (`disks),
		    `opt (`notify, `immediate),
		    _("D&isks"), disks_order));
		UI::ChangeWidget (`id (`disks), `CurrentItem, active);
	    }
	    else if (op == `add)
	    {
		term popup = `VBox (`VSpacing (1),
		    // textentry header
		    `TextEntry (`id (`devname), _("&Device")),
		    `VSpacing (1),
		    `HBox (`HStretch (),
			`PushButton (`id (`ok), `opt (`key_F10, `default), Label::OKButton ()),
			`HStretch (),
			`PushButton (`id (`cancel), `opt (`key_F8), Label::CancelButton ()),
			`HStretch ()
		    ),
		    `VSpacing (1)
		);
		UI::OpenDialog (popup);
		symbol pushed = (symbol)UI::UserInput ();
		string new_dev = (string)
		    UI::QueryWidget (`id (`devname), `Value);
		UI::CloseDialog ();
		if (pushed == `ok)
		{
		    disks_order = add (disks_order, new_dev);
		    UI::ReplaceWidget (`id (`disks_rp),
			`SelectionBox(`id (`disks),
			    `opt (`notify, `immediate),
			    _("D&isks"), disks_order));
		}
	    }
	    else if (op == `delete)
	    {
		disks_order = (list<string>)
		    filter (string i, disks_order, ``(i != active));
		UI::ReplaceWidget (`id (`disks_rp), `SelectionBox(`id (`disks),
                    `opt (`notify, `immediate),
                    _("D&isks"), disks_order));
		UI::ChangeWidget (`id (`delete), `Enabled, size (disks_order) > 0);
		UI::ChangeWidget (`id (`disks),`CurrentItem, disks_order[0]:"");
	    }

	UI::SetFocus (`id (`disks));
    }

    /**
      * Init function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void initOrderPopup (any opt_id, string opt_key) ``{
        disks_order = getDisksOrder ();
	UI::ReplaceWidget (`id (`disks_rp), `SelectionBox(`id (`disks),
                    `opt (`notify, `immediate),
                    _("D&isks"), disks_order));
	UI::ChangeWidget (`id (`disks), `CurrentItem, disks_order[0]:"");
	UI::SetFocus (`id (`disks));
	handleOrderPopup (nil, nil, $[]);
    }

    /**
      * Store function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void storeOrderPopup (any opt_id, string opt_key) ``{
            list<list<string> > dl = filter (list<string> i, device_map,
                ``(substring (i[0]:"", 0, 3) == "(hd"));
            dl=sort (list<string> a, list<string> b, dl, ``(a[0]:"" < b[0]:""));

	    map olddiskmap = $[];
	    foreach (list<string> d, dl, ``{
		olddiskmap[d[1]:""] = d[0]:"";
	    });
	    map<string,string> remap = $[];
	    integer pos = 0;
	    list<list<string> > new_map = filter (list<string> i, device_map,
		``(substring (i[0]:"", 0, 3) != "(hd"));
	    foreach (string d, disks_order, ``{
		string gd = sformat ("(hd%1)", pos);
		if (gd != olddiskmap[d]:"")
		{
		    remap[olddiskmap[d]:""] = gd;
		}
		new_map = add (new_map, [gd, d]);
		pos = pos + 1;
	    });
	    remap = (map<string,string>)
		filter (string k, string v, remap, ``(k != "" && v != ""));
	    BootCommon::current_globals
		= BootGRUB::remapDisks (BootCommon::current_globals, remap);
	    BootCommon::sections = maplist (list<map> s, BootCommon::sections, {
		return BootGRUB::remapDisks (s, remap);
	    });
	    BootCommon::current_section = BootGRUB::remapDisks (
		BootCommon::current_section, remap);
	    BootGRUB::device_map = new_map;
	    BootCommon::mbrDisk = disks_order[0]:BootCommon::mbrDisk;
	    BootCommon::loader_device = BootCommon::GetBootloaderDevice ();
	    disks_order = nil;
	    BootCommon::markGeneralOptionChanged ((string)opt_key);
	    BootCommon::location_changed = true;
	    BootCommon::changed = true;
	    BootCommon::redraw_table = true;
    }

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getOrderPopup () ``{
	return $[
	    "table" : $[
		"summary" : BootGRUB::orderSummary,
		// label / table cell
		"label" : _("Disk Order"),
		"optional" : false,
		"help" : getDiskOrderHelp (),
		"unique_key" : true,
	    ],
	    "popup" : $[
		"widget" : `custom,
		"custom_widget" : `HBox (`VBox (
                    `ReplacePoint (`id (`disks_rp),
                        `SelectionBox (`id (`disks),
                            `opt (`notify, `immediate),
			    // selectionn box label
                            _("D&isks"), [])
                    ),
		    `HBox (
			`HStretch (),
			`PushButton (`id (`add), `opt (`key_F3), Label::AddButton ()),
			`PushButton (`id (`delete), `opt(`key_F5), Label::DeleteButton ()),
			`HStretch ()
		    )
                ),
                `HSquash (
                    `VBox (
                        `VStretch (),
                        `PushButton (`id (`up), `opt (`hstretch), _("&Up")),
                        `PushButton (`id (`down), `opt (`hstretch), _("&Down")),
                        `VStretch ()
                    )
                )),
		"init" : BootGRUB::initOrderPopup,
		"handle" : BootGRUB::handleOrderPopup,
		"store" : BootGRUB::storeOrderPopup,
	    ],
	];
    }

// gfx menu option

    /**
      * Store function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void gfxMenuStore (any opt_id, string opt_key) ``{
	BootCommon::commonPopupStore (opt_id, opt_key);
	map intern = (map)lookup_value (BootCommon::current_section,
	    "__intern__", $[]);
	intern["changed"] = true;
	BootCommon::addValueToBootloaderSection (
	    `current_section, "__intern__", intern);
	y2milestone ("Final current section: %1", BootCommon::current_section);
    }

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getGfxMenuWidget () ``{
	return $[
	    "table" : $[
		"delete" : BootCommon::deleteMessage,
		"unique_key" : true,
	    ],
	    "popup" : $[
		"store" : BootGRUB::gfxMenuStore,
	    ],
	];
    }

// single section widget

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getSingleSectionWidget () ``{
	return (map<string,any>)TablePopup::CreateTableDescr (
	    $[
		"add_delete_buttons" : true,
		"up_down_buttons" : true,
		"changed_column" : true,
		"unique_keys" : true,
	    ],
	    $[
		"store" : BootCommon::singleSectionStore,
		"options": BootCommon::cwm_options,
		"id2key": BootCommon::id2key,
		"ids": BootGRUB::getTableContents,
		"help": BootCommon::getSingleSectionHelp (),
		"fallback" : $[
		    "init": BootCommon::commonPopupInit,
		    "store": BootCommon::commonPopupStore,
		    "summary": BootCommon::commonTableEntrySummary,
		    "changed" : BootCommon::commonTableChanged,
		],
		"handle" : BootCommon::singleSectionHandle,
		"option_move" : BootCommon::moveTableItem,
		"option_delete": BootCommon::commonTableEntryDelete,
	    ]
	);
    }

    /**
      * Init function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void addOrigMbrInit (any opt_id, string opt_key) ``{
        UI::ChangeWidget (`id (`value), `Value, insert_saved_mbr);
        UI::SetFocus (`id (`value));
    }

    /**
      * Store function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      */
    global define void addOrigMbrStore (any opt_id, string opt_key) ``{
        insert_saved_mbr = (boolean)UI::QueryWidget (`id (`value), `Value);
	if (insert_saved_mbr)
	{
	    boolean found = false;
	    foreach (list<map> s, BootCommon::sections, ``{
		map intern = (map)lookup_value (s, "__intern__", $[]);
		if (intern["original_mbr"]:false)
		{
		    found = true;
		    y2error ("Found %1", s);
		}
	    });
	    if (! found)
	    {
		BootCommon::current_sections = add (
		    BootCommon::current_sections,
		    createLinuxSection ("original MBR"));
	    }
	}
	else
	{
	    BootCommon::current_sections = filter (list<map> s,
		BootCommon::current_sections,
	    {
		map intern = (map)lookup_value (s, "__intern__", $[]);
		return ! intern["original_mbr"]:false;
	    });
	}
	BootCommon::markGeneralOptionChanged ((string)opt_key);
    }

    /**
      * Summary function of a table entry
      * @param opt_id any option id
      * @param opt_key any option key
      * @return string summary to the table
      */
    global define string addOrigMbrSummary (any opt_id, string opt_key) ``{
        if (insert_saved_mbr)
            // table item / label
            return _("Yes");
        else
            // table item / label
            return _("No");
    }

    /**
      * Get map of widget
      * @return map of widget
      */
    global define map<string,any> getAddOrigMbrWidget () ``{
	return $[
	    "table" : $[
		// table item / label
		"label" : _("Add Saved MBR to Boot Loader Menu"),
		"summary" : BootGRUB::addOrigMbrSummary,
		"optional" : false,
		"ordering" : false,
		"unique_key" : true,
	    ],
	    "popup" : $[
		"init" : BootGRUB::addOrigMbrInit,
		"store" : BootGRUB::addOrigMbrStore,
		"widget" : `checkbox,

	    ],
	];
    }

// password widget

    /**
      * Validate function of a popup
      * @param opt_id any option id
      * @param opt_key any option key
      * @param event map event that caused validation
      * @return boolean true if widget settings ok
      */
    global define boolean validatePasswdWidget (any opt_id, string opt_key,
	map event)
    {
	boolean ret = BootCommon::validatePasswdWidget (opt_id, opt_key, event);
	if (ret && (boolean)UI::QueryWidget (`id (`usepas), `Value))
	{
	    ret = Popup::YesNo (
// yes-no popup
_("If you set the password, the boot dialog is displayed
only in the text mode. Continue?
"));
	}
	return ret;
    }

    global define map<string,any> getPasswdWidget () {
	map<string,any> ret = BootCommon::getPasswdWidget ();
	ret["popup", "validate_function"] = BootGRUB::validatePasswdWidget;
	return ret;
    }

// embed stage 1.5

/**
 * Init function of a popup
 * @param opt_id any option id
 * @param opt_key any option key
 */
global define void embed15Init (any opt_id, string opt_key) ``{
    UI::ChangeWidget (`id (opt_key), `Value, BootCommon::embed_stage15);
    UI::SetFocus (`id (opt_key));
}

/**
 * Store function of a popup
 * @param opt_id any option id
 * @param opt_key any option key
 */
global define void embed15Store (any opt_id, string opt_key) ``{
    BootCommon::embed_stage15
	= (boolean)UI::QueryWidget (`id (opt_key), `Value);
    BootCommon::location_changed = true;
    BootCommon::markGeneralOptionChanged ("__embed_15");
}

/**
 * Summary function of a table entry
 * @param opt_id any option id
 * @param opt_key any option key
 * @return string summary to the table
 */
global define string embed15Summary (any opt_id, string opt_key) ``{
    if (BootCommon::embed_stage15)
	// table item / label
	return _("Yes");
    else
	// table item / label
	return _("No");
}

/**
 * Get map of widget
 * @return map of widget
 */
global define map<string,any> getEmbed15Widget () ``{
    return $[
	"table" : $[
	    // table item / label
	    "label" : _("Use Dedicated Boot Loader Area"),
	    "summary" : embed15Summary,
	    "optional" : false,
	    "ordering" : false,
	    "unique_key" : true,
	],
	"popup" : $[
	    "init" : embed15Init,
	    "store" : embed15Store,
	    "widget" : `checkbox,
	    // label displayed as help
	    "help" : _("Using the dedicated boot loader area prevents
boot loader files from being moved during
automatic disk defragmentation.  The movement could prevent the
boot loader from loading."),
	    // checkbox label
	    "widget_label" : _("Use Dedicated Boot Loader Area"),
	],
    ];
}

    /**
      * Get map of dialogs and widgets
      * @return map of dialogs and widgets
      */
    global define map<string,map<string,any> > GetWidgetMaps () ``{
        return $[
	    "sections" : BootGRUB::getSectionsWidget (),
	    "singlesection" : BootGRUB::getSingleSectionWidget (),
	    "globalsection" : BootGRUB::getGlobalSectionWidget (),
        ];
    }

    /**
      * Get map of dialogs and widgets
      * @return map of dialogs and widgets
      */
    global define map<string,map<string,any> > GetOptionMaps () ``{
        return $[
	    "__location": BootGRUB::getTargetWidget (),
	    "title" : BootCommon::getLabelWidget (),
	    "gfxmenu" : BootGRUB::getGfxMenuWidget (),
	    "__diskorder" : BootGRUB::getOrderPopup (),
	    "__add_orig_mbr" : BootGRUB::getAddOrigMbrWidget (),
	    "password" : BootGRUB::getPasswdWidget (),
	    "__embed_15" : getEmbed15Widget (),
	];
    }

}
