/**
 * File:
 *   loop.ycp
 *
 * Module:
 *   Configuration loop file setup
 *
 * Summary:
 *   Functions for configuration of loop file setup
 *
 * Authors:
 *   Thomas Fehr <fehr@suse.de>
 *
 * $Id: loop.ycp 19964 2004-10-26 15:37:35Z fehr $
 *
 */

{

  textdomain "storage";

  import "Wizard";
  import "Storage";
  import "FileSystems";
  import "Partitions";
  import "Label";
  
  include "partitioning/partition_defines.ycp";
  include "partitioning/custom_part_dialogs.ycp";
  include "partitioning/custom_part_lib.ycp";

/**
 * LoopDlgHelp
 * @return string
 */
define string LoopDlgHelp()
    ``{
    // help text richtext format
    string helptext = _("
<p><b>Path Name of File:</b><br>This must be an absolute path to the file
containing the data for the encrypted loop device to set up.</p>
");

    // help text richtext format, continued
    helptext = helptext + _("
<p><b>Create Crypt File:</b><br>If this is checked, the file will be 
created with the size given in the next field. <b>NOTE:</b> If the 
file already exists, all data in it is lost.</p>
");

    // help text richtext format, continued
    helptext = helptext + _("
<p><b>Size of Crypt File:</b><br>This is the size of the loop file.
The file system to create in the encrypted loop device will have 
this size.</p>
");

    // help text richtext format, continued
    helptext = helptext + _("
<p><b>NOTE:</b>During installation, there cannot be any consistency
checks about file size and path names because the file system is not 
accessible. It will be created at the end of installation. Be 
careful about the size and path name you provide.</p>
");

    return helptext;
    };


/**
 *  LoopExpertDlg dialog
 *  edit loop options
 */
define map<string,any> LoopExpertDlg( boolean edit, map<string,any> part, map<symbol,map> file_systems )
    ``{
    string caption = "";
    if( edit )
	{
	// heading text
	caption = sformat( _("Edit Loop Device Setup of %1"), 
	                   part["fpath"]:"" );
	}
    else
	{
	// heading text
	caption = _("Create New Loop Device Setup");
	}

    term contents = `VBox( `HSpacing( 60 ),
                           `HBox( `HSpacing(2), 
			          LoopOptionsDlg(), 
				  `HSpacing(20)
				),
			   `VSpacing(1),
			   `HBox( FormatDlg( part, file_systems ),
			          `HSpacing(2),
				  `Top(`ReplacePoint( `id(`mount_dlg_rp), 
						      MountDlg( part, [] )))
				)
			 );

    contents = `VBox(
		     `Heading(caption),
		     `VSpacing(1),
		     `VStretch(),
		     contents,
		     `VSpacing(1),
		     `VStretch(),
		     `HBox(
			   `PushButton(`id(`ok), `opt(`default), 
				       Label::OKButton()  ),
			   `PushButton(`id(`cancel), Label::CancelButton() )
		    ));



    /////////////////////////////////////////////////////////////
    // Open main dialog for Raid
    /////////////////////////////////////////////////////////////
    UI::OpenDialog( `opt(`decorated ),
		    `HBox( `HWeight(30,`RichText(LoopDlgHelp())),
			   `HStretch(),
			   `HSpacing(1),
			   `HWeight(70, contents ),
			   `HSpacing(1),
			   `HStretch()
			 ));

    ////////////////////////////////////////////////////////////////
    // configure main dialog for the first call
    string lsize = ByteToHumanStringWithZero(part["region",1]:0*1024*1024);

    UI::ChangeWidget( `id(`loop_path), `Value, part["fpath"]:"" );
    UI::ChangeWidget( `id(`loop_path), `ValidChars, 
                      FileSystems::nchars + "-._:/" );
    UI::ChangeWidget( `id(`loop_create), `Value, part["create"]:false );
    UI::ChangeWidget( `id(`loop_size), `Value, lsize );
    UI::ChangeWidget( `id(`loop_size), `Enabled, part["create"]:false );
    UI::ChangeWidget( `id(`crypt_fs), `Enabled, true );

    map<string,any> retval = eval(part);
    symbol ret = `ok;

    retval = HandlePartWidgetChanges( true, ret, file_systems, part, retval );

    repeat
	{
	ret = (symbol)UI::UserInput();
	y2milestone( "DlgLoop %1", ret);

	////////////////////////////////////////////////////////////
	if( ret != `cancel )
	    {
	    retval = HandlePartWidgetChanges( false, ret, file_systems, part, 
	                                      retval );
	    }

	if( ret == `loop_create )
	    {
	    retval["create"] = UI::QueryWidget( `id(`loop_create), `Value );
	    UI::ChangeWidget( `id(`loop_size), `Enabled, 
			      retval["create"]:false );
	    if( retval["create"]:false )
		{
		retval["format"] = true;
		UI::ChangeWidget( `id(`format), `Value, true );
		}
	    }

	if( ret == `ok )
	    {
	    retval["fpath"] = UI::QueryWidget(`id(`loop_path), `Value);
	    retval["create"] = UI::QueryWidget(`id(`loop_create), `Value);

	    lsize = (string)UI::QueryWidget(`id(`loop_size), `Value);
	    integer nsize = kmgt_str_to_byte( lsize );
	    retval["region",1] = nsize/(1024*1024);
	    y2milestone( "size:%1 num:%2", lsize, nsize );
	    y2milestone( "retval:%1", retval );
	    if( !check_max_size( nsize, 0 ) )
		{
		ret = `again;
		continue;
		}
	    if( size(retval["fpath"]:"")==0 || 
	        substring( retval["fpath"]:" ", 0, 1)!="/" )
		{
		// popup text
		Popup::Error( sformat(_("The file name \"%1\" is invalid.
Use an absolute path name.
"), retval["fpath"]:" " ));
		ret = `again;
		continue;
		}

	    if( Mode::normal () && !retval["create"]:false &&
	        SCR::Read( .target.size, retval["fpath"]:"" )<=0 )
		{
		// popup text
		Popup::Error( sformat(_("The file name \"%1\" does not exist
and the flag for create is off. Either use an existing file or activate
the create flag."), retval["fpath"]:" " ));
		ret = `again;
		continue;
		}

	    if( !retval["format"]:false && retval["create"]:false )
		{
		// popup text
		Popup::Error( _("You chose to create the crypt file, but did not specify 
that it should be formatted. This does not make sense. 

Also check the format option.
"));
		ret = `again;
		continue;
		}

	    map ret_mp = CheckOkMount( part["device"]:"", part, retval );
	    retval = ret_mp["map"]:$[];
	    y2milestone( "ret_mp %1 part %2", ret_mp, part );
	    if( !ret_mp["ok"]:false )
	       {
	        if( ret_mp["field"]:`none != `none )
		    UI::SetFocus(`id( ret_mp["field"]:`none ));
		ret = `again;
		continue;
	       }

	    if( size(retval["mount"]:"")==0 )
		{
		// popup text
		Popup::Error( _("Provide a mount point."));
		ret = `again;
		continue;
		}

	    ret_mp = CheckCryptOk( retval );
	    if( !ret_mp["ok"]:false )
		{
		ret = `again;
		}
	    else
		{
		retval = ret_mp["map"]:$[];
		}
	    }
        } until( ret == `ok || ret == `cancel || ret == `next ||
		 ret == `back || ret == `abort );

    retval["symbol"] = ret;
    y2milestone( "ret:%1 retval=%2", ret, retval );
    UI::CloseDialog();
    return retval;
    }


/**
 * LoopSetup dialog
 *
 * Provide dialog for settings of loop device related parameters
 */
define symbol LoopSetup( boolean edit )
    ``{
    string id = Storage::GetWizardKey();
    string key = "/dev/loop";
    y2milestone( "edit %1 id %2", edit, id );
    map<string,any> part = Storage::InitialLoopEntry();
    map<string,map> tg = Storage::GetTargetMap();
    if( edit )
	{
	part = Storage::GetSubDev( id );
	}
    else
	{
	integer n = 0;
	list nlist = maplist( map p, tg[key,"partitions"]:[], ``(p["nr"]:(any)0));
	while( n<size(nlist) && contains( nlist, n) )
	    {
	    n = n+1;
	    }
	if( Mode::normal () )
	    {
	    part["device"] = Storage::GetLoopDev(n);
	    map d = Storage::GetDiskPartition( part["device"]:"" );
	    part["nr"] = d["nr"]:(any)0;
	    }
	else
	    {
	    part["nr"] = n;
	    part["device"] = Storage::GetDeviceName( key, part["nr"]:(any)0 );
	    }
	part["format"] = true;
	part["crypt"] = "twofish256";
	part["create"] = true;
	part["region",1] = 50;
	part["used_fs"] = `ext3;
	}
    y2milestone( "part %1", part );

    y2milestone( "fs %1", FileSystems::GetAllFileSystems(false, false) );
    part = LoopExpertDlg( edit, part, (map <symbol, map>)
                          filter( any k, map e, 
			          FileSystems::GetAllFileSystems(false, false),
				  ``(e[`crypt]:false)));

    symbol ret = part["symbol"]:`next;
    // remove symbol key from data
    part = filter( string key, any value, part, ``( key != "symbol" ));

    if( ret == `ok )
	{
	if( size(tg[key]:$[]) == 0 )
	    {
	    tg[key] = Storage::InitialLoopMaindev();
	    }
	tg = Storage::SetPartition( tg, part );
	Storage::SetTargetMap( tg );
	}
    y2milestone( "ret = %1", ret );
    return  ret;
    }



}
