/**
 * File:	clients/tv.ycp
 * Package:	TV cards configuration
 * Summary:	Main file
 * Authors:	Jan Holesovsky <kendy@suse.cz>
 *
 * $Id: tv.ycp 20375 2004-11-22 16:20:55Z lslezak $
 *
 * Main file for tv configuration. Uses all other files.
 */

{

    /***
     * <h3>Configuration of the TV cards</h3>
     */

    textdomain "tv";

    /* The main () */
    y2milestone ("----------------------------------------");
    y2milestone ("Tv module started");

    import "Mode";
    import "Report";
    import "CommandLine";
    import "RichText";

    include "tv/ui.ycp";

    /**
     * Should we suppress Read() and Write()? It is necessary in proposals...
     */
    boolean no_io = false;

    integer i = 0;
    while (i < size (WFM::Args()))
    {
	if (WFM::Args (i) == .noio)
	{
	    no_io = true;
	}
	else if (WFM::Args (i) == .test)
	{
	    Mode::SetTest("test");
	}
	i = i + 1;
    }

// --------------------------------------------------------------------------
// --------------------------------- cmd-line handlers

/**
 * Print summary of basic options
 * @return boolean false
 */
define boolean SummaryHandler (map options ) ``{

    CommandLine::Print (RichText::Rich2Plain(Tv::Summary ()));
    return false; // do not call Write...
}


/**
 * Handler for adding a card via command line
 * @param options parameters passed as cmdline args
 * @return boolean true on success
 */
define boolean AddCardHandler (map options ) {

    integer card_no	= tointeger (options["no"]:"-1");
    string card_model	= options["card"]:"-1";
    string modname	= options["module"]:"";
    map card		= $[];

    // add the detected card
    if (card_no == -1 && modname == "" && card_model == "-1")
    {
	card_no = 0; // first detected card
    }

    card = Tv::DetectedCardGet (card_no);

    // add the card manualy
    if (card == $[])
    {
	if (modname == "" && card_model == "-1")
	{
	    // error message
	    Report::Error(_("There is no such card to add."));
	    return false;
	}
	if (card_model == "-1")
	{
	    Tv::ReadKernelModules ();
	    if (!haskey (Tv::kernel_modules, modname) &&
		!haskey (Tv::radio_modules, modname))
	    {
		// error message, %1 is module (driver) name
		Report::Error(sformat (_("There is no such card to add. Module %1 is unknown."),modname));
		return false;
	    }
	    card = $[ "module": modname, "name": _("User-Defined TV Card") ];
	    if (haskey (Tv::radio_modules, modname))
	    {
		card ["name"]	= _("User-Defined Radio Card");
		card ["radio"]	= true;
	    }
	}
	else
	{
	    card	= Tv::GetTvCard (card_model, modname);
	    if (card == $[])
	    {
		// error message
		Report::Error(_("There is no such card to add. Probably driver or card model is wrong."));
		return false;
	    }
	    options = remove (options, "card");
	}
	if (haskey (options, "module"))
	    options = remove (options, "module");
    }
    if (contains (Tv::CardsUniqueKeys(), card["unique_key"]:""))
    {
	//error message, %1 is name
	Report::Message(sformat(_("The card '%1' is already configured."),
	    card["name"]:""));
	return false;
    }

    if (!haskey (card, "parameters"))
	card ["parameters"] = $[];

    // add tuner parameters
    string tuner_id = (string) options["tuner"]:nil;
    if (tuner_id != nil)
    {
	card["parameters", "tuner"] = tuner_id;
	options	= remove (options, "tuner");
    }
    if (haskey (options, "no"))
	options = remove (options, "no");

    // add more parameters
    if (size (options) > 0)
    {
	map kernel_module = Tv::GetKernelModuleInfo (card["module"]:"");
	foreach (string option, string val, (map<string,string>) options, {
	    if (haskey (kernel_module, option))
		card["parameters", option] = val;
	});
    }

    // TODO add sound card number automatically?
    //    card ["sound_card_no"] = ...

    Tv::current_card	= card;
    Tv::CardAddCurrent (); // return value is card index

    return true;
}

/**
 * Handler for setting the paramerer values of tv card
 * @param options parameters on command line
 * @return boolean success
 */
define boolean SetParametersHandler (map options) {

    integer card_no = tointeger (options["no"]:"-1");
    if (card_no == -1)
    {
	//error message
	Report::Error( _("Specify the card number."));
	return false;
    }
    map card = (map) Tv::CardGet (card_no);
    if (size (card) == 0)
    {
	//error message, %1 is number
	Report::Error(sformat(_("There is no card with number %1."), card_no));
	return false;
    }
    options = remove (options, "no");

    // add more parameters
    if (size (options) > 0)
    {
	map kernel_module = Tv::GetKernelModuleInfo (card["module"]:"");
	foreach (string option, string val, (map<string,string>) options, {
	    if (haskey (kernel_module, option))
		card["parameters", option] = val;
	});
    }
    Tv::current_card = card;
    return Tv::CardReplaceWithCurrent (card_no);
}


/**
 * Handler for adding a card via command line
 * @param options parameters passed as cmdline args
 * @return boolean true on success
 */
define boolean RemoveCardHandler (map options ) ``{

    integer card_no = tointeger (options["no"]:"-1");
    if (card_no == -1)
    {
	//error message
	Report::Error( _("Specify the card number."));
	return false;
    }
    map card = (map) Tv::CardGet (card_no);
    if (size (card) == 0)
    {
	//error message, %1 is number
	Report::Error(sformat(_("There is no card with number %1."), card_no));
	return false;
    }
    return Tv::CardRemove (card_no);
}

/**
 * Handler for showing TV card information
 * @param options parameters on command line
 * @return boolean false (no write)
 */
define boolean ShowCardHandler (map options) {

    integer card_no = tointeger (options["no"]:"-1");
    if (card_no == -1)
	card_no = 0;

    if (card_no == -1)
    {
	//error message
	Report::Error( _("Specify the card number."));
	return false;
    }
    map card = (map) Tv::CardGet (card_no);
    if (size (card) == 0)
    {
	//error message, %1 is number
	Report::Error(sformat(_("There is no card with number %1."), card_no));
	return false;
    }

    string modname = card["module"]:"";
    // label: list of card parameters will follow; %1 is card name, %2 driver
    string out = sformat (_("Parameters of card '%1' (using module %2):\n"),
	card["name"]:"", modname);

    map kernel_module = Tv::GetKernelModuleInfo (modname);
    foreach (string option, string val, (map<string,string>) kernel_module, {
	if (option == "module_description" || option == "module_author")
	    return;
	out = out + sformat ("\n%1", option) + "\n\t" + val;
	if (card["parameters", option]:nil != nil)
	{
	    // label (current value of sound module parameter)
	    out = out + sformat(_("\n\tCurrent Value: %1
"),
		card["parameters", option]:"");
	}
    });
    CommandLine::Print (out);
    return false; // write not necessary
}

/**
 * Handler for listing available tv models
 */
define boolean ListModelsHandler (map options) {

    string modname	= options["module"]:"";
    map out		= $[];
    foreach (map vendor, (list<map>) Tv::cards_database, {
	foreach (map card, vendor["cards"]:[], {
	    integer id	= tointeger (card["parameters","card"]:"0");
	    if (id == nil) return;
	    out [id]	= add (out [id]:[], sformat ("%1 (%2)",
		card["name"]:"", card["module"]:""));
	});
    });
    foreach (integer id, list<string> cards,(map<integer,list<string> >) out, {
	CommandLine::Print (sformat ("%1",id));
	foreach (string c, cards, {
	    CommandLine::Print (" " + c);
	});
    });
    return false;
}

/**
 * Handler for listing available kernel modules for tv
 */
define boolean ListModulesHandler (map options) {

    Tv::ReadKernelModules ();
    map modules = haskey (options,"radio") ?
	Tv::radio_modules : Tv::kernel_modules;
    foreach (string key, map value, (map<string,map>) modules, {
	string space = "\t";
	CommandLine::Print (key + space + value["module_description"]:"");
    });
    return false;
}

/**
 * Handler for enabling/disabling IRC
 */
define boolean IRCHandler (map<string,string> options) {

    string command = CommandLine::UniqueOption (options,
	["enable", "disable", "status"] );

    if (command == "status")
    {
	if (!Tv::use_irc)
	    // status text
	    CommandLine::Print (_("Infrared control is disabled."));
	else
	    // status text
	    CommandLine::Print (sformat (
	    _("Infrared control is enabled using module %1."),Tv::irc_module));
	return false;
    }

    Tv::irc_modified	= Tv::irc_modified ||
			  (command == "enable" && !Tv::use_irc) ||
			  (command == "diasble" && Tv::use_irc);
    Tv::use_irc		= command == "enable";
//    Tv::irc_module	= TODO

    return Tv::irc_modified;
}

/**
 * Wrapper function for reading the settings (used by cmd-line)
 * @return boolean success
 */
define boolean TvRead () ``{

    block<boolean> abort_block = ``{return false;};
    return Tv::Read (abort_block);
}

/**
 * Wrapper function for writing the settings (used by cmd-line)
 * @return boolean success
 */
define boolean TvWrite () ``{

    block<boolean> abort_block = ``{return false;};
    return Tv::Write (abort_block);
}


/* the command line description map */
map cmdline = $[
    "id"		: "tv",
    // translators: command line help text for Tv module
    "help"		: _("TV card configuration module."),
    "guihandler"	: TvSequence,
    "initialize"	: TvRead,
    "finish"		: TvWrite,
    "actions"		: $[
	"summary" :$[
	    "handler"	: SummaryHandler,
	    // translators: command line help text for summary action
	    "help"	: _("Configuration summary of TV cards")
	],
	"add" :$[
	    "handler"	: AddCardHandler,
	    // translators: command line help text for add action
	    "help"	: _("Add TV card. Without parameters, add first one detected."),
	    "options"	: [ "non_strict" ],
	    // help text for unknown parameters
	    "non_strict_help": _("Value of the specific module parameter"),
	],
	"remove" :$[
	    "handler"	: RemoveCardHandler,
	    // translators: command line help text for remove action
	    "help"	: _("Remove TV or radio card")
	],
	"modules": $[
	    "handler"	: ListModulesHandler,
	    // translators: command line help text for modules action
	    "help"	: _("List all available TV kernel modules (drivers).")
	],
	"cards": $[
	    "handler"	: ListModelsHandler,
	    // translators: command line help text for 'cards' action
	    "help"	: _("List supported TV models with their ID numbers.")
	],
	"set": $[
	    "handler"	: SetParametersHandler,
	    // translators: command line help text for set action
	    "help"	: _("Set the new values for given card parameters."),
	    "options"	: [ "non_strict" ],
	    // help text for unknownd parameters; do not translate 'show'
	    "non_strict_help" : _("Value of the specific module parameter."),
	],
	"show": $[
	    "handler"	: ShowCardHandler,
	    // translators: command line help text for test action
	    "help"	: _("Show the information of given TV card")
	],
	"irc": $[
	    "handler"	: IRCHandler,
	    // translators: command line help text for test action
	    "help"	: _("Enable or Disable Infrared Control")
	],
    ],
    "options"		: $[
	"no"	:$[
	    // translators: command line help text for the 'no' option
	    "help"	: _("Number of TV or radio card"),
	    "type"	: "string"
	],
	"tuner"	:$[
	    // translators: command line help text for the 'tuner' option
	    "help"	: _("TV tuner type"),
	    "type"	: "string"
	],
	"module"	:$[
	    // translators: command line help text for the 'module' option
	    "help"	: _("Kernel module (driver) for the TV or radio card"),
	    "type"	: "string"
	],
	"card"	:$[
	    // translators: command line help text for the 'card' option
	    "help"	: _("ID of specific TV card model. Use the 'cards' command to see the list of possible values."),
	    "type"	: "string"
	],
	"radio"	:$[
	    // translators: command line help text for the 'radio' option
	    "help"	: _("List radio modules instead of TV ones"),
	],
	"enable"	:$[
	    // translators: command line help text for the 'enable' option
	    "help"	: _("Enable IRC"),
	],
	"disable"	:$[
	    // translators: command line help text for the 'disable' option
	    "help"	: _("Disable IRC"),
	],
	"status"	:$[
	    // translators: command line help text for the 'status' option
	    "help"	: _("Show current status of IRC"),
	],
    ],
    "mappings"		: $[
	"summary"	: [],
	"add"		: [ "no", "tuner", "card", "module"],
	"set"		: [ "no", "tuner", "card"],//TODO edit alias
	"modules"	: [ "radio" ],
	"cards"		: [ "module" ],
	"show"		: [ "no" ],
	"remove"	: [ "no" ],//delete alias
	"irc"		: [ "enable", "disable", "status"],
	//FIXME use irc client! + "module" option
    ]
];

// --------------------------------------------------------------------------

    any ret = nil;
    if (no_io)
    {
	ret = TvSequenceNoIO ();
    }
    else
    {
	ret = CommandLine::Run( cmdline );
    }

    y2debug ("ret == %1", ret);

    /* Finish */
    y2milestone ("Tv module finished");
    y2milestone ("----------------------------------------");
    return ret;

/* EOF */
}
