' PROGRTM(1.1)  Dspl File Prc Progress Ind with Times  06/27/1994-03/26/2003
' --------------------------------------------------------------------------
' Copyright (C) 1994-2003 by Vladimir Veytsel                  www.davar.net

' Type ---------------------------------------------------------------------

'    Routine

' Declaration --------------------------------------------------------------

'    DECLARE SUB PROGRTM(File%,Nam$,Title$,Record$,Mode$,Appear$)

' Parameters ---------------------------------------------------------------

'    File%    - File number (as it was opened in the calling program)
'    Name$    - Program name and version (E.g.: "CONVERT(0.0)")
'    Title$   - Process title string (truncated to 64 chars if longer)
'    Record$  - Current input record
'    Mode$    - Progress indicator display mode:
'               S  - Start
'               P  - Progress
'               F  - Finish (any value different from "S" or "P" is equivalent to "F")
'    Appear$  - Appearance control string (fixed structure 6-character):
'               +------- Incomplete symbol          (Default: ">")
'               |+------ Complete   symbol          (Default: "=")
'               ||+----- Incomplete color attribute (Default: "E"  - Yellow)
'               |||+---- Complete   color attribute (Default: "B"  - Bright Cayan)
'               ||||+--- Running    color attribute (Default: "A"  - Bright Green)
'               |||||+-- Background color attribute (Default: "0"  - Black)
'               ||||||
'               123456
'               >=EBA0 - Default appearance control string (padded with blanks)
'                        Individual blanks default to corresponding symbols
'                 Note:  This parameter is processed only in "Start" mode
'                        (in "Progress" and "Finish" mode it is ignored)

' Notes --------------------------------------------------------------------

'  - Routine is intended for use in file processing/conversion procedures
'    running from DOS prompt and showing processing progress on DOS screen.
'  - Use it with long running (over 1 minute) procedures.
'  - For short procedures see routine PROGRES (without elapsed/left time display).
'  - Rotating indicator wheel is synchronized with completeness % display.
'  - At the end of first line processing elapsed time is shown (MM:SS).
'  - At the end of second line an estimate of processing left time is shown
'    (evaluation and display of left time starts after 5% completeness).

' Examples -----------------------------------------------------------------

'    Start: CALL PROGRTM(1,"CONVERT(0.0)","File...","","S",">=EBA0")  - After OPEN

'    CONVERT(0.0)  File SOURCE.TXT is converted to TARGET.TXT
'         0% [Ä]   >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'    Progress: CALL PROGRTM(1,"","",Input.Record$,"P","")  - After every LINE INPUT

'    CONVERT(0.0)  File SOURCE.TXT is converted to TARGET.TXT  6:25
'        50% [|]   =====================>>>>>>>>>>>>>>>>>>>>>  6:25

'    Finish: CALL PROGRTM(1,"","","","F","")  - After encountering EOF

'    CONVERT(0.0)  File SOURCE.TXT is converted to TARGET.TXT
'       100% [*]   ==========================================  12:50

' Start Routine ------------------------------------------------------------

     DEFINT A-Z     ' All defaulted variables are integer
     OPTION BASE 1  ' Default array indexation starts from "1"

     SUB PROGRTM(File%,Nam$,Title$,Record$,Mode$,Appear$) STATIC PUBLIC

     DIM Wheel$(4)

' Initialize Routine Constants (Start) -------------------------------------

     SELECT CASE (UCASE$(Mode$))
            CASE ("S")
                 Wheel$(1)="-"
                 Wheel$(2)="\"
                 Wheel$(3)="|"
                 Wheel$(4)="/"
                 IF (LEN(Appear$)=0) THEN
                    App$=">=EBA0"
                 ELSE
                    App$=Appear$+"      "
                 END IF
                 Incompl.Symb$    =MID$(App$,1,1)
                 Complete.Symb$   =MID$(App$,2,1)
                 Incompl.Color$   =MID$(App$,3,1)
                 Complete.Color$  =MID$(App$,4,1)
                 Running.Color$   =MID$(App$,5,1)
                 Background.Color$=MID$(App$,6,1)
                 IF (Incompl.Symb$    =" ") THEN Incompl.Symb$    =">"
                 IF (Complete.Symb$   =" ") THEN Complete.Symb$   ="="
                 IF (Incompl.Color$   =" ") THEN Incompl.Color$   ="E"
                 IF (Complete.Color$  =" ") THEN Complete.Color$  ="B"
                 IF (Running.Color$   =" ") THEN Running.Color$   ="A"
                 IF (Background.Color$=" ") THEN Background.Color$="0"
                 Incompl.Color   =VAL("&H"+Incompl.Color$)
                 Complete.Color  =VAL("&H"+Complete.Color$)
                 Running.Color   =VAL("&H"+Running.Color$)
                 Background.Color=VAL("&H"+Background.Color$)

' Display Initial Processing Progress Message ------------------------------

     Start.Time!=TIMER
     File.Size!=LOF(File%)   ' Get input file size
     IF (LEN(Title$)>57) THEN Title$=LEFT$(Title$,57)
     Title.Len=LEN(Title$)
     Percent.Pos=LEN(Nam$)-8
     Time.Pos=LEN(Nam$)+LEN(Title$)+5
     Share!=File.Size!/Title.Len
     IF (Share!=0) THEN Share!=1
     Limit!=Share!
     COLOR Complete.Color,Background.Color
     PRINT Nam$;"  ";Title$;"       "
     PRINT TAB(Percent.Pos);"  0% [";Wheel$(1);"]   ";
     COLOR Incompl.Color,Background.Color
     PRINT STRING$(Title.Len,Incompl.Symb$);"       ";
     Length.Ratio!=Title.Len/File.Size!
     Curs.Line=CSRLIN

' Redisplay Processing Progress Message ------------------------------------

     CASE ("P")
          Curr.Size!=Curr.Size!+LEN(Record$)+2
          Percent.Compl=Curr.Size!/File.Size!*100
          Elapsed.Time=TIMER-Start.Time!
          IF (Elapsed.Time>Prev.Time) THEN
             Prev.Time=Elapsed.Time
             COLOR Running.Color,Background.Color
             Curs.Pos=Time.Pos+(MAX(Elapsed.Time,Left.Time)<600)
             LOCATE Curs.Line-1,Curs.Pos
             Dspl.Time=Elapsed.Time
             GOSUB Display.Time
             IF (Percent.Compl>4) THEN
                Left.Time=Elapsed.Time*(File.Size!-Curr.Size!)/Curr.Size!
'               Left.Time=600  ' Was used for >9 minutes debugging
                LOCATE Curs.Line,Curs.Pos
                Dspl.Time=Left.Time
                GOSUB Display.Time
             END IF
          END IF
          LOCATE Curs.Line,Percent.Pos
          COLOR Running.Color,Background.Color
          PRINT USING "###";Percent.Compl;
          PRINT "% [";Wheel$((Percent.Compl MOD 4)+1);"]   ";
          IF (Curr.Size!>Limit!) THEN
             COLOR Complete.Color,Background.Color
             PRINT STRING$(Curr.Size!*Length.Ratio!,Complete.Symb$);
             Counter=Counter+1
             Limit!=Counter*Share!
          END IF

' Redisplay Process Finish Message -----------------------------------------

     CASE ELSE
          COLOR Complete.Color,Background.Color
          LOCATE Curs.Line-1,Time.Pos+(Elapsed.Time<600)
          Dspl.Time=Elapsed.Time
          GOSUB Display.Time
          LOCATE Curs.Line,Percent.Pos
          PRINT "100% [*]   ";STRING$(Title.Len,Complete.Symb$);"       "

     END SELECT

     GOTO Finish.Routine

Display.Time:  ' Routine ---------------------------------------------------

     Dspl.Mins=INT(Dspl.Time/60)
     Dspl.Secs=INT(Dspl.Time MOD 60)
     PRINT USING "##";Dspl.Mins;
     PRINT ":";
     IF (Dspl.Secs<10) THEN
        PRINT "0";
        PRINT USING "#";Dspl.Secs;
     ELSE
        PRINT USING "##";Dspl.Secs;
     END IF
     IF (Dspl.Mins<10) THEN PRINT " ";

     RETURN  ' From Display.Time routine

Finish.Routine: ' ----------------------------------------------------------

     COLOR 7,0  ' Grey on Black
     END SUB
