/**
 * File:	include/profile-manager/dialogs.ycp
 * Package:	Configuration of profile-manager
 * Summary:	Dialogs definitions
 * Authors:	Jiri Suchomel <jsuchome@suse.cz>
 *
 * $Id: dialogs.ycp 20797 2005-01-18 13:55:34Z jsuchome $
 */

{

textdomain "profile-manager";

import "ProfileManager";
import "Report";
import "Wizard";

import "Popup";
import "Label";

include "profile-manager/helps.ycp";

/**
 * Profile settings dialog
 * @return any Returned value from UserInput() call
 */
define any ProfileSettingsDialog () ``{

    string edited = ProfileManager::selected_profile;
    string action = ProfileManager::profile_action;
    map profiles = ProfileManager::profiles;

    // reading the profile settings
    ProfileManager::GetProfile();

    map settings = ProfileManager::profile_settings;

    map string2symbol = $[
	"prestart"	: `prestart,
	"poststart"	: `poststart,
	"prestop"	: `prestop,
	"poststop"	: `poststop,
    ];

    // Dialog caption label
    string caption = _("Special profile settings");
    term contents = `HBox(`HSpacing(1.5),
        `VBox(
        `VSpacing(1),
	// frame label
        `Frame(_("Special profile settings"), `HBox(`HSpacing(1),
            `VBox(
                `VSpacing(0.2),
                // Text entry label
                `TextEntry(`id(`name),_("Pro&file Name")),
                `VSpacing(0.2),
                `HBox(
                    `HSpacing(0.5),
                    // Text entry label (profile description)
                    `MultiLineEdit(`id(`desc),_("&Description"),
			settings ["description"]:""),
                    `HSpacing(0.5)
                    ),
                `VSpacing(0.2),
		`HBox(
		    // text entry
		    `TextEntry(`id(`prestart),_("Pr&e Start Script"),
			settings ["prestart"]:""),
		    `VBox(
			`Label (""),
			// button label
			`PushButton(`id("prestart"), _("Bro&wse...")))
		),
                `VSpacing(0.2),
		`HBox(
		    // text entry
                    `TextEntry(`id(`poststart),_("Po&st Start Script"),
			settings ["poststart"]:""),
		    `VBox(
			`Label (""),
			`PushButton(`id("poststart"), _("Bro&wse...")))
		),
                `VSpacing(0.2),
		`HBox(
		    // text entry
		    `TextEntry(`id(`prestop),_("P&re Stop Script"),
			settings ["prestop"]:""),
		    `VBox(
			`Label (""),
			`PushButton(`id("prestop"), _("Bro&wse...")))
		),
                `VSpacing(0.2),
		`HBox(
		    // text entry
		    `TextEntry(`id(`poststop), _("Pos&t Stop Script"),
			settings ["poststop"]:""),
		    `VBox(
			`Label (""),
			`PushButton(`id("poststop"), _("Bro&wse...")))
		),
                `VSpacing(0.2),
                `Left(`CheckBox(`id(`secure_ch),
		    // checkbox label
                    _("Set file &permissions of all scripts secure (0700)."), true)),
                `VSpacing(0.2)
            ),
            `HSpacing(1))),
	    `VSpacing(1)),
        `HSpacing(1.5));

    Wizard::RestoreBackButton ();

    Wizard::SetContentsButtons ( caption, contents, HELPS["profilesettings"]:"",
	Label::CancelButton (), Label::OKButton () );

    if (action == "edit")
        UI::ChangeWidget(`id(`name), `Value, edited);
    else
        UI::SetFocus(`id(`name));

    any ret = nil;
    while (true)
    {
	ret = UI::UserInput ();
	if (is (ret, string))
	{
	    symbol file_s = string2symbol [ret]:`nothing;
	    if (file_s == nil)
		continue;
	    string file = (string) UI::QueryWidget(`id(file_s), `Value);
	    string f = UI::AskForExistingFile ((file != "")? "/":file, "*", "");
	    if (f != nil)
		file = f;
	    UI::ChangeWidget (`id(file_s), `Value, file);
	}
	else if (ret == `back || ret == `cancel)
	{
	    break;
	}
	else if (ret == `next)
	{
	    boolean secure = (boolean) UI::QueryWidget(`id(`secure_ch), `Value);
	    string selected =(string) UI::QueryWidget(`id(`name), `Value);

	    if (!ProfileManager::CheckNameValidity(selected))
	    {
		// Popup text (wrong data):
		Popup::Message(_("Choose valid name."));
		continue;
	    }

	    map new_settings = $[];
	    new_settings["prestart"] = UI::QueryWidget(`id(`prestart), `Value);
	    new_settings["poststart"]= UI::QueryWidget(`id(`poststart), `Value);
	    new_settings["prestop"] = UI::QueryWidget(`id(`prestop), `Value);
	    new_settings["poststop"] = UI::QueryWidget(`id(`poststop), `Value);

	    list files = ProfileManager::CheckFilesValidity(new_settings);
	    if (files != [])
	    {
		// Popup text (file paths are wrong):
		Popup::Error(sformat (_("These are not executable files:

%1"), mergestring ((list<string>) files, "\n")));
		continue;
	    }

	    new_settings ["name"] = selected;
	    new_settings ["description"] = UI::QueryWidget(`id(`desc), `Value);

	    if (action == "new")
	    {
		if (haskey (profiles, selected))
		{
		    // Popup text:
		    Popup::Message(_("A profile with this name already exists."));
		    continue;
		}
		ProfileManager::AddProfile(selected);
		ProfileManager::ProgressPopup("", 0, 100);
		if (!ProfileManager::Wait())
		{
		    // Error popup text, %1 is additional error message
		    Popup::Error(sformat(_("Adding new profile was not successful:
%1
"), ProfileManager::scpm_error));
		    continue;
		}
		else
		{
		    ProfileManager::profiles = add (ProfileManager::profiles,
                        selected, "");

		    if (ProfileManager::auto)
			ProfileManager::active_profile = selected;

		    ProfileManager::profile_settings = new_settings;
		    if (!ProfileManager::SetProfile (selected, new_settings))
		    {
			Popup::Error(sformat(
			    // Error popup text, %1 is additional error message
			    _("Writing profile settings was not successful:
%1
"),
			    ProfileManager::scpm_error));
		    }
		}
	    }
	    else if (action == "copy")
	    {
		if (haskey (profiles, selected))
		{
		    // Popup text
		    Popup::Message(_("A profile with this name already exists."));
		    continue;
		}
		ProfileManager::CopyProfile(edited, selected);
		ProfileManager::ProgressPopup("",0,100);
		if (!ProfileManager::Wait())
		{
		    // Error popup text, %1 is additional error message
		    Popup::Error(sformat(_("Copying profile was not successful:
:%1
"), ProfileManager::scpm_error));
		    continue;
		}
		else
		{
		    ProfileManager::profiles = add (ProfileManager::profiles,
                        selected, "");

		    ProfileManager::profile_settings = new_settings;
		    if (!ProfileManager::SetProfile(selected, new_settings))
		    {
			Popup::Error(sformat(
			    // Error popup text, %1 is additional error message
			    _("Writing profile settings was not successful:
%1
"),
			    ProfileManager::scpm_error));
		    }
		}
	    }
	    else if (action == "edit")
	    {
		if (selected != edited)
		{

		    if (haskey (profiles, selected))
		    {
			// Popup text
			Popup::Message(_("A profile with this name already exists."));
			continue;
		    }
		    if (!ProfileManager::RenameProfile(edited, selected))
		    {
			// Error popup text, %1 is additional error text
			Popup::Error(sformat(_("Renaming profile was not successful:
%1
"),
			    ProfileManager::scpm_error));
			continue;
		    }
		}
		if (ProfileManager::ModifiedSettings(new_settings))
		{
		    ProfileManager::profile_settings = new_settings;
		    if (!ProfileManager::SetProfile (selected, new_settings))
		    {
			// Error popup text, %1 is additional error message
			Popup::Error(sformat(
			    _("Writing profile settings was not successful:
%1
"),
			    ProfileManager::scpm_error));
		    }
		}
	    }
	    if (secure && !ProfileManager::SetFilePermitions (new_settings))
		// Error popup text
		Popup::Error(_("Setting file permissions was not successful."));
	    break;
	}
    };

    return ret;
}

/**
 * Popup which shows changes of selected resource
 * @return boolean true on success
 */
define boolean ShowChangesPopup() ``{

    string changes = ProfileManager::ShowChanges();
    string recoded = (string)
	UI::Recode (WFM::GetEnvironmentEncoding(),"UTF-8", changes);

    UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
        `VSpacing(25),
        `VBox(
            `HSpacing(70),
            `VSpacing(1),
			// Popup text
            `Label(_("Changes to the resource")),
            `Label(ProfileManager::active_resource_name),
            `VSpacing(1),
            `RichText(recoded),
            `VSpacing(1),
            `PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton()),
            `VSpacing(1)),
        `HSpacing(1.5)
        ));

    any ret = UI::UserInput();
    UI::CloseDialog();

    return true;
}


/**
 * Switch dialog
 * @return any Returned value from UserInput() call
 */
define any SwitchDialog () {

    string active_group = "";

    string active = ProfileManager::active_profile;
    string selected = ProfileManager::selected_profile;

    // Dialog caption label
    string caption = _("Confirm Switch");

    term contents = `HBox (`HSpacing(1.5),`VBox(
	`VSpacing(1),
        `HBox(
            `HSpacing(1),
            // Label text
            `Left(`Label(_("Active Profile"))),
            `Right(`Heading(active)),
            `HSpacing(2)
            ),
        `VSpacing(0.2),
        `HBox(
            `HSpacing(1),
            // Label text
            `Left(`Label(_("New Profile"))),
            `Right(`Heading(selected)),
            `HSpacing(2)
            ),
        `VSpacing(1),
	// frame label
        `Frame(_("Modified Resource Groups of Active Profile"),
	    `HBox(`HSpacing(1),
            `VBox(
                `VSpacing(0.2),
		`Table(`id(`modified),`opt(`notify),
                    `header(
                            "",
                            // Header of the table with modified resources 2/2
                            _("Resource Group"),
                            // Header of the table with modified resources 3/3
                            _("Description")),
                    []
                    ),
                `VSpacing(0.2),
		`HBox(
		    `PushButton (`id(`save_b), `opt(`key_F4),
			// Push button label
			_("&Save or Ignore")),
                    `Right(`PushButton(`id (`details), `opt(`key_F2),
                        // Push button label
                        _("&Details")))
		),
                `VSpacing(0.2)
            ),
            `HSpacing(1)
            )),
        `VSpacing(1)
	),
    `HSpacing(1.5));


    Wizard::RestoreBackButton ();

    Wizard::SetContentsButtons ( caption, contents, HELPS["switch"]:"",
				Label::CancelButton (), Label::OKButton () );

    list res_groups_as_items = ProfileManager::GetGroupsAsItems();

    UI::ChangeWidget(`id(`modified), `Items, res_groups_as_items);

    if (size (res_groups_as_items) < 1)
    {
        UI::ChangeWidget(`id(`modified), `Enabled, false);
	UI::ChangeWidget(`id(`save_b), `Enabled, false);
	UI::ChangeWidget(`id(`details), `Enabled, false);
    }
    else
    {
	active_group = ProfileManager::current_resource_group;
	if (active_group == "")
	    active_group = res_groups_as_items[0,2]:"";
	UI::ChangeWidget(`id(`modified), `CurrentItem, active_group);
	UI::SetFocus(`id(`modified));
    }

    symbol ret = nil;
    while (true)
    {
	ret = (symbol) UI::UserInput ();

	any selected_res = UI::QueryWidget(`id(`modified), `CurrentItem);
	if (ret == `back || ret == `cancel)
	{
            break;
	}
	// only for resource groups
	else if (contains ([`save_b,`ignore_b, `modified], ret))
	{
	    boolean set =ProfileManager::SetGroupSaveFlag((string)selected_res);
	    UI::ChangeWidget(`id(`modified), `Items,
		ProfileManager::GetGroupsAsItems());
//	    UI::ChangeWidget(`id(`modified), `Item (selected_res,0),
//		set ? "X":"");
	    UI::ChangeWidget(`id(`modified), `CurrentItem, selected_res);
	}
	// only for resource groups!
	else if (ret == `details)
	{
	    ProfileManager::current_resource_group = (string) selected_res;
	    break;
	}
        else if (ret == `next)
	{
            // saving changes: not necessary if "drop all" is checked
            ProfileManager::Save();
            ProfileManager::ProgressPopup("first",0,15);
            if (!ProfileManager::Wait())
            {
                // Error popup text, %1 is additional translated error message
                Popup::Error (sformat(_("Saving the profile was not successful:
%1
"),
                    ProfileManager::scpm_error));
                break;
            }
            ProfileManager::Switch();
            ProfileManager::ProgressPopup("last",15,100);
            if (!ProfileManager::Wait())
                // Error popup text, %1 is additional translated error message
                Popup::Error (sformat(_("Switching was not successful:
%1
"),
                    ProfileManager::scpm_error));
            else
                ProfileManager::active_profile = selected;
	    break;
	}
    };
    return (any) ret;
}

/**
 * Dialog with switch details of one resource group
 * @return any Returned value from UserInput() call
 */
define symbol DetailsSwitchDialog () ``{

    string groupname	= ProfileManager::current_resource_group;
    map resources	= ProfileManager::GetModifiedGroupResources(groupname);

    /**
     * helper function for building table items with modified resources
     */
    define list resources_items() ``{

	list items = [];
	foreach (any i, any res, resources, ``{
	    if (!is(i, integer))
		return;
	    map resource	= $[];
	    if (is (res,map))
		resource	= (map) res;
	    // flag for resource action
	    string save = _("save");
	    if (resource["save_mode"]:"normal" == "normal")
	    {
		if (!resource["save"]:true)
		    // flag for resource action
		    save = _("ignore");
	    }
	    else if (resource["save_mode"]:"normal" == "save_all")
		// flag for resource action
		save = _("all");
	    else if (resource["save_mode"]:"normal" == "patch_all")
		// flag for resource action
		save = _("patch");

	    string flag = "";
	    if (resource["is_new"]:false)
		// flag
		flag = _("NEW");
	    else if (resource["is_deleted"]:false)
		// flag
		flag = _("DELETED");

	    items = add (items, `item(
		`id(i), save, resource["resource_name"]:"",
		resource["resource_type"]:"", flag));
	});
	return items;
    }

    list actions_list = [
	// button label
	 `item(`id(`save), _("&Save Resource")),
	// button label
	 `item(`id(`ignore), _("&Ignore Resource")),
	// button label
	 `item(`id(`save_p), _("Save to &All Profiles")),
	// button label
	 `item(`id(`patch), _("&Patch All Profiles")),
    ];
    list all_actions_list = [
	// button label
	 `item(`id(`save_all), _("&Save All Resources")),//&r
	// button label
	 `item(`id(`ignore_all), _("&Ignore All Resources"))//&g
    ];
    list show_list = [
	// button label
	 `item(`id(`show_ch), _("Sho&w Changes")),
	// button label
	 `item(`id(`show_r), _("Show &Resource"))
    ];

    // Caption of the dialog:
    string caption = _("Resource Group Details");

    term contents = `HBox(
	`HSpacing(1.5),
	`VBox(
        `VSpacing(1),
        `HBox(
            `HSpacing(1),
            // Label text
            `Left(`Label(_("Resource Group"))),
            `Right(`Label(groupname)),
            `HSpacing(2)
            ),
        `VSpacing(1),
	// frame label:
        `Frame(_("Modified Resources"), `HBox(`HSpacing(1),
            `VBox(
                `VSpacing(0.2),
		`Table(`id(`resources), `opt (`notify),
                    `header(
                        // Header of the table with resources 1/4
                        _("Action"),
                        // Header of the table with resources 2/4
                        _("Resource"),
                        // Header of the table with resources 3/4
                        _("Type"),
                        // Header of the table with resources 4/4
                        _("Flags")),
                    []
                ),
                `VSpacing(0.2),
		`HBox(
		    `MenuButton(`id(`action_b), `opt(`key_F3),
			// menubutton label
			_("&Action"),
			actions_list),
		    `PushButton(`id(`all_action_b), `opt(`key_F4),
			// button label
			_("Save or Ignore A&ll")), // all_actions_list),
		    `Right(
			// button label
			`PushButton(`id(`show_ch), `opt(`key_F2),
			    _("&Show Changes"))
		    )
		),
		`VSpacing(0.2)
                ),
            `HSpacing(1)
        )),
        `VSpacing(1)
	),
	`HSpacing(1.5)
    );

    Wizard::SetContentsButtons ( caption, contents, HELPS["switchdetails"]:"",
        Label::CancelButton (), Label::OKButton () );

    Wizard::HideAbortButton();

    list items = resources_items();
    UI::ChangeWidget(`id(`resources), `Items, items);

    if (items != [])
	UI::SetFocus(`id(`resources));

    any ret = nil;
    integer selected = 0;
    while (true)
    {
	ret = UI::UserInput ();
	selected = (integer) UI::QueryWidget(`id(`resources), `CurrentItem);

	if (ret == `resources)
	{
	    if (resources[selected,"save_mode"]:"" == "normal")
	    {
		resources[selected,"save"] = !resources[selected, "save"]:false;
		UI::ChangeWidget (`id(`resources), `Item (selected,0),
		    resources[selected,"save"]:false ? _("save"):_("ignore"));
	    }
	    continue;
	}
	else if (ret ==`save)
	{
	    resources[selected,"save"] = true;
	    resources[selected,"save_mode"] = "normal";
	    UI::ChangeWidget (`id(`resources), `Item (selected,0),_("save"));
	}
	else if (ret ==`ignore)
	{
	    resources[selected,"save"] = false;
	    resources[selected,"save_mode"] = "normal";
	    UI::ChangeWidget (`id(`resources), `Item (selected,0),_("ignore"));
	}
	else if (ret ==`save_p)
	{
	    resources[selected,"save"] = true;
	    resources[selected,"save_mode"] = "save_all";
	    UI::ChangeWidget (`id(`resources), `Item (selected,0),_("all"));
	}
	else if (ret ==`patch)
	{
	    resources[selected,"save"] = true;
	    resources[selected,"save_mode"] = "patch_all";
	    UI::ChangeWidget (`id(`resources), `Item (selected,0),_("patch"));
	}
	else if (ret == `all_action_b)
	{
	    foreach (any i, any resource, resources, ``{
		if (!is(i, integer) || ! is(resource,map))
		    return;
		map r_map = (map)resource;
		r_map["save"] = !(r_map["save"]:false);
		r_map["save_mode"] = "normal";
		UI::ChangeWidget (`id(`resources), `Item (i,0),
		    // action to do with resource
		    r_map["save"]:true ? _("save") : _("ignore"));
	    });
	}
	else if (ret == `show_ch)
	{
	    ProfileManager::active_resource = selected;
	    ShowChangesPopup();
	}
	else if (ret == `back || ret == `cancel)
	{
	    // throw away changes
	    break;
	}
	else if (ret == `next)
	{
	    ProfileManager::CheckAndUpdateResources (groupname, resources);
	    break;
	}
    };

    return (symbol) ret;
}

/**
 * Popup for adding new profile
 * @return boolean true if user confirms action
 */
define boolean AddProfilePopup() ``{

    map profiles = ProfileManager::profiles;

    UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
        `VBox(
            `VSpacing(1),
			// Popup text, part 1/3
	        `Left(`Label(_("Add a new profile based"))),
            `VSpacing(1),
            `RadioButtonGroup(`id(`rb),
	            `VBox(
			`Left(`RadioButton(`id(`new), `opt(`notify),
			    // Popup text, part 2/3
			    _("on the c&urrent system configuration"))),
                    `VSpacing(0.2),
                    `HBox(
			`HSpacing(2),
			// Checkbox label, part 1/2
			`CheckBox(`id(`auto), _("&Make the added profile the new active profile."))),
                    `HBox(
			`HSpacing(4.5),
			// Checkbox label, part 2/2
			`Label(`id(`autol),_("This does not save anything to the old active
profile nor does it start or stop services."))),
		    `VSpacing(1),
		    `Left(`RadioButton(`id(`copy), `opt(`notify),
			// Popup text, part 3/3
                        _("on an &existing profile:")))
                    )),
            `SelectionBox (`id(`profiles), "", maplist (
		string name, any desc, (map<string,any>) profiles, ``(name))),
            `VSpacing(1),
	    `HBox (
		`HSpacing (1),
		`Left (`PushButton(`id(`ok), `opt(`default),Label::OKButton())),
	        `Right (`PushButton(`id(`cancel), Label::CancelButton())),
	        `HSpacing (1)
	    ),
            `VSpacing(1)),
        `HSpacing(1.5)
        ));

    UI::ChangeWidget(`id(`rb), `CurrentButton, `new);

    any ret = nil;
    while (true)
    {
        ret = UI::UserInput();
        if (ret == `new)
        {
            UI::ChangeWidget(`id(`profiles), `Enabled, false);
            UI::ChangeWidget(`id(`auto), `Enabled, true);
            UI::ChangeWidget(`id(`autol), `Enabled, true);
        }
        else if (ret == `copy)
        {
            UI::ChangeWidget(`id(`profiles), `Enabled, true);
            UI::ChangeWidget(`id(`auto), `Enabled, false);
            UI::ChangeWidget(`id(`autol), `Enabled, false);
        }
        else if (ret == `ok)
        {
            if (UI::QueryWidget(`id(`rb), `CurrentButton) == `copy)
            {
                string selected = (string)
		    UI::QueryWidget(`id(`profiles), `CurrentItem);
                if (selected == nil)
                {
					// Popup text
                    Popup::Message(_("Select a profile to copy."));
                    continue;
                }
                ProfileManager::profile_action = "copy";
                ProfileManager::selected_profile = selected;
            }
            else
            {
                ProfileManager::profile_action = "new";
//                ProfileManager::selected_profile = ProfileManager::active_profile;
                ProfileManager::auto = (boolean)
		    UI::QueryWidget(`id(`auto), `Value);
            }
            break;
        }
        if (ret == `cancel)
            break;
    }

    UI::CloseDialog();

	if (ret == `ok)
		return true;
	else
		return false;
}
/**
 * Shows the text of scpm introduciton
 * @return boolean true on success
 */
define boolean IntroductionTextPopup() ``{

    UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
        `VSpacing(30),
        `VBox(
            `HSpacing(80),
            `VSpacing(1),
            `RichText(`id(`info),""),
            `VSpacing(0.5),
            `PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton()),
            `VSpacing(0.5)),
        `HSpacing(1.5)
        ));
    UI::ChangeWidget(`id(`info), `Value, HELPS["intro"]:"");
    any ret = UI::UserInput();
    UI::CloseDialog();
    return true;
}


/**
 * Introduction popup
 * @return boolean true on success
 */
define boolean IntroductionPopup() ``{

	// Inroduction text, part 1/2
    string intro_text = _("<p>SCPM is currently disabled.<br>
To enable it, use the Options button.<br></p>
") +

	// Inroduction text, part 2/2
 _("<p>If you are new to SCPM, read at least the help texts. It is better to read the introduction in the info pages. You should know what 'active profile' and 'current configuration' mean before using SCPM.</p>");

    UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
        `VSpacing(15),
        `VBox(
            `HSpacing(40),
            `VSpacing(1),
            `RichText(intro_text),
            `VSpacing(1),
	      `HBox(
		`HSpacing(1),
		// Push button label (read the intrduction before starting)
		`PushButton(`id(`intro),`opt(`default),_("&Show introduction")),
                // Push button label (start without reading the intrduction)
	        `PushButton(`id(`cont), _("&Go")),
	        `HSpacing(1)
	      ),
            `VSpacing(1)),
        `HSpacing(1.5)
        ));

    any ret = nil;
    ret = UI::UserInput();
    UI::CloseDialog();

    if (ret == `intro)
    {
        IntroductionTextPopup();
    }

    ProfileManager::first_time = false;
    return true;
}

/**
 * popup for entering new service for resource group
 * @return service name; empty string on cancel
 */
define string GetService() ``{

    // read the list of services...
    map services	= (map) SCR::Read (.init.scripts.comments);
    list service_items	= [];

    foreach (any k, map v, (map<any,map>) services, ``{
	service_items = add (service_items,
	    `item( `id(k), k, false));
    });

    string service = "";
    UI::OpenDialog( `opt(`decorated), `HBox(
	`HSpacing(1),
	`VBox(
	    `VSpacing(0.2),
	    // combo box label
	    `ComboBox( `id(`services), _("Available &Services"), service_items),
	    `VSpacing(0.2),
	    `HBox(
		`PushButton(`id(`ok),`opt(`default), Label::OKButton()),
		`PushButton(`id(`cancel), Label::CancelButton())
	    ),
	    `VSpacing(0.2)),
	`HSpacing(1)
    ));

    UI::SetFocus (`id (`services));

    any ret = nil;
    do {
	ret	= UI::UserInput();
	service = (string) UI::QueryWidget(`id(`services), `Value);

	if (ret == `cancel)
	{
	    service = "";
	}
	else if (ret == `ok)
	{
	    // check service existence
	    // TODO it has to exist, if combo is not editable
	    if (service != "" &&
		!(boolean)SCR::Read (.init.scripts.exists, service))
	    {
		// yes/no popup
		if (!Popup::YesNo (sformat(_("Service %1 does not exist.
Are you sure?"), service)))
		    continue;
	    }
	}
    } while (ret != `ok && ret != `cancel);

    UI::CloseDialog();
    return service;
}

/**
 * popup for entering new file for resource group
 * @return file name; empty string on cancel
 */
define string GetFile() ``{

    string filename = "";
    UI::OpenDialog( `opt(`decorated), `HBox(
	`HSpacing(1),
	`VBox(
	    `VSpacing(0.2),
	    `HBox (
		`TextEntry (`id(`file), Label::FileName(), ""),
		`HSpacing (1),
		`VBox (
		    `Label(""),
		    // button label
		    `PushButton (`id (`browse), `opt (`key_F6), _("&Browse"))
		)
	    ),
	    `VSpacing(0.2),
	    `HBox(
		`PushButton(`id(`ok),`opt(`default), Label::OKButton()),
		`PushButton(`id(`cancel), Label::CancelButton())
	    ),
	    `VSpacing(0.2)),
	`HSpacing(1)
    ));

    UI::SetFocus (`id (`file));

    any ret = nil;
    do {
	ret		= UI::UserInput();
	filename	= (string) UI::QueryWidget(`id(`file), `Value);

	if (ret == `cancel)
	{
	    filename = "";
	}
	else if (ret == `browse)
	{
	    string f = UI::AskForExistingFile (
		(filename != "")? "/" : filename, "*", "");
	    if (f != nil)
		filename = f;
	    UI::ChangeWidget (`id(`file), `Value, filename);
	}
	else if (ret == `ok)
	{
	    if (filename != "" && SCR::Read (.target.size, filename) < 0)
	    {
		// error popup
		Popup::Error (_("Such a file does not exist."));
		continue;
	    }
	}
    } while (ret != `ok && ret != `cancel);

    UI::CloseDialog();
    return filename;
}


/**
 * Popup for editing or adding resource group settings
 * @param group map with info of the group
 * @return modified group
 */
define map ResourceGroupPopup (map group) ``{

    string groupname	= group["name"]:"";
    string descr	= group["description"]:"";
    string what		= (group == $[] || group["what"]:""=="added")
			? "added": "edited";
    list<term> items		= [];
    map org_group	= (map) eval (group);

    // map for saving user_defined flags of each resource
    map user_defined	= $[];

    /**
     * Scan table items for presence of given resource
     */
    define boolean has_resource (string name, string type) ``{

	return (contains (items, `item(`id(name), "X", name, type)) ||
	    contains (items, `item(`id(name), "", name, type)));
    }
    /**
     * helper function for building table items of one resource group
     */
    define list<term> resource_group_items() ``{

	return maplist (map res, group["resources"]:[], ``{
	    string name = res["name"]:"";
	    user_defined [name] = res["user_defined"]:false; //TODO not needed?
	    if (res["active"]:false)
		return `item(`id(name), "X", name, res["type"]:"");
	    else
		return `item(`id(name), "", name, res["type"]:"");
    });

    }

    term con = `HBox(`VSpacing(26),`HSpacing(1.5), `VBox(
        `HSpacing(60),
	`VSpacing(0.5),
	// textentry label
	`TextEntry (`id(`name), _("Resource &Group"), groupname),
        `VSpacing(0.5),
	// textentry label
	`TextEntry (`id(`descr), _("D&escription"), descr),
        `VSpacing(0.5),
	// frame label
	`Frame(_("Resources"), `HBox(`HSpacing(1), `VBox(
            `VSpacing(0.2),
	    `Table(`id(`resources), `opt (`notify),
		`header(
		    " ",
                    // Header of the table with resources of one group 2/3
                    _("Name"),
                    // Header of the table with resources of one group 3/3
                    _("Type")),
                items
            ),
            `VSpacing(0.2),
	    `HBox(
		// Push button label
		`PushButton(`id(`adds_b), `opt(`key_F3), _("Add &Service")),
                // Push button label
		`PushButton(`id(`addf_b), `opt(`key_F4),_("Add &File")),
		`Left(
                    // Push button label
		    `PushButton(`id(`delete_b),`opt(`key_F5),_("&Delete"))),
		`Right(
                    // Push button label
		    `PushButton(`id(`reset_b),`opt(`key_F6),_("&Reset Group")))
		),
	    `VSpacing(0.2)),
	    `HSpacing())
	),
        `VSpacing(0.5),
	`HBox(
	    `HSpacing(1.5),
	    `Left (`PushButton (`id(`ok), `opt(`default),Label::OKButton())),
	    `Right (`PushButton(`id(`cancel), Label::CancelButton())),
	    `HSpacing(1.5)
	),
        `VSpacing(0.5)
	),
        `HSpacing(1.5)
    );

    UI::OpenDialog(`opt(`decorated), con);

    // create the table items
    items = resource_group_items ();
    UI::ChangeWidget(`id(`resources), `Items, items);
    UI::SetFocus(`id(`name));

    y2debug ("edited group: %1", group);
    if (group["user_defined"]:true == false)
    {
	// default group cannot be renamed
	UI::ChangeWidget(`id(`name), `Enabled, false);
    }
    else
	// user defined group cannot be reset
	UI::ChangeWidget(`id(`reset_b), `Enabled, false);

    symbol ret = nil;
    do
    {
        ret		= (symbol) UI::UserInput ();
	groupname	= (string) UI::QueryWidget (`id(`name), `Value);
	string selected	= (string)UI::QueryWidget(`id(`resources),`CurrentItem);

	if (ret == `resources)
	{
	    items = maplist (term i, items, ``{
		if (i[2]:"" != selected)
		    return i;
		if (i[1]:"" == "X")
		    return `item(`id(selected), "", selected, i[3]:"");
		else
		    return `item(`id(selected), "X", selected, i[3]:"");
	    });
	    UI::ChangeWidget(`id(`resources), `Items, items);
	    UI::ChangeWidget(`id(`resources), `CurrentItem, selected);
	}
	if (ret == `reset_b)
	{
	    // yes/no popup
	    if (Popup::YesNo (_("The current resource group will be reset to its initial default values.
All user modifications will be lost.
Really do this now?
")))
	    {
		if (!ProfileManager::ResetResourceGroup (groupname))
		{
		    // error message
		    Report::Error( sformat(_("Problem with resetting resource group:
%1
"),
			ProfileManager::scpm_error));
		    continue;
		}
		map orig_group = ProfileManager::ReadResourceGroup (groupname);
		group["resources"] = eval (orig_group["resources"]:[]);
		group["description"] = eval (orig_group["description"]:"");
		items = resource_group_items ();
		UI::ChangeWidget(`id(`resources), `Items, items);
		UI::ChangeWidget(`id(`descr), `Value, group["description"]:"");
	    }
	}
	if (ret == `delete_b)
	{
	    if (Popup::YesNo(sformat(
// Popup text (confirmation), %1 is name of file or service
_("Really delete resource \'%1\' from this group?"),
		selected)))
	    {
		y2debug ("deleting %1 from group %2", selected, groupname);
		// delete entry from local items
		items = filter (term i, items, ``(i[2]:"" != selected));
		UI::ChangeWidget(`id(`resources), `Items, items);
	    }
	}
	if (ret == `adds_b)
	{
	    string service = GetService ();
	    if (service != "" && !has_resource (service,"service"))
	    {
		y2debug ("new service %1 for group %2", service, groupname);
		items = add (items, `item(`id(service), "", service,"service"));
		user_defined [service] = true;
		UI::ChangeWidget(`id(`resources), `Items, items);
	    }
	}
	if (ret == `addf_b)
	{
	    string file = GetFile ();
	    if (file != "" && !has_resource (file,"file"))
	    {
		y2debug ("new file %1 for group %2", file, groupname);
		items = add (items, `item(`id(file), "", file, "file"));
		user_defined [file] = true;
		UI::ChangeWidget(`id(`resources), `Items, items);
	    }
	}
	if (ret == `ok)
	{
	    // check name contents
	    if (!ProfileManager::CheckNameValidity (groupname))
	    {
		// Popup text (wrong data):
		Popup::Message(_("Choose valid name."));
		continue;
	    }
	    // check possible name conflicts
	    if (groupname != group["name"]:"")
	    {
		if (ProfileManager::GroupnameExists (groupname))
		{
		    // error message, %1 is group name
		    Popup::Error(sformat(_("Resource group \"%1\" already exists.
Choose another name."), groupname));
		    continue;
		}
		if (group["name"]:"" != "")
		{
		    group["org_name"]	= group["name"]:"";
		}
		if (what != "added")
		{
		    what		= "renamed";
		}
		group["name"]		= groupname;
	    }
	    group["description"]	= UI::QueryWidget (`id(`descr), `Value);
	    group["resources"]		= maplist (term i, items, ``{
		return $[
		    "active"		: i[1]:"" == "X",
		    "name"		: i[2]:"",
		    "type"		: i[3]:"",
		    "user_defined"	: user_defined [ i[2]:""]:false
		];
	    });
	    if (what == "added")
	    {
		group["user_defined"]	= true;
		group["active"]		= true;
	    }
	    boolean group_modified = false;
	    foreach (string k, any v, (map<string,any>) group,``{
		if (org_group[k]:nil != v)
		    group_modified = true;
	    });
	    if (group_modified)
	    {
		group["user_modified"]	= true;
		group["what"]		= what;
		y2milestone ("resource group %1 modified", groupname);
	    }
	    else ret = `back;
	}
	if (ret == `cancel || ret == `back)
	{
	    group = $[];
	}
    } while ( !contains ([`ok, `next, `cancel, `back], ret));

    UI::CloseDialog();

    return group;
}


/**
 * Resource configuration dialog
 * @return any Returned value from UserInput() call
 */
define symbol ConfigureResourcesDialog () ``{

    /**
     * helper function for building table items with resource groups
     */
    define list resource_groups_items() ``{

	list items = [];
	foreach (string name, map group, (map<string,map>) ProfileManager::GetResourceGroups(),``{
	    if (group["what"]:"" == "deleted")
		return;
	    string desc = group["description"]:"";
	    if (group["active"]:false)
		items = add (items, `item(`id(name),"X", name, desc));
	    else
		items = add (items, `item(`id(name),"", name, desc));
	});
	return items;
    }

    // read resource groups every time entering the dialog
    if (!ProfileManager::ReadResourceGroups())
    {
	// error message (%1 is additional error message)
	Report::Error( sformat(_("Cannot read resource groups:\n%1"),
	    ProfileManager::scpm_error));
    }

    // Caption of the dialog:
    string caption = _("Configuration of Resource Groups");

    term contents = `HBox(
	`HSpacing(1.5),
	`VBox(
        `VSpacing(1),
	// frame label:
        `Frame(_("Select Resource Group"), `HBox(`HSpacing(1),
            `VBox(
                `VSpacing(0.2),
		    `Table(`id(`rgroups), `opt (`notify),
                    `header(
                        " ",
                        // Header of the table with resource groups 2/3
                        _("Name"),
                        // Header of the table with resource groups 3/3
                        _("Description")),
                    []
                    ),
                `VSpacing(0.2),
		`HBox(
                    // Push button label
		    `PushButton(`id(`add_button), `opt(`key_F3), _("&Add")),
                    // Push button label
		    `PushButton(`id(`edit_button), `opt(`key_F4),_("&Edit")),
		    `Left(
                    // Push button label
		    `PushButton(`id(`delete_button),`opt(`key_F5),_("&Delete"))),
		    `Right(`PushButton(`id(`reset_button),`opt(`key_F6),
			// Push button label
			_("&Reset All")))
		    ),
		`VSpacing(0.2)
                ),
            `HSpacing(1)
        )),
        `VSpacing(1)
	),
	`HSpacing(1.5)
    );

    Wizard::SetContentsButtons (caption, contents, HELPS["resources"]:"",
                Label::CancelButton (), Label::OKButton ());

    Wizard::HideAbortButton();

    list items = resource_groups_items();
    UI::ChangeWidget(`id(`rgroups), `Items, items);

    if (items != [])
	UI::SetFocus(`id(`rgroups));

    any ret = nil;
    string selected = "";
    boolean modified = false;
    while (true)
    {
	ret		= UI::UserInput ();
	selected	= (string) UI::QueryWidget(`id(`rgroups), `CurrentItem);
	if (ret == `delete_button)
	{
	    if (Popup::YesNo(sformat(_("Delete group %1?"), selected)))
	    {
		ProfileManager::MarkGroupDeleted (selected);
		UI::ChangeWidget(`id(`rgroups),`Items, resource_groups_items());
		modified = true;
	    }
	    continue;
	}
	else if (ret == `add_button || ret == `edit_button)
	{
	    map group = $[];
	    if (ret == `add_button)
		group = ResourceGroupPopup($[]);
	    else
		group = ResourceGroupPopup (ProfileManager::GetGroup(selected));
	    if (group != $[])
	    {
		ProfileManager::ChangeGroup (group);
		UI::ChangeWidget(`id(`rgroups),`Items, resource_groups_items());
		UI::ChangeWidget(`id(`rgroups), `CurrentItem, group["name"]:"");
		modified = true;
	    }
	    continue;
	}
	else if (ret == `reset_button)
	{
	    // yes/no popup
	    if (Popup::YesNo (_("All resource groups will be reset to their initial default values.
All user modifications (including new groups) will be lost.
Really do this now?
")))
	    {
		if (!ProfileManager::ResetResourceGroups ())
		{
		    // error message
		    Report::Error( sformat(_("Problem with resetting resource groups:
%1
"),
			ProfileManager::scpm_error));
		    continue;
		}
		// read resource groups again
		if (!ProfileManager::ReadResourceGroups())
		{
		    // error message
		    Report::Error(sformat(_("Cannot read resource groups:\n%1"),
			ProfileManager::scpm_error));
		    continue;
		}
		// reload the list of groups
		UI::ChangeWidget(`id(`rgroups),`Items, resource_groups_items());
	    }
	}
	else if (ret == `rgroups)
	{
	    boolean active = ProfileManager::MarkGroupActive (selected);
	    UI::ChangeWidget (`id(`rgroups),`Item (selected, 0), active?"X":"");
	    modified = true;
	}
	else if (ret == `back || ret == `cancel)
	{
	    // throw away changes
	    break;
	}
	else if (ret == `next)
	{
	    if (!modified)
		break;
	    // yes/no popup
	    if (Popup::YesNo (_("Apply changes to resource groups now?
(Resource database will be rebuilt.)
")))
	    {
		// really delete/add/modify
		if (!ProfileManager::SaveResourceGroups ())
		{
		    // Error popup text, %1 is additional error text
		    Popup::Error(sformat(_("Saving resource groups failed:
%1"),
			ProfileManager::scpm_error));
	}
		// TODO ask for rebuild?
		else
		{
		    ProfileManager::RebuildDB();
		}
	    }
	    else
		continue;
	    break;
	}
    };

    return (symbol) ret;
}

/* EOF */
}
