{$Debug}
{$PageSize:85}
Module Bar;
(*
(
(	FILENAME:	BarMod.Pas
(				Handles data collection for preparing a Bar Chart
(
(	CONTENTS:	GetBarData
(				SaveBarData
(				Bar_Chart
(
(	REVISION HISTORY
(
(	VERSION	DATE		BY	DESCRIPTION
(					
(
(	1.3.1	060486	CB	Loose highlight on bar name field if
(							bar value field has an invalid entry.
(	1.2		021786	CB	Allow retries in OpenDataFile
(	1.1		011086	CB	Fixed CodeS
(	1.0		120185	CB	First release
(
(
*)

Type
   Pointer     = Ads of Word;
   BarNameType = Array[1..5] of LString(20);
   BarGrpType  = Array[1..12] of LString(20);
   BarValueType= Array[1..12,1..5] of Real;
   LSFileSpec  = LString(50);

Const
   BarCode   = 0;
   Bars      = ' Bars';
   Cancel    = 7;
   CodeS     = 211;
   Code_s    = 243;
   ColorFmt  = '[sys]<sys>ColorBar.Fm';
   DownArrow = 11;
   DType     = 'Character.';
   F1        = 21;
   F3        = 23;
   F4        = 24;
   F5        = 25;
   F6        = 26;
   F8        = 29;
   F9        = 30;
   F10       = 31;
   Finish    = 4;
   Fmt       = 'ChgFmt';
   Go        = 27;
   Graph     = 'Graph';
   Groups    = 'Groups';
   ModeRead  = ReType(Word,'mr');
   ModeWrite = ReType(Word,'mw');
   MonoFmt   = '[sys]<sys>Bar.Fm';
   Next      = ' Next';
   NextPage  = 12;
   OverType  = 7;
   Prev      = ' Prev';
   PrevPage  = 5;
   Retrn     = 'Return';
   Saving    = 'Saving...';
   SaveCmplt = 'Save Complete';
   StatusFld = 'Status';
   UpArrow   = 1;
   Values    = 'Values';
   WaitMsg   = 'Please wait....';

Var [Extern]
   BarForm : Word;

Var
   BarGrpName  : BarGrpType;
   BarName     : BarNameType;
   BarTitle    : LSFileSpec;
   BarValue    : BarValueType;
   ByteRet     : Byte;
   cBarGrps    : Word;
   cBarsPerGrp : Word;
   cbRead      : Word;
   ChartType   : Word;
   DataRet     : LSFileSpec;
   ExitState   : Record
                    ich[0]       : Word;
                    ch[2]        : Word;
                    fAutoExit[4] : Boolean;
                    fModified[6] : Word;
                    fEmpty[8]    : Word;
                    Reserved[10] : Array[1..6] of Byte;
                 End;
   fDone       : Boolean;
   fGraph      : Boolean;
   FldName     : Array[1..20] of Lstring(13);
   FmFile      : LSFileSpec;
   Hdr         : Array[1..8] of Word;
   iBNames     : Integer;
   iBGNames    : Integer;
   FormColumn  : Integer;
   FormRow     : Integer;
   InitState   : Array[1..4] of Word;
   I,J         : Integer;
   Ok          : Boolean;
   PicFile     : LSFileSpec;
   Vals        : Lstring(20);
   xLabel      : LSFileSpec;
   yLabel      : LSFileSpec;

Value
   FldName[1] := 'BarTitle';
   FldName[2] := 'xAxis';
   FldName[3] := 'yAxis';
   FldName[4] := 'cBarGroups';
   FldName[5] := 'cBarsPerGroup';
   FldName[6] := 'BarData1';
   FldName[7] := 'BarData2';
   FldName[8] := 'BarData3';
   FldName[9] := 'BarData4';
   FldName[10] := 'BarData5';
   FldName[11] := 'BarData6';
   FldName[12] := 'BarData7';
   FldName[13] := 'BarData8';
   FldName[14] := 'BarData9';
   FldName[15] := 'BarData10';
   FldName[16] := 'BarData11';
   FldName[17] := 'BarData12';
   FldName[18] := 'Bar';
   FldName[19] := 'BRGrp';
   FldName[20] := 'Format';

{$Include:'Forms.Edf'}
{$Include:'Main.Edf'}
{$Include:'MiscMod.Edf'}

{
 Read the data file and load the data 
 into the appropriate variables.      
}
Procedure GetBarData(VarS DataFile : LSFileSpec);
Begin
   CheckErc(OpenDataFile(DataFile,ModeRead,False));
   CheckErc(ReadDataFile(Ads ChartType, 2, Ads CbRead));
   CheckErc(ReadDataFile(Ads Hdr[1], 16, Ads cbread));
   CheckErc(ReadDataFile(Ads cBarGrps, 2, Ads cbRead));
   CheckErc(ReadDataFile(Ads cBarsPerGrp, 2, Ads cbRead));
   For I := 1 To Ord(cBarGrps) Do
   Begin
       For J := 1 To Ord(cBarsPerGrp) Do
           CheckErc(ReadDataFile(Ads BarValue[I,J], 4, Ads cbRead));
   End;

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads PicFile[1], Wrd(ByteRet), Ads cbRead));
   PicFile.Len := Wrd(ByteRet);

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads FmFile[1], Wrd(ByteRet), Ads cbRead));
   FmFile.Len := Wrd(ByteRet);

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads DataFile[1], Wrd(ByteRet), Ads cbRead));
   DataFile.Len := Wrd(ByteRet);

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads BarTitle[1], Wrd(ByteRet), Ads cbRead));
   BarTitle.Len := Wrd(ByteRet);

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads xLabel[1], Wrd(ByteRet), Ads cbRead));
   xLabel.Len := Wrd(ByteRet);

   CheckErc(Read_a_Byte(Ads ByteRet));
   CheckErc(ReadDataFile(Ads yLabel[1], Wrd(ByteRet), Ads cbRead));
   yLabel.Len := Wrd(ByteRet);

   For I := 1 to Ord(cBarsPerGrp) Do 
   Begin
       CheckErc(Read_a_Byte(Ads ByteRet));
       CheckErc(ReadDataFile(Ads BarName[I,1], Wrd(ByteRet), Ads cbRead));
       BarName[I].Len := Wrd(ByteRet);
   End;

   For I := 1 to Ord(cBarGrps) Do 
   Begin
       CheckErc(Read_a_Byte(Ads ByteRet));
       CheckErc(ReadDataFile(Ads BarGrpName[I,1], Wrd(ByteRet), Ads cbRead));
       BarGrpName[I].Len := Wrd(ByteRet);
   End;
   CloseDataFile;
End;

{
 Write the BGP data file and append the 
 memory params to the end of the file   
}
Procedure SaveBarData(VarS DataFile : LSFileSpec);

Begin
   If fGraph
(**)
(*     If fGraph then check to see if file already exists    *)
(**)
     THEN
        Repeat
             cbRead := ULCMPB(Ads DataFile[Ord(DataFile.len3)], Ads '.dat',4);
             If cbRead <> FFFF Then ConCat(DataFile, '.Dat');
             Movesl(Ads DataFile[1],Ads PicFile[1],DataFile.Len4);
             PicFile.Len := DataFile.Len4;
        Until OverWriteOk(DataFile)
     ELSE
(**)
(* Used CODES, do not check for data file go ahead and save *)
(**)
        Begin
           cbRead := ULCMPB(Ads DataFile[Ord(DataFile.len3)], Ads '.dat',4);
           If cbRead <> FFFF Then ConCat(DataFile, '.Dat');
           Movesl(Ads DataFile[1],Ads PicFile[1],DataFile.Len4);
           PicFile.Len := DataFile.Len4;
        End;

  CheckErc(OpenDataFile(DataFile,ModeWrite,fGraph));
  (**)
  (* Write BGP data file *)
  (**)
   WriteDataFile(Ads BarCode,2);
   For I := 1 To 8 Do Hdr[I] := FFFF;
   WriteDataFile(Ads Hdr[1],16);
   WriteDataFile(Ads cBarGrps,2);
   WriteDataFile(Ads cBarsPerGrp,2);
   For I := 1 to Ord(cBarGrps) Do
   Begin
       For J := 1 to Ord(cBarsPerGrp) Do WriteDataFile(Ads BarValue[I,J],4);
   End;

  (**)
  (* Append parameters passed to BGP via memory (VLPB) *)
  (* to the end of the data file. This is done so that *)
  (* all data for a given graph is located in one file *)
  (* and can be easily recalled for Editing.           *)
  (**)
   If fGraph Then ParamInit(2048,8);

   If fGraph Then ParamSetSimple(1,PicFile);
   WriteDataFile(Ads PicFile[0], PicFile.len+1);

   If fGraph Then ParamSetSimple(2,FmFile);
   WriteDataFile(Ads FmFile[0], FmFile.len+1);

   If fGraph Then ParamSetSimple(3,DataFile);
   WriteDataFile(Ads DataFile[0], DataFile.len+1);

   If fGraph Then ParamSetSimple(4,BarTitle);
   WriteDataFile(Ads BarTitle[0], BarTitle.len+1);

   If fGraph Then ParamSetSimple(5,xLabel);
   WriteDataFile(Ads xLabel[0], xLabel.len+1);

   If fGraph Then ParamSetSimple(6,yLabel);
   WriteDataFile(Ads yLabel[0], yLabel.len+1);

   If fGraph Then ParamListStart(7);
   For I := 1 TO Ord(cBarsPerGrp) Do
   Begin
       If fGraph Then ParamSetNextInList(BarName[I]);
       WriteDataFile(Ads BarName[I].Len,BarName[I].Len+1);
   End;

   If fGraph Then ParamListStart(8);
   For I := 1 TO Ord(cBarGrps) Do
   Begin
       If fGraph Then ParamSetNextInList(BarGrpName[I]);
       WriteDataFile(Ads BarGrpName[I].Len,BarGrpName[I].Len+1);
   End;

   CloseDataFile;
End;

{
 1) Collects all the data from the BARFORM necessary to graph       
    a Line graph.                                                   
                                                                    
 fEdit will be TRUE if the Edit Function key has been pressed  or   
 all form fields have been accessed. DataSpec will then contain the 
 file spec of the data file.                                        
                                                                    
 Fields on the form are accessed by:                                
        setting FormColumn >  for the COLUMN the field is in    
        setting FormRow   >  for the ROW the field is in       
                                                                    
             FormColumn = 1     FormColumn = 2      FormColumn = 3  
                          
 FormRow = 1 Title                                                  
           2 X Axis Name                                            
           3 Y Axis Name                                            
           4  of Bar Grps                                          
           5  of BarsGrp                                          
           6 BarName[1]         BGrpName[1]         BarVal[1]       
           7 BarName[2]         BGrpName[2]         BarVal[2]       
           8 BarName[3]         BGrpName[3]         BarVal[3]       
           9 BarName[4]         BGrpName[4]         BarVal[4]       
          10 BarName[5]         BGrpName[5]         BarVal[5]       
          11                    BGrpName[6]                         
          12                    BGrpName[7]                         
          13                    BGrpName[8]                         
          14                    BGrpName[9]                         
          15                    BGrpName[10]                        
          16                    BGrpName[11]                        
          17                    BGrpName[12]                        
                                                                    
}
Procedure Bar_Chart(fEdit  : Boolean;
                    DataSpec : LSFileSpec);
Begin
   InitState[1] := 0;
   cBarGrps  := 0;
   cBarsPerGrp := 0;
   For I := 1 To 12 Do For J := 1 To 5 Do BarValue[I,J] := 0;
   iBNames := 1;
   iBGNames := 1;
   FormRow := 1;
   FormColumn := 1;

   DisplayFKeys;
   DisplayFunctionKey(10,Retrn,0);
   fDone := False;
   fGraph := False;
   CheckErc(DisplayForm(Ads BarForm, 0, 255, 255));

   If fEdit
     Then
        Begin
       (**)
       (* Go read the data file and display the data into *)
       (* the form.                                       *)
       (**)
           GetBarData(DataSpec);
           Write_the_FieldC(Ads BarForm, FldName[1], 0, Ads BarTitle[1],
                            BarTitle.Len);
           Write_the_FieldC(Ads BarForm, FldName[2], 0, Ads xLabel[1],
                            xLabel.Len);
           Write_the_FieldC(Ads BarForm, FldName[3], 0, Ads yLabel[1],
                            yLabel.Len);
           Write_the_FieldB(Ads BarForm, FldName[4], 0, Ads cBarGrps);
           Write_the_FieldB(Ads BarForm, FldName[5], 0, Ads cBarsPerGrp);
           For I := 1 To Ord(cBarsPerGrp) Do
           Write_the_FieldC(Ads BarForm, FldName[5+I], 1, Ads BarName[I,1],
                            BarName[I].Len);
           For I := 1 To Ord(cBarGrps) Do
           Write_the_FieldC(Ads BarForm, FldName[5+I], 2, Ads BarGrpName[I,1],
                            BarGrpName[I].Len);
           For I := 1 To Ord(cBarsPerGrp) Do
           Begin
              Ok := Encode(Vals,BarValue[1,I]:20:2);
              Write_the_FieldC(Ads BarForm, FldName[5+I], 3, Ads Vals[1],
                               Vals.Len);
           End;
           Write_the_FieldC(Ads BarForm, FldName[20], 0, Ads FmFile[1],
                            FmFile.Len);
        End
     ELSE
         Begin
        (**)
        (* Set up the default Format file to be used to    *)
        (* create the graph and display it to the form.    *)
        (**)
            If Color_Hdw Then FmFile := ColorFmt Else FmFile := MonoFmt;
            Write_the_FieldC(Ads BarForm, FldName[20], 0, Ads FmFile[1],
                             FmFile.Len);
         End;

   WHILE NOT(fDone) DO
   Begin
      If fEdit
         THEN [DisplayFunctionKey(1,Graph,4);
               DisplayFunctionKey(3,Fmt,5);
               DisplayFunctionKey(4,Bars,5);
               DisplayFunctionKey(5,Groups,5);
               DisplayFunctionKey(6,Values,5);
               CheckErc(SetKbdLed(OverType,True))]
         ELSE [DisplayFunctionKey(1,Graph,5);
               DisplayFunctionKey(3,Fmt,5);
               DisplayFunctionKey(4,Null,5);
               DisplayFunctionKey(5,Null,5);
               DisplayFunctionKey(6,Null,5);
               CheckErc(SetKbdLed(OverType,False))];
      If (cBarsPerGrp > 0) Then [DisplayFunctionKey(4,Bars,5);
                                 DisplayFunctionKey(5,Groups,5);
                                 DisplayFunctionKey(6,Values,5)];
      Case FormColumn of
      (**)
      (* If the FormRow is > 5 then the Title, XAxis   *)
      (* name, YAxis name, Number of Bar groups       *)
      (* Number of bars per group have been entered.   *)
      (* 
                                             *)
      (*    FormColumn = 1 is the BarName column.      *)
      (*    FormColumn = 2 is the BarGrpName column.   *)
      (*    FormColumn = 3 is the BarValue column.     *)
      (*                                               *)
      (* This Case statement writes the number of the  *)
      (* BarName, BarGrpName or the number of the      *)
      (* BarValue into the form, that is currently     *)
      (* being input.                                  *)
      (**)
           1 : If FormRow > 5 Then
               Begin
                  Write_the_FieldB(Ads BarForm, FldName[18], 1, Ads iBNames);
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[19,1],
                                        FldName[19].Len, 1));
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[18,1],
                                        FldName[18].Len, 2));
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[19,1],
                                        FldName[19].Len, 2));
                  DisplayFunctionKey(8,Null,5);
                  DisplayFunctionKey(9,Null,5)
               End;
           2 : Begin
                  Write_the_FieldB(Ads BarForm, FldName[19], 1, Ads iBGNames);
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[18,1],
                                        FldName[18].Len, 1));
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[18,1],
                                        FldName[18].Len, 2));
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[19,1],
                                        FldName[19].Len, 2));
                  DisplayFunctionKey(8,Null,5);
                  DisplayFunctionKey(9,Null,5)
               End;
           3 : Begin
                  Write_the_FieldB(Ads BarForm, FldName[18], 2, Ads iBNames);
                  Write_the_FieldB(Ads BarForm, FldName[19], 2, Ads iBGNames);
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[18,1],
                                        FldName[18].Len, 1));
                  CheckErc(DefaultField(Ads BarForm, Ads FldName[19,1],
                                        FldName[19].Len, 1));
                  If (FormRow >= 1) AND (FormRow <= 5)
                     Then [DisplayFunctionKey(8,Null,5);
                           DisplayFunctionKey(9,Null,5);
                           CheckErc(DefaultField(Ads BarForm,Ads FldName[18,1],
                                                 FldName[18].Len,2));
                           CheckErc(DefaultField(Ads BarForm,Ads FldName[19,1],
                                                 FldName[19].Len,2));
                           CheckErc(SetFieldAttrs(Ads BarForm,
                                                  Ads FldName[iBGNames+5,1],
                                              FldName[iBGNames+5].Len, 2, 0));]
                     Else [CheckErc(SetFieldAttrs(Ads BarForm,
                                    Ads FldName[iBNames+5,1],
                                    FldName[iBNames+5].Len, 1, 5));
                           CheckErc(SetFieldAttrs(Ads BarForm,
                                    Ads FldName[iBGNames+5,1],
                                    FldName[iBGNames+5].Len, 2, 5));
                           DisplayFunctionKey(8,Prev,4);
                           DisplayFunctionKey(9,Next,4)];
                  If (FormRow = 6) OR (ExitState.ch = F6) Then
                  Begin
                     For I := 1 TO Ord(cBarsPerGrp) Do
                     Begin
                        CheckErc(DefaultField(Ads BarForm, Ads FldName[I+5,1],
                                 FldName[I+5].Len, 3));
                        If (BarValue[iBGNames,I] <> 0) OR fEdit Then
                        Begin
                            Ok := Encode(Vals,BarValue[iBGNames,I]:20:2);
                            Write_the_FieldC(Ads BarForm, FldName[I+5], 3,
                                             Ads Vals[1], Vals.Len)
                        End
                     End
                  End
               End {Case of 3}
            Otherwise ;
      End;{Case}

      Ok := FALSE;
      WHILE NOT(Ok) DO
      Begin
     (**)
     (* Ok will be set to TRUE if the data entered for *)
     (* the form field is appropriate for that field.  *)
     (* Data read from the field in the form is        *)
     (* returned in the LString DataRet.               *)
     (**)

         Read_The_FieldC(Ads BarForm, FldName[FormRow], Wrd(FormColumn), DataRet, Upper(DataRet), Ads ExitState);
         WriteStatusLine(Ads BarForm, Null, 0, False);

         If (FormColumn = 3) AND THEN (FormRow5 = Ord(cBarsPerGrp)) Then
            CheckErc(SetFieldAttrs(Ads BarForm, Ads FldName[iBGNames+5,1],
                                   FldName[iBGNames+5].Len, 2, 0));
         Case FormRow Of 
         (**)
         (* Based on which Row and Column is active on  *)
         (* the form this case statement knows what data*)
         (* is being input and does the appropriate     *)
         (* checks and places the entered data in the   *)
         (* appropriate variable.                       *)
         (**)
             1 : [BarTitle := DataRet;
                  RemoveBlanks(BarTitle,DataSpec);
                  If DataSpec.Len = 0
                    Then Ok := False
                    Else [Ok := True;FormColumn := 1;iBNames := 1;iBGNames := 1];
                  Case ExitState.ch Of
                       F10, Finish, Cancel : Ok := True;
                     Otherwise ;
                  End;
                  If Not(OK) Then [Beep; WriteStatusLine(Ads BarForm,
                                         'An entry is required', 0,False)]];
             2 : [xLabel := DataRet; FormColumn := 1; Ok := True];
             3 : [yLabel := DataRet; FormColumn := 1; Ok := True];
             4 : [RemoveBlanks(DataRet,DataRet); FormColumn := 1;
                  Ok := Decode(DataRet,cBarGrps);
                  If (cBarGrps <= 0) OR (cBarGrps > 12) Then Ok := False;
                    Case ExitState.ch Of
                        F10, Finish, Cancel, UpArrow : Ok := True;
                      Otherwise ;
                    End;
                  If Not(OK) Then [Beep; WriteStatusLine(Ads BarForm,
                                       'Valid entries are 1  12.', 0,False)]];
             5 : [RemoveBlanks(DataRet,DataRet);
                  Ok := Decode(DataRet,cBarsPerGrp);
                  If (cBarsPerGrp <= 0) OR (cBarsPerGrp > 5) Then Ok := False;
                  Case ExitState.ch Of
                       F10, Finish, Cancel, UpArrow : Ok := True;
                    Otherwise ;
                  End;
                  If Not(OK) Then [Beep; WriteStatusLine(Ads BarForm,
                                        'Valid entries are 1  5.', 0,False)]];
         Otherwise  [Case FormColumn Of
                         1 : [BarName[iBNames]    := DataRet; Ok := True];
                         2 : [BarGrpName[iBGNames] := DataRet; Ok := True];
                         3 : [CheckErc(SetFieldAttrs(Ads BarForm,
                              Ads FldName[iBNames+5,1], FldName[iBNames+5].Len,
                              1, 0)); RemoveBlanks(DataRet,DataRet);
                              Ok := Decode(DataRet,BarValue[iBGNames,iBNames]);
                              Case ExitState.ch Of
                                     F10, Finish, Cancel, UpArrow : Ok := True;
                                  Otherwise ;
                              End;
                              If Not(OK)
                                 Then [Beep;
                                      CheckErc(SetFieldAttrs(Ads BarForm,
                                               Ads FldName[iBNames+5,1],
                                               FldName[iBNames+5].Len,1, 5));
                                       WriteStatusLine(Ads BarForm,
                                       'A Number is required', 0,False)]];
                         Otherwise ;
                    End];{Case of FormColumn}
         End;{Case of FormRow}
      End; {While Not(OK)}

      Case ExitState.ch of
     (**)
     (* This case statement checks the value of *)
     (* the keyboard key used to terminate the  *)
     (* current form field.                     *)
     (**)
        CodeS,
        Code_s   : If DataSpec.Len <> 0 Then
                     [WriteStatusLine(Ads BarForm, Saving, 0, False);
                      SaveBarData(DataSpec);
                      WriteStatusLine(Ads BarForm, SaveCmplt, 0, False)];
        F1,Go    : If fEdit Then [fDone := TRUE; fGraph := TRUE];
        F10      : [fDone := True; fGraph := FALSE];
        Finish   : ConfirmFinish;
        Cancel   : WriteStatusLine(Ads BarForm, Null, 0, False);
        F3       : Read_The_FieldC(Ads BarForm, FldName[20], 0, FmFile,
                                   Upper(FmFile), Ads ExitState);
        F4       : [CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBNames+5,1], FldName[iBNames+5].Len,1,0));
                    CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBGNames+5,1], FldName[iBGNames+5].Len,2,0));
                    DisplayFunctionKey(8,Null,5);DisplayFunctionKey(9,Null,5);
                    If fEdit OR (cBarsPerGrp > 0)
                    THEN [FormColumn := 1; FormRow := iBNames+5]];
        F5       : [CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBNames+5,1], FldName[iBNames+5].Len,1,0));
                    CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBGNames+5,1], FldName[iBGNames+5].Len,2,0));
                    DisplayFunctionKey(8,Null,5);DisplayFunctionKey(9,Null,5);
                    If fEdit OR (cBarsPerGrp > 0)
                    THEN [FormColumn := 2; FormRow := iBGNames+5]];
        F6       : [If fEdit OR (cBarsPerGrp > 0)
                    THEN [FormColumn := 3; FormRow := iBNames+5]];
     F8,PrevPage : If (FormColumn = 3) AND THEN (FormRow > 5) Then
                   [CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBGNames+5,1], FldName[iBGNames+5].Len,2,0));
                    If iBGNames <> 1
                      Then [iBGNames := iBGNames 1;iBNames := 1; FormRow := 6]];
     F9,NextPage : If (FormColumn = 3) AND THEN (FormRow > 5) Then
                   [CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBGNames+5,1], FldName[iBGNames+5].Len, 2, 0));
                    If iBGNames <> Ord(cBarGrps)
                      Then [iBGNames := iBGNames +1 ;iBNames := 1;FormRow := 6]];
        UpArrow  : If FormRow = 1
                       THEN {Do nothing}
                       ELSE [FormRow := FormRow 1;
                             If FormRow > 5
                             Then
                                Begin
                                   Case FormColumn of
                                      1 : iBNames  := FormRow  5;
                                      2 : iBGNames := FormRow  5;
                                      3 : iBNames  := FormRow  5;
                                    Otherwise ;
                                   End
                                End];
        DownArrow: [Case FormRow of
                       1 : FormRow := FormRow +1;
                       2 : FormRow := FormRow +1;
                       3 : FormRow := FormRow +1;
                       4 : FormRow := FormRow +1;
                       5 : FormRow := FormRow +1;
                   6..17 : [Case FormColumn of
                              1 : If FormRow5 = Ord(cBarsPerGrp)
                                     Then [FormRow :=6;iBNames := FormRow5]
                                     Else [FormRow :=FormRow +1;iBNames := FormRow5];
                              2 : If FormRow5 = Ord(cBarGrps)
                                     Then [FormRow:= 6;iBGNames := FormRow5]
                                     Else [FormRow :=FormRow+1;iBGNames := FormRow5];
                              3 : If FormRow5 = Ord(cBarsPerGrp)
                                     Then [FormRow := 6; iBNames := 1;]
                                     Else [FormRow := FormRow +1;iBNames := iBNames +1;];
                               Otherwise ;
                            End];{Case of FormColumn}
                      Otherwise ;
                    End];{Case of FormRow}
       Otherwise  [Case FormRow of
                       1 : FormRow := FormRow +1;
                       2 : FormRow := FormRow +1;
                       3 : FormRow := FormRow +1;
                       4 : FormRow := FormRow +1;
                       5 : FormRow := FormRow +1;
                   6..17 : [Case FormColumn of
                              1 : If FormRow5 = Ord(cBarsPerGrp)
                                     Then [FormRow :=6; FormColumn := 2;iBNames:=1]
                                     Else [FormRow :=FormRow+1;iBNames := FormRow5];
                              2 : If FormRow5 = Ord(cBarGrps)
                                     Then [FormRow :=6; FormColumn :=3;iBGNames:=1]
                                     Else [FormRow :=FormRow +1;iBGNames:=FormRow5];
                              3 : Begin
                                     If (iBNames = Ord(cBarsPerGrp)) AND
                                        (iBGNames = Ord(cBarGrps))
                                       Then [FormRow := 1; fEdit := True]
                                       Else Begin
                                              If FormRow5 = Ord(cBarsPerGrp)
                                                Then [FormRow := 6; iBNames := 1;
                                                      iBGNames := iBGNames +1;]
                                                Else [FormRow := FormRow +1;
                                                      iBNames := iBNames +1;];
                                            End;
                                  End;
                               Otherwise ;
                            End];{Case of FormColumn}
                      Otherwise ;
                    End];{Case of FormRow}

      End;{Case of ExitState.ch}

  (**)
  (* Check that all required fields have been entered, *)
  (* if not, set the form row  column to where the    *)
  (* entry is in error and activate that field.        *)
  (**)
   If (fDone AND fGraph) Then
      For I := Ord(cBarsPerGrp) DownTo 1 Do If BarName[I].Len = 0 Then
         Begin
            Beep;
            WriteStatusLine(Ads BarForm, 'Invalid or missing entry.',0,False);
            iBNames := I;
            FormRow := iBNames+5;
            FormColumn := 1;
            fDone := False
         End;

   If (fDone AND fGraph) Then
      For I := Ord(cBarGrps) DownTo 1 Do If BarGrpName[I].Len = 0 Then
         Begin
            Beep;
            WriteStatusLine(Ads BarForm, 'Invalid or missing entry.',0,False);
            iBGNames := I;
            FormRow := iBGNames+5;
            FormColumn := 2;
            fDone := False
         End;

   End; {While Not(fDone)}

   CheckErc(UnDisplayForm(Ads BarForm));
   If fGraph Then [SaveBarData(DataSpec);
                   ZipBGP];

End;{Procedure}
End.
If (FormColumn = 3) AND THEN (FormRow > 5) Then
                   [CheckErc(SetFieldAttrs(Ads BarForm,
                    Ads FldName[iBGNames+5,1], FldName[iBGNames+5].Len, 2, 0));
                    If iBGNames <> Ord(cBarGrps)
                      Then [iBGNames := iBGNames +1 ;iBNames := 