/**
 * File:
 *   sound_write.ycp
 *
 * Module:
 *   Sound
 *
 * Summary:
 *   Provides saving /etc/modules.conf and volume.
 *
 * Authors:
 *   Dan Vesely <dan@suse.cz>
 *   Dan Meszaros <dmeszar@suse.cz>
 *
 * $Id: sound_write.ycp 22358 2005-03-07 17:01:55Z lslezak $
 *
 * Parameters are given in a map with keys:
 *         "modules_conf" ... save info- list of configured cards:
 *	   [
 *		$[
 *		    "model"	: "sb live!",
 *		    "alias"	: "snd-card-0",
 *		    "options"	: $["snd_id":"0" ...],
 *		    "module"	: "snd-emu10k1",
 *		    "unique_key": "abcd.efghijklmn"
 *                  "bus"       : "pci",
 *                  "bus_id"    : "0000:00:07.0"
 *		],
 *              $[
 *                  "model"     : "avi onboard!",
 *                  "alias"     : "snd-card-1",
 *                  "options"   : $["snd_id":"1" ...],
 *                  "module"    : "snd-asf",
 *                  "unique_key": "abcd.abcdefghij"
 *                  "bus"       : "pci",
 *                  "bus_id"    : "0000:00:03.1"
 *              ]
 *         ]
 *
 *	   "rc_vars" ... sysconfig values
 *	   $[
 *		"LOAD_SEQUENCER" : "yes"
 *         ]
 *
 *	   "vol_settings" ... volume setting (usefull only for autoconfig)
 *	   [
 *		[  // card #1
 *		    ["PCM", 32, false], ["Master", 100, true] ...
 *	        ],
 *		[  // card #2
 *		],
 *		...
 *
 *	   ]
 *
 * Steps:
 *        1. save '/etc/modules.conf'
 *        2. save '/etc/rc.config'
 *        3. save volume
 *        4. call function to provide some additional work
 *
 * Return boolean true on success, false if failed
 */
{
    textdomain "sound";


    include "sound/write_routines.ycp";

    import "Progress";
    import "Wizard";
    import "Service";
    import "Package";

    import "Sound";
    import "Joystick";

    // ==== MAIN ====

    map settings	= (map) WFM::Args(0);
    map rc_values	= settings["rc_vars"]:$[];
    list save_info	= settings["modules_conf"]:[];
    list vol_settings	= settings["volume_settings"]:[];

    // do nothing when proposal is empty
    // (Sound::installation is set to true in proposal mode)
    if (Sound::installation && size(save_info) == 0)
    {
	y2debug("empty proposal. exiting.");
	return true;
    }

    list<string> stones = [
	    // progress bar item
	    _("Save module configuration"),
	    // progress bar item
            _("Save sound card information"),
	    // progress bar item
	    _("Save sysconfig values"),
	    // progress bar item
	    _("Start sound card"),
	    // progress bar item
	    _("Store volume"),
	    // progress bar item
	    _("Store joystick settings")];

    list stones2 = [
	    // progress bar item
	    _("Saving sound card settings."),
	    // progress bar item
	    _("Saving card information..."),
	    // progress bar item
	    _("Saving sysconfig values..."),
	    // progress bar item
	    _("Starting sound card..."),
	    // progress bar item
	    _("Storing volume settings"),
	    // progress bar item
	    _("Storing joystick settings...")];


    // not really necessary for Progress stuf (it is set off in _auto client)
    if (!Sound::write_only)
    {
	// progres bar label
	Progress::New (_("Saving sound card settings."), " ", size(stones) - 1,
		// progres bar label
		stones, stones2, _("Saving sound card settings."));
        if (Sound::use_ui)
	    Wizard::DisableAbortButton();
    }

    Progress::NextStage();

    // get required sound and joystick kernel modules
    list<string> reqmodules = Sound::RequiredKernelModules();
    list<string> reqjoymodules = Joystick::RequiredKernelModules();

    if (reqmodules == nil)
    {
	reqmodules = [];
    }

    if (reqjoymodules == nil)
    {
	reqjoymodules = [];
    }

    // merge lists, remove duplicates
    reqmodules = (list<string>) union(reqmodules, reqjoymodules);

    if (size(reqmodules) > 0)
    {
	// ensure that all required kernel modules are installed
	Package::InstallKernel(reqmodules);
    }

    // save config to /etc/modprobe.d/sound
    SaveModulesEntry(save_info, []);

    sleep(10);
    Progress::NextStage();

    Sound::StoreUniqueKeys();

    sleep(10);
    Progress::NextStage();

    SaveRCValues(rc_values);

    sleep(10);
    Progress::NextStage();

    list configuredcards = Sound::GetSoundCardList();
    if (!Sound::write_only)
    {
	// stop joystick before restarting ALSA
	SCR::Execute(.target.bash, "/etc/init.d/joystick stop", $[]);

	// restart ALSA
	if (size(configuredcards) > 0)
	{
	    SCR::Execute(.target.bash, "/etc/init.d/alsasound restart", $[]);
	}
    }

    Progress::NextStage();

    if (SCR::Read(.target.size, "/etc/asound.state") == -1 || Sound::write_only)
    {
	integer i = 0;
	maplist (map e, (list<map>) save_info, ``{
	    Sound::InitMixer (i, e["module"]:"");
	    i = i + 1;
	});
    }

    SaveVolume();

    if (Sound::write_only && haskey (settings, "volume_settings"))
    {
	set_vol_settings (vol_settings);
    }

    sleep(10);
    Progress::NextStage();

    // abort block for read/write dialogs
    block<boolean> abort_block = ``{ return false; };

    // write joystick configuration
    Joystick::Write (abort_block);

    if (size(configuredcards) > 0)
    {
	// enable alsasound service in runlevels 2,3,5
	Service::Finetune("alsasound", ["2", "3", "5"]);
    }
    else
    {
	// disable sound service - it's not needed, no soundcard is present
	Service::Adjust("joystick", "disable");
	Service::Adjust("alsasound", "disable");
    }

    return true;// TODO return value!
}
