/*
 *************************************************************
 *
 *     YaST2      SuSE Labs                        -o)
 *     --------------------                        /\\
 *                                                _\_v
 *           www.suse.de / www.suse.com
 * ----------------------------------------------------------
 *
 * Author:        Michael Hager <mike@suse.de>
 *                Johannes Buchhold <jbuch@suse.de>
 *
 *
 * Description:   Partitioner for experts.
 *                include for dialogs
 *
 *************************************************************

 $Id: custom_part_dialogs.ycp 21865 2005-02-23 13:33:50Z mvidner $

*/
{
  textdomain "storage";

  import "Storage";
  import "Partitions";
  import "FileSystems";
  import "Mode";
  import "Arch";
  import "Label";

  //////////////////////////////////////////////////////////////////////////////
  // Dialog Password for Crypted FS
  //////////////////////////////////////////////////////////////////////////////

  include "partitioning/partition_defines.ycp";
  include "partitioning/custom_part_helptexts.ycp";

  include "partitioning/signatures.ycp";

  
define string DlgCreateCryptFs( integer minpwlen )
  ``{
    string helptext = GetCreateCryptFsHelptext(minpwlen);
    y2milestone( "DlgCreateCryptFs minpwlen:%1", minpwlen );
	     
    UI::OpenDialog(
	     `opt(`decorated ),
	     `HBox(
		   `HWeight(3, `RichText( helptext ) ),
		   `HWeight(6, `VBox(
				    `VSpacing(0.3),
				    `HBox(
					  `HSpacing(1),
					  // heading text
					  `Heading(_("Enter your password for the encrypted file system")),
					  `HSpacing(1)
					 ),
				    `VSpacing(4),
				    `HBox(
					  `HSpacing(4),
					  `VBox(
						// label text
						`Label(_("Don't forget what you enter here!")),
						`VSpacing(),
	 
						`Left(`Password(`id("pw1"),
						 // Label: get password for user root
						 // Please use newline if label is longer than 40 characters
								_("&Enter a password for your file system:"), "")),
						`VSpacing(0.5),
						    
						`Left(`Password(`id("pw2"),
						 // Label: get same password again for verification
						 // Please use newline if label is longer than 40 characters
								_("Reenter the password for &verification:"), ""))
						),
					  `HSpacing(4)
					 ),
				    `VSpacing(3),
				    `HBox(
					  // Ok button
					  `PushButton(`id("ok"), `opt(`default),  Label::OKButton()),
					  // Cancel button
					  `PushButton(`id("cancel"),   Label::CancelButton())
					  ),
				    `VSpacing(0.5)
				    )
			   )
	     ));

      string  ret         = "";
      boolean input_is_ok = false;
      string pw1 	  = "";
      string pw2 	  = "";
	  
      repeat
      {
	  // Clear password fields on every round.
	  UI::ChangeWidget(`id("pw1"), `Value, "");
	  UI::ChangeWidget(`id("pw2"), `Value, "");
      
	  UI::SetFocus(`id("pw1"));
	  
	  ret = (string) UI::UserInput();

      
	  if (ret != "cancel")
	  {
	      pw1 = (string)UI::QueryWidget(`id("pw1"), `Value);
	      pw2 = (string)UI::QueryWidget(`id("pw2"), `Value);
	  
	      if ( pw1 != pw2 )
	      {
		  // popup text
		  Popup::Message(_("The first and the second version\nof the password do not match!\nPlease try again."));
	      }
	      else  if (pw1 == "")
	      {
		  // popup text
		  Popup::Message(_("You did not enter a password.
Try again.
"));
	      }
	      else if (size (pw1) < minpwlen)
	      {
		  // popup text
		  Popup::Message(sformat(_("The password must have at least %1 characters.
Try again.
"),minpwlen));
	      }
	      else if ( size(pw1) >= minpwlen )
	      {
		  any ret2 = findfirstnotof( pw1, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#* ,.;:._-+!$%&/|\?{[()]}" );

		  if ( ret2 != nil )
		  {
		      // popup text
		      Popup::Message(_("The password may only contain the following characters:
 0..9, a..z, A..Z, and any of \"#* ,.;:._-+!$%&/|\?{[()]}\".
Please try again."));
		  }
		  else
		  {
		      input_is_ok = true;
		  }
	      }
	  }

      } until ( input_is_ok || ret == "cancel" );

      UI::CloseDialog();

      if (ret == "cancel")
	  {
	  pw1 = "";
	  }
    y2milestone( "DlgCreateCryptFs size(ret):%1", size(pw1) );
    return( pw1 );
  }


//////////////////////////////////////////////////////////////////////////////
// Dialog Password for Crypted FS Update
//////////////////////////////////////////////////////////////////////////////

  
define string DlgUpdateCryptFs( string device, string mount )
    ``{
    string helptext = GetUpdateCryptFsHelptext();

// translator comment: %1 is the device name, %2 is a directory
//            example: "...password for device /dev/hda6 mounted on /var"
    string enter = sformat(_("You have to enter your crypt password for 
device %1 mounted on %2"),device,mount);
	     
    UI::OpenDialog(
	     `opt(`decorated ),
	     `HBox(
		   `HWeight(3, `RichText( helptext ) ),
		   `HWeight(6, `VBox(
				    `VSpacing(0.3),
				    `HBox(
					  `HSpacing(1),
					  // heading text
					  `Heading(_("Enter your password for the encrypted file system")),
					  `HSpacing(1)
					 ),
				    `VSpacing(2),
				    `HBox(
					  `HSpacing(4),
					  `VBox(
						// advise user to remember his new password
						`Label(enter),
						`VSpacing(),
	 
						`Left(`Password(`id("pw1"),
						 // Label: get password for user root
						 // Please use newline if label is longer than 40 characters
								_("&Enter a password for your file system:"), "")),
						`VSpacing(0.5),
						
						`Left(`Password(`id("pw2"),
						 // Label: get same password again for verification
						 // Please use newline if label is longer than 40 characters
								_("Reenter the password for &verification:"), ""))
						),
					  `HSpacing(4)
					  ),
				    `VSpacing(2),
				    `HBox(
					  // Ok button
					  `PushButton(`id("ok"), `opt(`default),  Label::OKButton()),
					  // Cancel button
					  `PushButton(`id("cancel"),   Label::CancelButton())
					  ),
				    `VSpacing(0.5)
				    )
			   )
	     ));

      string ret         = "";
      boolean input_is_ok = false;
      string pw1 	  = "";
      string pw2 	  = "";
	  
      repeat
      {
	  // Clear password fields on every round.
	  UI::ChangeWidget(`id("pw1"), `Value, "");
	  UI::ChangeWidget(`id("pw2"), `Value, "");
      
	  UI::SetFocus(`id("pw1"));
	  
	  ret = (string)UI::UserInput();

      
	  if (ret != "cancel")
	  {
	      pw1 = (string)UI::QueryWidget(`id("pw1"), `Value);
	      pw2 = (string)UI::QueryWidget(`id("pw2"), `Value);
	  
	      if ( pw1 != pw2 )
	      {
		  // popup text
		  Popup::Message(_("The first and the second version\nof the password do not match!\nPlease try again."));
	      }
	      else  if (pw1 == "")
	      {
		  // popup text
		  Popup::Message(_("You did not enter a password.
Try again.
"));
	      }
	      else if ( size(pw1) >= 5 )
	      {
		  input_is_ok = true;
	      }
	  }

      } until ( input_is_ok || ret == "cancel" );

      UI::CloseDialog();
		       
      if (ret != "cancel")
      {
	  return( pw1 );
      }
      else
      {
	  return( "" );
      }
	      
  }

define symbol DoInputChecks( map entry, string query )
    ``{
    symbol ret = `ok;
    list between = entry[`between]:[];
    string valid_chars = entry[`valid_chars]:"";
    integer str_length = entry[`str_length]:0;

    if( between != [] )
	{
	if( between[0]:0 > tointeger(query)  ||
	    ( (between[1]:0 != -1) && (between[1]:0 < tointeger(query) ) ) )
	    {
	    Popup::Error(entry[`error_text]:"");
	    ret = `error;
	    }
	}

    if( valid_chars != ""  && ret != `error )
	{
	if( nil != findfirstnotof( query, valid_chars ))
	    {
	    Popup::Error(entry[`error_text]:"");
	    ret = `error;
	    }
	}

    if( str_length != 0 && size(query) > str_length && ret != `error )
	{
	Popup::Error(entry[`error_text]:"");
	ret = `error;
	}
    y2milestone( "value %1 ret %2", query, ret );
    return( ret );
    }

  /**
   * Dialog: Filesystem options
   * @parm new_val map that contains a partition
   * @parm file_systems filesystem definitions
   */
define map FileSystemOptions( map org_fs_options, map fs_define  ) 
    ``{
    map<any, map<string,any> > fs_options     = (map<any, map<string,any> >)eval(org_fs_options);
    term contents 	= `VBox(`VSpacing (1));
    string helptext   = "";
    
    foreach( map option, fs_define[`options]:[],  
	``{
	term emptyterm = `Empty();
	contents = add( contents, option[`widget]:emptyterm);
	string add_help = option[`help_text]:"";
	if( add_help != "")
	    helptext = helptext + add_help ;
	});
 
    UI::OpenDialog( `opt(`decorated), 
		    `HBox(
			`HWeight(4, `RichText( helptext )),
			`HWeight(7, 
			    `VBox(
				`HSpacing(50),
				// heading text
				`Left(`Heading(_("File system options:"))),
				`VStretch(),
				`VSpacing(1),
				`HBox(
				    `HStretch(),
				    `HSpacing(1),
				    contents,
				    `HStretch(),
				    `HSpacing(1)),
				    `VSpacing(1),
				    `VStretch(),
				    `HBox(
					`Bottom(`PushButton(`id(`ok),
							    `opt(`default),
							    Label::OKButton())),
					`Bottom(
					  `PushButton(`id(`cancel), 
						      Label::CancelButton())))
					))));

    foreach(any query_key, map<string, any> option_map, fs_options , 
	``{
	UI::ChangeWidget( `id(query_key), `Value, 
			  option_map["option_value"]:"" );
	});

	    
    symbol ret = `ok;
    repeat
	{
	ret = (symbol)UI::UserInput();
	if( ret == `ok )
	    {
	    foreach( map entry, fs_define[`options]:[],  
		``{
		y2milestone( "FileSystemOptions entry %1", entry );
		if( ret != `error )
		    {
		    any query = UI::QueryWidget( `id(entry[`query_key]:nil), 
		                                 `Value );
		    y2milestone( "FileSystemOptions query %1", query );
		    map<string,any> fs_option = 
			$[ "option_str"   : entry[`option_str]:"", 
			   "option_value" : query ];
		    y2milestone( "FileSystemOptions fs_option %1", fs_option );

		    if( entry[`option_blank]:false )
			{
			fs_option["option_blank"] = true;
			}


		    if( is( query, string) && 
		        !contains( (list<any>)["auto", "none", "default"], 
			           query ))
			{
			ret = DoInputChecks( entry, (string)query );
			}

		    if( query != entry[`default]:nil && ret != `error )
			{
			fs_options[entry[`query_key]:nil] = fs_option;
			}
		    y2milestone( "FileSystemOptions fs_options %1", fs_options );
		    }
		});
	    }
	} until ( ret == `ok || ret == `cancel );

    UI::CloseDialog();

    if( ret == `ok )
	return fs_options;
    return ( org_fs_options );
    }

  /**
   * Dialog: Fstab options
   * @parm old map with original partition
   * @parm new map with changes filled in
   */
define map<string,any> FstabOptions( map<string,any> old, map<string,any> new ) 
    ``{
    string helptext = "";
    term contents = `VBox();
    term emptyterm = `Empty();
    
    if( !new["loop_fs"]:false && new["mount"]:"" != "swap" )
	{
	// help text, richtext format
	helptext = helptext + _("<p><b>Mount in /etc/fstab by:</b>
Normally, a file system to mount is identified in /etc/fstab
by the device name. This identification can be changed so the file system to mount
is found by searching for a UUID or a volume label. Not all file systems can be 
mounted by UUID or a volume label. If an option is disabled, it is not possible.
");

	// help text, richtext format
	helptext = helptext + _("<p><b>Volume label:</b>
The name entered in this field is used as the volume label. This normally only
makes sense when you activate the option for mounting by volume label.
");

	contents = add( contents,
			`VBox(  
			    `RadioButtonGroup( 
				`id(`mt_group),
				`VBox( 
				     // label text
				    `Left( `Label(_("Mount in /etc/fstab by"))),
				    `Left( `RadioButton( `id(`device),
							 // label text
							 _("&Device name") )),
				    `Left( `RadioButton( `id(`label),
							 // label text
							 _("Volume &label") )),
				    `Left( `RadioButton( `id(`uuid), "U&UID" ))
				     )
				),
			   `TextEntry( `id(`vol_label), `opt(`hstretch), 
				       // label text
				       _("Volume &Label")),
			   `VSpacing(1)
		       ));
	}
    list<map> opt_list = [];
    if( new["mount"]:"" != "swap" )
	{
	foreach( map entry, FileSystems::GetGeneralFstabOptions(),
	    ``{
	    opt_list = add( opt_list, entry );
	   
	    contents = add( contents, entry[`widget]:emptyterm );
	    helptext = helptext + entry[`help_text]:"";
	    });
	contents = add( contents, `VSpacing(1) );
	}
    foreach( map entry, FileSystems::GetFstabOptWidgets( new["used_fs"]:`ext2 ),
	``{
	opt_list = add( opt_list, entry );
	contents = add( contents, entry[`widget]:emptyterm );
	helptext = helptext + entry[`help_text]:"";
	});
    contents = add( contents, `VSpacing(1) );
    map entry = FileSystems::GetArbitraryOptionField();
    opt_list = add( opt_list, entry );
    contents = add( contents, entry[`widget]:emptyterm );
    helptext = helptext + entry[`help_text]:"";

    string fstopt = deletechars( new["fstopt"]:"", " \t" );
    if( fstopt == "default" )
	fstopt = "";

    list<string> opt_lstr = splitstring( fstopt, "," );
    map old_state = $[];
    integer pos = 0;
    foreach( map opt, opt_list,
	``{
	if( opt[`type]:`text == `boolean )
	    {
	    boolean value = opt[`default]:false;
	    pos = 0;
	    while( pos < size(opt_lstr) )
		{
		foreach( list list_el, opt[`str_scan]:[],
		    ``{
		    if( list_el[0]:""==opt_lstr[pos]:"" )
			{
			value = list_el[1]:0 == 1;
			opt_lstr[pos] = "";
			}
		    });
		pos = pos + 1;
		}
	    old_state[opt[`query_key]:""] = value;
	    }
	else
	    {
	    string value = opt[`default]:"";
	    integer pos = 0;
	    while( pos < size(opt_lstr) )
		{
		if( size(opt[`str_scan]:"")>0 && 
		    regexpmatch( opt_lstr[pos]:"", opt[`str_scan]:"" ))
		    {
		    value = regexpsub( opt_lstr[pos]:"", 
		                       opt[`str_scan]:"", "\\1" );
		    opt_lstr[pos] = "";
		    }
		pos = pos + 1;
		}
	    old_state[opt[`query_key]:""] = value;
	    }
	});

    pos = size(opt_lstr)-1;
    while( pos>=0 )
	{
	if( size(opt_lstr[pos]:"")==0 )
	    {
	    opt_lstr = remove( opt_lstr, pos );
	    }
	pos = pos - 1;
	};
    y2milestone( "key=%1 val:%2", opt_list[size(opt_list)-1,`query_key]:"",
                 mergestring( opt_lstr, "," ) );
    string arb_opt = mergestring( opt_lstr, "," );
    if( new["loop_fs"]:false && !new["noauto"]:false && 
        new["crypt"]:"none"!="none" )
	{
	arb_opt = FileSystems::RemoveCryptOpts( arb_opt );
	}

    old_state[opt_list[size(opt_list)-1,`query_key]:""] = arb_opt;
    y2milestone( "old_state=%1", old_state );

    UI::OpenDialog( `opt(`decorated), 
                    `HBox(
			`HWeight(4, `RichText( helptext )),
			`HWeight(7, 
			    `VBox(
				`HSpacing(50),
			        // heading text
				`Left(`Heading(_("Fstab options:"))),
				`VStretch(),
				`VSpacing(1),
				`HBox(`HStretch(),
				`HSpacing(1),
				contents,
				`HStretch(),
				`HSpacing(1)),
				`VSpacing(1),
				`VStretch(),
				`HBox(
				    `Bottom(`PushButton(`id(`ok),
							`opt(`default),
							Label::OKButton())),
				    `Bottom(`PushButton(`id(`cancel), 
				                        Label::CancelButton()))
				    )
				)
			    )
			)
		  );

    if( UI::WidgetExists( `id(`mt_group) ))
	{
	UI::ChangeWidget( `id(`mt_group), `CurrentButton, 
	                  new["mountby"]:`device );
	UI::ChangeWidget( `id(`label), `Enabled, 
			  FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
			      !new["loop_fs"]:false );
	UI::ChangeWidget( `id(`uuid), `Enabled, 
			  (new["format"]:false || size(new["uuid"]:"")>0) &&
			      FileSystems::MountUuid( new["used_fs"]:`unknown ) &&
			      !new["loop_fs"]:false );
	}

    if( UI::WidgetExists( `id(`vol_label) ))
	{
	UI::ChangeWidget( `id(`vol_label), `Enabled, 
			  FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
			      !new["loop_fs"]:false );
	UI::ChangeWidget( `id(`vol_label), `ValidChars, 
			  FileSystems::nchars + "-._:/" );
	UI::ChangeWidget( `id(`vol_label), `Value, new["label"]:"" );
	}

    y2milestone( "Exists opt_user %1", UI::WidgetExists( `id("opt_user")));
    y2milestone( "new=%1", new );
    if( UI::WidgetExists( `id("opt_user") ))
	{
	UI::ChangeWidget( `id("opt_user"), `Enabled, 
			  new["crypt"]:"none"=="none" || new["noauto"]:false );
	}
    foreach( any key, any value, old_state,
	``{
	UI::ChangeWidget( `id(key), `Value, value );
	});

    any ret = `ok;
    repeat
	{
	ret = UI::UserInput();
	y2milestone( "ret %1", ret );
	if( ret == "opt_noauto" )
	    {
	    if( UI::WidgetExists( `id("opt_user") ))
		{
		boolean val = (boolean)UI::QueryWidget( `id("opt_noauto" ), `Value );
		UI::ChangeWidget( `id("opt_user"), `Enabled, 
		                  new["crypt"]:"none"=="none" || val );
		}
	    }
	if( ret == `ok )
	    {
	    if( UI::WidgetExists( `id(`mt_group) ))
		{
		new["mountby"] = UI::QueryWidget( `id(`mt_group), 
		                                  `CurrentButton );
		if( !new["format"]:false && !new["create"]:false &&
		    new["mountby"]:`device != old["mountby"]:`device )
		    {
		    if( !haskey( new, "ori_mountby" ) )
			new["ori_mountby"] = old["mountby"]:`device;
		    }
		new["label"] = UI::QueryWidget( `id(`vol_label), `Value );
		if( new["label"]:"" != old["label"]:"" )
		    {
		    integer max_len = 
			FileSystems::LabelLength( new["used_fs"]:`unknown );
		    if( size(new["label"]:"") > max_len )
			{
			new["label"] = substring( new["label"]:"", 0, max_len );
			// popup text %1 is a number
			Popup::Error( sformat(_("
Maximum volume label length for the selected file system 
is %1. Your volume label was truncated to this size.
"), max_len ));

			}
		    if( !new["format"]:false && !new["create"]:false &&
			!haskey( new, "ori_label" ) )
			{
			new["ori_label"] = old["label"]:"";
			}
		    }
		if( new["mountby"]:`device == `label && size(new["label"]:"")==0 )
		    {
		    ret = `again;
		    // popup text 
		    Popup::Error( _("Provide a volume label to mount by label."));
		    continue;
		    }
		if( new["mountby"]:`device == `label && 
		    !check_unique_label( Storage::GetTargetMap(), new ))
		    {
		    ret = `again;
		    // popup text 
		    Popup::Error( _("This volume label is already in use. Select a different one."));
		    continue;
		    }
		}
	    if( UI::WidgetExists( `id("opt_noauto") ))
		{
		new["noauto"] = UI::QueryWidget( `id("opt_noauto"), `Value );
		}
	    map new_state = $[];
	    string text = "";
	    string new_fstopt = "";
	    foreach( map entry, opt_list, 
		``{
		text = "";
		any value = UI::QueryWidget( `id(entry[`query_key]:""), 
		                             `Value );
		new_state[entry[`query_key]:""] = value;
		if( entry[`type]:`text == `boolean )
		    {
		    text = entry[`str_opt,"default"]:"";
		    if( value == true && haskey( entry[`str_opt]:$[], 1 ))
			{
			text = entry[`str_opt,1]:"";
			}
		    else if( value == false && haskey( entry[`str_opt]:$[], 0 ))
			{
			text = entry[`str_opt,0]:"";
			}
		    }
		else
		    {
		    if( DoInputChecks( entry, (string)value ) != `ok )
			{
			ret = `again;
			}
		    else if( size((string)value)>0 )
			{
			text = sformat( entry[`str_opt]:"%1", value );
			}
		    /* this is the default journal mode, no option needed for it */
		    if( text == "data=ordered" )
			{
			text = "";
			}
		    }
		if( size(text)>0 )
		    {
		    if( size(new_fstopt)>0 )
			new_fstopt = new_fstopt + ",";
		    new_fstopt = new_fstopt + text;
		    }
		});
	    y2milestone( "new_state=%1", new_state );
	    y2milestone( "old_fstopt=%1 new_fstopt=%2", old["fstopt"]:"",
	                 new_fstopt );
	    if( old_state!=new_state && old["fstopt"]:"" != new_fstopt )
		{
		if( !new["format"]:false && !new["create"]:false &&
		    !haskey( new, "ori_fstopt" ) )
		    {
		    new["ori_fstopt"] = old["fstopt"]:"";
		    }
		new["fstopt"] = new_fstopt;
		}
	    if( !CheckFstabOptions( new ))
		{
		new["fstopt"] = old["fstopt"]:"";
		ret = `again;
		}
	    }
	} until ( ret == `ok || ret == `cancel );

    UI::CloseDialog();
    y2milestone( "fstopt %1 mountby:%2 label:%3", new["fstopt"]:"", 
                 new["mountby"]:`device, new["label"]:"" );
    return( new );
    };


/**
   * Dialogpart: Filesystem
   * @parm new_val map that contains a partition
   * @parm file_systems filesystem definitions
   * @return term the term contains a ComboBox with the different filesystems
   */
define term FileSystemsComboBox( map new_val, map<symbol,map> file_systems ) 
    ``{
    map<symbol,map> fs_sel = $[];
    list filesystems = [ ];
    boolean is_swap = new_val["fsid"]:0 == Partitions::fsid_swap;

    y2debug( "new=%1 swap=%2", new_val, is_swap );
    foreach( symbol file_system_name, map file_system_map, file_systems, 
	``{
	if( file_system_map[`supports_format]:false )
	    {
	    fs_sel[file_system_name] = $[];
	    fs_sel[file_system_name,"text"] = file_system_map[`name]:"Ext2";
	    if( is_swap )
		fs_sel[file_system_name,"selected"] = file_system_name == `swap;
	    else
		fs_sel[file_system_name,"selected"] = 
		    new_val["used_fs"]:`reiser == file_system_name;
	    }
	});
    y2debug( "fs_sel=%1", fs_sel );
    if( haskey( fs_sel, `reiser ) &&
	size(filter( any k, map e, fs_sel, ``(e["selected"]:false) ))==0 )
	{
	fs_sel[`reiser,"selected"] = true;
	}
    foreach( symbol fs_type, map entry, fs_sel, 
	``{
	if( fs_type != `swap )
	    filesystems = add( filesystems, 
		`item(`id(fs_type), entry["text"]:"Ext2", entry["selected"]:false ));
	});
    if( haskey( fs_sel, `swap ))
	{
	filesystems = add( filesystems, 
	    `item( `id(`swap), fs_sel[`swap,"text"]:"Swap", 
		    fs_sel[`swap,"selected"]:false ));
	}

    term CryptWidget = `Empty();
    if( !Arch::s390 () )
	{
	boolean cr = new_val["loop_fs"]:false && new_val["crypt"]:""!="none";
	CryptWidget = `VBox( `VSpacing(0.7),
	                     `Left(`CheckBox(`id(`crypt_fs), `opt(`notify),
					    // button text 
			                     _("&Encrypt file system"), cr )));
	}

    return `VBox( 
               `ReplacePoint( `id(`type_dlg_rp), 
			      `ComboBox(`id(`fs), `opt(`hstretch, `notify), 
					// label text 
					_("File &system"), filesystems )),
			      `PushButton( `id(`fs_options ),`opt(`hstretch), 
					   // button text 
					   _("O&ptions") ),
			      CryptWidget );
    }

/**
 * Dialogpart: Filesystem ID
 * @parm new_val map that contains a partition
 * @parm file_systems filesystem definitions
 * @return term the term contains a ComboBox that allow the user to  edit the filesystem ID
 */
define term FsidComboBox( map new_val, map<symbol, map> file_systems  ) 
    ``{
    list items = [];
    list added_items = [];
    list added_fsids = [];
    foreach( any fs_name, map fs_map, file_systems, 
	``{
	string fsid_item =  fs_map[`fsid_item]:" ";
	if( !contains( added_items, fsid_item ))
	    {
	    items = add( items, 
		`item( `id(fsid_item), fsid_item, 
			fs_map[`fsid]:0 == new_val["fsid"]:0));
	    added_fsids = add( added_fsids, fs_map[`fsid]:0 );
	    added_items = add( added_items, fsid_item );
	    }
	});

    integer id = new_val["fsid"]:0;
    if( id != 0 && !contains( added_fsids, id ) )
	{
	string part_id = Partitions::ToHexString(id) + " " +
			 Partitions::FsIdToString(id);
	items = add( items, `item( `id(part_id), part_id, true ));
	}

    return( `ComboBox(`id(`fsid_point), `opt(`notify,`editable, `hstretch), 
	    // label text 
	    _("File system &ID:"), items ));
    };


/**
 * Dialogpart: Size Dialog
 * @parm new_val map that contains a partition
 * @parm edit_size flag 
 * @return term the term contains two TextEntries or to Labels with the start and the end cylinder of
 * the partition in new_val
 */
define term SizeDlg( map new_val , integer cyl_size , boolean edit_size ) 
    ``{
    string start_cyl = sformat( "%1", new_val["region",0]:0 );
    string end_part  = sformat( "%1", (integer)(new_val["region",0]:0) +
				      (integer)(new_val["region",1]:1) -1 );

    float mb_cyl_size   =  ( tofloat(cyl_size) /1024.0 /1024.0 );
    string str_cyl_size =  substring( sformat( "%1", mb_cyl_size ), 0, 4);


    if( new_val["create"]:false && edit_size )
    {		
	// label text 
	return `Frame ( _("Size"),
		`VBox(
		    // label text 
		    `Left(`Label(_("Cylinder size: ")+ str_cyl_size + " M" )),
		    `VSpacing(0.5),
		    // label text
		    `TextEntry(`id(`start_cyl), _("S&tart cylinder:"), start_cyl ),
		    `VSpacing(0.5),
		    // label text
		    `TextEntry(`id(`end_part), _("En&d:  (9 or +9M or +3.2GB)"), end_part)
		    )
		);
    }
    else
    {
	return ( 
		`HBox(      
		    // label text
		    `Left(`Label( _("Type of partition: ")
			    // label text
			    +  _("\nStart cylinder:")
			    // label text
			    +  _("\nEnd cylinder:  ") )),
		    `Left(`Label( new_val["fstype"]:""
			    + "\n " + start_cyl
			    + "\n " + end_part ))
		    ));
    }
}


define term FormatDlg( map new_val, map<symbol, map> file_systems ) 
    ``{
    y2debug( "FormatDlg val:%1", new_val );

    term fsid = `Empty();

    if( new_val["type"]:`primary != `lvm &&
	new_val["type"]:`primary != `sw_raid &&
	new_val["type"]:`primary != `evms &&
	new_val["type"]:`primary != `loop && !Partitions::no_fsid_menu )
	{
	fsid = `VBox( 
		`HBox( `HSpacing(2),
		    `ReplacePoint( `id(`fsid_dlg_rp),  
			FsidComboBox( new_val, file_systems ))
		    ),
		`VSpacing(0.5),
		`VStretch() 
		);
	}
    else
	{
	fsid = `VSpacing(0.5);
	}

		    // label text
    return `Frame (substring(_("2:Format"),2),
	    `RadioButtonGroup(`id(`format),
		`VBox(
		    `VSpacing(1),
		    // button text
		    `Left(`RadioButton(`id(`format_false), `opt(`notify),
		                       _("Do &not format"), !new_val["format"]:false )),
		    fsid,
		    `Left(`RadioButton(`id(`format_true), `opt(`notify),
					// button text
		                        _("&Format"), new_val["format"]:false )),
		    `HBox(
			`HSpacing(2),
			FileSystemsComboBox( new_val , file_systems )),
			`VSpacing(0.5)
					 )));


    }

  

define term RaidOptionsDlg( map new_val, boolean edit_raid_type )
    ``{
    string chunk_size = new_val["chunk_size"]:"";
    string parity_algorithm = new_val["parity_algorithm"]:"";
    boolean persistent_superblock = new_val["persistent_superblock"]:true;
    string raid_type = new_val["raid_type"]:"";
    term editRaid = `VSpacing(1);

    // 4KB .. 4096KB
    list     chunk_list = [];
    integer  i          = 4;
    while(  i <= 4096 )
	{
        string chunk_item = sformat( "%1", i);
        chunk_list = add( chunk_list, 
	                  `item(`id(chunk_item), chunk_item, 
			        chunk_size==chunk_item ));
        i = i*2;
        }
    
    if( edit_raid_type )
	{
	editRaid = `VBox(
			 `VSpacing(),
			 `Left (`ComboBox( `id(`raid_combo), 
			                   `opt(`notify, `hstretch ), 
					   // button text
					   _("RAID T&ype"),
				    [ `item(`id("raid_0"), "raid_0", 
				            "raid0"==raid_type ),
				      `item(`id("raid_1"), "raid_1", 
				            "raid1"==raid_type ),
				      `item(`id("raid_5"), "raid_5",
				            "raid5"==raid_type ),
				      `item(`id("multipath"), "multipath",
				            "multipath"==raid_type )
				    ])),
			 `VSpacing()
			);
	}
  
    return `VSquash(
		    `VBox(
		 editRaid,
		 // Raid combobox description (don't translate to much ..)       
		 `Left (`ComboBox ( `id(`chunk_size),`opt(`hstretch ), _("Chunk s&ize in KB"), chunk_list )),
		 `VSpacing (),
		 // Raid combobox description (don't translate to much ..)       
		 `Left (`ComboBox ( `id(`parity),`opt(`hstretch ), _("Parity &algorithm (only for RAID 5)"),
				    [ `item(`id("left-asymmetric"),  "left-asymmetric",  "left-asymmetric"  == parity_algorithm ),
				    `item(`id("left-symmetric"),   "left-symmetric",   "left-symmetric"   == parity_algorithm ),
				    `item(`id("right-asymmetric"), "right-asymmetric", "right-asymmetric" == parity_algorithm ),
				    `item(`id("right-symmetric"),  "right-symmetric",  "right-symmetric"  == parity_algorithm )
				    ])),
		 `VSpacing (),
				
		 // Raid checkbox option (don't translate to much ..)       
		 `Left (`CheckBox (`id (`persist), _("Persistent s&uperblock"), persistent_superblock)),
		 `VSpacing ()
		 ));	

    }

define term LoopOptionsDlg()
    ``{
    term widget = 
	`VSquash(
	    `VBox(
		 `VSpacing(),
		 `Left( `TextEntry( `id(`loop_path), `opt(`notify),
				   // label text
		                    _("P&ath Name of File"))), 
		 `VSpacing(1),
		 `Left( `CheckBox( `id(`loop_create), `opt(`notify),
				   // button text
		                   _("C&reate Loop File"))),
		 `Left( `TextEntry( `id(`loop_size), `opt(`notify),
				   // label text
		                    _("Si&ze of Loop File"))),
		 `VSpacing()
		 ));	

    return widget;
    }
  
  /**
   * Change the state of all symbol from the list symbols
   * @parm symbols all symbols
   * @parm what true or false
   * @return nil
   */
define void ChangeExistingSymbolsState( list symbols , boolean what ) 
    ``{
    foreach( any sym, symbols, ``{
	  UI::ChangeWidget(`id(sym), `Enabled, what );
      });
    }
  
 
  /**
   * Return a map with the filesystem definitions for the map new_val
   * @parm new_val map that contains a partition
   * @parm file_systems filesystem definitions
   * @return map
   */
define map GetFirstFilesystemDefinition( integer fsid, map<symbol,map> file_systems )
    ``{
    map<symbol,map> define_map  = filter( symbol key, map val, file_systems, 
                              ``(fsid == val[`fsid]:Partitions::fsid_native ));
    list<map> define_list = maplist( symbol k, map v , define_map, ``( v ));
    if( size( define_list ) == 0) 
	return $[];
    else 
	return define_list[0]:$[];
    }
  
  
  /**
   * Dialogpart: Mount part	
   * @parm new_val map that contains a partition
   * @parm file_systems filesystem definitions
   * @return term ComboBox with all mountpoints
   */
define term MountDlg( map new_val, list mountpoints ) 
    ``{
    if( mountpoints == nil  )
	mountpoints = [ "/", "/usr", Partitions::BootMount(), "/var", "/home",
	                "/opt" , ""];

    if( !contains( mountpoints, "" ) && !new_val["loop_fs"]:false )
	mountpoints = add( mountpoints , "");
    string mount = new_val["mount"]:"";

    if( !contains( mountpoints, mount ))
	mountpoints = union( [mount], mountpoints);
    
    term dlg = `VBox(  
		   `PushButton( `id(`fstab_options), `opt(`hstretch), 
			        // button text
				_("Fs&tab Options")),
		   `VSpacing(1),
		   `ComboBox(`id(`mount_point), `opt(`editable, `hstretch), 
			     // label text
			     _("&Mount Point"), mountpoints  )
		   );
    // return term
    return ( dlg );
    }



  
define boolean UseChangedPartitionContinueCancelPopup()
    ``{
    // popup text
    if( Popup::ContinueCancel(_("CAUTION:
You have changed the parameters of a partition currently
mounted. In some cases, this can damage your Linux installation.

Proceed only if you know what you are doing. If you are unsure,
press Cancel.
    
")))
	return true;

     return false;
     };
  
define boolean ModifyPartitionInSystemWarningPopup( string part, string mount )
    ``{
      
    // popup text %1 is a partition name, %2 a dirctory
    string warning = sformat(_("
The selected partition (%1) is currently mounted on %2.
If you change parameters (such as the mount point or the file system type),
your Linux installation might be damaged.

Unmount the partition if possible. If you are unsure,
it is recommended to abort. Do not proceed unless you know
exactly what you are doing.

Continue?
"), part, mount );

      boolean ret = false;

      ret = Popup::YesNo( warning );

      return( ret );
  };


define string AddLvm( boolean lvm, string txt )
    ``{
    txt = sformat( txt, lvm ? _("logical volume") : _("partition") );
    return( txt );
    }

define boolean FsysCannotShrinkPopup( boolean ask, boolean lvm )
    ``{
    boolean ret = true;
    // Popup text
    // %1 is either replaced by "logical volume" or by "partition"
    string txt =  AddLvm( lvm, _("
The file system on the %1 cannot be shrunk by YaST2.
Only fat, ext2, ext3, and reiser allow shrinking of a file system."));
    if( ask )
	{
	txt = txt + "\n";
	txt = txt + AddLvm( lvm, 
			    // Popup text
			    // %1 is either replaced by "logical volume" or by "partition"
	                    _("You risk losing data if you shrink this %1."));
	txt = txt + "\n\n";
	txt = txt + _("Continue?");
	}
    if( ask )
	{
	ret = Popup::YesNo( txt );
	}
    else
	{
	Popup::Error( txt );
	ret = false;
	}
    return( ret );
    }

define boolean FsysCannotGrowPopup( boolean ask, boolean lvm )
    ``{
    boolean ret = true;
    // Popup text
    // %1 is either replaced by "logical volume" or by "partition"
    string txt =  AddLvm( lvm, _("
The file system on the selected %1 cannot be extended by YaST2.
Only fat, ext2, ext3, xfs, and reiser allow extending a file system."));
    if( ask )
	{
	txt = txt + "\n\n";
	// Popup text
	// %1 is either replaced by "logical volume" or by "partition"
	txt = txt + AddLvm( lvm, _("Continue resizing the %1?"));
	}
    if( ask )
	{
	ret = Popup::YesNo( txt );
	}
    else
	{
	Popup::Error( txt );
	ret = false;
	}
    return( ret );
    }

define void FsysCannotResizeMountPopup( boolean lvm, string mount )
    ``{
    string txt = sformat( _("
The %1 is currently mounted on %2.
It is not possible to resize the file system while it is mounted.

Unmount the file system and retry resizing.
"), 
                          AddLvm( lvm, "%1"), mount );
    Popup::Error( txt );
    }

define boolean FsysShrinkReiserWarning( boolean lvm )
    ``{
    boolean ret = true;
    // Popup text
    // %1 is either replaced by "logical volume" or by "partition"
    ret = Popup::YesNo( AddLvm( lvm, _("
You decreased a %1 with a reiser file system on it.
It is possible to shrink a reiser file system, but this feature is not
very thoroughly tested. A backup of your data is recommended.

Shrink the file system now?")));
    return( ret );
    }


  /** 
     * Scan exiting partitions for fstab files and if one found read the mountpoints
     * from the fstab file and build a new targetMap.
     * Ask the user if he like to use the new or old targetMap
     * (with or without found mountpoints)
     *------------------------------------
     * @parm targetMap all targets
     * @parm installation !!
     * @parm file_systems  filesystems definition map
     * @return targetMap new or unmodified targetMap
     *---------------------------------------------------------------------
     */
define integer FstabAddDialog( list table_input )
    ``{  
    if( table_input == [] || table_input == nil )
	{
	// popup text 
	Popup::Message(_("No previous system with mount points was detected."));
	return -1;
	}
	
    // heading text 
    term header = `header( _("Device      "),  _("Mount       "));
	    
    // help text, richtext format
    string help_text = _("<P><B><BIG>Attention:</BIG></B><BR>YaST2 has scanned your hard disks and found an old Linux system
with mount points. On the right, see a list with the mount points found. </P>
")+
    // help text, richtext format
_("<P>To use these mount points, <BR>press <B>Yes</B>.</P>")+
    // help text, richtext format
_("<P>To ignore these mount points, <BR> press <B>No</B>.</P>");

    UI::OpenDialog(
	`opt(`decorated ),
        `HBox(
	    `VBox( `HSpacing(20), `RichText(help_text)),
	    `VBox( `VSpacing(1),
		   `ReplacePoint( `id(`heading), `Empty() ),
		   `HBox(  
		       `HSpacing(3.0),
		       `VSpacing(8),
		       `VBox( `VSpacing(1),
			       `Table(`id(`table), header, [] )
			    ),
		       `HSpacing(3.0)
		       ),
					
		   `VSpacing(1),
		   // popup text
		   `Heading(_("Would you like to use these mount points
for your new installation?")),	
		   `VSpacing(1),
		   `ReplacePoint( `id(`bbox), `Empty() )
		 ))
	     );

    symbol userinput = `none;
    integer idx = 0;
    repeat
	{
	// popup text %1 is replaced by a device name (e.g. /dev/hda1)
	string tmp = sformat( 
_("A previous system with the following mount points was detected:
/etc/fstab found on %1"), table_input[idx,"root"]:"/dev/emil" );
	UI::ReplaceWidget( `id(`heading), `Heading( tmp ) );

	UI::ChangeWidget( `id(`table), `Items, table_input[idx,"tbl"]:[] );

	term bbox = `HBox( `PushButton( `id(`ok), `opt(`default),
					Label::YesButton() ),
			   `PushButton(`id(`cancel), Label::NoButton())
			 );
	if( size(table_input)>0 )
	    {
	    bbox = add( bbox, `HSpacing(5) );
	    if( idx>0 )
		{
		bbox = add( bbox, 
		            `PushButton( `id(`show_p), _("Show &Previous") ));
		}
	    if( idx<size(table_input)-1 )
		{
		bbox = add( bbox, 
		            `PushButton( `id(`show_n), _("Show &Next") ));
		}
	    }
	UI::ReplaceWidget( `id(`bbox), bbox );
		      
	userinput = (symbol)UI::UserInput();

	if( userinput == `show_n )
	    {
	    idx = idx+1;
	    }
	else if( userinput == `show_p )
	    {
	    idx = idx-1;
	    }
	}
    until( userinput == `ok || userinput == `cancel );
    UI::CloseDialog();

    integer ret = userinput == `ok ? idx : -1;
    y2milestone( "ret %1", ret );
    return ret;
    };


define term TargetShowBarGraph( map target, string dev )
    ``{
    list partitions_size = [];
    list partitions_text = [];
    integer sum_used     = 0;
    integer cyl_size     = target["cyl_size"]:1;
    integer cyl_count    = target["cyl_count"]:1;
    integer min_size     = tointeger( cyl_count / 8 );

    
    y2milestone( " target %1" ,target );
    y2milestone( " parts %1", target["partitions"]:[] );
    
    foreach( map part, target["partitions"]:[],
	``{
	if( part["type"]:`primary != `extended && !part["delete"]:false )
	    {
	    integer part_size =  part["region",1]:0;
	    string  part_size_str = "";

	    part_size_str = ByteToHumanString(part_size * cyl_size);

	    sum_used        = sum_used + part_size;
	    if( part_size < min_size )
		part_size = min_size;
      
	    partitions_size = add( partitions_size , part_size);

	    string part_text =  part["mount"]:"";

	    if( part_text  == "" || part_text == nil )
		part_text = dev + sformat("%1", part["nr"]:(any)0);

	    part_text = part_text + "\n" + part_size_str; 
	    
	    partitions_text = add( partitions_text, part_text );
	    }
	});

    integer free  = cyl_count - sum_used;

    if( free > 0 )
	{
	if( free > min_size )
	    partitions_size = add( partitions_size, free );
	else partitions_size = add( partitions_size, min_size );
	// label text
	partitions_text = add( partitions_text, _("free"));
	}

    if( Mode::test () )
	{
	y2milestone(" partitions_size : %1", partitions_size);
	y2milestone(" partitions_text : %1", partitions_text);
	}
		    
    return `BarGraph(`opt(`vstretch), partitions_size , partitions_text );
    };


    
define boolean TargetAllocationDlg( map target, string dev) 
    ``{
    if( ! UI::HasSpecialWidget(`BarGraph) )
	{
	// %1 is a disk device, example: You have selected the disk /dev/hda, but can only edit a partition like /dev/hda11, /dev/hda2,
	Popup::Warning(sformat(_("\n You have selected the disk %1, but you can \n  only edit a partition like %11, %12, ... \n"), dev));
	}
    else
	{
	UI::OpenDialog(`opt(`decorated ),     
		       `VBox(
			     `VSpacing(1),
			     `Left( `Heading( dev + ":")),
			     `VSpacing(1),
			     `VStretch(),
			     `HSpacing(80),
			     TargetShowBarGraph(target ,dev),
			     `VStretch(),
			     `VSpacing(1),
			     `HBox(
				   `PushButton(`id(`close), Label::CloseButton()  )
				   )
			     ));

	UI::UserInput();
	UI::CloseDialog();
	}

    return true;
    };

    


define boolean DDZeroPartitionTable( string del_dev )
    ``{
    // popup text
    if( Popup::YesNo(sformat(_("CAUTION
If you delete the partition table and disk label of
device %1, data on this device will be lost.

Really do this now?
"), del_dev)))
	{
	UI::OpenDialog(`opt(`decorated, `warncolor),
			`HBox(
			      `HSpacing(1),
			      `VBox(
				    `VSpacing(0.2),
				     // popup text
				    `Heading(_("Warning:

Do you really want to do this now?
") ),
				    `HBox(
					  // button text
					  `PushButton(`id(`yes),  _("&Yes, delete the partition table now.")),
					  `HStretch(),
					  // no, don't go on, i just changed my mind
					  `PushButton(`opt(`default), Label::NoButton() )
					  ),
				    `VSpacing(0.2)
				    ),
			      `HSpacing(1)
			      )
		       );

	symbol ret = (symbol)UI::UserInput();
	UI::CloseDialog();
	
	if( !Mode::test () && ret == `yes )
	    {
	    Storage::ZeroDevice(del_dev);			   
	    return true;
	    }	    
	}
    return false;
    };

    
define symbol ReallyInstPrepdisk( )
    ``{
    map<string,map> targetMap = Storage::GetTargetMap();
    map modTg = Storage::GetModifyTargets();
    symbol ret = `none;
    
    string doto = TargetChangesToRichText(targetMap, modTg);
    term dlg = `Empty();
    if( size(doto) == 0 && size(modTg)>0 )
	{
	// popup text
	doto = _("Perform LVM configuration changes");
	}
    y2milestone( "doto:%1", doto );
    if( size(doto) == 0 )
	{
	// popup text
	Popup::Message( _("No changes made so far could be performed."));
	ret = `back;
	}
    else
	{
	dlg = `VBox( `VSpacing(1),
		     `HSpacing(60),
		     // label text
		     `Left(`Heading(_("Changes:"))),
		     `RichText( doto ) );

	UI::OpenDialog(`opt(`decorated, `warncolor),
		       `HBox(
			     `HSpacing(1),
			     `VBox( 
				   dlg,
				   `VSpacing(1),
				   // popup text
				   `Heading(_(" Do you really want to execute these changes?")),
				   `VSpacing(1),   
				   
				   `HBox(
					 // all right, start installation *now*
				       
					 `PushButton(`id(`back), Label::CancelButton()),
					 `HStretch(),
					 // button text
					 `PushButton(`id(`apply),   _("&Apply")),
					 `PushButton(`id(`finish),  Label::FinishButton() )
					 // no, don't go on, i just changed my mind
					 ),
				   `VSpacing(0.2)
				   ),
			     `HSpacing(1)
			     )
					  );

	ret = (symbol)UI::UserInput();
	UI::CloseDialog();
	}

    y2milestone( "ReallyInstPrepdisk ret=%1", ret );
	
    return ret;
    };


    /**
     * Delete all partition in targetMap from the device "del_dev" and return
     * a new targetMap.
     * Check if LVM partition exists on the device.
     * Check if at least on partition is mounted.
     * @return map targetMap
     */
define map deleteAllDevPartitions( map<string, map> targetMap, string del_dev, 
				   boolean installation, boolean bsd_label )
    ``{
    map new_targetMap = targetMap;
    boolean go_on     = true;

    /////////////////////////////////////////////////////////////////
    // check mount points if not installation

    if ( ! installation )
	{
	list<map> mounts = 
	    Partitions::mountedPartitionsOnDisk( del_dev, 
						 Partitions::CurMounted() );

	if( size( mounts ) != 0 )
	    {
	    /////////////////////////////////////////////////////////
	    // mount points found

	    string mounted_parts  = "";
	    foreach( map mount, mounts, 
		``{
		//The selected device contains partitions which are currently mounted:
		//           /dev/hda1 on /
		//           /dev/hdd1 on /usr
		//   ....
		mounted_parts = mounted_parts + 
		                sformat("%1 on %2",
				        mount["spec"]:"", 
					mount["file"]:"") +
				"\n";
		});

	    // popup text, %1 is replaced by device name
	    string message = sformat(_("The selected device contains partitions that are currently mounted:
%1
It is *strongly* recommended to unmount these partitions before deleting the partition table.
Choose Cancel unless you know exactly what you are doing.
"), mounted_parts );

	    if( !Popup::ContinueCancel(message))
		{
		go_on = false;
		}
	    }
	}


    if( go_on )
	{
	foreach( string dev, map target, targetMap, 
	    ``{
	    /////////////////////////////////////////////////////////
	    // find device

	    if( dev == del_dev )
		{
		list<map> partitions = target["partitions"]:[];
		partitions      = filter( map part, partitions, 
		                          ``( !part["delete"]:false ));

		map part_nr_3_bsd_check = (map)find( map part, partitions, 
						     ``( part["nr"]:0 == 3));
		
		symbol ret_delete = 
		    check_partition_delete( target, part_nr_3_bsd_check, 
		                            bsd_label, true, false, false,
					    true ); // raid_check

		if( ret_delete == `no_delete )
		    {
		    go_on = false;
		    }

		if( partitions != []  && go_on )
		    {

		    /////////////////////////////////////////////////
		    // check LVM partitions

		    if( size(filter( map part, partitions, ``( part["lvm_group"]:"" != "" ))) != 0)
			{
			// popup text, Do not translate LVM.
			Popup::Message(_("
The selected device contains at least one LVM partition
assigned to a volume group. Remove all
partitions from their respective volume groups
before deleting the partition table.
"));
			go_on = false;
			}


		    /////////////////////////////////////////////////
		    // check RAID partitions

		    if( size(filter( map part, partitions, ``( part["raid_name"]:"" != "" ))) != 0)
			{
			// popup text, Do not translate RAID.
			Popup::Message(_("
The selected device contains at least one partition
that is part of a RAID system. Unassign the
partitions from their respective RAID systems before
deleting the partition table.
"));
			go_on = false;
			}
		    
		    }
		if( go_on )
		    {
		    /////////////////////////////////////////////////
		    // delete all partition in targetMap and add dd string to targetMap

		    // add delete -> true to all partitions
		    list<map> partitions = [];
		    foreach( map part, target["partitions"]:[], 
			``{
			part       = add( part, "delete" , true);
			partitions = add( partitions , part);
			});

		    partitions = filter( map parti, partitions,
					 ``( !parti["create"]:false ));
		    
		    target        = add( target, "partitions", partitions );
		    new_targetMap = add( new_targetMap , dev, target );
		    }
		}
	    });
	}

    if( go_on )
	{
	return new_targetMap;
	}
    return($[]);
    };

  
}
