/*******************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright (C) 1997-2006, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: Progress_bar
*
* %I
* Written by: Emmanuel Farhi
* Date: 2002
* Version: $Revision: 1.14 $
* Origin: ILL
* Release: McStas 1.9.1
*
* A simulation progress bar
*
* %D
* An indicator of the progress of the simulation, monitoring
* the Init, Trace with the achieved percentage, and the Finally section.
* Intermediate savings (e.g. triggered by USR2 signal) are also shown.
* This component should be positioned at the very begining of the instrument
*
* Example: Progress_bar(percent=10,flag_save=1) AT (0,0,0)
*
* %P
* INPUT PARAMETERS:
* percent:  (%)   percentage interval between indications. Default is 10%.
* flag_save:(0|1) flag to enable intermediate saving for all monitors
*
* %E
*******************************************************************************/

DEFINE COMPONENT Progress_bar
DEFINITION PARAMETERS ()
SETTING PARAMETERS (percent=10,flag_save=0)
OUTPUT PARAMETERS (IntermediateCnts,StartTime,EndTime)
STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p)

DECLARE
%{
#ifndef PROGRESS_BAR
#define PROGRESS_BAR
#endif

  double IntermediateCnts=0;
  time_t StartTime       =0;
  time_t EndTime         =0;
%}

INITIALIZE
%{
  fprintf(stdout, "[%s] Initialize\n", mcinstrument_name);
  if (percent*mcget_ncount()/100 < 1e5) {
    percent=1e5*100.0/mcget_ncount();
  }
%}

TRACE
%{
  double ncount;
  ncount = mcget_run_num();
  if (!StartTime) {
    time(&StartTime); /* compute starting time */
    IntermediateCnts = 1e5;
  }
  if (!EndTime && ncount >= IntermediateCnts) {
    time_t NowTime;
    time(&NowTime);
    if (difftime(NowTime,StartTime) > 10) {
      EndTime = StartTime + (time_t)(difftime(NowTime,StartTime)
                           *mcget_ncount()/ncount);
      IntermediateCnts = 0;
      fprintf(stdout, "\nTrace ETA ");
      if (difftime(EndTime,StartTime) < 60.0)
        fprintf(stdout, "%g [s] %% ", difftime(EndTime,StartTime));
      else if (difftime(EndTime,StartTime) > 3600.0)
        fprintf(stdout, "%g [h] %% ", difftime(EndTime,StartTime)/3660.0);
      else
        fprintf(stdout, "%g [min] %% ", difftime(EndTime,StartTime)/60.0);
    } else IntermediateCnts += 1e5;
    fflush(stdout);
  }

  if (EndTime && ncount >= IntermediateCnts)
  {
    double tmp;
    tmp = percent*mcget_ncount()/100;
    fprintf(stdout, "%d ", (int)(ncount*100/mcget_ncount())); fflush(stdout);
    IntermediateCnts = ncount + tmp;
    if (IntermediateCnts >= mcget_ncount()) fprintf(stdout, "\n");
    if (flag_save) mcsave(NULL);
  }
%}

SAVE
%{
  fprintf(stdout, "\nSave [%s]\n", mcinstrument_name);
%}

FINALLY
%{
  time_t NowTime;
  time(&NowTime);
  fprintf(stdout, "\nFinally. Time: ");
  if (difftime(NowTime,StartTime) < 60.0)
    fprintf(stdout, "%g [s] ", difftime(NowTime,StartTime));
  else if (difftime(NowTime,StartTime) > 3600.0)
    fprintf(stdout, "%g [h] ", difftime(NowTime,StartTime)/3660.0);
  else
    fprintf(stdout, "%g [min] ", difftime(NowTime,StartTime)/60.0);
  fprintf(stdout, "\n");
%}

END
