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

IMPLEMENTATION MODULE HelpKeys;

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

FROM Universe IMPORT EndOfLineCh, BYTE, Editing, EscapeCh, TabCh, HelpCh,
		     CatastrophyCh;

IMPORT Actions, List, Windows;

FROM Characters IMPORT ArrowShaftChar, RightArrowHeadChar,
		       LeftArrowHeadChar, UpArrowLeftChar,
		       LeftBracket, RightBracket,
		       UpArrowRightChar, DownArrowLeftChar,
		       DownArrowRightChar;


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

FROM Version IMPORT version; (* Clash if just import Version *)
IMPORT TimeAndDate;

IMPORT Debug;

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

TYPE FunctionKeyName  = ARRAY [ 0..4 ] OF CHAR;

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

VAR
   ExitCh	     : BYTE;
   FunctionKeyNames  : ARRAY [0..15] OF FunctionKeyName;
   ColumnsRequired   : BITSET;
   SelectedAction    : List.NameListP;

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

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

   VAR
      TimeString  : ARRAY [0..30] OF CHAR;
      Length	  : CARDINAL;
      NameP	  : List.NameListP;

   BEGIN
      IF (HelpLevel = CurrentLevel + 1) AND MenuPosition [CurrentLevel + 1].Virgin THEN
         WITH MenuPosition [CurrentLevel + 1] DO
  	    Virgin := FALSE;
	    Y := 0;
	    MinY := 0;
	    MaxY := 3;
	    X := 0;
	    MaxX := 0
         END (* with *);
         Changed := TRUE
      END (* if *);

      IF HelpLevel >= (CurrentLevel + 2) THEN

         IF SelectedSensitive (0, 0, CurrentLevel + 1) THEN
	    IF Actions.FindName (NameP, "Escape") THEN
	       Details (RelativeY, NameP)
	    END (* if *)
         ELSIF SelectedSensitive (0, 1, CurrentLevel + 1) THEN
	    IF Actions.FindName (NameP, "MoreHelp") THEN
	       Details (RelativeY, NameP)
	    END (* if *)
         ELSIF SelectedSensitive (0, 2, CurrentLevel + 1) THEN
	    IF Actions.FindName (NameP, "QuitEdit") THEN
	       Details (RelativeY, NameP)
	    END (* if *)
         ELSIF SelectedSensitive (0, 3, CurrentLevel + 1) THEN
	    IF Actions.FindName (NameP, "Disaster") THEN
	       Details (RelativeY, NameP)
	    END (* if *)
         END (* if *)

      ELSE

         CASE RelativeY OF
            0, 1, 2: Header (RelativeY)
         |  4:

 	    PadTo (20);
	    AddText ("Important    Keys")

         |  8:

 	    PadTo (21);
	    SensitiveBox (0, 0, CurrentLevel + 1, "Escape");
	    AddText ("  - Abandon current operation ( if any )")

         |  10:

	    PadTo (15);
	    SensitiveBox (0, 1, CurrentLevel + 1, "SHIFT-Escape");
	    AddText ("  - More detailed help in the current context")

         |  12:

	    PadTo (12);
	    SensitiveBox (0, 2, CurrentLevel + 1, "SHIFT-F3, Y(es)");
	    AddText ("  - Quit from the Editor")

         |  15:

	    PadTo (2);
	    SensitiveBox (0, 3, CurrentLevel + 1, "CTRL-SHIFT-Escape ( twice )");
	    AddText ("- Emergency return to Panos")

         |  19:

	    PadTo (5);
	    AddText ("Version  : ");
	    AddText (version)

         |  21:

	    IF TimeAndDate.TimeAndDate (TimeString, Length) >= 0 THEN
	       PadTo (5);
	       AddText ("Time now : ");
	       AddText (TimeString);
	    END (* if *)

         ELSE
         END (* case *)

      END (* if *)

   END HelpPrimativeKeys;

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

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

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

   PROCEDURE HelpFunctionKeyRow (F: CARDINAL);

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

      PROCEDURE CtrlName (F: CARDINAL; BaseCh: CHAR; Shifted: BOOLEAN);

         BEGIN
  	    IF Shifted THEN AddText ("Shift-")
	    ELSE AddChar (BYTE (' '))
 	    END (* if *);
	    AddText ("Ctrl-");
	    AddChar (BYTE (F + ORD (BaseCh)));
	    AddChar (BYTE (' '))
         END CtrlName;

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

      VAR
         I 		 : CARDINAL ;
         Action		 : List.NameListP ;
         Byte		 : BYTE ;

      BEGIN

         IF MenuPosition [CurrentLevel + 1].X <= 3 THEN
 	    AddChar (BYTE (' '));
	    AddText (FunctionKeyNames [F])
         ELSIF MenuPosition [CurrentLevel + 1].X < 8 THEN
	    CtrlName (F + 0, '@', MenuPosition [CurrentLevel + 1].X >= 6)
         ELSE
 	    CtrlName (F + 0, '0', TRUE)
         END (* if *);

         AddChar (BYTE ('|'));
         AddChar (BYTE (' '));

         FOR I := 0 TO 8 DO

 	    WITH MenuPosition [CurrentLevel + 1] DO
	       IF I IN ColumnsRequired THEN
	          CASE I OF
	             0..3: Byte := BYTE (080H + F + (I * 010H))
	          |  4:

                     (* CTRL-M is mapped differently *)

		     IF F = 00DH THEN Byte := BYTE (0C0H)
		     ELSE Byte := BYTE (F)
		     END (* if *)

	          |  5: Byte := BYTE (F + 010H)
	          |  6: Byte := BYTE (F + 0E0H)
	          |  7: Byte := BYTE (F + 0F0H)
	          |  8: Byte := BYTE (F + 0D0H)
	          END (* case *);
	          IF (I = 5) OR (I = 7) THEN
		     PadTo (40);
		     CtrlName (F + 010H, '@', I >= 6);
		     AddChar (BYTE ('|'));
		     AddChar (BYTE (' '))
	          END (* if *);
	          Actions.GetBoundAction (Action, Windows.Selected^.Buffer, Byte);
	          IF (X = I) AND (Y = F) AND (HelpLevel = CurrentLevel + 1) THEN
		     HighLight := TRUE;
		     ReplaceChar (BYTE (LeftBracket));
		     AddText (Action^.CurrentValue^.Text);
		     HighLight := FALSE;
		     AddChar (BYTE (RightBracket));
(*
		     Actions.GetBoundAction (SelectedAction, Windows.Selected^.Buffer, Byte);
*)
                     SelectedAction := Action
	          ELSE AddText (Action^.CurrentValue^.Text)
	          END (* if *);
	          HighLight := FALSE;
	          IF I + 1 IN ColumnsRequired THEN PadToNextColumn END;
	       END (* if *)
	    END (* with *)

         END (* for *);

         NewLine

      END HelpFunctionKeyRow;

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

   VAR
      I		: CARDINAL;
      F		: [0..15];
      EndLabel	: CARDINAL;

   BEGIN

      IF HelpLevel = CurrentLevel THEN ColumnsRequired := { 0..2 }
      ELSIF ( HelpLevel = CurrentLevel + 1 ) AND MenuPosition [CurrentLevel + 1].Virgin THEN
         WITH MenuPosition [CurrentLevel + 1] DO
  	    Virgin := FALSE;
	    Y := 0;
	    MinY := 0;
	    MaxY := 15;
	    X := 0;
	    MaxX := 8
         END (* with *);
         ColumnsRequired := {0..2};
         Changed := TRUE
      END (* if *);
      IF HelpLevel >= (CurrentLevel + 2) THEN Details (RelativeY, SelectedAction)
      ELSE
         CASE RelativeY OF
            0, 1, 2: Header (RelativeY)
         |  3: AddText ("  Current Function Key Actions :")
         |  4:

 	    WITH MenuPosition [CurrentLevel + 1] DO

	       IF ColumnsRequired = {0..2} THEN
	          IF X = 3 THEN ColumnsRequired := {1..3} END
	       ELSIF ColumnsRequired = {1..3} THEN
	          IF X = 4 THEN ColumnsRequired := {4..5}
 	          ELSIF X = 1 THEN ColumnsRequired := {0..2}
	          END (* if *)
  	       ELSIF ColumnsRequired = {4..5} THEN
	          IF X = 3 THEN ColumnsRequired := {1..3}
	          ELSIF X = 6 THEN ColumnsRequired := {6..7}
	          END (* if *)
	       ELSIF ColumnsRequired = {6..7} THEN
	          IF X = 5 THEN ColumnsRequired := {4..5}
	          ELSIF X = 8 THEN ColumnsRequired := {8}
	          END (* if *)
	       ELSIF ColumnsRequired = {8} THEN
	          IF X = 7 THEN ColumnsRequired := {6..7}
	          END (* if *)
 	       END (* if *);

	       IF ColumnsRequired * {0..3} # {} THEN
	          AddText (" Key");
	          PadTo (8 + 2);
	          EndLabel := 7
	       ELSIF {4, 5} * ColumnsRequired # {} THEN
	          EndLabel := 8
 	       ELSE
	          EndLabel := 13
 	       END (* if *);

	       IF 0 IN ColumnsRequired THEN
	          AddText ("on its own");
	          PadToNextColumn
 	       END (* if *);
	       IF 1 IN ColumnsRequired THEN
	          AddText ("with SHIFT");
	          PadToNextColumn
	       END (* if *);
	       IF 2 IN ColumnsRequired THEN
	          AddText ("with CTRL");
	          PadToNextColumn
	       END (* if *);
	       IF 3 IN ColumnsRequired THEN
	          AddText ("with SHIFT+CTRL")
	       END (* if *);
	       IF {4, 5} * ColumnsRequired # {} THEN
	          PadTo (30);
	          AddText ("Ctrl Keys")
	       END (* if *);
	       IF {6, 7} * ColumnsRequired # {} THEN
	          PadTo (25);
	          AddText ("Ctrl Keys with SHIFT")
	       END (* if *);
	       IF {8} * ColumnsRequired # {} THEN
	          PadTo (15);
	          AddText ("Ctrl Digit Keys with SHIFT")
	       END (* if *);

	    END (* with *)

         |  5:

	    PadTo (EndLabel);
	    FOR I := EndLabel TO HelpWindow^.Width - 2  DO
	       AddChar (BYTE ('-'))
	    END (* for *)

         |  6..(6 + 15):

	    HelpFunctionKeyRow (RelativeY - 6)

         ELSE
         END (* case *)

      END (* if *)

   END HelpFunctionKeys;

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

VAR
   F	 : [0..15];
   Name  : FunctionKeyName;

BEGIN
   ExitCh := BYTE (093H);
   FOR F := 0 TO 9 DO
      FunctionKeyNames [F] := "  Fx ";
      FunctionKeyNames [F][3] := CHAR (F + ORD ('0'))
   END (* for *);
   FunctionKeyNames [10] := " Tab ";
   FunctionKeyNames [11] := "Copy ";
   Name := "     ";
   Name [2] := CHAR (LeftArrowHeadChar);
   Name [3] := CHAR (ArrowShaftChar);
   FunctionKeyNames [12] := Name;
   Name [2] := CHAR (ArrowShaftChar);
   Name [3] := CHAR (RightArrowHeadChar);
   FunctionKeyNames [13] := Name;
   Name [2] := CHAR (DownArrowLeftChar);
   Name [3] := CHAR (DownArrowRightChar);
   FunctionKeyNames [14] := Name;
   Name [2] := CHAR (UpArrowLeftChar);
   Name [3] := CHAR (UpArrowRightChar);
   FunctionKeyNames [15] := Name

END HelpKeys.

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

