{$Debug}
Module Pie;
(*
(
(	FILENAME:	PieMod.Pas
(				Handles data collection for preparing a Pie Chart
(
(	CONTENTS:	GetPieData
(				SavePieData
(				Pie_Chart
(
(	REVISION HISTORY
(
(	VERSION	DATE		BY	DESCRIPTION
(					
(
(	2.1		112688	CB	Supports OFIS Graphics (16 Pie Slices)
(	1.2		021786	CB	Allow retries in OpenDataFile
(	1.1		011086	CB	Fixed CodeS
(	1.0		120185	CB	First release
(
(
*)

TYPE 
   ExitStateType =  RECORD
                       ich[0]       :  WORD;
                       ch[2]        :  WORD;
                       fAutoExit[4] :  BOOLEAN;
                       fModified[6] :  WORD;
                       fEmpty[8]    :  WORD;
                       Reserved[10] :  ARRAY[1..6] OF BYTE;
                    END;
   LSFileSpec    =  LSTRING(50);
   Pointer       =  ADS OF WORD;
   SliceNameType =  ARRAY[1..16] OF LSTRING(20);
   SliceValueType =  ARRAY[1..16] OF Real;

CONST 
   Cancel    =  7;
   CodeS     =  211;
   Code_s    =  243;
   ColorFmt  =  '[sys]<sys>ColorPie.Fm';
   DownArrow =  11;
   DType     =  'Character.';
   F1        =  21;
   F3        =  23;
   F4        =  24;
   F5        =  25;
   F10       =  31;
   Finish    =  4;
   Fmt       =  'ChgFmt';
   Go        =  27;
   Graph     =  'Graph';
   ModeRead  =  ReType(WORD,'mr');
   ModeWrite =  ReType(WORD,'mw');
   MonoFmt   =  '[sys]<sys>Pie.Fm';
   Names     =  'Names';
   OverType  =  7;
   PieCode   =  1;
   Retrn     =  'Return';
   Saving    =  'Saving...';
   SaveCmplt =  'Save Complete';
   UpArrow   =  1;
   Values    =  'Values';

VAR [EXTERN]
   PieForm :  WORD;

VAR 
   ByteRet     :  BYTE;
   cbRead      :  WORD;
   ChartType   :  WORD;
   Color       :  BOOLEAN;
   cSlices     :  Integer;
   DataRet     :  LSTRING(32);
   ExitState   :  ExitStateType;
   fDone,Ok    :  BOOLEAN;
   fGraph      :  BOOLEAN;
   FldName     :  ARRAY[1..20] OF LSTRING(14);
   FmFile      :  LSFileSpec;
   FormColumn  :  Integer;
   FormRow     :  Integer;
   Hdr         :  ARRAY[1..8] OF WORD;
   I           :  Integer;
   InitState   :  ARRAY[1..4] OF WORD;
   PicFile     :  LSFileSpec;
   PieTitle    :  LSFileSpec;
   SliceName   :  SliceNameType;
   SliceNumber :  Integer;
   SliceValue  :  SliceValueType;
   SlVals      :  LSTRING(18);

   VALUE
   FldName[1]  := 'PieTitle';
   FldName[2]  := 'NumberofSlices';
   FldName[3]  := 'SliceData1';
   FldName[4]  := 'SliceData2';
   FldName[5]  := 'SliceData3';
   FldName[6]  := 'SliceData4';
   FldName[7]  := 'SliceData5';
   FldName[8]  := 'SliceData6';
   FldName[9]  := 'SliceData7';
   FldName[10] := 'SliceData8';
   FldName[11] := 'SliceData9';
   FldName[12] := 'SliceData10';
   FldName[13] := 'SliceData11';
   FldName[14] := 'SliceData12';
   FldName[15] := 'SliceData13';
   FldName[16] := 'SliceData14';
   FldName[17] := 'SliceData15';
   FldName[18] := 'SliceData16';
   FldName[19] := 'Slice';
   FldName[20] := 'Format';

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

{
 Read the data from the data file and load  
 into the appropriate variables.            
}

PROCEDURE GetPieData(VARS DataFile : LSFileSpec );

BEGIN
   CheckErc(OpenDataFile(DataFile,ModeRead,False));

   CheckErc(ReadDataFile(ADS ChartType,2, ADS cbRead));
   CheckErc(ReadDataFile(ADS Hdr,16, ADS cbRead));
   CheckErc(ReadDataFile(ADS cSlices,2, ADS cbRead));
   FOR I := 1 TO Ord(cSlices) DO
      CheckErc(ReadDataFile(ADS SliceValue[I],4,ADS cbRead));

   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 PieTitle[1],Wrd(ByteRet),ADS cbRead));
   PieTitle.Len := Wrd(ByteRet);

   FOR I := 1 TO Ord(cSlices) DO
      BEGIN
         CheckErc(Read_A_Byte(ADS ByteRet));
         CheckErc(ReadDataFile(ADS SliceName[I,1], Wrd(ByteRet),ADS cbRead));
         SliceName[I].Len := Wrd(ByteRet);
      END;

   CloseDataFile;
END;

{
 Save data entered for this pie chart 
}

PROCEDURE SavePieData(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 PieCode, 2);
   FOR I := 1 TO 8 DO
      Hdr[I] := FFFF;
   WriteDataFile(ADS Hdr[1],16);
   WriteDataFile(ADS cSlices, 2);
   FOR I := 1 TO Ord(cSlices) DO
      WriteDataFile(ADS SliceValue[I], 4);

(**)
(* 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, 5);

   WriteDataFile(ADS PicFile[0],PicFile.Len+1);
   IF fGraph
      THEN ParamSetSimple(1, PicFile);

   WriteDataFile(ADS FmFile, FmFile.Len+1);
   IF fGraph
      THEN ParamSetSimple(2, FmFile);

   WriteDataFile(ADS DataFile[0],DataFile.Len+1);
   IF fGraph
      THEN ParamSetSimple(3, DataFile);

   WriteDataFile(ADS PieTitle[0],PieTitle.Len+1);
   IF fGraph
      THEN ParamSetSimple(4, PieTitle);

   IF fGraph
      THEN ParamListStart(5);
   FOR I := 1 TO Ord(cSlices) DO
      BEGIN
         WriteDataFile(ADS SliceName[I].Len,Wrd(SliceName[I].Len)+1);
         IF fGraph
            THEN ParamSetNextInList(SliceName[I]);
      END;
   FOR I := 1 TO Ord(cSlices) DO
      BEGIN
         WriteDataFile(ADS SliceName[I].Len,Wrd(SliceName[I].Len)+1);
      END;
   CloseDataFile;

END;

{
 1) Collects all the data from the PIEFORM necessary to graph      
    a Pie chart.                                                   
 2) Chains to the graphics software                                
                                                                   
 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            
                                       
 FormRow = 1 Title                                                 
           2 Number of Slices                                      
           3 SliceName[1]                SliceAmount[1]            
           4 SliceName[2]                SliceAmount[2]            
           5 SliceName[3]                SliceAmount[3]            
           6 SliceName[4]                SliceAmount[4]            
           7 SliceName[5]                SliceAmount[5]            
           8 SliceName[6]                SliceAmount[6]            
           9 SliceName[7]                SliceAmount[7]            
          10 SliceName[8]                SliceAmount[8]            
                                                                   
}

PROCEDURE Pie_Chart(fEdit    : BOOLEAN;
                    DataSpec : LSFileSpec;
                    fBTOSIIGraphics : Boolean );
BEGIN
   cSlices := 0;
   DisplayFKeys;
   DisplayFunctionKey(10,Retrn,0);
   fDone := False;
   fGraph := False;
   FormRow := 1;
   InitState[1] := 0;
   FormColumn := 1;
   SliceNumber := 1;
   CheckErc(DisplayForm(ADS PieForm, 0, 255,255));

   IF fEdit
      THEN
(**)
(* Go read the data file and display the data into *)
(* the form.                                       *)
(**)
         BEGIN
            GetPieData(DataSpec);
            Write_the_FieldC(ADS PieForm, FldName[1], 0, ADS PieTitle[1],
                             PieTitle.Len);
            Write_the_FieldB(ADS PieForm, FldName[2], 0, ADS cSlices);
            FOR I := 1 TO Ord(cSlices) DO
               BEGIN
                  Write_The_FieldC(ADS PieForm, FldName[I+2], 1,
                                   ADS SliceName[I,1], Wrd(SliceName[I].Len));
                  Ok := Encode(SlVals,SliceValue[I]:18:2);
                  Write_the_FieldC(ADS PieForm, FldName[I+2], 2, ADS SlVals[1],
                                   SlVals.Len);
               END;
            Write_the_FieldC(ADS PieForm, FldName[20], 0, ADS FmFile[1],
                             FmFile.Len);
         END
      ELSE
(**)
(* Set up the default Format file to be used to    *)
(* create the graph and display it to the form.    *)
(**)
         BEGIN
            IF Color_Hdw
               THEN FmFile := ColorFmt
               ELSE FmFile := MonoFmt;
            Write_the_FieldC(ADS PieForm, FldName[20], 0, ADS FmFile[1],
                             FmFile.Len);
         END;

   WHILE NOT(fDone) DO
      BEGIN
         IF fEdit
            THEN
               BEGIN
                  CheckErc(SetKbdLed(OverType,True));
                  DisplayFunctionKey(1 ,Graph,4);
                  DisplayFunctionKey(3,Fmt,0);
                  DisplayFunctionKey(4,Names,0);
                  DisplayFunctionKey(5,Values,0)
               END
            ELSE
               BEGIN
                  CheckErc(SetKbdLed(OverType,False));
                  DisplayFunctionKey(1 ,Graph,0);
                  DisplayFunctionKey(3,Fmt,0);
                  DisplayFunctionKey(4,Null,0);
                  DisplayFunctionKey(5,Null,0)
               END;
         CASE FormColumn OF
(**)
(* If the FormRow is > 2 then the Title  Number *)
(* of Slices have been entered.                  *)
(*    FormColumn = 1 is the SliceName column.    *)
(*    FormColumn = 2 is the SliceValue column.   *)
(*                                               *)
(* This Case statement writes the number of the  *)
(* SliceName or the number of the SliceValue     *)
(* into the form, that the user is currently     *)
(* inputting.                                    *)
(**)
            1 :  IF FormRow > 2
                    THEN
                       BEGIN
                          DisplayFunctionKey(4,Names,0);
                          DisplayFunctionKey(5,Values,0);
                          Write_the_FieldB(ADS PieForm, FldName[19],
                                           Wrd(FormColumn), ADS SliceNumber);
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 2));
                       END
                    ELSE
                       BEGIN
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 2));
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 1))
                       END;
            2 :  IF FormRow > 2
                    THEN
                       BEGIN
                          DisplayFunctionKey(4,Names,0);
                          DisplayFunctionKey(5,Values,0);
                          Write_the_FieldB(ADS PieForm, FldName[19],
                                           Wrd(FormColumn), ADS SliceNumber);
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 1));
                       END
                    ELSE
                       BEGIN
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 2));
                          CheckErc(DefaultField(ADS PieForm, ADS FldName[19,1],
                                                FldName[19].Len, 1))
                       END;
      END;

   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 PieForm, FldName[FormRow], Wrd(FormColumn),
                         DataRet, Upper(DataRet), ADS ExitState);
         WriteStatusLine(ADS PieForm, Null, 0, False);
         IF (FormRow2 = cSlices) AND (FormColumn = 2)
            THEN fEdit := TRUE;

         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 :  BEGIN
                    PieTitle := DataRet;
                    RemoveBlanks(PieTitle,DataSpec);
                    IF DataSpec.Len = 0
                       THEN Ok := False
                       ELSE
                          BEGIN
                             Ok := True;
                             FormColumn := 1
                          END;
                    CASE ExitState.ch OF
                       F10, Finish, Cancel :  Ok := True;
                    OTHERWISE ;
                    END;
                    IF NOT(OK)
                       THEN
                          BEGIN
                             Beep;
                             WriteStatusLine(ADS PieForm,
                                             'An entry is required', 0,False)
                          END
                 END;
            2 :  BEGIN
                    RemoveBlanks(DataRet,DataRet);
                    Ok := Decode(DataRet,cSlices);
                    IF Not fBTOSIIGraphics AND THEN (cSlices <= 0) OR (cSlices > 8)
                       THEN Ok := False;
                    IF fBTOSIIGraphics AND THEN (cSlices <= 0) OR (cSlices > 16)
                       THEN Ok := False;
                    CASE ExitState.ch OF
                       F10, Finish, Cancel, UpArrow :  Ok := True;
                    OTHERWISE ;
                    END;
                    IF NOT(OK)
                       THEN
                          BEGIN
                             Beep;
                             If NOT fBTOSIIGraphics THEN WriteStatusLine(ADS PieForm,'Valid entries are 1  8.',0,False);
                             If fBTOSIIGraphics THEN WriteStatusLine(ADS PieForm,'Valid entries are 1  16.',0,False)
                          END
                 END;
         OTHERWISE
            BEGIN
               IF FormColumn = 1
                  THEN
                     BEGIN
                        SliceName[FormRow2] := DataRet;
                        Ok := True
                     END
                  ELSE
                     BEGIN
                        RemoveBlanks(DataRet,DataRet);
                        Ok := Decode(DataRet,SliceValue[FormRow2]);
                        CASE ExitState.ch OF
                           F10, Finish, Cancel, UpArrow :  Ok := True;
                        OTHERWISE ;
                        END;
                        IF NOT(OK)
                           THEN
                              BEGIN
                                 Beep;
                                 WriteStatusLine(ADS PieForm,'A number is required',0,False)
                              END
                     END
            END;
         END;
      END; {While Not(Ok)}

(**)
(* This case statement checks the value of *)
(* the keyboard key used to terminate the  *)
(* current form field.                     *)
(**)
   CASE ExitState.Ch OF
      CodeS,
      Code_s:  IF DataSpec.Len <> 0
                  THEN
                     BEGIN
                        WriteStatusLine(ADS PieForm, Saving, 0, False);
                        SavePieData(DataSpec);
                        WriteStatusLine(ADS PieForm, SaveCmplt, 0, False)
                     END;
      F1,Go :  IF fEdit
                  THEN
                     BEGIN
                        fDone := True;
                        fGraph := True
                     END;
      F10   :  BEGIN
                  fDone := True;
                  fGraph := False
               END;
      F3    :  Read_The_FieldC(ADS PieForm, FldName[20], 0, FmFile,Upper(FmFile), ADS ExitState);
      F4    :  IF fEdit OR (cSlices > 0)
                  THEN
                     BEGIN
                        FormColumn := 1;
                        IF FormRow < 3
                           THEN FormRow := 3
                     END;
      F5    :  IF fEdit OR (cSlices > 0)
                  THEN
                     BEGIN
                        FormColumn := 2;
                        IF FormRow < 3
                           THEN FormRow := 3
                     END;
      Cancel:  WriteStatusLine(ADS PieForm, Null, 0, False);
      Finish:  ConfirmFinish;
      UpArrow:  IF FormRow = 1
                   THEN Don't do anything
                   ELSE FormRow := FormRow 1;
      DownArrow:  BEGIN
                     IF FormRow = cSlices+2
                        THEN
                           BEGIN
                              IF FormColumn = 1
                                 THEN
                                    BEGIN
                                       FormRow := 3
                                    END
                                 ELSE
                                    BEGIN
                                       fEdit := TRUE;
                                       FormRow := 3
                                    END
                           END
                        ELSE FormRow := FormRow + 1
                  END;
   OTHERWISE
      BEGIN
         IF FormRow = cSlices+2
            THEN
               BEGIN
                  IF FormColumn = 1
                     THEN
                        BEGIN
                           FormColumn := 2;
                           FormRow := 3
                        END
                     ELSE
                        BEGIN
                           fEdit := TRUE;
                           FormRow := 1
                        END
               END
            ELSE FormRow := FormRow + 1
      END;
   END;
   SliceNumber := FormRow  2;

(**)
(* 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(cSlices) DOWNTO 1 DO
              IF SliceValue[I] <= 0
                 THEN
                    BEGIN
                       Beep;
                       WriteStatusLine(ADS PieForm,'Invalid or missing entry.', 0,False);
                       SliceNumber := I;
                       FormRow := SliceNumber+2;
                       FormColumn := 2;
                       fDone := False
                    END;

   IF (fDone AND fGraph)
      THEN FOR I := Ord(cSlices) DOWNTO 1 DO
              IF SliceName[I].Len = 0
                 THEN
                    BEGIN
                       Beep;
                       WriteStatusLine(ADS PieForm,
                                       'Invalid or missing entry.', 0,False);
                       SliceNumber := I;
                       FormRow := SliceNumber+2;
                       FormColumn := 1;
                       fDone := False
                    END;

END; {While Not(fDone)}

CheckErc(UnDisplayForm(ADS PieForm));
IF fGraph
   THEN
      BEGIN
         SavePieData(DataSpec);
         ZipBGP
      END;
END;
END.
  ELSE
                     BEGIN
          