/**
 * File:
 *   OSRProgress.ycp
 *
 * Module:
 *
 * Summary:
 *
 * Author:
 *   Johannes Buchhold <jbuch@suse.de>
 *
 * $Id: OSRProgress.ycp 20450 2004-12-01 11:55:31Z jsuchome $
 */

{
  module "OSRProgress";

  textdomain "repair";

  import "Mode";

  /**
   * The length of a ProgressBar
   */
  global integer length	= 1000;

  /**
   * Data of all created ProgressBar and Downloadprogress
   */
  map progresses	= $[];

  /**
   * Reset module settings.
   */
  global define void Reset()``{
      progresses = $[];
  }

  global define term CreateProgressBar (symbol id, string label,
					integer real_steps ) ``{

    if( ! haskey( progresses, id ) )
    {
	progresses = add( progresses, id , $[ "type"		: "ProgressBar",
					      "current"		: 0,
					      "increment"	: 1,
					      "label"		: label ]);
    }
    return `ProgressBar( `id( id ), progresses[id, "label"]:"" ,  real_steps );
  }

  /**
   * Create a new Progress Widget
   */
  global define term Create(symbol id, string label, integer steps, boolean downloadprogress ) ``{


      if ( ! (downloadprogress && UI::HasSpecialWidget(`DownloadProgress)))
      {

	  if( ! haskey( progresses , id ))
	  {
	    progresses = add( progresses, id , $[
		"type"     : "ProgressBar",
		"current"  : 0,
		"increment": tointeger( length / steps ),
		"label"    : label ]
	    );
	  }
	  return `ProgressBar(
			      `id( id ),
			      progresses[id, "label"]:"",
			      length );
      }
      else {
	  if ( ! haskey( progresses, id ))
	  {
	      progresses = add(progresses, id, $[ "type"  : "DownloadProgress",
						  "label" : label
						  ] );
	  }

	  return `DownloadProgress(`id( id ),  progresses[id, "label"]:"", progresses[id, "file"]:"", length );
      }
  }

  global define void Update()``{
      y2milestone(" progresses data %1" ,progresses);
      foreach( symbol id, map p_data , (map<symbol,map<string,any> >)progresses, ``{
	  if ( UI::WidgetExists(`id(id)))
	  {
	      UI::ChangeWidget(`id(id), `Value, p_data["current"]:length);
	      UI::ChangeWidget(`id(id), `Label, p_data["label"]:"");
	  }
      });
  }

  /**
   * Set the Steps of a normal ProgressBar Widget.
   */
  global define void SetSteps( symbol id, integer steps)``{

    if (Mode::test ()) return;

      map progress = progresses[id]:$[];

      if ( progress["type"]:"" == "ProgressBar" ) {

	  progresses[id, "increment"]   = tointeger( length / steps );
	  progresses[id, "current"]	= 0;

	  UI::ChangeWidget(`id(id), `Value, 0);
      }
  }

  /**
   *  This method is called after one detection function is successfully
   *  executed. It shows the continuous progress to the user with the global
   *  progress bar.
   *
   *  For internal use only.
   *
   *  @return boolean True if the progress value was increased successfully.
   */
  global define boolean Increase(symbol id ) ``{

    if (Mode::test ()) return true;

      map progress		= progresses[id]:$[];

      if ( progress["type"]:"" == "ProgressBar" ) {
	  integer new_current = progress["current"]:length +
	    progress["increment"]:0;

	  if ( new_current <= length )
	  {
	      progresses[id, "current"]	= new_current;

	      return (UI::ChangeWidget( `id(id), `Value, new_current ));
	  }
      }
      return false;
  };

  global define boolean DownloadIncrease(symbol id, string new_label ) ``{
      map progress		= progresses[id]:$[];

      if ( progress["type"]:"" == "DownloadProgress" ) {

	    return ((integer) WFM::Execute (.local.bash,
		sformat ("/bin/echo  \"%1\" >> %2", new_label,
		    UI::QueryWidget(`id(id), `Filename) )) == 0);
      }
      return false;
  }


 /**
   *  Set the label of a progress-bar to the specified one.
   *  @param string new_label The new label.
   *  @return boolen True if the label was set correctly.
   */
  global define boolean SetLabel(symbol id, string new_label) ``{

    if (Mode::test ()) return true;

    if (UI::QueryWidget(`id(id), `Label) != new_label)
    {
	  if ( new_label != "")
	  {
	      UI::ChangeWidget(`id(id), `Label, new_label);

	      // save label
	      progresses[id, "label"] = new_label;
	  }
	  if ( progresses[id, "type"]:"" == "ProgressBar" ) 
	      return (Increase(id));
	  else {
	      return DownloadIncrease(id, new_label);
	  }
    }
    return false;
  };

  /**
   *  Fills the global-progress-bar with 100%.
   *  @return boolean True if the progress value was increased successfully.
   */
  global define boolean Fill(symbol id) ``{

    if (Mode::test ()) return true;

      map progress		= progresses[id]:$[];

      if ( progress["type"]:"" == "ProgressBar" ) {

	  progresses[id, "current"] = length ;
	  return (UI::ChangeWidget(`id(id), `Value, length));
      }
      else {
	  string  file     = (string) UI::QueryWidget(`id(id), `Filename);
	  integer current  = (integer) WFM::Read(.local.size, file);
	  integer diff     = 0;
	  integer result   = 0;

	  if (current < 0)
	  {
	      current = 0;
	  }

	  diff = (integer) UI::QueryWidget(`id(id), `ExpectedSize) - current;

	  if (diff >= 0)
	  {
	      while ( UI::QueryWidget(`id(id), `ExpectedSize) > current )
	      {
		  string fill    = "##########";
		  while (size (fill) < diff/3)
		  {
		      fill = fill + fill;
		  }
		  string command = sformat("/bin/echo \"%1\" >> %2", fill, file);
		  result  = (integer) WFM::Execute(.local.bash, command);
		  current = (integer) WFM::Read(.local.size, file);
	      }
	      return (result == 0);
	  }
	  else
	  {
	      return true;
	  }
      }
  };

  /**
   * Only for DownloadProgress !!
   * Delete the progress file.
   */
  global define boolean DeleteFile(string file ) ``{

      if( file == "" || file == nil ) return false;

      string cmd = sformat("if /usr/bin/test -f %1; then /bin/rm %1; fi", file);
      // delete the old progress_file, if it exists
      if (  WFM::Execute(.local.bash, cmd) != 0 ) {
	  y2error("The file %1 could not be deleted.", file);
	  return false;
      }
      return true;
  }

  /**
   *  Specifies a new filename for the DownloadProgress widget.
   *  @param string file Filename as a string.
   *  @example OSRModuleProgress::SetFile("/tmp/YaST2-823/osr_lilo_progress");
   */
  global define boolean SetFile(symbol id, string new_file) ``{
      map progress		= progresses[id]:$[];

      if ( progress["type"]:"" == "DownloadProgress" ) {
	  DeleteFile ((string) UI::QueryWidget(`id(id), `Filename));
	  progresses[id, "file"] = new_file;
	  return UI::ChangeWidget(`id(id), `Filename,     new_file   );
      }
      return false;
  };

  /**
   * Set the length of a progress bar.
   */
  global define boolean SetLength(symbol id, integer new_length) ``{
      map progress		= progresses[id]:$[];
      if ( progress["type"]:"" == "DownloadProgress" )
	  return UI::ChangeWidget(`id(id), `ExpectedSize, new_length);
      return false;
  };
}
