/**
 * File:
 *   manual.ycp
 *
 * Module:
 *   Sound
 *
 * Summary:
 *   Module for manual selection of sound card from the database
 *
 * Authors:
 *   Dan Veselư <dan@suse.cz>
 *   Dan Meszaros <dmeszar@suse.cz>
 *
 * String corrections by Christian Steinruecken <cstein@suse.de>, 2001/08/01
 *
 *
 * $Id: manual.ycp 20357 2004-11-18 13:37:56Z lslezak $
 *
 */

{

    textdomain "sound";
    import "Wizard";
    import "Sound";
    import "Label";

    include "sound/routines.ycp"; // get_module_names, get_card_names
    include "sound/ui.ycp"; // ReallyAbort

    /**
     * returns module name for a given card model
     * @param cardname string card name
     * @return string module name
     */
    define string get_module_by_cardname(string cardname) ``{

	if (!Sound::use_alsa)
	{
	    // the name is in the form sformat("Sound card (%1)", key)
	    list card_l = splitstring (cardname, "()");
	    return card_l[1]:"";
	}

	integer i = -1;
	foreach (integer module_index, list names, (map<integer,list>)Sound::db_cards, ``{
	    if (contains (names, cardname))
	    {
		i = module_index;
	    }
	});
	return Sound::db_module_index[i]:"error";
    }

    /**
     * returns vendor name for a given card model
     * @param cardname string card name
     * @return string vendor name
     */
    define string get_vendor_by_cardname(string cardname) ``{

	if (!Sound::use_alsa)
	    return "";

	list card_l	= splitstring (cardname, ",");
	string vendor	= card_l [ size (card_l) - 1 ]:"";
	if (size (card_l) == 1)
	    return "other";
	if (substring (vendor, 0,1) == " ")
	    vendor = substring (vendor, 1);
	if (!haskey (Sound::db_vendors, vendor))
	    vendor = "other";
	return vendor;
    }

    /**
     * returns list of card vendors
     * @return list of items with vendors (into table)
     */
    define list get_vendor_names () ``{

	if (!Sound::use_alsa)
	    return [];

	Sound::LoadDatabase(true);
	list items = maplist (string v, list cs, (map<string,list>)Sound::db_vendors, ``{
	    if (v == "other")
		// table entry (vendor was not defined)
		return `item(`id(v), _("Other"));
	    return `item(`id(v), v);
	});
	// table entry (all vendors)
	return prepend (items, `item(`id("all"), _("All")));
    }

    /**
     * Update the settings for manualy choosed card: get the default options
     * and check if it tha card wasn't detected
     * @param card_map the current card (map with at least "module" entry)
     * @return updated map of current card
     */
    define map update_manual_card (map card_map) ``{

	string uniq_k	= isa_uniq();
	string label	= card_map["model"]:"Sound card";
	string modname	= card_map["module"]:"";

	// set default values for options
	map optlist = Sound::db_modules[modname]:$[];
	map options = $[];
	maplist(string name, map val, optlist["params"]:$[], ``{
	    if (haskey(val, "default"))
	    {
	        options = add (options, name, val["default"]:"");
	    }
	});

	// if user selects the soundcard that has been already autodetected,
	// use the detected card instead of manual selection (because it causes
	// some problems with uniq. keys)
	list det_cards = filter (map card, Sound::unconfigured_cards, ``(
	    card["module"]:nil == modname));

	y2debug("%1", det_cards);
	if (size(det_cards) > 0)
	{
	    label  = det_cards[0, "model"]:label;
	    uniq_k = det_cards[0, "unique_key"]:uniq_k;
	}

	return $[
	    "module"     : modname,
	    "model"	 : label,
	    "unique_key" : uniq_k,
	    "options"    : options
	];
    }

    /**
     * Dialog for manual adding the sound card
     * (shows the lists of Vendors/Drivers and Models)
     *  @return map result
     */
    define map ManualDialog () ``{

	string helptext		= Sound::STRINGS["ManualDialog"]:"";
	string keys		= Sound::use_alsa ? "vendors": "modules";

	list vendor_names	= get_vendor_names ();
	list module_names	= get_module_names ();
	list keys_names		= vendor_names;
	string curr_key		= Sound::curr_vendor;
	if (keys == "modules")
	{
	    curr_key		= Sound::curr_driver;
	    keys_names		= module_names;
	}
	if (!Sound::use_alsa && curr_key == "")
	{
	    Sound::curr_driver	= module_names[0]:"";
	    curr_key		= Sound::curr_driver;
	}
	list card_names		= get_card_names (curr_key, keys);
	term contents = `VBox (
	    `HBox (
		`ReplacePoint (`id (`rep_keys),
		    `SelectionBox (`id (`sel_keys), `opt(`notify),
			(keys == "vendors") ?
			    // selection box title
			    _("Sound Card &Vendor") :
			    // selection box title
			    _("Sound card &driver"),
			keys_names)
		),
		`ReplacePoint (`id(`rep_mod),
		    `SelectionBox (`id (`sel_mod), `opt(`notify),
		    // selection box title
		    _("Sound card &model"), card_names)
		)
	    ),
	    Sound::use_alsa ?
	    `Left(`CheckBox (`id(`ch_sets), `opt(`notify),
		// checkbox label
		_("Show List of Kernel Modules"), false))
	    : `VSpacing(),
	    // textentry label
	    `TextEntry (`id(`search), `opt(`notify), _("&Search")),
	    `VSpacing ()
	);

	// dialog title
	Wizard::SetContentsButtons (_("Manual sound card selection"), contents,
	    helptext, Label::BackButton(), Label::NextButton());

	if (Sound::curr_model == "")
	    Sound::curr_model = card_names[0]:"";
	if (curr_key == "")
	    curr_key = (string) keys_names[0,1]:"";

	if (keys == "vendors")
	    Sound::curr_vendor = curr_key;
	else
	    Sound::curr_driver = curr_key;

	UI::ChangeWidget(`id(`sel_keys), `CurrentItem, curr_key);
	UI::ChangeWidget(`id(`sel_mod), `CurrentItem, Sound::curr_model);

	UI::SetFocus (`id(`sel_keys));
	symbol ui = nil;
	do
	{
	    ui = (symbol) UI::UserInput ();

	    if (ui == `ch_sets)
	    {
		boolean mods = (boolean)UI::QueryWidget (`id(`ch_sets), `Value);

		string key	= (string)
		    UI::QueryWidget (`id(`sel_keys),`CurrentItem);
		string model	= (string)
		    UI::QueryWidget (`id(`sel_mod), `CurrentItem);
		string new_key	= key;
		string new_model= model;

		if (mods && keys == "vendors")
		{
		    if (key != "other" && key != "all")
		    {
			if (!issubstring (model, ", " + key))
			{
			    new_model = sformat ("%1, %2", model, key);
			}
		    }
		    new_key	= get_module_by_cardname (new_model);
		    keys	= "modules";
		}
		else if (!mods && keys == "modules")
		{
		    new_key	= get_vendor_by_cardname (model);
		    keys	= "vendors";
		    list card_l = splitstring (model, ",");
		    new_model	= card_l[0]:model;
		}
		else continue;

		keys_names	= (keys=="vendors")? vendor_names: module_names;
		UI::ReplaceWidget (`id(`rep_keys),
		    `SelectionBox (`id (`sel_keys), `opt(`notify),
			(keys == "vendors") ?
			    // selection box title
			    _("Sound Card &Vendor") :
			    // selection box title
			    _("Sound card &driver"),
			keys_names));

		UI::ChangeWidget(`id(`sel_keys), `CurrentItem, new_key);
		Sound::curr_model	= new_model;
		ui = `sel_keys;// we must adapt the list of card names
	    }
	    if (ui == `sel_keys)
	    {
		card_names = get_card_names (
		    (string) UI::QueryWidget (`id(`sel_keys), `CurrentItem),
		    keys);

		UI::ReplaceWidget (`id(`rep_mod), `SelectionBox (`id (`sel_mod),
		    // To translators: selection box title
		    _("Sound card &model"), card_names));

		if (contains (card_names, Sound::curr_model))
		    UI::ChangeWidget(`id(`sel_mod), `CurrentItem,
			Sound::curr_model);
		else
		    UI::ChangeWidget(`id(`sel_mod), `CurrentItem,
			card_names[0]:"");
	    }
	    else if (ui == `search)
	    {
		string entry = (string) UI::QueryWidget (`id(`search), `Value);
		integer card_id = search_card_id (entry);
		card_names = get_card_names ("all", keys);
		// always "all" field in vendors list
		UI::ChangeWidget (`id(`sel_keys),`CurrentItem, "all");
		if (card_id >= 0)
		{
		    UI::ReplaceWidget (`id(`rep_mod),
			// To translators: selection box title
			`SelectionBox (`id (`sel_mod), _("Sound card &model"),
			    card_names));

		    UI::ChangeWidget(`id(`sel_mod), `CurrentItem,
			card_names[card_id]:"");
		}
	    }
	    else if (ui == `abort || ui == `cancel)
	    {
		if (!ReallyAbort())
		    ui = nil;
	    }
	} while (!contains([`next, `back, `abort], ui));

	map ret = $["ui" : ui];


	if (ui == `next)
	{
	    string key = (string) UI::QueryWidget (`id(`sel_keys),`CurrentItem);
	    string model =(string)UI::QueryWidget (`id(`sel_mod), `CurrentItem);
	    string longmodel	= model;
	    string vendor	= (keys == "vendors") ?
				key : get_vendor_by_cardname (model);

	    if (Sound::use_alsa)
	    {
		if (vendor != "all")
		{
		    // vendor is included in model name
		    if (vendor != "other" && !issubstring (model,", " + vendor))
			longmodel = sformat ("%1, %2", model, vendor);
		}
		else
		{
		    vendor = get_vendor_by_cardname (model);
		}
		if (issubstring (model, ", " + vendor))
		{
		    list card_l = splitstring (model, ",");
		    model	= card_l[0]:model;
		}
	    }
	    string modname = get_module_by_cardname (longmodel);

	    Sound::curr_vendor	= vendor;
	    Sound::curr_driver	= modname;
	    Sound::curr_model	= model;

	    ret = $["ui" : `next, "module" : modname, "model" : model];
	}
	return ret;
    }

    /**
     * just calls ManualDialog
     * @return map passed result from ManualDialog
     */
    define map sound_manual() ``{

	return ManualDialog();
    }
}
