(*----------------------------------------------------------------------*)

IMPLEMENTATION MODULE HelpBuffers;

(*----------------------------------------------------------------------*)

FROM Strings IMPORT CopyCC;

FROM Universe IMPORT EndOfLineCh, BYTE, Editing, EscapeCh, TabCh;
IMPORT StringData, Buffers, Fast;

FROM Help IMPORT HelpWindow, HighLight, HelpLevel,
		 Changed, MenuPosition,
		 SelectedSensitive, SensitiveBox, Details, Header,
		 PadTo, PadToNextColumn, AddComment, AddNumber,
		 AddText, AddChar, NewLine, ReplaceChar;

IMPORT TimeAndDate;

IMPORT Debug;

(*----------------------------------------------------------------------*)

PROCEDURE GetString (    string  : StringData.StringP;
		     VAR array   : ARRAY OF CHAR      );

   BEGIN
      IF string = NIL THEN
         CopyCC ("<None>", array);
      ELSIF string^.Array.Size = 0 THEN
         CopyCC ("<Empty>", array);
      ELSE
         IF StringData.CopyDC (string, array) THEN END;
      END (* if *);
   END GetString;

(*----------------------------------------------------------------------*)

PROCEDURE HelpBuffers (CurrentLevel: CARDINAL; RelativeY: CARDINAL);

   (*-------------------------------------------------------------------*)

   PROCEDURE HelpBuffer (Buffer: Buffers.BufferP; RelativeY: CARDINAL);

      VAR FirstStatusBit: BOOLEAN;

      (*----------------------------------------------------------------*)

      PROCEDURE AddStatusBit (Status  : Buffers.BufferStatus;
			      Bit     : Buffers.BufferFlags;
			      Name    : ARRAY OF CHAR        );

         BEGIN
	    IF Bit IN Status THEN
	       IF FirstStatusBit THEN FirstStatusBit := FALSE
	       ELSE AddText (" + ")
	       END (* if *);
	       AddText (Name)
	    END (* if *)
         END AddStatusBit;

      (*----------------------------------------------------------------*)

      PROCEDURE LinesWithin (Area: Buffers.AreaR): CARDINAL;

         VAR Lines: CARDINAL;

         BEGIN
  	    Lines := 0;
	    WHILE Fast.SkipUntilEndOfLineCh (Buffer^.Array, Area) DO
	       INC (Lines);
	       INC (Area.Start)
	    END (* while *);
	    RETURN Lines
         END LinesWithin;

      (*----------------------------------------------------------------*)

   VAR
      used		       : CARDINAL;
      linesBefore              : CARDINAL;
      linesAfter               : CARDINAL;
      TimeStamp 	       : TimeAndDate.TimeStamp;
      FileName		       : ARRAY [0..255] OF CHAR;
      None		       : ARRAY [0..3] OF CHAR;
      Length		       : CARDINAL ;
      TextualTime	       : ARRAY [0..40] OF CHAR;
      Junk		       : CARDINAL;

   BEGIN
      None := "None" ;
      FirstStatusBit := TRUE ;
      WITH Buffer^ DO
	 used := (Before.End - Before.Start) + (After.End - After.Start);
	 CASE RelativeY OF
	 6 :
	    AddComment( "Name :" ) ;
	    GetString( Name , FileName ) ;
	    AddText( FileName ) ;
      |
	 7 :
	    AddComment( "Maximum size :" ) ;
	    AddNumber( Array.Size ) ;
      |
	 8 :
	    AddComment( "Used :" ) ;
	    AddNumber( used ) ;
	    AddText( " ( " ) ;
	    AddNumber( ( used * 100 ) DIV Array.Size ) ;
	    AddText( "% )" ) ;
      |
	 9 :
            linesBefore := LinesWithin (Before) + 1;
            linesAfter := LinesWithin (After);
	    AddComment ("Total lines :");
	    AddNumber (linesBefore + linesAfter)
      |
	 10 :
            linesBefore := LinesWithin (Before) + 1;
	    AddComment ("Cursor at line :");
	    AddNumber (linesBefore)
      |
	 11 :
	    AddComment( "          character :" ) ;
	    AddNumber( Before.End - Before.Start ) ;
	    AddText( " ( " ) ;
	    IF used = 0 THEN
	       AddNumber( 0 ) ;
	    ELSE   
	       AddNumber( ( ( Before.End - Before.Start ) * 100 ) DIV used ) ;
	    END (* if *) ;
	    AddText( "% )" ) ;
      |
	 12 :
	    AddComment( "Status :" ) ;
	    AddStatusBit( Status , Buffers.ModifiedF , "Modified" ) ;
	    AddStatusBit( Status , Buffers.LockedF , "Locked" )  ;
	    IF Status = Buffers.BufferStatus{ } THEN
	       AddText( None ) ;
	    END (* if *) ;
      |
	 13 :
	    AddComment( "File TimeStamp :" ) ;
	    IF TimeAndDate.TextualTimeOfBinaryTime( TextualTime ,
						    Length ,
						    StampedTime ) >= 0 THEN
	       AddText( TextualTime ) ;
	    ELSE
	       AddText( None ) ;
	    END (* if *) ;
      ELSE
	 END (* case *) ;
      END (* with *) ;
   END HelpBuffer ;

   (*-------------------------------------------------------------------*)

VAR BufferBoxNumber: CARDINAL;

BEGIN
   IF HelpLevel = CurrentLevel + 1 THEN
      IF MenuPosition[ CurrentLevel + 1 ].Virgin THEN
	 WITH MenuPosition[ CurrentLevel + 1 ] DO
	    Virgin := FALSE ;
	    X := 0 ;
	    Y := 0 ;
	    MinX := 0 ;
	    MinY := 0 ;
	    MaxX := 2 ;
	    MaxY := 0 ;
	    Changed := TRUE ;
	 END (* with *) ;
      END(* if *) ;
   END (* if *) ;
   CASE RelativeY OF
   0 , 1 , 2 :
      Header( RelativeY ) ;
|
   3 :
      AddText( "Buffer : " ) ;
      SensitiveBox( 0 , 0 , CurrentLevel + 1 , "Current" ) ;
      PadTo( 30 ) ;
      SensitiveBox( 1 , 0 , CurrentLevel + 1 , "Others" ) ;
      PadTo( 45 ) ;
      SensitiveBox( 2 , 0 , CurrentLevel + 1 , "Special" ) ;
|
   4 , 5 :
   ELSE
      CASE MenuPosition[ CurrentLevel + 1 ].X OF
      0 :
	 HelpBuffer( Buffers.Selected , RelativeY ) ;
	 MenuPosition[ CurrentLevel + 1 ].MaxY := 0 ;
   |
      1 :
	 IF RelativeY = 6 THEN
	    AddText( "No others at present" ) ;
	 END (* if *) ;
	 MenuPosition[ CurrentLevel + 1 ].MaxY := 3 ; (* How many others ?? *)
   |
      2 :
	 IF RelativeY = 6 THEN
	    AddText( "No specials at present" ) ;
	 END (* if *) ;
	 MenuPosition[ CurrentLevel + 1 ].MaxY := 5 ;(* How many specials ?? *)
      END (* case *) ;
   END (* case *) ;
END HelpBuffers ;

(*----------------------------------------------------------------------*)

END HelpBuffers.

