/**
 * File:	include/network/lan/address.ycp
 * Package:	Network configuration
 * Summary:	Network card adresss configuration dialogs
 * Authors:	Michal Svec <msvec@suse.cz>
 *
 * $Id: address.ycp 22390 2005-03-09 16:10:59Z mvidner $
 */

{

textdomain "network";

import "Arch";
import "Detection";
import "IP";
import "Label";
import "Lan";
import "Netmask";
import "NetworkDevices";
import "Popup";
import "ProductFeatures";
import "Routing";
import "SuSEFirewall4Network";
import "Wizard";

include "network/summary.ycp";

/**
 * Precedes AddressDialog.
 * #63767:
 * Usercontrol needs to be on for new wlan cards. But we only know that it
 * is wlan at this point, not yet in Lan::Select or so. And it cannot
 * be done in AddressDialog itself because there the user may want to
 * change the value in a subdialog.
 */
symbol ChangeDefaults () {
    if (Lan::type == "wlan" && Lan::operation == `add)
    {
	y2milestone ("Adding wlan, usercontrol is on");
	Lan::usercontrol = true;
    }
    return `next;
}

/**
 * Dialog for setting up IP address
 * @return dialog result
 */
define any AddressDialog() {

    ScreenName("lan-address");

    /* Address dialog caption */
    string caption = _("Network Address Setup");

    /* Address dialog help 1/8 */
    string help = _("<p>Configure your IP address.</p>") +

	(ProductFeatures::force_static_ip ?

    /* Address dialog help 2-6/8: static address preferred */
    _("<p>DHCP configuration is not recommended for this product.
Components of this product might not work with DHCP.</p>")
	 :
    /* Address dialog help 2-6/8: dynamic address preferred */
    /* Address dialog help 2/8 */
    _("<p>You can select dynamic address assignment
if you have a <b>DHCP server</b> running on your local network.</p>
") +

    /* Address dialog help 3/8 */
    _("<p>Also select this if you do not have a static IP address assigned
by the system administrator or your cable or DSL provider.</p>") +

    /* Address dialog help 4/8 */
    _("<p>Network addresses are then obtained
<b>automatically</b> from the server.</p>
") +

    /* Address dialog help 5/8 */
    _("<p>Clicking <b>Next</b> completes the configuration.</p>") +

    /* Address dialog help 6/8 */
    _("<p>Otherwise, network addresses must be assigned <b>manually</b>.</p>")
	 ) +

    /* Address dialog help 7/8 */
    _("<p>Enter the IP address (e.g., 192.168.100.99) for your computer,
the network mask (usually 255.255.255.0), and, optionally, the default gateway
IP address.</p>") +

    /* Address dialog help 8/8 */
    _("<p>Contact your <b>network administrator</b> for more information about
the network configuration.</p>");

    string bootproto = Lan::bootproto;
    string ipaddr = Lan::ipaddr;
    string remoteip = Lan::remoteip;
    string netmask = Lan::netmask;
    string type = Lan::type;
    string device = "";

    if(!Arch::s390 () && type != "dummy" && bootproto == "static" && ipaddr == "")
	bootproto = "dhcp";

    if(ipaddr == "" && netmask == "") {
	netmask = "255.255.255.0";
    }

    if(false && Lan::device == "") {
	y2error("Empty device");
	/* Label text (Network device: unknown device) */
	device = _("Unknown Device");
    }
    else if(Lan::alias == "") {
	device = NetworkDevices::device_name(NetworkDevices::RealType(Lan::type, Lan::hotplug), Lan::device);
    }
    else {
	device = NetworkDevices::alias_name(NetworkDevices::RealType(Lan::type, Lan::hotplug), Lan::device, Lan::alias);
	bootproto = "static";
    }

    // FIXME duplicated in hardware.ycp
    list<string> device_types = [ "arc", "bnep", "dummy", "eth", "fddi", "myri", "tr", "usb", "wlan" ];

    if(Arch::s390 ())
	device_types = [ "eth", "tr", "hsi", "ctc", "escon", "iucv", "qeth", "lcs" ];

    if(Arch::ia64 ())
	device_types = add(device_types, "xp");

    term label = `HBox(
	/* Label text */
	`Label(_("Network Device")),
	`HSpacing(0.5),
	`Label(`opt(`outputField), device)
    );
    if(Lan::operation == `add) {
	/* TextEntry label */
//	label = `TextEntry(`id(`device), _("&Configuration Name"), device);
	label = `HBox (
	    `HSpacing(0.5),
	    // The combo is a hack to allow changing misdetected
	    // interface types. It will work in some cases, like
	    // overriding eth to wlan but not in others where we woild
	    // need to change the contents of the dialog. #30890.
	    `ComboBox(`id(`dev), `opt(`hstretch, `notify),
		      /* ComboBox label */
		      _("&Device Type"), BuildTypesList(device_types, type)),
		    `HSpacing(1.5),
	    `ComboBox (`id(`num), `opt(`editable, `hstretch), _("&Configuration Name"), [Lan::device]),
		    `HSpacing(0.5)
	    );
    }

    /* Allow to edit the device (#17346) * /
    if(Lan::operation == `add)
	label = `ComboBox(`id(`num), `opt(`hstretch),
		_("N&etwork device"),
		maplist(integer d, Lan::FreeDevices(RealType), ``(
		    sformat("%1%2",type,d)
		)));

    Moved to lan/hardware.ycp */

    /* Frame label */
    term frame1 = `Frame(_("Setup Method"),
	`RadioButtonGroup(`id(`rb), `HBox(`HSpacing(1),
	    `VBox(
		`VSpacing(0.5),
		/* Radio button label */
		`Left(`RadioButton(`id(`dhcp), `opt(`notify), _("A&utomatic Address Setup (via DHCP)"), bootproto == "dhcp")),
		`VSpacing(0.4),
		/* Radio button label */
		`Left(`RadioButton(`id(`static), `opt(`notify), _("S&tatic Address Setup"), bootproto == "static")),
		`HBox(
		    /* Text entry label for IP address */
		    `TextEntry(`id(`ipaddr), _("&IP Address"), ipaddr),
		    `HSpacing(2),
		    /* Text entry label for network mask */
		    `TextEntry(`id(`netmask), _("&Subnet Mask"), netmask)
		),
		`VSpacing(0.5)
	    ),
	`HSpacing(1)))
    );

    if(Arch::s390 ()) {

    /* Address dialog help 1/8 */
    help = _("<p>Configure your IP address.</p>");

    if(!Arch::s390 ())
    /* Address dialog help 2/8 */
    help = help + _("<p>You can select dynamic address assignment
if you have a <b>DHCP server</b> running on your local network.</p>
") +

    /* Address dialog help 3/8 */
_("<p>Also select this if you do not have a static
IP address assigned by the system administrator or your cable or DSL provider.
</p>") +

    /* Address dialog help 4/8 */
_("<p>Network addresses are then obtained
<b>automatically</b> from the server.</p>
") +

    /* Address dialog help 5/8 */
_("<p>Otherwise, network addresses must be assigned
<b>manually</b>.</p>");

    if(type == "ctc" || type == "escon" || type == "iucv")
    /* Address dialog help 6/8 */
help = help + _("<p>Enter the <b>IP Address</b> (e.g., 192.168.100.99)
for your computer and the <b>Remote IP Address</b> (e.g., 192.168.100.254)
of your peer.</p>");

    else
    /* Address dialog help 6/8 */
    help = help + _("<p>Enter the IP address (e.g., 192.168.100.99) for
your computer, the network mask (usually 255.255.255.0), and, optionally, the
default gateway IP address.</p>");

    /* Address dialog help 7/8 */
    help = help + _("<p>Contact your <b>network administrator</b>
for more information about the network configuration.</p>") +

    /* Address dialog help 8/8 */
_("<p>Clicking <b>Next</b>
completes the configuration.</p>");

    /* s390 help hackery */
    }

    /* No DHCP Setup */
    if(type == "dummy" || type == "hsi" || Lan::alias != "" || Arch::s390 ())

	/* Frame label */
	frame1 = `Frame(_("Static Address Setup"), `VBox(
	    `VSpacing(0.5),
	    `HBox(
		/* Text entry label */
		`TextEntry(`id(`ipaddr), _("&IP Address"), ipaddr),
		`HSpacing(2),
		/* Text entry label */
		`TextEntry(`id(`netmask), _("&Subnet Mask"), netmask)
	    ),
	    `VSpacing(0.5)
	));

    /* PPP devices */
    if(type == "ctc" || type == "escon" || type == "iucv")

	/* Frame label */
	frame1 = `Frame(_("Static Address Setup"), `VBox(
	    `VSpacing(0.5),
	    `HBox(
		/* Text entry label */
		`TextEntry(`id(`ipaddr), _("&IP Address"), ipaddr),
		`HSpacing(2),
		/* Text entry label */
		`TextEntry(`id(`remoteip), _("R&emote IP Address"), remoteip)
	    ),
	    `VSpacing(0.5)
	));

    list MB_list = [
	/* MenuButton item */
	`item(`id(`hardware), _("H&ardware Details")),
	/* MenuButton item */
	`item(`id(`dhclient), _("DHCP &Client Options")),
	/* MenuButton item */
	`item(`id(`details), _("&Detailed Settings")),
	/* MenuButton item */
	`item(`id(`virtual), _("Addi&tional Addresses")),
    ];

    list MB_backup = [
	/* MenuButton item */
	`item(`id(`hostname), _("&Host Name and Name Server")),
	/* MenuButton item */
	`item(`id(`routing), _("R&outing")),
	/* MenuButton item */
	`item(`id(`hosts), _("Host&s")),
	/* MenuButton item */
	`item(`id(`proxy), _("&Proxy")),
    ];

    /* MenuButton item */
    if(Arch::s390 () && (Lan::type == "qeth" || Lan::type == "ctc" || Lan::type == "lcs"))
	MB_list = add(MB_list, `item(`id(`s390), _("&S/390")));

    /* MenuButton label */
    term MB = `MenuButton(`id(`mb), `opt(`hstretch), _("&Advanced..."), MB_list);

    /* Frame label */
    term frame2 = `Frame(_("Detailed Settings"), `HBox(`HStretch(),
	`HSquash(`VBox(
	    `VSpacing(0.4),
	    /* Push button label */
	    `PushButton(`id(`hostname), `opt(`hstretch), _("&Host Name and Name Server")),
	    /* Push button label */
	    `PushButton(`id(`routing), `opt(`hstretch), _("R&outing")),
	    MB,
	    `VSpacing(0.4)
	)),
	`HStretch()
    ));

    if(Lan::alias != "")
	frame2 = `VSpacing(0);

    /* Address dialog help */
    term contents = `HSquash(`VBox(
//	`Left (`TextEntry (`id (`persistent), _("&Persistent name"), "BAR")),
//	`VSpacing(0.4),
	`Left(label),
	`VSpacing(1),
	frame1,
	`VSpacing(1),
	frame2
    ));

    /* Address dialog help * /
    term contents = `HSquash(`VBox(
	`Left(label),
	`VSpacing(1),
	frame1,
//	`VSpacing(1),
//	frame2,
	`VSpacing(0.4),
	MB
    ));
    */

    Wizard::SetContentsButtons(caption, contents, help,
	    Label::BackButton(), Label::NextButton());

    UI::ChangeWidget(`id(`ipaddr), `Enabled, bootproto == "static");
    ChangeWidgetIfExists(`id(`netmask), `Enabled, bootproto == "static");
    ChangeWidgetIfExists(`id(`dhcp), `Value, bootproto == "dhcp");
    ChangeWidgetIfExists(`id(`static), `Value, bootproto == "static");
    ChangeWidgetIfExists(`id(`num), `ValidChars, NetworkDevices::ValidCharsIfcfg ());

    if(bootproto == "static" /* && ipaddr == "" */)
	UI::SetFocus(`id(`ipaddr));

    any ret = nil;
    while(true) {

	ret = UI::UserInput();

	/* abort? */
	if(ret == `abort || ret == `cancel) {
	    if(ReallyAbort()) break;
	    else continue;
	}
	/* static ip address */
	else if(ret == `dhcp) {
	    UI::ChangeWidget(`id(`ipaddr), `Enabled, false);
	    ChangeWidgetIfExists(`id(`netmask), `Enabled, false);
	    ChangeWidgetIfExists(`id(`remoteip), `Enabled, false);
	    continue;
	}
	/* dynamic ip address via dhcp */
	else if(ret == `static) {
	    UI::ChangeWidget(`id(`ipaddr), `Enabled, true);
	    ChangeWidgetIfExists(`id(`netmask), `Enabled, true);
	    ChangeWidgetIfExists(`id(`remoteip), `Enabled, true);
	    continue;
	}
	/* netmask from bits to IP mapping */
	else if(ret == `netmask) {
	    string nm = (string) UI::QueryWidget(`id(`netmask), `Value);
	    if(regexpmatch(nm, "^[0-9]+$"))
		UI::ChangeWidget(`id(`netmask), `Value, Netmask::FromBits(tointeger(nm)));
	    continue;
	}
	/* back */
	else if(ret == `back) {
	    break;
	}
	/* next|routing|hostname|hardware */
	else if(ret == `next || ret == `routing || ret == `hostname ||
		ret == `hardware || ret == `dhclient || ret == `virtual ||
		ret == `details || ret == `hosts || ret == `proxy ||
		ret == `s390) {

	    y2debug("bootproto=%1", bootproto);
	    if(UI::WidgetExists(`id(`rb))) {
		if(UI::QueryWidget(`id(`rb), `CurrentButton) == `dhcp)
		    bootproto = "dhcp";
		else if(UI::QueryWidget(`id(`rb), `CurrentButton) == `static)
		    bootproto = "static";
		else
		    bootproto = "";
	    }

	    y2debug("bootproto=%1", bootproto);
	    if(bootproto == "static") {
		string ipa = (string) UI::QueryWidget(`id(`ipaddr), `Value);
		if(!IP::Check(ipa)) {
		    /* Popup text */
		    Popup::Error(_("The IP address is invalid."));
		    UI::SetFocus(`id(`ipaddr));
		    continue;
		}
		if (Detection::DuplicateIP (ipa)) {
		    /* Popup text */
		    string pop = _("Duplicate IP address detected.
Really continue?
");
		    if(Popup::YesNoHeadline(Label::WarningMsg(), pop) != true) {
			UI::SetFocus(`id(`ipaddr));
			continue;
		    }
		}
		if(UI::WidgetExists(`id(`remoteip)) && !IP::Check((string) UI::QueryWidget(`id(`remoteip), `Value))) {
		    /* Popup text */
		    Popup::Error(_("The remote IP address is invalid."));
		    UI::SetFocus(`id(`remoteip));
		    continue;
		}
		if(UI::WidgetExists(`id(`netmask)) && !Netmask::Check((string) UI::QueryWidget(`id(`netmask), `Value))) {
		    /* Popup text */
		    Popup::Error(_("The subnet mask is invalid."));
		    UI::SetFocus(`id(`netmask));
		    continue;
		}
	    }
	    if(Lan::operation == `add) {
		device = NetworkDevices::device_name (
		    (string) UI::QueryWidget(`id(`dev), `Value),
		    (string) UI::QueryWidget(`id(`num), `Value));
		y2debug("device=%1", device);
		if(NetworkDevices::Check(device)) {
		    /* Popup text */
		    Popup::Error(sformat(_("Configuration %1 already present."), device));
		    UI::SetFocus(`id(`dev));
		    continue;
		}
		// FIXME obsolete?
		if(!regexpmatch(NetworkDevices::device_type(device), NetworkDevices::DeviceRegex["netcard"]:"")) {
		    /* Popup text */
		    Popup::Error(sformat(_("Unsupported network card type: %1."), NetworkDevices::device_type(device)));
		    UI::SetFocus(`id(`dev));
		    continue;
		}
		if (NetworkDevices::device_type (device) != Lan::type)
		{
		    UI::SetFocus(`id(`dev));
		    if (!Popup::ContinueCancel (
_("You have changed the interface type from the one
that has been detected. This only makes sense
if you know that the detection is wrong.")))
		    {
			continue; // continue means cancel here... ;-)
		    }
		}

		// If firewall is active and interface in no zone, nothing
		// gets through (#47309) so add it to the external zone
		if ((ret == `next || ret == `details) &&
		    SuSEFirewall4Network::IsOn ())
		{
		    SuSEFirewall4Network::ProtectByFirewall (device, "EXT", true);
		}
	    }
	    else // not add
	    {
		// If firewall is active and interface in no zone, nothing
		// gets through (#47309) so warn and redirect to details
		if (ret == `next &&
		    SuSEFirewall4Network::IsOn () &&
		    SuSEFirewall4Network::GetZoneOfInterface (device) == "")
		{
		    if (Popup::YesNoHeadline (Label::WarningMsg (),
_("The firewall is active, but this interface is not
in any zone. All its traffic would be blocked.
Assign it to a zone now?")))
		    {
			ret = `details;
		    }
		}
	    }

	    break;
	}
	else {
	    y2error("Unexpected retcode: %1", ret);
	    continue;
	}

    }

    /* update the configuration */
    if(ret == `next || ret == `routing || ret == `hostname || ret == `hardware
	    || ret == `dhclient || ret == `virtual || ret == `details ||
	    ret == `hosts || ret == `proxy || ret == `s390) {

	if(Lan::operation == `add) {
	    device = NetworkDevices::device_name (
		(string) UI::QueryWidget(`id(`dev), `Value),
		(string) UI::QueryWidget(`id(`num), `Value));
	    Lan::device = NetworkDevices::device_num(device);
	    Lan::type = NetworkDevices::device_type(device);
	}

	Lan::bootproto = bootproto;
	Lan::ipaddr = (string) UI::QueryWidget(`id(`ipaddr), `Value);

	Lan::netmask = (string) QueryWidgetIfExists(`id(`netmask), `Value, Lan::netmask);
	Lan::remoteip = (string) QueryWidgetIfExists(`id(`remoteip), `Value, Lan::remoteip);
    }

    // proceed with WLAN settings if appropriate, #42420
    if (ret == `next && Lan::type == "wlan" && Lan::alias == "")
    {
	ret = `wire;
    }

    if(ret == `routing)
	Routing::SetDevices(NetworkDevices::List(""));

    return ret;
}

/* EOF */
}
